Skip to content

Commit

Permalink
better cleanup of filecache when deleting an external storage
Browse files Browse the repository at this point in the history
this way it can delete the cache entries even with per-user credentials

Signed-off-by: Robin Appelman <robin@icewind.nl>
  • Loading branch information
icewind1991 committed May 18, 2021
1 parent ab7a117 commit 599a4da
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 38 deletions.
39 changes: 1 addition & 38 deletions apps/files_external/lib/Service/StoragesService.php
Original file line number Diff line number Diff line change
Expand Up @@ -479,44 +479,7 @@ public function removeStorage($id) {
$this->triggerHooks($deletedStorage, Filesystem::signal_delete_mount);

// delete oc_storages entries and oc_filecache
try {
$rustyStorageId = $this->getRustyStorageIdFromConfig($deletedStorage);
\OC\Files\Cache\Storage::remove($rustyStorageId);
} catch (\Exception $e) {
// can happen either for invalid configs where the storage could not
// be instantiated or whenever $user vars where used, in which case
// the storage id could not be computed
\OC::$server->getLogger()->logException($e, [
'level' => ILogger::ERROR,
'app' => 'files_external',
]);
}
}

/**
* Returns the rusty storage id from oc_storages from the given storage config.
*
* @param StorageConfig $storageConfig
* @return string rusty storage id
*/
private function getRustyStorageIdFromConfig(StorageConfig $storageConfig) {
// if any of the storage options contains $user, it is not possible
// to compute the possible storage id as we don't know which users
// mounted it already (and we certainly don't want to iterate over ALL users)
foreach ($storageConfig->getBackendOptions() as $value) {
if (strpos($value, '$user') !== false) {
throw new \Exception('Cannot compute storage id for deletion due to $user vars in the configuration');
}
}

// note: similar to ConfigAdapter->prepateStorageConfig()
$storageConfig->getAuthMechanism()->manipulateStorageConfig($storageConfig);
$storageConfig->getBackend()->manipulateStorageConfig($storageConfig);

$class = $storageConfig->getBackend()->getStorageClass();
$storageImpl = new $class($storageConfig->getBackendOptions());

return $storageImpl->getId();
\OC\Files\Cache\Storage::cleanByMountId($id);
}

/**
Expand Down
40 changes: 40 additions & 0 deletions lib/private/Files/Cache/Storage.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

namespace OC\Files\Cache;

use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\Files\Storage\IStorage;
use Psr\Log\LoggerInterface;

Expand Down Expand Up @@ -219,4 +220,43 @@ public static function remove($storageId) {
$query->execute();
}
}

/**
* remove the entry for the storage by the mount id
*
* @param int $mountId
*/
public static function cleanByMountId(int $mountId) {
$db = \OC::$server->getDatabaseConnection();

try {
$db->beginTransaction();

$query = $db->getQueryBuilder();
$query->select('storage_id')
->from('mounts')
->where($query->expr()->eq('mount_id', $query->createNamedParameter($mountId, IQueryBuilder::PARAM_INT)));
$storageIds = $query->executeQuery()->fetchAll(\PDO::FETCH_COLUMN);

$query = $db->getQueryBuilder();
$query->delete('filecache')
->where($query->expr()->in('storage', $query->createNamedParameter($storageIds, IQueryBuilder::PARAM_INT_ARRAY)));
$query->executeStatement();

$query = $db->getQueryBuilder();
$query->delete('storages')
->where($query->expr()->eq('id', $query->createNamedParameter($storageIds, IQueryBuilder::PARAM_INT_ARRAY)));
$query->executeStatement();

$query = $db->getQueryBuilder();
$query->delete('mounts')
->where($query->expr()->eq('mount_id', $query->createNamedParameter($mountId, IQueryBuilder::PARAM_INT)));
$query->executeStatement();

$db->commit();
} catch (\Exception $e) {
$db->rollBack();
throw $e;
}
}
}

0 comments on commit 599a4da

Please sign in to comment.