Compare commits

...

5 Commits

6 changed files with 46 additions and 27 deletions

@ -65,12 +65,12 @@ class DeleteOrphanedFilesTest extends TestCase {
return $query->executeQuery()->fetchAllAssociative(); return $query->executeQuery()->fetchAllAssociative();
} }
protected function getMounts(int $storageId): array { protected function getMountsCount(int $storageId): int {
$query = $this->connection->getQueryBuilder(); $query = $this->connection->getQueryBuilder();
$query->select('*') $query->select($query->func()->count('*'))
->from('mounts') ->from('mounts')
->where($query->expr()->eq('storage_id', $query->createNamedParameter($storageId))); ->where($query->expr()->eq('storage_id', $query->createNamedParameter($storageId)));
return $query->executeQuery()->fetchAllAssociative(); return $query->executeQuery()->fetchOne();
} }
/** /**
@ -96,12 +96,12 @@ class DeleteOrphanedFilesTest extends TestCase {
$numericStorageId = $fileInfo->getStorage()->getStorageCache()->getNumericId(); $numericStorageId = $fileInfo->getStorage()->getStorageCache()->getNumericId();
$this->assertCount(1, $this->getFile($fileInfo->getId()), 'Asserts that file is available'); $this->assertCount(1, $this->getFile($fileInfo->getId()), 'Asserts that file is available');
$this->assertCount(1, $this->getMounts($numericStorageId), 'Asserts that mount is available'); $this->assertEquals(1, $this->getMountsCount($numericStorageId), 'Asserts that mount is available');
$this->command->execute($input, $output); $this->command->execute($input, $output);
$this->assertCount(1, $this->getFile($fileInfo->getId()), 'Asserts that file is still available'); $this->assertCount(1, $this->getFile($fileInfo->getId()), 'Asserts that file is still available');
$this->assertCount(1, $this->getMounts($numericStorageId), 'Asserts that mount is still available'); $this->assertEquals(1, $this->getMountsCount($numericStorageId), 'Asserts that mount is still available');
$deletedRows = $this->connection->executeUpdate('DELETE FROM `*PREFIX*storages` WHERE `id` = ?', [$storageId]); $deletedRows = $this->connection->executeUpdate('DELETE FROM `*PREFIX*storages` WHERE `id` = ?', [$storageId]);
@ -125,7 +125,7 @@ class DeleteOrphanedFilesTest extends TestCase {
$this->command->execute($input, $output); $this->command->execute($input, $output);
$this->assertCount(0, $this->getFile($fileInfo->getId()), 'Asserts that file gets cleaned up'); $this->assertCount(0, $this->getFile($fileInfo->getId()), 'Asserts that file gets cleaned up');
$this->assertCount(0, $this->getMounts($numericStorageId), 'Asserts that mount gets cleaned up'); $this->assertEquals(0, $this->getMountsCount($numericStorageId), 'Asserts that mount gets cleaned up');
// Rescan folder to add back to cache before deleting // Rescan folder to add back to cache before deleting
$rootFolder->getUserFolder($this->user1)->getStorage()->getScanner()->scan(''); $rootFolder->getUserFolder($this->user1)->getStorage()->getScanner()->scan('');

@ -186,12 +186,6 @@ class AddMissingIndicesListener implements IEventListener {
'mounts_class_index', 'mounts_class_index',
['mount_provider_class'] ['mount_provider_class']
); );
$event->addMissingIndex(
'mounts',
'mounts_user_root_path_index',
['user_id', 'root_id', 'mount_point'],
['lengths' => [null, null, 128]]
);
$event->addMissingIndex( $event->addMissingIndex(
'systemtag_object_mapping', 'systemtag_object_mapping',

@ -467,16 +467,8 @@ class UserMountCache implements IUserMountCache {
public function getUsedSpaceForUsers(array $users) { public function getUsedSpaceForUsers(array $users) {
$builder = $this->connection->getQueryBuilder(); $builder = $this->connection->getQueryBuilder();
$slash = $builder->createNamedParameter('/'); $mountPointHashes = array_map(static fn (IUser $user) => hash('xxh128', '/' . $user->getUID() . '/'), $users);
$userIds = array_map(static fn (IUser $user) => $user->getUID(), $users);
$mountPoint = $builder->func()->concat(
$builder->func()->concat($slash, 'user_id'),
$slash
);
$userIds = array_map(function (IUser $user) {
return $user->getUID();
}, $users);
$query = $builder->select('m.user_id', 'f.size') $query = $builder->select('m.user_id', 'f.size')
->from('mounts', 'm') ->from('mounts', 'm')
@ -485,7 +477,7 @@ class UserMountCache implements IUserMountCache {
$builder->expr()->eq('m.storage_id', 'f.storage'), $builder->expr()->eq('m.storage_id', 'f.storage'),
$builder->expr()->eq('f.path_hash', $builder->createNamedParameter(md5('files'))) $builder->expr()->eq('f.path_hash', $builder->createNamedParameter(md5('files')))
)) ))
->where($builder->expr()->eq('m.mount_point', $mountPoint)) ->where($builder->expr()->in('m.mount_point_hash', $builder->createNamedParameter($mountPointHashes, IQueryBuilder::PARAM_STR_ARRAY)))
->andWhere($builder->expr()->in('m.user_id', $builder->createNamedParameter($userIds, IQueryBuilder::PARAM_STR_ARRAY))); ->andWhere($builder->expr()->in('m.user_id', $builder->createNamedParameter($userIds, IQueryBuilder::PARAM_STR_ARRAY)));
$result = $query->executeQuery(); $result = $query->executeQuery();

@ -22,6 +22,7 @@ use OC\DB\SchemaWrapper;
use OC\Migration\MetadataManager; use OC\Migration\MetadataManager;
use OCP\App\AppPathNotFoundException; use OCP\App\AppPathNotFoundException;
use OCP\App\IAppManager; use OCP\App\IAppManager;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IDBConnection; use OCP\IDBConnection;
use OCP\Migration\Attributes\AddColumn; use OCP\Migration\Attributes\AddColumn;
use OCP\Migration\Attributes\AddIndex; use OCP\Migration\Attributes\AddIndex;
@ -113,6 +114,17 @@ class MigrationsTest extends \Test\TestCase {
$this->db->expects($this->once()) $this->db->expects($this->once())
->method('migrateToSchema'); ->method('migrateToSchema');
$qb = $this->createMock(IQueryBuilder::class);
$qb
->expects($this->once())
->method('insert')
->willReturn($qb);
$this->db
->expects($this->once())
->method('getQueryBuilder')
->willReturn($qb);
$wrappedSchema = $this->createMock(Schema::class); $wrappedSchema = $this->createMock(Schema::class);
$wrappedSchema->expects($this->exactly(2)) $wrappedSchema->expects($this->exactly(2))
->method('getTables') ->method('getTables')
@ -156,6 +168,17 @@ class MigrationsTest extends \Test\TestCase {
$this->db->expects($this->never()) $this->db->expects($this->never())
->method('migrateToSchema'); ->method('migrateToSchema');
$qb = $this->createMock(IQueryBuilder::class);
$qb
->expects($this->once())
->method('insert')
->willReturn($qb);
$this->db
->expects($this->once())
->method('getQueryBuilder')
->willReturn($qb);
$step = $this->createMock(IMigrationStep::class); $step = $this->createMock(IMigrationStep::class);
$step->expects($this->once()) $step->expects($this->once())
->method('preSchemaChange'); ->method('preSchemaChange');

@ -90,6 +90,7 @@ class PartitionedQueryBuilderTest extends TestCase {
'storage_id' => $query->createNamedParameter(1001001, IQueryBuilder::PARAM_INT), 'storage_id' => $query->createNamedParameter(1001001, IQueryBuilder::PARAM_INT),
'user_id' => $query->createNamedParameter('partitioned_test'), 'user_id' => $query->createNamedParameter('partitioned_test'),
'mount_point' => $query->createNamedParameter('/mount/point'), 'mount_point' => $query->createNamedParameter('/mount/point'),
'mount_point_hash' => $query->createNamedParameter(hash('xxh128', '/mount/point')),
'mount_provider_class' => $query->createNamedParameter('test'), 'mount_provider_class' => $query->createNamedParameter('test'),
'root_id' => $query->createNamedParameter($fileId, IQueryBuilder::PARAM_INT), 'root_id' => $query->createNamedParameter($fileId, IQueryBuilder::PARAM_INT),
]); ]);
@ -138,7 +139,7 @@ class PartitionedQueryBuilderTest extends TestCase {
$builder->addPartition(new PartitionSplit('filecache', ['filecache'])); $builder->addPartition(new PartitionSplit('filecache', ['filecache']));
// query borrowed from UserMountCache // query borrowed from UserMountCache
$query = $builder->select('storage_id', 'root_id', 'user_id', 'mount_point', 'mount_id', 'f.path', 'mount_provider_class') $query = $builder->select('storage_id', 'root_id', 'user_id', 'mount_point', 'mount_point_hash', 'mount_id', 'f.path', 'mount_provider_class')
->from('mounts', 'm') ->from('mounts', 'm')
->innerJoin('m', 'filecache', 'f', $builder->expr()->eq('m.root_id', 'f.fileid')) ->innerJoin('m', 'filecache', 'f', $builder->expr()->eq('m.root_id', 'f.fileid'))
->where($builder->expr()->eq('storage_id', $builder->createNamedParameter(1001001, IQueryBuilder::PARAM_INT))); ->where($builder->expr()->eq('storage_id', $builder->createNamedParameter(1001001, IQueryBuilder::PARAM_INT)));
@ -151,6 +152,7 @@ class PartitionedQueryBuilderTest extends TestCase {
$this->assertCount(1, $results); $this->assertCount(1, $results);
$this->assertEquals($results[0]['user_id'], 'partitioned_test'); $this->assertEquals($results[0]['user_id'], 'partitioned_test');
$this->assertEquals($results[0]['mount_point'], '/mount/point'); $this->assertEquals($results[0]['mount_point'], '/mount/point');
$this->assertEquals($results[0]['mount_point_hash'], hash('xxh128', '/mount/point'));
$this->assertEquals($results[0]['mount_provider_class'], 'test'); $this->assertEquals($results[0]['mount_provider_class'], 'test');
$this->assertEquals($results[0]['path'], 'file1'); $this->assertEquals($results[0]['path'], 'file1');
} }
@ -159,7 +161,7 @@ class PartitionedQueryBuilderTest extends TestCase {
$builder = $this->getQueryBuilder(); $builder = $this->getQueryBuilder();
$builder->addPartition(new PartitionSplit('filecache', ['filecache', 'filecache_extended'])); $builder->addPartition(new PartitionSplit('filecache', ['filecache', 'filecache_extended']));
$query = $builder->select('storage_id', 'root_id', 'user_id', 'mount_point', 'mount_id', 'f.path', 'mount_provider_class', 'fe.upload_time') $query = $builder->select('storage_id', 'root_id', 'user_id', 'mount_point', 'mount_point_hash', 'mount_id', 'f.path', 'mount_provider_class', 'fe.upload_time')
->from('mounts', 'm') ->from('mounts', 'm')
->innerJoin('m', 'filecache', 'f', $builder->expr()->eq('m.root_id', 'f.fileid')) ->innerJoin('m', 'filecache', 'f', $builder->expr()->eq('m.root_id', 'f.fileid'))
->innerJoin('f', 'filecache_extended', 'fe', $builder->expr()->eq('f.fileid', 'fe.fileid')) ->innerJoin('f', 'filecache_extended', 'fe', $builder->expr()->eq('f.fileid', 'fe.fileid'))
@ -173,6 +175,7 @@ class PartitionedQueryBuilderTest extends TestCase {
$this->assertCount(1, $results); $this->assertCount(1, $results);
$this->assertEquals($results[0]['user_id'], 'partitioned_test'); $this->assertEquals($results[0]['user_id'], 'partitioned_test');
$this->assertEquals($results[0]['mount_point'], '/mount/point'); $this->assertEquals($results[0]['mount_point'], '/mount/point');
$this->assertEquals($results[0]['mount_point_hash'], hash('xxh128', '/mount/point'));
$this->assertEquals($results[0]['mount_provider_class'], 'test'); $this->assertEquals($results[0]['mount_provider_class'], 'test');
$this->assertEquals($results[0]['path'], 'file1'); $this->assertEquals($results[0]['path'], 'file1');
$this->assertEquals($results[0]['upload_time'], 1234); $this->assertEquals($results[0]['upload_time'], 1234);
@ -182,7 +185,7 @@ class PartitionedQueryBuilderTest extends TestCase {
$builder = $this->getQueryBuilder(); $builder = $this->getQueryBuilder();
$builder->addPartition(new PartitionSplit('filecache', ['filecache'])); $builder->addPartition(new PartitionSplit('filecache', ['filecache']));
$query = $builder->select('storage', 'm.root_id', 'm.user_id', 'm.mount_point', 'm.mount_id', 'path', 'm.mount_provider_class') $query = $builder->select('storage', 'm.root_id', 'm.user_id', 'm.mount_point', 'm.mount_point_hash', 'm.mount_id', 'path', 'm.mount_provider_class')
->from('filecache', 'f') ->from('filecache', 'f')
->innerJoin('f', 'mounts', 'm', $builder->expr()->eq('m.root_id', 'f.fileid')); ->innerJoin('f', 'mounts', 'm', $builder->expr()->eq('m.root_id', 'f.fileid'));
$query->where($builder->expr()->eq('storage', $builder->createNamedParameter(1001001, IQueryBuilder::PARAM_INT))); $query->where($builder->expr()->eq('storage', $builder->createNamedParameter(1001001, IQueryBuilder::PARAM_INT)));
@ -195,6 +198,7 @@ class PartitionedQueryBuilderTest extends TestCase {
$this->assertCount(1, $results); $this->assertCount(1, $results);
$this->assertEquals($results[0]['user_id'], 'partitioned_test'); $this->assertEquals($results[0]['user_id'], 'partitioned_test');
$this->assertEquals($results[0]['mount_point'], '/mount/point'); $this->assertEquals($results[0]['mount_point'], '/mount/point');
$this->assertEquals($results[0]['mount_point_hash'], hash('xxh128', '/mount/point'));
$this->assertEquals($results[0]['mount_provider_class'], 'test'); $this->assertEquals($results[0]['mount_provider_class'], 'test');
$this->assertEquals($results[0]['path'], 'file1'); $this->assertEquals($results[0]['path'], 'file1');
} }
@ -204,7 +208,7 @@ class PartitionedQueryBuilderTest extends TestCase {
$builder->addPartition(new PartitionSplit('filecache', ['filecache'])); $builder->addPartition(new PartitionSplit('filecache', ['filecache']));
// query borrowed from UserMountCache // query borrowed from UserMountCache
$query = $builder->select('storage_id', 'root_id', 'user_id', 'mount_point', 'mount_id', 'f.path', 'mount_provider_class') $query = $builder->select('storage_id', 'root_id', 'user_id', 'mount_point', 'mount_point_hash', 'mount_id', 'f.path', 'mount_provider_class')
->selectAlias('s.id', 'storage_string_id') ->selectAlias('s.id', 'storage_string_id')
->from('mounts', 'm') ->from('mounts', 'm')
->innerJoin('m', 'filecache', 'f', $builder->expr()->eq('m.root_id', 'f.fileid')) ->innerJoin('m', 'filecache', 'f', $builder->expr()->eq('m.root_id', 'f.fileid'))
@ -219,6 +223,7 @@ class PartitionedQueryBuilderTest extends TestCase {
$this->assertCount(1, $results); $this->assertCount(1, $results);
$this->assertEquals($results[0]['user_id'], 'partitioned_test'); $this->assertEquals($results[0]['user_id'], 'partitioned_test');
$this->assertEquals($results[0]['mount_point'], '/mount/point'); $this->assertEquals($results[0]['mount_point'], '/mount/point');
$this->assertEquals($results[0]['mount_point_hash'], hash('xxh128', '/mount/point'));
$this->assertEquals($results[0]['mount_provider_class'], 'test'); $this->assertEquals($results[0]['mount_provider_class'], 'test');
$this->assertEquals($results[0]['path'], 'file1'); $this->assertEquals($results[0]['path'], 'file1');
$this->assertEquals($results[0]['storage_string_id'], 'test1'); $this->assertEquals($results[0]['storage_string_id'], 'test1');

@ -62,6 +62,7 @@ class FileAccessTest extends TestCase {
'root_id' => $queryBuilder->createNamedParameter(10, IQueryBuilder::PARAM_INT), 'root_id' => $queryBuilder->createNamedParameter(10, IQueryBuilder::PARAM_INT),
'mount_provider_class' => $queryBuilder->createNamedParameter('TestProviderClass1'), 'mount_provider_class' => $queryBuilder->createNamedParameter('TestProviderClass1'),
'mount_point' => $queryBuilder->createNamedParameter('/files'), 'mount_point' => $queryBuilder->createNamedParameter('/files'),
'mount_point_hash' => $queryBuilder->createNamedParameter(hash('xxh128', '/files')),
'user_id' => $queryBuilder->createNamedParameter('test'), 'user_id' => $queryBuilder->createNamedParameter('test'),
]) ])
->executeStatement(); ->executeStatement();
@ -72,6 +73,7 @@ class FileAccessTest extends TestCase {
'root_id' => $queryBuilder->createNamedParameter(30, IQueryBuilder::PARAM_INT), 'root_id' => $queryBuilder->createNamedParameter(30, IQueryBuilder::PARAM_INT),
'mount_provider_class' => $queryBuilder->createNamedParameter('TestProviderClass1'), 'mount_provider_class' => $queryBuilder->createNamedParameter('TestProviderClass1'),
'mount_point' => $queryBuilder->createNamedParameter('/documents'), 'mount_point' => $queryBuilder->createNamedParameter('/documents'),
'mount_point_hash' => $queryBuilder->createNamedParameter(hash('xxh128', '/documents')),
'user_id' => $queryBuilder->createNamedParameter('test'), 'user_id' => $queryBuilder->createNamedParameter('test'),
]) ])
->executeStatement(); ->executeStatement();
@ -82,6 +84,7 @@ class FileAccessTest extends TestCase {
'root_id' => $queryBuilder->createNamedParameter(31, IQueryBuilder::PARAM_INT), 'root_id' => $queryBuilder->createNamedParameter(31, IQueryBuilder::PARAM_INT),
'mount_provider_class' => $queryBuilder->createNamedParameter('TestProviderClass2'), 'mount_provider_class' => $queryBuilder->createNamedParameter('TestProviderClass2'),
'mount_point' => $queryBuilder->createNamedParameter('/foobar'), 'mount_point' => $queryBuilder->createNamedParameter('/foobar'),
'mount_point_hash' => $queryBuilder->createNamedParameter(hash('xxh128', '/foobar')),
'user_id' => $queryBuilder->createNamedParameter('test'), 'user_id' => $queryBuilder->createNamedParameter('test'),
]) ])
->executeStatement(); ->executeStatement();
@ -147,6 +150,7 @@ class FileAccessTest extends TestCase {
'root_id' => $queryBuilder->createNamedParameter(40, IQueryBuilder::PARAM_INT), 'root_id' => $queryBuilder->createNamedParameter(40, IQueryBuilder::PARAM_INT),
'mount_provider_class' => $queryBuilder->createNamedParameter(LocalHomeMountProvider::class), 'mount_provider_class' => $queryBuilder->createNamedParameter(LocalHomeMountProvider::class),
'mount_point' => $queryBuilder->createNamedParameter('/home/user'), 'mount_point' => $queryBuilder->createNamedParameter('/home/user'),
'mount_point_hash' => $queryBuilder->createNamedParameter(hash('xxh128', '/home/user')),
'user_id' => $queryBuilder->createNamedParameter('test'), 'user_id' => $queryBuilder->createNamedParameter('test'),
]) ])
->executeStatement(); ->executeStatement();
@ -159,6 +163,7 @@ class FileAccessTest extends TestCase {
'root_id' => $queryBuilder->createNamedParameter(41, IQueryBuilder::PARAM_INT), 'root_id' => $queryBuilder->createNamedParameter(41, IQueryBuilder::PARAM_INT),
'mount_provider_class' => $queryBuilder->createNamedParameter('TestMountProvider3'), 'mount_provider_class' => $queryBuilder->createNamedParameter('TestMountProvider3'),
'mount_point' => $queryBuilder->createNamedParameter('/test/files/foobar'), 'mount_point' => $queryBuilder->createNamedParameter('/test/files/foobar'),
'mount_point_hash' => $queryBuilder->createNamedParameter(hash('xxh128', '/test/files/foobar')),
'user_id' => $queryBuilder->createNamedParameter('test'), 'user_id' => $queryBuilder->createNamedParameter('test'),
]) ])
->executeStatement(); ->executeStatement();