diff options
author | Morris Jobke <hey@morrisjobke.de> | 2015-03-26 19:36:18 +0100 |
---|---|---|
committer | Morris Jobke <hey@morrisjobke.de> | 2015-03-26 19:36:18 +0100 |
commit | 70e64822b985763c2029681b870c023c16598412 (patch) | |
tree | c84f081a44fe10d2952cc6b3fc499047e0eb27b3 /lib | |
parent | 9c6649f4f181bb1c3a452d0fe1f210430e955f03 (diff) | |
parent | f056558b72db3a2eac72ac4e1b2889f7f7940b6a (diff) | |
download | nextcloud-server-70e64822b985763c2029681b870c023c16598412.tar.gz nextcloud-server-70e64822b985763c2029681b870c023c16598412.zip |
Merge pull request #14665 from owncloud/fileid-increment
SQLite autoincrement test
Diffstat (limited to 'lib')
-rw-r--r-- | lib/private/db/connectionfactory.php | 1 | ||||
-rw-r--r-- | lib/private/db/ocsqliteplatform.php | 35 | ||||
-rw-r--r-- | lib/private/repair.php | 2 | ||||
-rw-r--r-- | lib/repair/sqliteautoincrement.php | 85 |
4 files changed, 123 insertions, 0 deletions
diff --git a/lib/private/db/connectionfactory.php b/lib/private/db/connectionfactory.php index 67e0d86710b..83a59cddd7f 100644 --- a/lib/private/db/connectionfactory.php +++ b/lib/private/db/connectionfactory.php @@ -113,6 +113,7 @@ class ConnectionFactory { break; case 'sqlite3': $journalMode = $additionalConnectionParams['sqlite.journal_mode']; + $additionalConnectionParams['platform'] = new OCSqlitePlatform(); $eventManager->addEventSubscriber(new SQLiteSessionInit(true, $journalMode)); break; } diff --git a/lib/private/db/ocsqliteplatform.php b/lib/private/db/ocsqliteplatform.php new file mode 100644 index 00000000000..fe39e20c864 --- /dev/null +++ b/lib/private/db/ocsqliteplatform.php @@ -0,0 +1,35 @@ +<?php +/** + * Copyright (c) 2015 Robin Appelman <icewind@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\DB; + +class OCSqlitePlatform extends \Doctrine\DBAL\Platforms\SqlitePlatform { + /** + * {@inheritDoc} + */ + public function getColumnDeclarationSQL($name, array $field) { + $def = parent::getColumnDeclarationSQL($name, $field); + if (!empty($field['autoincrement'])) { + $def .= ' PRIMARY KEY AUTOINCREMENT'; + } + return $def; + } + + /** + * {@inheritDoc} + */ + protected function _getCreateTableSQL($name, array $columns, array $options = array()){ + // if auto increment is set the column is already defined as primary key + foreach ($columns as $column) { + if (!empty($column['autoincrement'])) { + $options['primary'] = null; + } + } + return parent::_getCreateTableSQL($name, $columns, $options); + } +} diff --git a/lib/private/repair.php b/lib/private/repair.php index 19ba53c2bcc..0674207bbee 100644 --- a/lib/private/repair.php +++ b/lib/private/repair.php @@ -32,6 +32,7 @@ use OC\Hooks\Emitter; use OC\Repair\AssetCache; use OC\Repair\CleanTags; use OC\Repair\Collation; +use OC\Repair\SqliteAutoincrement; use OC\Repair\DropOldTables; use OC\Repair\FillETags; use OC\Repair\InnoDB; @@ -118,6 +119,7 @@ class Repair extends BasicEmitter { $steps = array( new InnoDB(), new Collation(\OC::$server->getConfig(), \OC_DB::getConnection()), + new SqliteAutoincrement(\OC_DB::getConnection()), new SearchLuceneTables(), new RepairConfig() ); diff --git a/lib/repair/sqliteautoincrement.php b/lib/repair/sqliteautoincrement.php new file mode 100644 index 00000000000..79b1fe7870e --- /dev/null +++ b/lib/repair/sqliteautoincrement.php @@ -0,0 +1,85 @@ +<?php +/** + * Copyright (c) 2015 Vincent Petry <pvince81@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Repair; + +use Doctrine\DBAL\Platforms\SqlitePlatform; +use Doctrine\DBAL\Schema\SchemaException; +use Doctrine\DBAL\Schema\SchemaDiff; +use Doctrine\DBAL\Schema\TableDiff; +use Doctrine\DBAL\Schema\ColumnDiff; +use OC\Hooks\BasicEmitter; + +/** + * Fixes Sqlite autoincrement by forcing the SQLite table schemas to be + * altered in order to retrigger SQL schema generation through OCSqlitePlatform. + */ +class SqliteAutoincrement extends BasicEmitter implements \OC\RepairStep { + /** + * @var \OC\DB\Connection + */ + protected $connection; + + /** + * @param \OC\DB\Connection $connection + */ + public function __construct($connection) { + $this->connection = $connection; + } + + public function getName() { + return 'Repair SQLite autoincrement'; + } + + /** + * Fix mime types + */ + public function run() { + if (!$this->connection->getDatabasePlatform() instanceof SqlitePlatform) { + return; + } + + $sourceSchema = $this->connection->getSchemaManager()->createSchema(); + + $schemaDiff = new SchemaDiff(); + + foreach ($sourceSchema->getTables() as $tableSchema) { + $primaryKey = $tableSchema->getPrimaryKey(); + if (!$primaryKey) { + continue; + } + + $columnNames = $primaryKey->getColumns(); + + // add a column diff for every primary key column, + // but do not actually change anything, this will + // force the generation of SQL statements to alter + // those tables, which will then trigger the + // specific SQL code from OCSqlitePlatform + try { + $tableDiff = new TableDiff($tableSchema->getName()); + $tableDiff->fromTable = $tableSchema; + foreach ($columnNames as $columnName) { + $columnSchema = $tableSchema->getColumn($columnName); + $columnDiff = new ColumnDiff($columnSchema->getName(), $columnSchema); + $tableDiff->changedColumns[] = $columnDiff; + $schemaDiff->changedTables[] = $tableDiff; + } + } catch (SchemaException $e) { + // ignore + } + } + + $this->connection->beginTransaction(); + foreach ($schemaDiff->toSql($this->connection->getDatabasePlatform()) as $sql) { + $this->connection->query($sql); + } + $this->connection->commit(); + } +} + |