Skip to content

Commit

Permalink
Merge pull request #39248 from nextcloud/custom-properties-preload
Browse files Browse the repository at this point in the history
preload custom properties when propfinding folders
  • Loading branch information
icewind1991 authored Jul 10, 2023
2 parents ed55c54 + 95c3b81 commit f152aef
Showing 1 changed file with 42 additions and 2 deletions.
44 changes: 42 additions & 2 deletions apps/dav/lib/DAV/CustomPropertiesBackend.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/

namespace OCA\DAV\DAV;

use Exception;
use OCA\DAV\Connector\Sabre\Directory;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IDBConnection;
use OCP\IUser;
Expand Down Expand Up @@ -134,7 +136,8 @@ class CustomPropertiesBackend implements BackendInterface {
public function __construct(
Tree $tree,
IDBConnection $connection,
IUser $user) {
IUser $user
) {
$this->tree = $tree;
$this->connection = $connection;
$this->user = $user;
Expand Down Expand Up @@ -180,6 +183,11 @@ public function propFind($path, PropFind $propFind) {
return;
}

$node = $this->tree->getNodeForPath($path);
if ($node instanceof Directory && $propFind->getDepth() !== 0) {
$this->cacheDirectory($path, $node);
}

// First fetch the published properties (set by another user), then get the ones set by
// the current user. If both are set then the latter as priority.
foreach ($this->getPublishedProperties($path, $requestedProps) as $propName => $propValue) {
Expand Down Expand Up @@ -262,6 +270,38 @@ private function getPublishedProperties(string $path, array $requestedProperties
return $props;
}

/**
* prefetch all user properties in a directory
*/
private function cacheDirectory(string $path, Directory $node): void {
$prefix = ltrim($path . '/', '/');
$query = $this->connection->getQueryBuilder();
$query->select('name', 'propertypath', 'propertyname', 'propertyvalue', 'valuetype')
->from('filecache', 'f')
->leftJoin('f', 'properties', 'p', $query->expr()->andX(
$query->expr()->eq('propertypath', $query->func()->concat(
$query->createNamedParameter($prefix),
'name'
)),
$query->expr()->eq('userid', $query->createNamedParameter($this->user->getUID()))
))
->where($query->expr()->eq('parent', $query->createNamedParameter($node->getInternalFileId(), IQueryBuilder::PARAM_INT)));
$result = $query->executeQuery();

$propsByPath = [];

while ($row = $result->fetch()) {
$childPath = $prefix . $row['name'];
if (!isset($propsByPath[$childPath])) {
$propsByPath[$childPath] = [];
}
if (isset($row['propertyname'])) {
$propsByPath[$childPath][$row['propertyname']] = $this->decodeValueFromDatabase($row['propertyvalue'], $row['valuetype']);
}
}
$this->userCache = array_merge($this->userCache, $propsByPath);
}

/**
* Returns a list of properties for the given path and current user
*
Expand Down Expand Up @@ -321,7 +361,7 @@ private function updateProperties(string $path, array $properties): bool {
$dbParameters = [
'userid' => $this->user->getUID(),
'propertyPath' => $this->formatPath($path),
'propertyName' => $propertyName
'propertyName' => $propertyName,
];

// If it was null, we need to delete the property
Expand Down

0 comments on commit f152aef

Please sign in to comment.