diff options
Diffstat (limited to 'lib/private/Files/Cache/Storage.php')
-rw-r--r-- | lib/private/Files/Cache/Storage.php | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/lib/private/Files/Cache/Storage.php b/lib/private/Files/Cache/Storage.php new file mode 100644 index 00000000000..90c451ecc21 --- /dev/null +++ b/lib/private/Files/Cache/Storage.php @@ -0,0 +1,189 @@ +<?php +/** + * @author Joas Schilling <nickvergessen@owncloud.com> + * @author Jörn Friedrich Dreyer <jfd@butonic.de> + * @author Morris Jobke <hey@morrisjobke.de> + * @author Robin Appelman <icewind@owncloud.com> + * @author Robin McCorkell <robin@mccorkell.me.uk> + * @author Thomas Müller <thomas.mueller@tmit.eu> + * @author Vincent Petry <pvince81@owncloud.com> + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see <http://www.gnu.org/licenses/> + * + */ + +namespace OC\Files\Cache; + +/** + * Handle the mapping between the string and numeric storage ids + * + * Each storage has 2 different ids + * a string id which is generated by the storage backend and reflects the configuration of the storage (e.g. 'smb://user@host/share') + * and a numeric storage id which is referenced in the file cache + * + * A mapping between the two storage ids is stored in the database and accessible trough this class + * + * @package OC\Files\Cache + */ +class Storage { + private $storageId; + private $numericId; + + /** + * @param \OC\Files\Storage\Storage|string $storage + * @param bool $isAvailable + * @throws \RuntimeException + */ + public function __construct($storage, $isAvailable = true) { + if ($storage instanceof \OC\Files\Storage\Storage) { + $this->storageId = $storage->getId(); + } else { + $this->storageId = $storage; + } + $this->storageId = self::adjustStorageId($this->storageId); + + if ($row = self::getStorageById($this->storageId)) { + $this->numericId = $row['numeric_id']; + } else { + $connection = \OC::$server->getDatabaseConnection(); + $available = $isAvailable ? 1 : 0; + if ($connection->insertIfNotExist('*PREFIX*storages', ['id' => $this->storageId, 'available' => $available])) { + $this->numericId = $connection->lastInsertId('*PREFIX*storages'); + } else { + if ($row = self::getStorageById($this->storageId)) { + $this->numericId = $row['numeric_id']; + } else { + throw new \RuntimeException('Storage could neither be inserted nor be selected from the database'); + } + } + } + } + + /** + * @param string $storageId + * @return array|null + */ + public static function getStorageById($storageId) { + $sql = 'SELECT * FROM `*PREFIX*storages` WHERE `id` = ?'; + $result = \OC_DB::executeAudited($sql, array($storageId)); + return $result->fetchRow(); + } + + /** + * Adjusts the storage id to use md5 if too long + * @param string $storageId storage id + * @return string unchanged $storageId if its length is less than 64 characters, + * else returns the md5 of $storageId + */ + public static function adjustStorageId($storageId) { + if (strlen($storageId) > 64) { + return md5($storageId); + } + return $storageId; + } + + /** + * Get the numeric id for the storage + * + * @return int + */ + public function getNumericId() { + return $this->numericId; + } + + /** + * Get the string id for the storage + * + * @param int $numericId + * @return string|null either the storage id string or null if the numeric id is not known + */ + public static function getStorageId($numericId) { + + $sql = 'SELECT `id` FROM `*PREFIX*storages` WHERE `numeric_id` = ?'; + $result = \OC_DB::executeAudited($sql, array($numericId)); + if ($row = $result->fetchRow()) { + return $row['id']; + } else { + return null; + } + } + + /** + * Get the numeric of the storage with the provided string id + * + * @param $storageId + * @return int|null either the numeric storage id or null if the storage id is not knwon + */ + public static function getNumericStorageId($storageId) { + $storageId = self::adjustStorageId($storageId); + + if ($row = self::getStorageById($storageId)) { + return $row['numeric_id']; + } else { + return null; + } + } + + /** + * @return array|null [ available, last_checked ] + */ + public function getAvailability() { + if ($row = self::getStorageById($this->storageId)) { + return [ + 'available' => ((int)$row['available'] === 1), + 'last_checked' => $row['last_checked'] + ]; + } else { + return null; + } + } + + /** + * @param bool $isAvailable + */ + public function setAvailability($isAvailable) { + $sql = 'UPDATE `*PREFIX*storages` SET `available` = ?, `last_checked` = ? WHERE `id` = ?'; + $available = $isAvailable ? 1 : 0; + \OC_DB::executeAudited($sql, array($available, time(), $this->storageId)); + } + + /** + * Check if a string storage id is known + * + * @param string $storageId + * @return bool + */ + public static function exists($storageId) { + return !is_null(self::getNumericStorageId($storageId)); + } + + /** + * remove the entry for the storage + * + * @param string $storageId + */ + public static function remove($storageId) { + $storageId = self::adjustStorageId($storageId); + $numericId = self::getNumericStorageId($storageId); + $sql = 'DELETE FROM `*PREFIX*storages` WHERE `id` = ?'; + \OC_DB::executeAudited($sql, array($storageId)); + + if (!is_null($numericId)) { + $sql = 'DELETE FROM `*PREFIX*filecache` WHERE `storage` = ?'; + \OC_DB::executeAudited($sql, array($numericId)); + } + } +} |