summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorMorris Jobke <hey@morrisjobke.de>2017-09-29 12:23:41 +0200
committerGitHub <noreply@github.com>2017-09-29 12:23:41 +0200
commit870d71689ab95a821d041a972d77637a9a2be988 (patch)
tree6f4816807c0249ae56d4ccf9eac3799df4cd78ef /lib
parent993dc77d9ea6691d839c02ba0e75d7afafe33540 (diff)
parentf2054123713289b16d13701d2aa73691653f8d46 (diff)
downloadnextcloud-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.php3
-rw-r--r--lib/composer/composer/autoload_static.php3
-rw-r--r--lib/private/DB/ConnectionFactory.php4
-rw-r--r--lib/private/DB/OCPostgreSqlPlatform.php94
-rw-r--r--lib/public/Migration/BigIntMigration.php66
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;
+ }
+}