From 846e62c225070cbe9f8a0c8b14ec2a1f87ba1ca1 Mon Sep 17 00:00:00 2001 From: Morris Jobke Date: Wed, 21 Jun 2017 16:50:20 -0500 Subject: Run repair step only once Signed-off-by: Morris Jobke --- lib/composer/composer/autoload_classmap.php | 1 + lib/composer/composer/autoload_static.php | 1 + lib/private/Repair.php | 2 +- lib/private/Repair/NC13/RepairInvalidPaths.php | 125 +++++++++++++++++++++++++ lib/private/Repair/RepairInvalidPaths.php | 121 ------------------------ version.php | 2 +- 6 files changed, 129 insertions(+), 123 deletions(-) create mode 100644 lib/private/Repair/NC13/RepairInvalidPaths.php delete mode 100644 lib/private/Repair/RepairInvalidPaths.php diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php index 02979b426b9..1832e7443b2 100644 --- a/lib/composer/composer/autoload_classmap.php +++ b/lib/composer/composer/autoload_classmap.php @@ -739,6 +739,7 @@ return array( 'OC\\Repair\\NC11\\MoveAvatarsBackgroundJob' => $baseDir . '/lib/private/Repair/NC11/MoveAvatarsBackgroundJob.php', 'OC\\Repair\\NC12\\InstallCoreBundle' => $baseDir . '/lib/private/Repair/NC12/InstallCoreBundle.php', 'OC\\Repair\\NC12\\UpdateLanguageCodes' => $baseDir . '/lib/private/Repair/NC12/UpdateLanguageCodes.php', + 'OC\\Repair\\NC13\\RepairInvalidPaths' => $baseDir . '/lib/private/Repair/NC13/RepairInvalidPaths.php', 'OC\\Repair\\OldGroupMembershipShares' => $baseDir . '/lib/private/Repair/OldGroupMembershipShares.php', 'OC\\Repair\\Owncloud\\SaveAccountsTableData' => $baseDir . '/lib/private/Repair/Owncloud/SaveAccountsTableData.php', 'OC\\Repair\\RemoveRootShares' => $baseDir . '/lib/private/Repair/RemoveRootShares.php', diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php index 5f9e571a687..02633a32ffc 100644 --- a/lib/composer/composer/autoload_static.php +++ b/lib/composer/composer/autoload_static.php @@ -769,6 +769,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c 'OC\\Repair\\NC11\\MoveAvatarsBackgroundJob' => __DIR__ . '/../../..' . '/lib/private/Repair/NC11/MoveAvatarsBackgroundJob.php', 'OC\\Repair\\NC12\\InstallCoreBundle' => __DIR__ . '/../../..' . '/lib/private/Repair/NC12/InstallCoreBundle.php', 'OC\\Repair\\NC12\\UpdateLanguageCodes' => __DIR__ . '/../../..' . '/lib/private/Repair/NC12/UpdateLanguageCodes.php', + 'OC\\Repair\\NC13\\RepairInvalidPaths' => __DIR__ . '/../../..' . '/lib/private/Repair/NC13/RepairInvalidPaths.php', 'OC\\Repair\\OldGroupMembershipShares' => __DIR__ . '/../../..' . '/lib/private/Repair/OldGroupMembershipShares.php', 'OC\\Repair\\Owncloud\\SaveAccountsTableData' => __DIR__ . '/../../..' . '/lib/private/Repair/Owncloud/SaveAccountsTableData.php', 'OC\\Repair\\RemoveRootShares' => __DIR__ . '/../../..' . '/lib/private/Repair/RemoveRootShares.php', diff --git a/lib/private/Repair.php b/lib/private/Repair.php index ca8dbd98758..65b131169f7 100644 --- a/lib/private/Repair.php +++ b/lib/private/Repair.php @@ -42,7 +42,7 @@ use OC\Repair\NC12\UpdateLanguageCodes; use OC\Repair\OldGroupMembershipShares; use OC\Repair\Owncloud\SaveAccountsTableData; use OC\Repair\RemoveRootShares; -use OC\Repair\RepairInvalidPaths; +use OC\Repair\NC13\RepairInvalidPaths; use OC\Repair\SqliteAutoincrement; use OC\Repair\RepairMimeTypes; use OC\Repair\RepairInvalidShares; diff --git a/lib/private/Repair/NC13/RepairInvalidPaths.php b/lib/private/Repair/NC13/RepairInvalidPaths.php new file mode 100644 index 00000000000..8551f8261e2 --- /dev/null +++ b/lib/private/Repair/NC13/RepairInvalidPaths.php @@ -0,0 +1,125 @@ + + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace OC\Repair\NC13; + + +use OCP\IDBConnection; +use OCP\Migration\IOutput; +use OCP\Migration\IRepairStep; + +class RepairInvalidPaths implements IRepairStep { + /** @var IDBConnection */ + private $connection; + + public function __construct(IDBConnection $connection) { + $this->connection = $connection; + } + + + public function getName() { + return 'Repair invalid paths in file cache'; + } + + private function getInvalidEntries() { + $builder = $this->connection->getQueryBuilder(); + + $computedPath = $builder->func()->concat( + 'p.path', + $builder->func()->concat($builder->createNamedParameter('/'), 'f.name') + ); + + //select f.path, f.parent,p.path from oc_filecache f inner join oc_filecache p on f.parent=p.fileid and p.path!='' where f.path != p.path || '/' || f.name; + $query = $builder->select('f.fileid', 'f.path', 'p.path AS parent_path', 'f.name', 'f.parent', 'f.storage') + ->from('filecache', 'f') + ->innerJoin('f', 'filecache', 'p', $builder->expr()->andX( + $builder->expr()->eq('f.parent', 'p.fileid'), + $builder->expr()->neq('p.name', $builder->createNamedParameter('')) + )) + ->where($builder->expr()->neq('f.path', $computedPath)); + + return $query->execute()->fetchAll(); + } + + private function getId($storage, $path) { + $builder = $this->connection->getQueryBuilder(); + + $query = $builder->select('fileid') + ->from('filecache') + ->where($builder->expr()->eq('storage', $builder->createNamedParameter($storage))) + ->andWhere($builder->expr()->eq('path', $builder->createNamedParameter($path))); + + return $query->execute()->fetchColumn(); + } + + private function update($fileid, $newPath) { + $builder = $this->connection->getQueryBuilder(); + + $query = $builder->update('filecache') + ->set('path', $builder->createNamedParameter($newPath)) + ->set('path_hash', $builder->createNamedParameter(md5($newPath))) + ->where($builder->expr()->eq('fileid', $builder->createNamedParameter($fileid))); + + $query->execute(); + } + + private function reparent($from, $to) { + $builder = $this->connection->getQueryBuilder(); + + $query = $builder->update('filecache') + ->set('parent', $builder->createNamedParameter($to)) + ->where($builder->expr()->eq('fileid', $builder->createNamedParameter($from))); + $query->execute(); + } + + private function delete($fileid) { + $builder = $this->connection->getQueryBuilder(); + + $query = $builder->delete('filecache') + ->where($builder->expr()->eq('fileid', $builder->createNamedParameter($fileid))); + $query->execute(); + } + + private function repair() { + $entries = $this->getInvalidEntries(); + foreach ($entries as $entry) { + $calculatedPath = $entry['parent_path'] . '/' . $entry['name']; + if ($newId = $this->getId($entry['storage'], $calculatedPath)) { + // a new entry with the correct path has already been created, reuse that one and delete the incorrect entry + $this->reparent($entry['fileid'], $newId); + $this->delete($entry['fileid']); + } else { + $this->update($entry['fileid'], $calculatedPath); + } + } + return count($entries); + } + + public function run(IOutput $output) { + $versionFromBeforeUpdate = $this->config->getSystemValue('version', '0.0.0'); + // was added to 12.0.0.30 and 13.0.0.1 + if (version_compare($versionFromBeforeUpdate, '12.0.0.30', '<') || version_compare($versionFromBeforeUpdate, '13.0.0.0', '==')) { + $count = $this->repair(); + + $output->info('Repaired ' . $count . ' paths'); + } + } +} diff --git a/lib/private/Repair/RepairInvalidPaths.php b/lib/private/Repair/RepairInvalidPaths.php deleted file mode 100644 index cdd0906295f..00000000000 --- a/lib/private/Repair/RepairInvalidPaths.php +++ /dev/null @@ -1,121 +0,0 @@ - - * - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - * - */ - -namespace OC\Repair; - - -use OCP\IDBConnection; -use OCP\Migration\IOutput; -use OCP\Migration\IRepairStep; - -class RepairInvalidPaths implements IRepairStep { - /** @var IDBConnection */ - private $connection; - - public function __construct(IDBConnection $connection) { - $this->connection = $connection; - } - - - public function getName() { - return 'Repair invalid paths in file cache'; - } - - private function getInvalidEntries() { - $builder = $this->connection->getQueryBuilder(); - - $computedPath = $builder->func()->concat( - 'p.path', - $builder->func()->concat($builder->createNamedParameter('/'), 'f.name') - ); - - //select f.path, f.parent,p.path from oc_filecache f inner join oc_filecache p on f.parent=p.fileid and p.path!='' where f.path != p.path || '/' || f.name; - $query = $builder->select('f.fileid', 'f.path', 'p.path AS parent_path', 'f.name', 'f.parent', 'f.storage') - ->from('filecache', 'f') - ->innerJoin('f', 'filecache', 'p', $builder->expr()->andX( - $builder->expr()->eq('f.parent', 'p.fileid'), - $builder->expr()->neq('p.name', $builder->createNamedParameter('')) - )) - ->where($builder->expr()->neq('f.path', $computedPath)); - - return $query->execute()->fetchAll(); - } - - private function getId($storage, $path) { - $builder = $this->connection->getQueryBuilder(); - - $query = $builder->select('fileid') - ->from('filecache') - ->where($builder->expr()->eq('storage', $builder->createNamedParameter($storage))) - ->andWhere($builder->expr()->eq('path', $builder->createNamedParameter($path))); - - return $query->execute()->fetchColumn(); - } - - private function update($fileid, $newPath) { - $builder = $this->connection->getQueryBuilder(); - - $query = $builder->update('filecache') - ->set('path', $builder->createNamedParameter($newPath)) - ->set('path_hash', $builder->createNamedParameter(md5($newPath))) - ->where($builder->expr()->eq('fileid', $builder->createNamedParameter($fileid))); - - $query->execute(); - } - - private function reparent($from, $to) { - $builder = $this->connection->getQueryBuilder(); - - $query = $builder->update('filecache') - ->set('parent', $builder->createNamedParameter($to)) - ->where($builder->expr()->eq('fileid', $builder->createNamedParameter($from))); - $query->execute(); - } - - private function delete($fileid) { - $builder = $this->connection->getQueryBuilder(); - - $query = $builder->delete('filecache') - ->where($builder->expr()->eq('fileid', $builder->createNamedParameter($fileid))); - $query->execute(); - } - - private function repair() { - $entries = $this->getInvalidEntries(); - foreach ($entries as $entry) { - $calculatedPath = $entry['parent_path'] . '/' . $entry['name']; - if ($newId = $this->getId($entry['storage'], $calculatedPath)) { - // a new entry with the correct path has already been created, reuse that one and delete the incorrect entry - $this->reparent($entry['fileid'], $newId); - $this->delete($entry['fileid']); - } else { - $this->update($entry['fileid'], $calculatedPath); - } - } - return count($entries); - } - - public function run(IOutput $output) { - $count = $this->repair(); - - $output->info('Repaired ' . $count . ' paths'); - } -} diff --git a/version.php b/version.php index e237770c820..d9e26eafcee 100644 --- a/version.php +++ b/version.php @@ -26,7 +26,7 @@ // between betas, final and RCs. This is _not_ the public version number. Reset minor/patchlevel // when updating major/minor version number. -$OC_Version = array(13, 0, 0, 0); +$OC_Version = array(13, 0, 0, 1); // The human readable string $OC_VersionString = '13.0.0 alpha'; -- cgit v1.2.3