diff options
Diffstat (limited to 'lib/connector/sabre/node.php')
-rw-r--r-- | lib/connector/sabre/node.php | 115 |
1 files changed, 95 insertions, 20 deletions
diff --git a/lib/connector/sabre/node.php b/lib/connector/sabre/node.php index ce5cc022085..b9bf474a041 100644 --- a/lib/connector/sabre/node.php +++ b/lib/connector/sabre/node.php @@ -22,6 +22,7 @@ */ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IProperties { + const GETETAG_PROPERTYNAME = '{DAV:}getetag'; /** * The path to the current node @@ -30,10 +31,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 $stat_cache; + protected $fileinfo_cache; + /** + * node properties cache + * @var array + */ + protected $property_cache = null; /** * Sets up the node, expects a full path name @@ -82,23 +88,38 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr } + public function setFileinfoCache($fileinfo_cache) + { + $this->fileinfo_cache = $fileinfo_cache; + } + /** - * Set the stat cache + * Make sure the fileinfo cache is filled. Uses OC_FileCache or a direct stat */ - protected function stat() { - if (!isset($this->stat_cache)) { - $this->stat_cache = OC_Filesystem::stat($this->path); + protected function getFileinfoCache() { + if (!isset($this->fileinfo_cache)) { + if ($fileinfo_cache = OC_FileCache::get($this->path)) { + } else { + $fileinfo_cache = OC_Filesystem::stat($this->path); + } + + $this->fileinfo_cache = $fileinfo_cache; } } + public function setPropertyCache($property_cache) + { + $this->property_cache = $property_cache; + } + /** * Returns the last modification time, as a unix timestamp * * @return int */ public function getLastModified() { - $this->stat(); - return $this->stat_cache['mtime']; + $this->getFileinfoCache(); + return $this->fileinfo_cache['mtime']; } @@ -144,37 +165,91 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr } } + $this->setPropertyCache(null); return true; } /** * Returns a list of properties for this nodes.; * - * The properties list is a list of propertynames the client requested, encoded as xmlnamespace#tagName, for example: http://www.example.org/namespace#author + * The properties list is a list of propertynames the client requested, + * encoded as xmlnamespace#tagName, for example: + * http://www.example.org/namespace#author * If the array is empty, all properties should be returned * * @param array $properties * @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 )); - - $existing = array(); - while( $row = $result->fetchRow()){ - $existing[$row['propertyname']] = $row['propertyvalue']; + public function getProperties($properties) { + 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 )); + + $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; } - // if the array was empty, we need to return everything $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; } + + /** + * Creates a ETag for this path. + * @param string $path Path of the file + * @return string|null Returns null if the ETag can not effectively be determined + */ + static protected function createETag($path) { + return uniqid('', true); + } + + /** + * Returns the ETag surrounded by double-quotes for this path. + * @param string $path Path of the file + * @return string|null Returns null if the ETag can not effectively be determined + */ + static public function getETagPropertyForPath($path) { + $tag = self::createETag($path); + if (empty($tag)) { + return null; + } + $etag = '"'.$tag.'"'; + $query = OC_DB::prepare( 'INSERT INTO `*PREFIX*properties` (`userid`,`propertypath`,`propertyname`,`propertyvalue`) VALUES(?,?,?,?)' ); + $query->execute( array( OC_User::getUser(), $path, self::GETETAG_PROPERTYNAME, $etag )); + return $etag; + } + + /** + * Remove the ETag from the cache. + * @param string $path Path of the file + */ + static public function removeETagPropertyForPath($path) { + // remove tags from this and parent paths + $paths = array(); + while ($path != '/' && $path != '') { + $paths[] = $path; + $path = dirname($path); + } + if (empty($paths)) { + return; + } + $paths[] = $path; + $path_placeholders = join(',', array_fill(0, count($paths), '?')); + $query = OC_DB::prepare( 'DELETE FROM `*PREFIX*properties`' + .' WHERE `userid` = ?' + .' AND `propertyname` = ?' + .' AND `propertypath` IN ('.$path_placeholders.')' + ); + $vals = array( OC_User::getUser(), self::GETETAG_PROPERTYNAME ); + $query->execute(array_merge( $vals, $paths )); + } } |