@@ -151,7 +151,8 @@ class ConfigAdapter implements IMountProvider { | |||
'/' . $user->getUID() . '/files' . $storage->getMountPoint(), | |||
null, | |||
$loader, | |||
$storage->getMountOptions() | |||
$storage->getMountOptions(), | |||
$storage->getId() | |||
); | |||
$mounts[$storage->getMountPoint()] = $mount; | |||
} |
@@ -170,6 +170,11 @@ | |||
<length>4000</length> | |||
</field> | |||
<field> | |||
<name>mount_id</name> | |||
<type>integer</type> | |||
</field> | |||
<index> | |||
<name>mounts_user_index</name> | |||
<unique>false</unique> | |||
@@ -197,6 +202,15 @@ | |||
</field> | |||
</index> | |||
<index> | |||
<name>mounts_mount_id_index</name> | |||
<unique>false</unique> | |||
<field> | |||
<name>mount_id</name> | |||
<sorting>ascending</sorting> | |||
</field> | |||
</index> | |||
<index> | |||
<name>mounts_user_root_index</name> | |||
<unique>true</unique> |
@@ -47,6 +47,11 @@ class CachedMountInfo implements ICachedMountInfo { | |||
*/ | |||
protected $mountPoint; | |||
/** | |||
* @var int|null | |||
*/ | |||
protected $mountId; | |||
/** | |||
* CachedMountInfo constructor. | |||
* | |||
@@ -54,12 +59,14 @@ class CachedMountInfo implements ICachedMountInfo { | |||
* @param int $storageId | |||
* @param int $rootId | |||
* @param string $mountPoint | |||
* @param int|null $mountId | |||
*/ | |||
public function __construct(IUser $user, $storageId, $rootId, $mountPoint) { | |||
public function __construct(IUser $user, $storageId, $rootId, $mountPoint, $mountId = null) { | |||
$this->user = $user; | |||
$this->storageId = $storageId; | |||
$this->rootId = $rootId; | |||
$this->mountPoint = $mountPoint; | |||
$this->mountId = $mountId; | |||
} | |||
/** | |||
@@ -104,4 +111,14 @@ class CachedMountInfo implements ICachedMountInfo { | |||
public function getMountPoint() { | |||
return $this->mountPoint; | |||
} | |||
/** | |||
* Get the id of the configured mount | |||
* | |||
* @return int|null mount id or null if not applicable | |||
* @since 9.1.0 | |||
*/ | |||
public function getMountId() { | |||
return $this->mountId; | |||
} | |||
} |
@@ -75,4 +75,8 @@ class LazyStorageMountInfo extends CachedMountInfo { | |||
} | |||
return parent::getMountPoint(); | |||
} | |||
public function getMountId() { | |||
return $this->mount->getMountId(); | |||
} | |||
} |
@@ -112,13 +112,7 @@ class UserMountCache implements IUserMountCache { | |||
/** @var ICachedMountInfo[] $removedMounts */ | |||
$removedMounts = array_udiff($cachedMounts, $newMounts, $mountDiff); | |||
$changedMounts = array_uintersect($newMounts, $cachedMounts, function (ICachedMountInfo $mount1, ICachedMountInfo $mount2) { | |||
// filter mounts with the same root id and different mountpoints | |||
if ($mount1->getRootId() !== $mount2->getRootId()) { | |||
return -1; | |||
} | |||
return ($mount1->getMountPoint() !== $mount2->getMountPoint()) ? 0 : 1; | |||
}); | |||
$changedMounts = $this->findChangedMounts($newMounts, $cachedMounts); | |||
foreach ($addedMounts as $mount) { | |||
$this->addToCache($mount); | |||
@@ -130,8 +124,28 @@ class UserMountCache implements IUserMountCache { | |||
unset($this->mountsForUsers[$user->getUID()][$index]); | |||
} | |||
foreach ($changedMounts as $mount) { | |||
$this->setMountPoint($mount); | |||
$this->updateCachedMount($mount); | |||
} | |||
} | |||
/** | |||
* @param ICachedMountInfo[] $newMounts | |||
* @param ICachedMountInfo[] $cachedMounts | |||
* @return ICachedMountInfo[] | |||
*/ | |||
private function findChangedMounts(array $newMounts, array $cachedMounts) { | |||
$changed = []; | |||
foreach ($newMounts as $newMount) { | |||
foreach ($cachedMounts as $cachedMount) { | |||
if ( | |||
$newMount->getRootId() === $cachedMount->getRootId() && | |||
($newMount->getMountPoint() !== $cachedMount->getMountPoint() || $newMount->getMountId() !== $cachedMount->getMountId()) | |||
) { | |||
$changed[] = $newMount; | |||
} | |||
} | |||
} | |||
return $changed; | |||
} | |||
private function addToCache(ICachedMountInfo $mount) { | |||
@@ -140,18 +154,20 @@ class UserMountCache implements IUserMountCache { | |||
'storage_id' => $mount->getStorageId(), | |||
'root_id' => $mount->getRootId(), | |||
'user_id' => $mount->getUser()->getUID(), | |||
'mount_point' => $mount->getMountPoint() | |||
'mount_point' => $mount->getMountPoint(), | |||
'mount_id' => $mount->getMountId() | |||
], ['root_id', 'user_id']); | |||
} else { | |||
$this->logger->error('Error getting storage info for mount at ' . $mount->getMountPoint()); | |||
} | |||
} | |||
private function setMountPoint(ICachedMountInfo $mount) { | |||
private function updateCachedMount(ICachedMountInfo $mount) { | |||
$builder = $this->connection->getQueryBuilder(); | |||
$query = $builder->update('mounts') | |||
->set('mount_point', $builder->createNamedParameter($mount->getMountPoint())) | |||
->set('mount_id', $builder->createNamedParameter($mount->getMountId(), IQueryBuilder::PARAM_INT)) | |||
->where($builder->expr()->eq('user_id', $builder->createNamedParameter($mount->getUser()->getUID()))) | |||
->andWhere($builder->expr()->eq('root_id', $builder->createNamedParameter($mount->getRootId(), IQueryBuilder::PARAM_INT))); | |||
@@ -169,7 +185,7 @@ class UserMountCache implements IUserMountCache { | |||
private function dbRowToMountInfo(array $row) { | |||
$user = $this->userManager->get($row['user_id']); | |||
return new CachedMountInfo($user, (int)$row['storage_id'], (int)$row['root_id'], $row['mount_point']); | |||
return new CachedMountInfo($user, (int)$row['storage_id'], (int)$row['root_id'], $row['mount_point'], $row['mount_id']); | |||
} | |||
/** | |||
@@ -179,7 +195,7 @@ class UserMountCache implements IUserMountCache { | |||
public function getMountsForUser(IUser $user) { | |||
if (!isset($this->mountsForUsers[$user->getUID()])) { | |||
$builder = $this->connection->getQueryBuilder(); | |||
$query = $builder->select('storage_id', 'root_id', 'user_id', 'mount_point') | |||
$query = $builder->select('storage_id', 'root_id', 'user_id', 'mount_point', 'mount_id') | |||
->from('mounts') | |||
->where($builder->expr()->eq('user_id', $builder->createPositionalParameter($user->getUID()))); | |||
@@ -196,7 +212,7 @@ class UserMountCache implements IUserMountCache { | |||
*/ | |||
public function getMountsForStorageId($numericStorageId) { | |||
$builder = $this->connection->getQueryBuilder(); | |||
$query = $builder->select('storage_id', 'root_id', 'user_id', 'mount_point') | |||
$query = $builder->select('storage_id', 'root_id', 'user_id', 'mount_point', 'mount_id') | |||
->from('mounts') | |||
->where($builder->expr()->eq('storage_id', $builder->createPositionalParameter($numericStorageId, IQueryBuilder::PARAM_INT))); | |||
@@ -211,7 +227,7 @@ class UserMountCache implements IUserMountCache { | |||
*/ | |||
public function getMountsForRootId($rootFileId) { | |||
$builder = $this->connection->getQueryBuilder(); | |||
$query = $builder->select('storage_id', 'root_id', 'user_id', 'mount_point') | |||
$query = $builder->select('storage_id', 'root_id', 'user_id', 'mount_point', 'mount_id') | |||
->from('mounts') | |||
->where($builder->expr()->eq('root_id', $builder->createPositionalParameter($rootFileId, IQueryBuilder::PARAM_INT))); | |||
@@ -68,14 +68,19 @@ class MountPoint implements IMountPoint { | |||
*/ | |||
private $invalidStorage = false; | |||
/** @var int|null */ | |||
protected $mountId; | |||
/** | |||
* @param string|\OC\Files\Storage\Storage $storage | |||
* @param string $mountpoint | |||
* @param array $arguments (optional) configuration for the storage backend | |||
* @param \OCP\Files\Storage\IStorageFactory $loader | |||
* @param array $mountOptions mount specific options | |||
* @param int|null $mountId | |||
* @throws \Exception | |||
*/ | |||
public function __construct($storage, $mountpoint, $arguments = null, $loader = null, $mountOptions = null) { | |||
public function __construct($storage, $mountpoint, $arguments = null, $loader = null, $mountOptions = null, $mountId = null) { | |||
if (is_null($arguments)) { | |||
$arguments = array(); | |||
} | |||
@@ -102,6 +107,7 @@ class MountPoint implements IMountPoint { | |||
$this->class = $storage; | |||
$this->arguments = $arguments; | |||
} | |||
$this->mountId = $mountId; | |||
} | |||
/** | |||
@@ -249,4 +255,8 @@ class MountPoint implements IMountPoint { | |||
public function getStorageRootId() { | |||
return (int)$this->getStorage()->getCache()->getId(''); | |||
} | |||
public function getMountId() { | |||
return $this->mountId; | |||
} | |||
} |
@@ -59,4 +59,12 @@ interface ICachedMountInfo { | |||
* @since 9.0.0 | |||
*/ | |||
public function getMountPoint(); | |||
/** | |||
* Get the id of the configured mount | |||
* | |||
* @return int|null mount id or null if not applicable | |||
* @since 9.1.0 | |||
*/ | |||
public function getMountId(); | |||
} |
@@ -102,4 +102,12 @@ interface IMountPoint { | |||
* @since 9.1.0 | |||
*/ | |||
public function getStorageRootId(); | |||
/** | |||
* Get the id of the configured mount | |||
* | |||
* @return int|null mount id or null if not applicable | |||
* @since 9.1.0 | |||
*/ | |||
public function getMountId(); | |||
} |
@@ -163,12 +163,14 @@ class UserMountCacheTest extends TestCase { | |||
$user = $this->userManager->get('u1'); | |||
$storage = $this->getStorage(10, 20); | |||
$mount = new MountPoint($storage, '/foo/'); | |||
$mount = new MountPoint($storage, '/bar/'); | |||
$this->cache->registerMounts($user, [$mount]); | |||
$this->clearCache(); | |||
$mount = new MountPoint($storage, '/foo/'); | |||
$this->cache->registerMounts($user, [$mount]); | |||
$this->clearCache(); | |||
@@ -180,6 +182,29 @@ class UserMountCacheTest extends TestCase { | |||
$this->assertEquals('/foo/', $cachedMount->getMountPoint()); | |||
} | |||
public function testChangeMountId() { | |||
$user = $this->userManager->get('u1'); | |||
$storage = $this->getStorage(10, 20); | |||
$mount = new MountPoint($storage, '/foo/', null, null, null, null); | |||
$this->cache->registerMounts($user, [$mount]); | |||
$this->clearCache(); | |||
$mount = new MountPoint($storage, '/foo/', null, null, null, 1); | |||
$this->cache->registerMounts($user, [$mount]); | |||
$this->clearCache(); | |||
$cachedMounts = $this->cache->getMountsForUser($user); | |||
$this->assertCount(1, $cachedMounts); | |||
$cachedMount = $cachedMounts[0]; | |||
$this->assertEquals(1, $cachedMount->getMountId()); | |||
} | |||
public function testGetMountsForUser() { | |||
$user1 = $this->userManager->get('u1'); | |||
$user2 = $this->userManager->get('u2'); |
@@ -25,7 +25,7 @@ | |||
// We only can count up. The 4. digit is only for the internal patchlevel to trigger DB upgrades | |||
// between betas, final and RCs. This is _not_ the public version number. Reset minor/patchlevel | |||
// when updating major/minor version number. | |||
$OC_Version = array(9, 1, 0, 11); | |||
$OC_Version = array(9, 1, 0, 12); | |||
// The human readable string | |||
$OC_VersionString = '9.1.0 RC1'; |