diff --git a/apps/files_sharing/appinfo/update.php b/apps/files_sharing/appinfo/update.php index ee6482d00c..d754a95705 100644 --- a/apps/files_sharing/appinfo/update.php +++ b/apps/files_sharing/appinfo/update.php @@ -28,6 +28,7 @@ $installedVersion = \OC::$server->getConfig()->getAppValue('files_sharing', 'ins if (version_compare($installedVersion, '0.9.0', '<')) { $m = new Migration(\OC::$server->getDatabaseConnection()); $m->removeReShares(); + $m->updateInitiatorInfo(); } \OC::$server->getJobList()->add('OCA\Files_sharing\Lib\DeleteOrphanedSharesJob'); diff --git a/apps/files_sharing/lib/migration.php b/apps/files_sharing/lib/migration.php index 4ec411d81d..90e0dead48 100644 --- a/apps/files_sharing/lib/migration.php +++ b/apps/files_sharing/lib/migration.php @@ -83,6 +83,29 @@ class Migration { } } + /** + * update all owner information so that all shares have an owner + * and an initiator for the upgrade from oC 8.2 to 9.0 with the new sharing + */ + public function updateInitiatorInfo() { + while (true) { + $shares = $this->getMissingInitiator(1000); + + if (empty($shares)) { + break; + } + + $owners = []; + foreach ($shares as $share) { + $owners[$share['id']] = [ + 'owner' => $share['uid_owner'], + 'initiator' => $share['uid_owner'] + ]; + } + $this->updateOwners($owners); + } + } + /** * find the owner of a re-shared file/folder * @@ -146,6 +169,49 @@ class Migration { return $ordered; } + /** + * Get $n re-shares from the database + * + * @param int $n The max number of shares to fetch + * @return array + */ + private function getMissingInitiator($n = 1000) { + $query = $this->connection->getQueryBuilder(); + $query->select(['id', 'uid_owner']) + ->from($this->table) + ->where($query->expr()->in( + 'share_type', + $query->createNamedParameter( + [ + \OCP\Share::SHARE_TYPE_USER, + \OCP\Share::SHARE_TYPE_GROUP, + \OCP\Share::SHARE_TYPE_LINK + ], + Connection::PARAM_INT_ARRAY + ) + )) + ->andWhere($query->expr()->in( + 'item_type', + $query->createNamedParameter( + ['file', 'folder'], + Connection::PARAM_STR_ARRAY + ) + )) + ->andWhere($query->expr()->isNull('uid_initiator')) + ->orderBy('id', 'asc') + ->setMaxResults($n); + $result = $query->execute(); + $shares = $result->fetchAll(); + $result->closeCursor(); + + $ordered = []; + foreach ($shares as $share) { + $ordered[(int)$share['id']] = $share; + } + + return $ordered; + } + /** * get a specific share * diff --git a/apps/files_sharing/tests/migrationtest.php b/apps/files_sharing/tests/migrationtest.php index fb9d1242ac..e1c047e034 100644 --- a/apps/files_sharing/tests/migrationtest.php +++ b/apps/files_sharing/tests/migrationtest.php @@ -246,9 +246,9 @@ class MigrationTest extends TestCase { } } - public function test100kDeepReshares() { + public function test1001DeepReshares() { $parent = null; - for ($i = 0; $i < 10; $i++) { + for ($i = 0; $i < 1001; $i++) { $query = $this->connection->getQueryBuilder(); $query->insert($this->table) ->values( @@ -270,7 +270,7 @@ class MigrationTest extends TestCase { ->setParameter('share_type', \OCP\Share::SHARE_TYPE_USER) ->setParameter('share_with', 'user'.($i+1)) ->setParameter('uid_owner', 'user'.($i)) - ->setParameter('uid_initiator', '') + ->setParameter('uid_initiator', null) ->setParameter('parent', $parent) ->setParameter('item_type', 'file') ->setParameter('item_source', '2') @@ -285,6 +285,7 @@ class MigrationTest extends TestCase { } $this->migration->removeReShares(); + $this->migration->updateInitiatorInfo(); $qb = $this->connection->getQueryBuilder(); @@ -296,13 +297,12 @@ class MigrationTest extends TestCase { $i = 0; while($share = $stmt->fetch()) { $this->assertEquals('user'.($i+1), $share['share_with']); - if ($i !== 0) { - $this->assertEquals('user' . ($i), $share['uid_initiator']); - $this->assertEquals('user0', $share['uid_owner']); - } + $this->assertEquals('user' . ($i), $share['uid_initiator']); + $this->assertEquals('user0', $share['uid_owner']); $this->assertEquals(null, $share['parent']); $i++; } $stmt->closeCursor(); + $this->assertEquals(1001, $i); } }