diff options
author | Morris Jobke <hey@morrisjobke.de> | 2017-09-29 12:23:41 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-09-29 12:23:41 +0200 |
commit | 870d71689ab95a821d041a972d77637a9a2be988 (patch) | |
tree | 6f4816807c0249ae56d4ccf9eac3799df4cd78ef /lib | |
parent | 993dc77d9ea6691d839c02ba0e75d7afafe33540 (diff) | |
parent | f2054123713289b16d13701d2aa73691653f8d46 (diff) | |
download | nextcloud-server-870d71689ab95a821d041a972d77637a9a2be988.tar.gz nextcloud-server-870d71689ab95a821d041a972d77637a9a2be988.zip |
Merge pull request #6563 from nextcloud/bigint-ids
Migrate ID columns to bigint
Diffstat (limited to 'lib')
-rw-r--r-- | lib/composer/composer/autoload_classmap.php | 3 | ||||
-rw-r--r-- | lib/composer/composer/autoload_static.php | 3 | ||||
-rw-r--r-- | lib/private/DB/ConnectionFactory.php | 4 | ||||
-rw-r--r-- | lib/private/DB/OCPostgreSqlPlatform.php | 94 | ||||
-rw-r--r-- | lib/public/Migration/BigIntMigration.php | 66 |
5 files changed, 170 insertions, 0 deletions
diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php index 29bca415ed6..50bd6d33274 100644 --- a/lib/composer/composer/autoload_classmap.php +++ b/lib/composer/composer/autoload_classmap.php @@ -222,6 +222,7 @@ return array( 'OCP\\Lockdown\\ILockdownManager' => $baseDir . '/lib/public/Lockdown/ILockdownManager.php', 'OCP\\Mail\\IEMailTemplate' => $baseDir . '/lib/public/Mail/IEMailTemplate.php', 'OCP\\Mail\\IMailer' => $baseDir . '/lib/public/Mail/IMailer.php', + 'OCP\\Migration\\BigIntMigration' => $baseDir . '/lib/public/Migration/BigIntMigration.php', 'OCP\\Migration\\IMigrationStep' => $baseDir . '/lib/public/Migration/IMigrationStep.php', 'OCP\\Migration\\IOutput' => $baseDir . '/lib/public/Migration/IOutput.php', 'OCP\\Migration\\IRepairStep' => $baseDir . '/lib/public/Migration/IRepairStep.php', @@ -498,6 +499,7 @@ return array( 'OC\\Core\\Migrations\\Version13000Date20170718121200' => $baseDir . '/core/Migrations/Version13000Date20170718121200.php', 'OC\\Core\\Migrations\\Version13000Date20170814074715' => $baseDir . '/core/Migrations/Version13000Date20170814074715.php', 'OC\\Core\\Migrations\\Version13000Date20170919121250' => $baseDir . '/core/Migrations/Version13000Date20170919121250.php', + 'OC\\Core\\Migrations\\Version13000Date20170926101637' => $baseDir . '/core/Migrations/Version13000Date20170926101637.php', 'OC\\DB\\Adapter' => $baseDir . '/lib/private/DB/Adapter.php', 'OC\\DB\\AdapterMySQL' => $baseDir . '/lib/private/DB/AdapterMySQL.php', 'OC\\DB\\AdapterOCI8' => $baseDir . '/lib/private/DB/AdapterOCI8.php', @@ -514,6 +516,7 @@ return array( 'OC\\DB\\MySQLMigrator' => $baseDir . '/lib/private/DB/MySQLMigrator.php', 'OC\\DB\\MySqlTools' => $baseDir . '/lib/private/DB/MySqlTools.php', 'OC\\DB\\NoCheckMigrator' => $baseDir . '/lib/private/DB/NoCheckMigrator.php', + 'OC\\DB\\OCPostgreSqlPlatform' => $baseDir . '/lib/private/DB/OCPostgreSqlPlatform.php', 'OC\\DB\\OCSqlitePlatform' => $baseDir . '/lib/private/DB/OCSqlitePlatform.php', 'OC\\DB\\OracleConnection' => $baseDir . '/lib/private/DB/OracleConnection.php', 'OC\\DB\\OracleMigrator' => $baseDir . '/lib/private/DB/OracleMigrator.php', diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php index 4cfbbcc2e39..1828957b32a 100644 --- a/lib/composer/composer/autoload_static.php +++ b/lib/composer/composer/autoload_static.php @@ -252,6 +252,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c 'OCP\\Lockdown\\ILockdownManager' => __DIR__ . '/../../..' . '/lib/public/Lockdown/ILockdownManager.php', 'OCP\\Mail\\IEMailTemplate' => __DIR__ . '/../../..' . '/lib/public/Mail/IEMailTemplate.php', 'OCP\\Mail\\IMailer' => __DIR__ . '/../../..' . '/lib/public/Mail/IMailer.php', + 'OCP\\Migration\\BigIntMigration' => __DIR__ . '/../../..' . '/lib/public/Migration/BigIntMigration.php', 'OCP\\Migration\\IMigrationStep' => __DIR__ . '/../../..' . '/lib/public/Migration/IMigrationStep.php', 'OCP\\Migration\\IOutput' => __DIR__ . '/../../..' . '/lib/public/Migration/IOutput.php', 'OCP\\Migration\\IRepairStep' => __DIR__ . '/../../..' . '/lib/public/Migration/IRepairStep.php', @@ -528,6 +529,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c 'OC\\Core\\Migrations\\Version13000Date20170718121200' => __DIR__ . '/../../..' . '/core/Migrations/Version13000Date20170718121200.php', 'OC\\Core\\Migrations\\Version13000Date20170814074715' => __DIR__ . '/../../..' . '/core/Migrations/Version13000Date20170814074715.php', 'OC\\Core\\Migrations\\Version13000Date20170919121250' => __DIR__ . '/../../..' . '/core/Migrations/Version13000Date20170919121250.php', + 'OC\\Core\\Migrations\\Version13000Date20170926101637' => __DIR__ . '/../../..' . '/core/Migrations/Version13000Date20170926101637.php', 'OC\\DB\\Adapter' => __DIR__ . '/../../..' . '/lib/private/DB/Adapter.php', 'OC\\DB\\AdapterMySQL' => __DIR__ . '/../../..' . '/lib/private/DB/AdapterMySQL.php', 'OC\\DB\\AdapterOCI8' => __DIR__ . '/../../..' . '/lib/private/DB/AdapterOCI8.php', @@ -544,6 +546,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c 'OC\\DB\\MySQLMigrator' => __DIR__ . '/../../..' . '/lib/private/DB/MySQLMigrator.php', 'OC\\DB\\MySqlTools' => __DIR__ . '/../../..' . '/lib/private/DB/MySqlTools.php', 'OC\\DB\\NoCheckMigrator' => __DIR__ . '/../../..' . '/lib/private/DB/NoCheckMigrator.php', + 'OC\\DB\\OCPostgreSqlPlatform' => __DIR__ . '/../../..' . '/lib/private/DB/OCPostgreSqlPlatform.php', 'OC\\DB\\OCSqlitePlatform' => __DIR__ . '/../../..' . '/lib/private/DB/OCSqlitePlatform.php', 'OC\\DB\\OracleConnection' => __DIR__ . '/../../..' . '/lib/private/DB/OracleConnection.php', 'OC\\DB\\OracleMigrator' => __DIR__ . '/../../..' . '/lib/private/DB/OracleMigrator.php', diff --git a/lib/private/DB/ConnectionFactory.php b/lib/private/DB/ConnectionFactory.php index d90d7737d40..8848f6db3b4 100644 --- a/lib/private/DB/ConnectionFactory.php +++ b/lib/private/DB/ConnectionFactory.php @@ -137,6 +137,10 @@ class ConnectionFactory { } unset($additionalConnectionParams['host']); break; + + case 'pgsql': + $additionalConnectionParams['platform'] = new OCPostgreSqlPlatform(); + break; case 'sqlite3': $journalMode = $additionalConnectionParams['sqlite.journal_mode']; $additionalConnectionParams['platform'] = new OCSqlitePlatform(); diff --git a/lib/private/DB/OCPostgreSqlPlatform.php b/lib/private/DB/OCPostgreSqlPlatform.php new file mode 100644 index 00000000000..524a62c2beb --- /dev/null +++ b/lib/private/DB/OCPostgreSqlPlatform.php @@ -0,0 +1,94 @@ +<?php +/** + * @author Victor Dubiniuk <dubiniuk@owncloud.com> + * + * @copyright Copyright (c) 2017, ownCloud GmbH + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * 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, version 3, + * along with this program. If not, see <http://www.gnu.org/licenses/> + * + */ + +namespace OC\DB; + +use Doctrine\DBAL\Platforms\PostgreSqlPlatform; +use Doctrine\DBAL\Schema\ColumnDiff; +use Doctrine\DBAL\Schema\TableDiff; +use Doctrine\DBAL\Types\Type; + +class OCPostgreSqlPlatform extends PostgreSqlPlatform { + + /** + * {@inheritDoc} + */ + public function getAlterTableSQL(TableDiff $diff){ + $queries = parent::getAlterTableSQL($diff); + foreach ($queries as $index => $sql){ + // BIGSERIAL could not be used in statements altering column type + // That's why we replace it with BIGINT + // see https://github.com/owncloud/core/pull/28364#issuecomment-315006853 + if (preg_match('|(ALTER TABLE\s+\S+\s+ALTER\s+\S+\s+TYPE\s+)(BIGSERIAL)|i', $sql, $matches)) { + $alterTable = $matches[1]; + $queries[$index] = $alterTable . 'BIGINT'; + } + + // Changing integer to bigint kills next autoincrement value + // see https://github.com/owncloud/core/pull/28364#issuecomment-315006853 + if (preg_match('|ALTER TABLE\s+(\S+)\s+ALTER\s+(\S+)\s+DROP DEFAULT|i', $sql, $matches)) { + $queryColumnName = $matches[2]; + $columnDiff = $this->findColumnDiffByName($diff, $queryColumnName); + if ($columnDiff && $this->shouldSkipDropDefault($columnDiff)) { + unset($queries[$index]); + continue; + } + } + } + + return $queries; + } + + /** + * We should NOT drop next sequence value if + * - type was changed from INTEGER to BIGINT + * - column keeps an autoincrement + * - default value is kept NULL + * + * @param ColumnDiff $columnDiff + * @return bool + */ + private function shouldSkipDropDefault(ColumnDiff $columnDiff) { + $column = $columnDiff->column; + $fromColumn = $columnDiff->fromColumn; + return $fromColumn->getType()->getName() === Type::INTEGER + && $column->getType()->getName() === Type::BIGINT + && $fromColumn->getDefault() === null + && $column->getDefault() === null + && $fromColumn->getAutoincrement() + && $column->getAutoincrement(); + } + + /** + * @param TableDiff $diff + * @param string $name + * @return ColumnDiff | false + */ + private function findColumnDiffByName(TableDiff $diff, $name) { + foreach ($diff->changedColumns as $columnDiff) { + $oldColumnName = $columnDiff->getOldColumnName()->getQuotedName($this); + if ($oldColumnName === $name) { + return $columnDiff; + } + } + return false; + } +} diff --git a/lib/public/Migration/BigIntMigration.php b/lib/public/Migration/BigIntMigration.php new file mode 100644 index 00000000000..91722671860 --- /dev/null +++ b/lib/public/Migration/BigIntMigration.php @@ -0,0 +1,66 @@ +<?php +/** + * @copyright Copyright (c) 2017 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 OCP\Migration; + +use Doctrine\DBAL\Schema\Schema; +use Doctrine\DBAL\Types\Type; + +/** + * @since 13.0.0 + */ +abstract class BigIntMigration extends SimpleMigrationStep { + + /** + * @return array Returns an array with the following structure + * ['table1' => ['column1', 'column2'], ...] + * @since 13.0.0 + */ + abstract protected function getColumnsByTable(); + + /** + * @param IOutput $output + * @param \Closure $schemaClosure The `\Closure` returns a `Schema` + * @param array $options + * @return null|Schema + * @since 13.0.0 + */ + public function changeSchema(IOutput $output, \Closure $schemaClosure, array $options) { + /** @var Schema $schema */ + $schema = $schemaClosure(); + + $tables = $this->getColumnsByTable(); + + foreach ($tables as $tableName => $columns) { + $table = $schema->getTable($tableName); + + foreach ($columns as $columnName) { + $column = $table->getColumn($columnName); + if ($column->getType()->getName() !== Type::BIGINT) { + $column->setType(Type::getType(Type::BIGINT)); + $column->setOptions(['length' => 20]); + } + } + } + + return $schema; + } +} |