From e11c5a23d52ba0bfe082f36311a504c72278aa40 Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Fri, 15 Jun 2012 17:51:56 +0200 Subject: [PATCH] Optimize WebDav access by preloading dav custom properties --- lib/connector/sabre/directory.php | 22 ++++++++++++++++++++-- lib/connector/sabre/node.php | 30 +++++++++++++++++++++--------- 2 files changed, 41 insertions(+), 11 deletions(-) diff --git a/lib/connector/sabre/directory.php b/lib/connector/sabre/directory.php index 6af4dd36562..9832449af3a 100644 --- a/lib/connector/sabre/directory.php +++ b/lib/connector/sabre/directory.php @@ -85,10 +85,28 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa */ public function getChildren() { - $nodes = array(); $folder_content = OC_FileCache::getFolderContent($this->path); + $paths = array(); foreach($folder_content as $info) { - $nodes[] = $this->getChild($info['name'], $info); + $paths[] = $this->path.'/'.$info['name']; + } + $placeholders = join(',', array_fill(0, count($paths), '?')); + $query = OC_DB::prepare( 'SELECT * FROM *PREFIX*properties WHERE userid = ?' . ' AND propertypath IN ('.$placeholders.')' ); + array_unshift($paths, OC_User::getUser()); // prepend userid + $result = $query->execute( $paths ); + $properties = array_fill_keys($paths, array()); + while($row = $result->fetchRow()) { + $propertypath = $row['propertypath']; + $propertyname = $row['propertyname']; + $propertyvalue = $row['propertyvalue']; + $properties[$propertypath][$propertyname] = $propertyvalue; + } + + $nodes = array(); + foreach($folder_content as $info) { + $node = $this->getChild($info['name'], $info); + $node->setPropertyCache($properties[$this->path.'/'.$info['name']]); + $nodes[] = $node; } return $nodes; } diff --git a/lib/connector/sabre/node.php b/lib/connector/sabre/node.php index 7a9d8198ae8..be315a0ffd9 100644 --- a/lib/connector/sabre/node.php +++ b/lib/connector/sabre/node.php @@ -30,10 +30,15 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr */ protected $path; /** - * file stat cache + * node fileinfo cache * @var array */ protected $fileinfo_cache; + /** + * node properties cache + * @var array + */ + protected $property_cache = null; /** * Sets up the node, expects a full path name @@ -101,6 +106,11 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr } } + public function setPropertyCache($property_cache) + { + $this->property_cache = $property_cache; + } + /** * Returns the last modification time, as a unix timestamp * @@ -153,6 +163,7 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr } } + $this->setPropertyCache(null); return true; } @@ -168,23 +179,24 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr * @return void */ function getProperties($properties) { - // At least some magic in here :-) - $query = OC_DB::prepare( 'SELECT * FROM *PREFIX*properties WHERE userid = ? AND propertypath = ?' ); - $result = $query->execute( array( OC_User::getUser(), $this->path )); + if (is_null($this->property_cache)) { + $query = OC_DB::prepare( 'SELECT * FROM *PREFIX*properties WHERE userid = ? AND propertypath = ?' ); + $result = $query->execute( array( OC_User::getUser(), $this->path )); - $existing = array(); - while( $row = $result->fetchRow()){ - $existing[$row['propertyname']] = $row['propertyvalue']; + $this->property_cache = array(); + while( $row = $result->fetchRow()){ + $this->property_cache[$row['propertyname']] = $row['propertyvalue']; + } } // if the array was empty, we need to return everything if(count($properties) == 0){ - return $existing; + return $this->property_cache; } $props = array(); foreach($properties as $property) { - if (isset($existing[$property])) $props[$property] = $existing[$property]; + if (isset($this->property_cache[$property])) $props[$property] = $this->property_cache[$property]; } return $props; }