]> source.dussan.org Git - nextcloud-server.git/commitdiff
preload custom properties when propfinding folders 39293/head
authorRobin Appelman <robin@icewind.nl>
Sun, 9 Jul 2023 00:41:10 +0000 (02:41 +0200)
committerbackportbot-nextcloud[bot] <backportbot-nextcloud[bot]@users.noreply.github.com>
Mon, 10 Jul 2023 20:24:32 +0000 (20:24 +0000)
Signed-off-by: Robin Appelman <robin@icewind.nl>
apps/dav/lib/DAV/CustomPropertiesBackend.php

index 0110990a408b6865f895608e662244b123dd0ffd..a1da75e9ec1900dd606ce4ac0c45d4efe45f5c9d 100644 (file)
  * 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;
@@ -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;
@@ -180,6 +183,11 @@ class CustomPropertiesBackend implements BackendInterface {
                        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) {
@@ -262,6 +270,38 @@ class CustomPropertiesBackend implements BackendInterface {
                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
         *
@@ -321,7 +361,7 @@ class CustomPropertiesBackend implements BackendInterface {
                                $dbParameters = [
                                        'userid' => $this->user->getUID(),
                                        'propertyPath' => $this->formatPath($path),
-                                       'propertyName' => $propertyName
+                                       'propertyName' => $propertyName,
                                ];
 
                                // If it was null, we need to delete the property