X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FCore%2FStorageManager.php;h=8cd7d439531824b3b836e086a4cfd0d71db2ca05;hb=a2c6240da02de21dc974b1fbe65a943f2abb37fb;hp=6f3e98ae7e2e57d77004b858ae3015764878e462;hpb=6a0ed7c298669ef0b0f33563df15bb2a3c7207b0;p=friendica.git diff --git a/src/Core/StorageManager.php b/src/Core/StorageManager.php index 6f3e98ae7e..8cd7d43953 100644 --- a/src/Core/StorageManager.php +++ b/src/Core/StorageManager.php @@ -2,8 +2,8 @@ namespace Friendica\Core; -use Friendica\Core\Config; - +use Friendica\Database\DBA; +use Friendica\Model\Storage\IStorage; /** @@ -14,23 +14,25 @@ use Friendica\Core\Config; */ class StorageManager { - private static $default_storages = [ + private static $default_backends = [ 'Filesystem' => \Friendica\Model\Storage\Filesystem::class, 'Database' => \Friendica\Model\Storage\Database::class, ]; - private static $storages = []; + private static $backends = []; private static function setup() { - if (count(self::$storages)==0) { - self::$storage = Config::get('storage', 'backends', self::$default_storages); + if (count(self::$backends) == 0) { + self::$backends = Config::get('storage', 'backends', self::$default_backends); } } /** * @brief Return current storage backend class + * * @return string + * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ public static function getBackend() { @@ -46,18 +48,25 @@ class StorageManager public static function getByName($name) { self::setup(); - return defaults(self::$storages, $name, ''); + return defaults(self::$backends, $name, ''); } /** * @brief Set current storage backend class * - * @param string $class Backend class name + * @param string $class Backend class name + * @return bool + * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ public static function setBackend($class) { - /// @todo Check that $class implements IStorage + if (!in_array('Friendica\Model\Storage\IStorage', class_implements($class))) { + return false; + } + Config::set('storage', 'class', $class); + + return true; } /** @@ -72,31 +81,100 @@ class StorageManager } - /** * @brief Register a storage backend class * - * @param string $name User readable backend name - * @param string $class Backend class name + * @param string $name User readable backend name + * @param string $class Backend class name + * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ public static function register($name, $class) { /// @todo Check that $class implements IStorage self::setup(); - self::$storages[$name] = $class; - Config::set('storage', 'backends', self::$storages); + self::$backends[$name] = $class; + Config::set('storage', 'backends', self::$backends); } /** * @brief Unregister a storage backend class * - * @param string $name User readable backend name + * @param string $name User readable backend name + * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - public static function unregister($class) + public static function unregister($name) { self::setup(); - unset(self::$storages[$name]); - Config::set('storage', 'backends', self::$storages); + unset(self::$backends[$name]); + Config::set('storage', 'backends', self::$backends); } -} \ No newline at end of file + + + /** + * @brief Move up to 5000 resources to storage $dest + * + * Copy existing data to destination storage and delete from source. + * This method cannot move to legacy in-table `data` field. + * + * @param string $destination Storage class name + * @param array|null $tables Tables to look in for resources. Optional, defaults to ['photo', 'attach'] + * @param int $limit Limit of the process batch size, defaults to 5000 + * @return int Number of moved resources + * @throws \Exception + */ + public static function move($destination, $tables = null, $limit = 5000) + { + if (empty($destination)) { + throw new \Exception('Can\'t move to NULL storage backend'); + } + + if (is_null($tables)) { + $tables = ['photo', 'attach']; + } + + $moved = 0; + foreach ($tables as $table) { + // Get the rows where backend class is not the destination backend class + $resources = DBA::select( + $table, + ['id', 'data', 'backend-class', 'backend-ref'], + ['`backend-class` IS NULL or `backend-class` != ?', $destination], + ['limit' => $limit] + ); + + while ($resource = DBA::fetch($resources)) { + $id = $resource['id']; + $data = $resource['data']; + /** @var IStorage $backendClass */ + $backendClass = $resource['backend-class']; + $backendRef = $resource['backend-ref']; + if (!empty($backendClass)) { + Logger::log("get data from old backend " . $backendClass . " : " . $backendRef); + $data = $backendClass::get($backendRef); + } + + Logger::log("save data to new backend " . $destination); + /** @var IStorage $destination */ + $ref = $destination::put($data); + Logger::log("saved data as " . $ref); + + if ($ref !== '') { + Logger::log("update row"); + if (DBA::update($table, ['backend-class' => $destination, 'backend-ref' => $ref, 'data' => ''], ['id' => $id])) { + if (!empty($backendClass)) { + Logger::log("delete data from old backend " . $backendClass . " : " . $backendRef); + $backendClass::delete($backendRef); + } + $moved++; + } + } + } + + DBA::close($resources); + } + + return $moved; + } +} +