diff options
author | Joas Schilling <coding@schilljs.com> | 2017-05-11 14:04:53 +0200 |
---|---|---|
committer | Joas Schilling <coding@schilljs.com> | 2017-05-18 10:48:54 +0200 |
commit | c6a5a25b4833065a040fcbeaf0f85e21254ce6c8 (patch) | |
tree | cf384012a66414c7fe7bb097d69329fea19c7a21 | |
parent | d41fd7471c05ccaff14d13ed1a8d721dc363b8b0 (diff) | |
download | nextcloud-server-c6a5a25b4833065a040fcbeaf0f85e21254ce6c8.tar.gz nextcloud-server-c6a5a25b4833065a040fcbeaf0f85e21254ce6c8.zip |
Add a migration step to save the data from the accounts table before migrating
Signed-off-by: Joas Schilling <coding@schilljs.com>
-rw-r--r-- | lib/composer/composer/autoload_classmap.php | 1 | ||||
-rw-r--r-- | lib/composer/composer/autoload_static.php | 1 | ||||
-rw-r--r-- | lib/private/Repair.php | 3 | ||||
-rw-r--r-- | lib/private/Repair/Owncloud/SaveAccountsTableData.php | 178 | ||||
-rw-r--r-- | version.php | 2 |
5 files changed, 184 insertions, 1 deletions
diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php index 10233f07a2a..8e65ca365e4 100644 --- a/lib/composer/composer/autoload_classmap.php +++ b/lib/composer/composer/autoload_classmap.php @@ -738,6 +738,7 @@ return array( 'OC\\Repair\\NC12\\InstallCoreBundle' => $baseDir . '/lib/private/Repair/NC12/InstallCoreBundle.php', 'OC\\Repair\\NC12\\UpdateLanguageCodes' => $baseDir . '/lib/private/Repair/NC12/UpdateLanguageCodes.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', 'OC\\Repair\\RepairInvalidShares' => $baseDir . '/lib/private/Repair/RepairInvalidShares.php', 'OC\\Repair\\RepairMimeTypes' => $baseDir . '/lib/private/Repair/RepairMimeTypes.php', diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php index 9c0f0871133..b9a1545e6a3 100644 --- a/lib/composer/composer/autoload_static.php +++ b/lib/composer/composer/autoload_static.php @@ -768,6 +768,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c 'OC\\Repair\\NC12\\InstallCoreBundle' => __DIR__ . '/../../..' . '/lib/private/Repair/NC12/InstallCoreBundle.php', 'OC\\Repair\\NC12\\UpdateLanguageCodes' => __DIR__ . '/../../..' . '/lib/private/Repair/NC12/UpdateLanguageCodes.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', 'OC\\Repair\\RepairInvalidShares' => __DIR__ . '/../../..' . '/lib/private/Repair/RepairInvalidShares.php', 'OC\\Repair\\RepairMimeTypes' => __DIR__ . '/../../..' . '/lib/private/Repair/RepairMimeTypes.php', diff --git a/lib/private/Repair.php b/lib/private/Repair.php index 65e0342905a..4d14bf2550c 100644 --- a/lib/private/Repair.php +++ b/lib/private/Repair.php @@ -40,6 +40,7 @@ use OC\Repair\NC11\MoveAvatars; use OC\Repair\NC12\InstallCoreBundle; use OC\Repair\NC12\UpdateLanguageCodes; use OC\Repair\OldGroupMembershipShares; +use OC\Repair\Owncloud\SaveAccountsTableData; use OC\Repair\RemoveRootShares; use OC\Repair\SqliteAutoincrement; use OC\Repair\RepairMimeTypes; @@ -166,9 +167,11 @@ class Repair implements IOutput{ */ public static function getBeforeUpgradeRepairSteps() { $connection = \OC::$server->getDatabaseConnection(); + $config = \OC::$server->getConfig(); $steps = [ new Collation(\OC::$server->getConfig(), \OC::$server->getLogger(), $connection, true), new SqliteAutoincrement($connection), + new SaveAccountsTableData($connection, $config), ]; return $steps; diff --git a/lib/private/Repair/Owncloud/SaveAccountsTableData.php b/lib/private/Repair/Owncloud/SaveAccountsTableData.php new file mode 100644 index 00000000000..0c3fc67d7d9 --- /dev/null +++ b/lib/private/Repair/Owncloud/SaveAccountsTableData.php @@ -0,0 +1,178 @@ +<?php +/** + * @copyright Copyright (c) 2017 Joas Schilling <coding@schilljs.com> + * + * @author Joas Schilling <coding@schilljs.com> + * + * @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 <http://www.gnu.org/licenses/>. + * + */ + +namespace OC\Repair\Owncloud; + +use Doctrine\DBAL\Exception\InvalidFieldNameException; +use OCP\DB\QueryBuilder\IQueryBuilder; +use OCP\IConfig; +use OCP\IDBConnection; +use OCP\Migration\IOutput; +use OCP\Migration\IRepairStep; +use OCP\PreConditionNotMetException; + +/** + * Copies the email address from the accounts table to the preference table, + * before the data structure is changed and the information is gone + */ +class SaveAccountsTableData implements IRepairStep { + + const BATCH_SIZE = 75; + + /** @var IDBConnection */ + protected $db; + + /** @var IConfig */ + protected $config; + + /** + * @param IDBConnection $db + * @param IConfig $config + */ + public function __construct(IDBConnection $db, IConfig $config) { + $this->db = $db; + $this->config = $config; + } + + /** + * @return string + */ + public function getName() { + return 'Copy data from accounts table when migrating from ownCloud'; + } + + /** + * @param IOutput $output + */ + public function run(IOutput $output) { + if (!$this->shouldRun()) { + return; + } + + $offset = 0; + $numUsers = $this->runStep($offset); + + while ($numUsers === self::BATCH_SIZE) { + $offset += $numUsers; + $numUsers = $this->runStep($offset); + } + + // Clear the table + $query = $this->db->getQueryBuilder(); + $query->delete('accounts'); + $query->execute(); + } + + /** + * @return bool + */ + protected function shouldRun() { + $query = $this->db->getQueryBuilder(); + $query->select('*') + ->from('accounts') + ->where($query->expr()->isNotNull('user_id')) + ->setMaxResults(1); + + try { + $query->execute(); + return true; + } catch (InvalidFieldNameException $e) { + return false; + } + } + + /** + * @param int $offset + * @return int Number of copied users + */ + protected function runStep($offset) { + $query = $this->db->getQueryBuilder(); + $query->select('*') + ->from('accounts') + ->orderBy('id') + ->setMaxResults(self::BATCH_SIZE); + + if ($offset > 0) { + $query->setFirstResult($offset); + } + + $result = $query->execute(); + + $update = $this->db->getQueryBuilder(); + $update->update('users') + ->set('displayname', $update->createParameter('displayname')) + ->where($update->expr()->eq('uid', $update->createParameter('userid'))); + + $updatedUsers = 0; + while ($row = $result->fetch()) { + try { + $this->migrateUserInfo($update, $row); + } catch (PreConditionNotMetException $e) { + // Ignore and continue + } catch (\UnexpectedValueException $e) { + // Ignore and continue + } + $updatedUsers++; + } + $result->closeCursor(); + + return $updatedUsers; + } + + /** + * @param IQueryBuilder $update + * @param array $userdata + * @throws PreConditionNotMetException + * @throws \UnexpectedValueException + */ + protected function migrateUserInfo(IQueryBuilder $update, $userdata) { + if ($userdata['state'] === '3') { + // Deleted user, ignore + return; + } + + if ($userdata['email'] !== null) { + $this->config->setUserValue($userdata['user_id'], 'settings', 'email', $userdata['email']); + } + if ($userdata['quota'] !== null) { + $this->config->setUserValue($userdata['user_id'], 'files', 'quota', $userdata['quota']); + } + if ($userdata['last_login'] !== null) { + $this->config->setUserValue($userdata['user_id'], 'login', 'lastLogin', $userdata['last_login']); + } + if ($userdata['state'] === '1') { + $this->config->setUserValue($userdata['user_id'], 'core', 'enabled', 'true'); + } + if ($userdata['state'] === '2') { + $this->config->setUserValue($userdata['user_id'], 'core', 'enabled', 'false'); + } + + if ($userdata['display_name'] !== null) { + $update->setParameter('displayname', $userdata['display_name']) + ->setParameter('userid', $userdata['user_id']); + $update->execute(); + } + + } +} + diff --git a/version.php b/version.php index eb6254a777f..37e15f35e1f 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(12, 0, 0, 21); +$OC_Version = array(12, 0, 0, 22); // The human readable string $OC_VersionString = '12.0 beta 4'; |