Merge pull request #38556 from nextcloud/techdebt/noid/doctrine/dbal-to-3.6.2

chore(deps): Bump doctrine/dbal to 3.7.x
This commit is contained in:
Joas Schilling 2023-10-06 16:21:07 +02:00 committed by GitHub
commit 71cd97c37f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 112 additions and 501 deletions

@ -1 +1 @@
Subproject commit a983a316487c666d6602923f0c067e32299501ba
Subproject commit e6c45c6c0d4f92ffec621446fcc3b34584772b13

View file

@ -0,0 +1,5 @@
<?php
#[\Attribute(Attribute::TARGET_PARAMETER)]
class SensitiveParameter {
}

View file

@ -1194,14 +1194,12 @@ return array(
'OC\\DB\\MissingColumnInformation' => $baseDir . '/lib/private/DB/MissingColumnInformation.php',
'OC\\DB\\MissingIndexInformation' => $baseDir . '/lib/private/DB/MissingIndexInformation.php',
'OC\\DB\\MissingPrimaryKeyInformation' => $baseDir . '/lib/private/DB/MissingPrimaryKeyInformation.php',
'OC\\DB\\MySQLMigrator' => $baseDir . '/lib/private/DB/MySQLMigrator.php',
'OC\\DB\\MySqlTools' => $baseDir . '/lib/private/DB/MySqlTools.php',
'OC\\DB\\OCSqlitePlatform' => $baseDir . '/lib/private/DB/OCSqlitePlatform.php',
'OC\\DB\\ObjectParameter' => $baseDir . '/lib/private/DB/ObjectParameter.php',
'OC\\DB\\OracleConnection' => $baseDir . '/lib/private/DB/OracleConnection.php',
'OC\\DB\\OracleMigrator' => $baseDir . '/lib/private/DB/OracleMigrator.php',
'OC\\DB\\PgSqlTools' => $baseDir . '/lib/private/DB/PgSqlTools.php',
'OC\\DB\\PostgreSqlMigrator' => $baseDir . '/lib/private/DB/PostgreSqlMigrator.php',
'OC\\DB\\PreparedStatement' => $baseDir . '/lib/private/DB/PreparedStatement.php',
'OC\\DB\\QueryBuilder\\CompositeExpression' => $baseDir . '/lib/private/DB/QueryBuilder/CompositeExpression.php',
'OC\\DB\\QueryBuilder\\ExpressionBuilder\\ExpressionBuilder' => $baseDir . '/lib/private/DB/QueryBuilder/ExpressionBuilder/ExpressionBuilder.php',
@ -1594,7 +1592,6 @@ return array(
'OC\\Repair\\RepairDavShares' => $baseDir . '/lib/private/Repair/RepairDavShares.php',
'OC\\Repair\\RepairInvalidShares' => $baseDir . '/lib/private/Repair/RepairInvalidShares.php',
'OC\\Repair\\RepairMimeTypes' => $baseDir . '/lib/private/Repair/RepairMimeTypes.php',
'OC\\Repair\\SqliteAutoincrement' => $baseDir . '/lib/private/Repair/SqliteAutoincrement.php',
'OC\\RichObjectStrings\\Validator' => $baseDir . '/lib/private/RichObjectStrings/Validator.php',
'OC\\Route\\CachingRouter' => $baseDir . '/lib/private/Route/CachingRouter.php',
'OC\\Route\\Route' => $baseDir . '/lib/private/Route/Route.php',

View file

@ -1227,14 +1227,12 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OC\\DB\\MissingColumnInformation' => __DIR__ . '/../../..' . '/lib/private/DB/MissingColumnInformation.php',
'OC\\DB\\MissingIndexInformation' => __DIR__ . '/../../..' . '/lib/private/DB/MissingIndexInformation.php',
'OC\\DB\\MissingPrimaryKeyInformation' => __DIR__ . '/../../..' . '/lib/private/DB/MissingPrimaryKeyInformation.php',
'OC\\DB\\MySQLMigrator' => __DIR__ . '/../../..' . '/lib/private/DB/MySQLMigrator.php',
'OC\\DB\\MySqlTools' => __DIR__ . '/../../..' . '/lib/private/DB/MySqlTools.php',
'OC\\DB\\OCSqlitePlatform' => __DIR__ . '/../../..' . '/lib/private/DB/OCSqlitePlatform.php',
'OC\\DB\\ObjectParameter' => __DIR__ . '/../../..' . '/lib/private/DB/ObjectParameter.php',
'OC\\DB\\OracleConnection' => __DIR__ . '/../../..' . '/lib/private/DB/OracleConnection.php',
'OC\\DB\\OracleMigrator' => __DIR__ . '/../../..' . '/lib/private/DB/OracleMigrator.php',
'OC\\DB\\PgSqlTools' => __DIR__ . '/../../..' . '/lib/private/DB/PgSqlTools.php',
'OC\\DB\\PostgreSqlMigrator' => __DIR__ . '/../../..' . '/lib/private/DB/PostgreSqlMigrator.php',
'OC\\DB\\PreparedStatement' => __DIR__ . '/../../..' . '/lib/private/DB/PreparedStatement.php',
'OC\\DB\\QueryBuilder\\CompositeExpression' => __DIR__ . '/../../..' . '/lib/private/DB/QueryBuilder/CompositeExpression.php',
'OC\\DB\\QueryBuilder\\ExpressionBuilder\\ExpressionBuilder' => __DIR__ . '/../../..' . '/lib/private/DB/QueryBuilder/ExpressionBuilder/ExpressionBuilder.php',
@ -1627,7 +1625,6 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OC\\Repair\\RepairDavShares' => __DIR__ . '/../../..' . '/lib/private/Repair/RepairDavShares.php',
'OC\\Repair\\RepairInvalidShares' => __DIR__ . '/../../..' . '/lib/private/Repair/RepairInvalidShares.php',
'OC\\Repair\\RepairMimeTypes' => __DIR__ . '/../../..' . '/lib/private/Repair/RepairMimeTypes.php',
'OC\\Repair\\SqliteAutoincrement' => __DIR__ . '/../../..' . '/lib/private/Repair/SqliteAutoincrement.php',
'OC\\RichObjectStrings\\Validator' => __DIR__ . '/../../..' . '/lib/private/RichObjectStrings/Validator.php',
'OC\\Route\\CachingRouter' => __DIR__ . '/../../..' . '/lib/private/Route/CachingRouter.php',
'OC\\Route\\Route' => __DIR__ . '/../../..' . '/lib/private/Route/Route.php',

View file

@ -42,7 +42,6 @@ use Doctrine\DBAL\Driver;
use Doctrine\DBAL\Exception;
use Doctrine\DBAL\Platforms\MySQLPlatform;
use Doctrine\DBAL\Platforms\OraclePlatform;
use Doctrine\DBAL\Platforms\PostgreSQL94Platform;
use Doctrine\DBAL\Platforms\SqlitePlatform;
use Doctrine\DBAL\Result;
use Doctrine\DBAL\Schema\Schema;
@ -600,10 +599,6 @@ class Connection extends \Doctrine\DBAL\Connection {
return new SQLiteMigrator($this, $config, $dispatcher);
} elseif ($platform instanceof OraclePlatform) {
return new OracleMigrator($this, $config, $dispatcher);
} elseif ($platform instanceof MySQLPlatform) {
return new MySQLMigrator($this, $config, $dispatcher);
} elseif ($platform instanceof PostgreSQL94Platform) {
return new PostgreSqlMigrator($this, $config, $dispatcher);
} else {
return new Migrator($this, $config, $dispatcher);
}

View file

@ -31,7 +31,6 @@ use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Exception;
use Doctrine\DBAL\Platforms\MySQLPlatform;
use Doctrine\DBAL\Schema\AbstractAsset;
use Doctrine\DBAL\Schema\Comparator;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Schema\SchemaDiff;
use Doctrine\DBAL\Types\StringType;
@ -75,7 +74,7 @@ class Migrator {
$schemaDiff = $this->getDiff($targetSchema, $this->connection);
$script = '';
$sqls = $schemaDiff->toSql($this->connection->getDatabasePlatform());
$sqls = $this->connection->getDatabasePlatform()->getAlterSchemaSQL($schemaDiff);
foreach ($sqls as $sql) {
$script .= $this->convertStatementToScript($sql);
}
@ -95,18 +94,20 @@ class Migrator {
}
return preg_match($filterExpression, $asset) === 1;
});
return $this->connection->getSchemaManager()->createSchema();
return $this->connection->createSchemaManager()->introspectSchema();
}
/**
* @return SchemaDiff
*/
protected function getDiff(Schema $targetSchema, Connection $connection) {
// adjust varchar columns with a length higher then getVarcharMaxLength to clob
// Adjust STRING columns with a length higher than 4000 to TEXT (clob)
// for consistency between the supported databases and
// old vs. new installations.
foreach ($targetSchema->getTables() as $table) {
foreach ($table->getColumns() as $column) {
if ($column->getType() instanceof StringType) {
if ($column->getLength() > $connection->getDatabasePlatform()->getVarcharMaxLength()) {
if ($column->getLength() > 4000) {
$column->setType(Type::getType('text'));
$column->setLength(null);
}
@ -122,7 +123,7 @@ class Migrator {
}
return preg_match($filterExpression, $asset) === 1;
});
$sourceSchema = $connection->getSchemaManager()->createSchema();
$sourceSchema = $connection->createSchemaManager()->introspectSchema();
// remove tables we don't know about
foreach ($sourceSchema->getTables() as $table) {
@ -137,9 +138,8 @@ class Migrator {
}
}
/** @psalm-suppress InternalMethod */
$comparator = new Comparator();
return $comparator->compare($sourceSchema, $targetSchema);
$comparator = $connection->createSchemaManager()->createComparator();
return $comparator->compareSchemas($sourceSchema, $targetSchema);
}
/**
@ -155,7 +155,7 @@ class Migrator {
if (!$connection->getDatabasePlatform() instanceof MySQLPlatform) {
$connection->beginTransaction();
}
$sqls = $schemaDiff->toSql($connection->getDatabasePlatform());
$sqls = $connection->getDatabasePlatform()->getAlterSchemaSQL($schemaDiff);
$step = 0;
foreach ($sqls as $sql) {
$this->emit($sql, $step++, count($sqls));
@ -178,7 +178,7 @@ class Migrator {
}
protected function getFilterExpression() {
return '/^' . preg_quote($this->config->getSystemValueString('dbtableprefix', 'oc_')) . '/';
return '/^' . preg_quote($this->config->getSystemValueString('dbtableprefix', 'oc_'), '/') . '/';
}
protected function emit(string $sql, int $step, int $max): void {

View file

@ -1,50 +0,0 @@
<?php
/**
* @copyright Copyright (c) 2016, ownCloud, Inc.
*
* @author Robin Appelman <robin@icewind.nl>
* @author Thomas Müller <thomas.mueller@tmit.eu>
*
* @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\Schema\Schema;
class MySQLMigrator extends Migrator {
/**
* @param Schema $targetSchema
* @param \Doctrine\DBAL\Connection $connection
* @return \Doctrine\DBAL\Schema\SchemaDiff
*/
protected function getDiff(Schema $targetSchema, \Doctrine\DBAL\Connection $connection) {
$platform = $connection->getDatabasePlatform();
$platform->registerDoctrineTypeMapping('enum', 'string');
$platform->registerDoctrineTypeMapping('bit', 'string');
$schemaDiff = parent::getDiff($targetSchema, $connection);
// identifiers need to be quoted for mysql
foreach ($schemaDiff->changedTables as $tableDiff) {
$tableDiff->name = $this->connection->quoteIdentifier($tableDiff->name);
foreach ($tableDiff->changedColumns as $column) {
$column->oldColumnName = $this->connection->quoteIdentifier($column->oldColumnName);
}
}
return $schemaDiff;
}
}

View file

@ -1,5 +1,8 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2023, Joas Schilling <coding@schilljs.com>
* @copyright Copyright (c) 2016, ownCloud, Inc.
*
* @author Christoph Wurst <christoph@winzerhof-wurst.at>
@ -29,176 +32,114 @@
namespace OC\DB;
use Doctrine\DBAL\Exception;
use Doctrine\DBAL\Schema\Column;
use Doctrine\DBAL\Schema\ColumnDiff;
use Doctrine\DBAL\Schema\ForeignKeyConstraint;
use Doctrine\DBAL\Schema\Index;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Schema\Table;
class OracleMigrator extends Migrator {
/**
* Quote a column's name but changing the name requires recreating
* the column instance and copying over all properties.
*
* @param Column $column old column
* @return Column new column instance with new name
*/
protected function quoteColumn(Column $column) {
$newColumn = new Column(
$this->connection->quoteIdentifier($column->getName()),
$column->getType()
);
$newColumn->setAutoincrement($column->getAutoincrement());
$newColumn->setColumnDefinition($column->getColumnDefinition());
$newColumn->setComment($column->getComment());
$newColumn->setDefault($column->getDefault());
$newColumn->setFixed($column->getFixed());
$newColumn->setLength($column->getLength());
$newColumn->setNotnull($column->getNotnull());
$newColumn->setPrecision($column->getPrecision());
$newColumn->setScale($column->getScale());
$newColumn->setUnsigned($column->getUnsigned());
$newColumn->setPlatformOptions($column->getPlatformOptions());
$newColumn->setCustomSchemaOptions($column->getPlatformOptions());
return $newColumn;
}
/**
* Quote an index's name but changing the name requires recreating
* the index instance and copying over all properties.
*
* @param Index $index old index
* @return Index new index instance with new name
*/
protected function quoteIndex($index) {
return new Index(
//TODO migrate existing uppercase indexes, then $this->connection->quoteIdentifier($index->getName()),
$index->getName(),
array_map(function ($columnName) {
return $this->connection->quoteIdentifier($columnName);
}, $index->getColumns()),
$index->isUnique(),
$index->isPrimary(),
$index->getFlags(),
$index->getOptions()
);
}
/**
* Quote an ForeignKeyConstraint's name but changing the name requires recreating
* the ForeignKeyConstraint instance and copying over all properties.
*
* @param ForeignKeyConstraint $fkc old fkc
* @return ForeignKeyConstraint new fkc instance with new name
*/
protected function quoteForeignKeyConstraint($fkc) {
return new ForeignKeyConstraint(
array_map(function ($columnName) {
return $this->connection->quoteIdentifier($columnName);
}, $fkc->getLocalColumns()),
$this->connection->quoteIdentifier($fkc->getForeignTableName()),
array_map(function ($columnName) {
return $this->connection->quoteIdentifier($columnName);
}, $fkc->getForeignColumns()),
$fkc->getName(),
$fkc->getOptions()
);
}
/**
* @param Schema $targetSchema
* @param \Doctrine\DBAL\Connection $connection
* @return \Doctrine\DBAL\Schema\SchemaDiff
* @throws Exception
*/
protected function getDiff(Schema $targetSchema, \Doctrine\DBAL\Connection $connection) {
$schemaDiff = parent::getDiff($targetSchema, $connection);
protected function getDiff(Schema $targetSchema, \Doctrine\DBAL\Connection $connection): \Doctrine\DBAL\Schema\SchemaDiff {
// oracle forces us to quote the identifiers
$schemaDiff->newTables = array_map(function (Table $table) {
return new Table(
$quotedSchema = new Schema();
foreach ($targetSchema->getTables() as $table) {
$quotedTable = $quotedSchema->createTable(
$this->connection->quoteIdentifier($table->getName()),
array_map(function (Column $column) {
return $this->quoteColumn($column);
}, $table->getColumns()),
array_map(function (Index $index) {
return $this->quoteIndex($index);
}, $table->getIndexes()),
[],
array_map(function (ForeignKeyConstraint $fck) {
return $this->quoteForeignKeyConstraint($fck);
}, $table->getForeignKeys()),
$table->getOptions()
);
}, $schemaDiff->newTables);
$schemaDiff->removedTables = array_map(function (Table $table) {
return new Table(
$this->connection->quoteIdentifier($table->getName()),
$table->getColumns(),
$table->getIndexes(),
[],
$table->getForeignKeys(),
$table->getOptions()
);
}, $schemaDiff->removedTables);
foreach ($schemaDiff->changedTables as $tableDiff) {
$tableDiff->name = $this->connection->quoteIdentifier($tableDiff->name);
$tableDiff->addedColumns = array_map(function (Column $column) {
return $this->quoteColumn($column);
}, $tableDiff->addedColumns);
foreach ($tableDiff->changedColumns as $column) {
$column->oldColumnName = $this->connection->quoteIdentifier($column->oldColumnName);
// auto increment is not relevant for oracle and can anyhow not be applied on change
$column->changedProperties = array_diff($column->changedProperties, ['autoincrement', 'unsigned']);
foreach ($table->getColumns() as $column) {
$newColumn = $quotedTable->addColumn(
$this->connection->quoteIdentifier($column->getName()),
$column->getType()->getTypeRegistry()->lookupName($column->getType()),
);
$newColumn->setAutoincrement($column->getAutoincrement());
$newColumn->setColumnDefinition($column->getColumnDefinition());
$newColumn->setComment($column->getComment());
$newColumn->setDefault($column->getDefault());
$newColumn->setFixed($column->getFixed());
$newColumn->setLength($column->getLength());
$newColumn->setNotnull($column->getNotnull());
$newColumn->setPrecision($column->getPrecision());
$newColumn->setScale($column->getScale());
$newColumn->setUnsigned($column->getUnsigned());
$newColumn->setPlatformOptions($column->getPlatformOptions());
}
// remove columns that no longer have changed (because autoincrement and unsigned are not supported)
$tableDiff->changedColumns = array_filter($tableDiff->changedColumns, function (ColumnDiff $column) {
return count($column->changedProperties) > 0;
});
$tableDiff->removedColumns = array_map(function (Column $column) {
return $this->quoteColumn($column);
}, $tableDiff->removedColumns);
foreach ($table->getIndexes() as $index) {
if ($index->isPrimary()) {
$quotedTable->setPrimaryKey(
array_map(function ($columnName) {
return $this->connection->quoteIdentifier($columnName);
}, $index->getColumns()),
//TODO migrate existing uppercase indexes, then $this->connection->quoteIdentifier($index->getName()),
$index->getName(),
);
} elseif ($index->isUnique()) {
$quotedTable->addUniqueIndex(
array_map(function ($columnName) {
return $this->connection->quoteIdentifier($columnName);
}, $index->getColumns()),
//TODO migrate existing uppercase indexes, then $this->connection->quoteIdentifier($index->getName()),
$index->getName(),
$index->getOptions(),
);
} else {
$quotedTable->addIndex(
array_map(function ($columnName) {
return $this->connection->quoteIdentifier($columnName);
}, $index->getColumns()),
//TODO migrate existing uppercase indexes, then $this->connection->quoteIdentifier($index->getName()),
$index->getName(),
$index->getFlags(),
$index->getOptions(),
);
}
}
$tableDiff->renamedColumns = array_map(function (Column $column) {
return $this->quoteColumn($column);
}, $tableDiff->renamedColumns);
foreach ($table->getUniqueConstraints() as $constraint) {
$quotedTable->addUniqueConstraint(
array_map(function ($columnName) {
return $this->connection->quoteIdentifier($columnName);
}, $constraint->getColumns()),
$this->connection->quoteIdentifier($constraint->getName()),
$constraint->getFlags(),
$constraint->getOptions(),
);
}
$tableDiff->addedIndexes = array_map(function (Index $index) {
return $this->quoteIndex($index);
}, $tableDiff->addedIndexes);
foreach ($table->getForeignKeys() as $foreignKey) {
$quotedTable->addForeignKeyConstraint(
$this->connection->quoteIdentifier($foreignKey->getForeignTableName()),
array_map(function ($columnName) {
return $this->connection->quoteIdentifier($columnName);
}, $foreignKey->getLocalColumns()),
array_map(function ($columnName) {
return $this->connection->quoteIdentifier($columnName);
}, $foreignKey->getForeignColumns()),
$foreignKey->getOptions(),
$this->connection->quoteIdentifier($foreignKey->getName()),
);
}
$tableDiff->changedIndexes = array_map(function (Index $index) {
return $this->quoteIndex($index);
}, $tableDiff->changedIndexes);
$tableDiff->removedIndexes = array_map(function (Index $index) {
return $this->quoteIndex($index);
}, $tableDiff->removedIndexes);
$tableDiff->renamedIndexes = array_map(function (Index $index) {
return $this->quoteIndex($index);
}, $tableDiff->renamedIndexes);
$tableDiff->addedForeignKeys = array_map(function (ForeignKeyConstraint $fkc) {
return $this->quoteForeignKeyConstraint($fkc);
}, $tableDiff->addedForeignKeys);
$tableDiff->changedForeignKeys = array_map(function (ForeignKeyConstraint $fkc) {
return $this->quoteForeignKeyConstraint($fkc);
}, $tableDiff->changedForeignKeys);
$tableDiff->removedForeignKeys = array_map(function (ForeignKeyConstraint $fkc) {
return $this->quoteForeignKeyConstraint($fkc);
}, $tableDiff->removedForeignKeys);
foreach ($table->getOptions() as $option => $value) {
$quotedTable->addOption(
$option,
$value,
);
}
}
return $schemaDiff;
foreach ($targetSchema->getSequences() as $sequence) {
$quotedSchema->createSequence(
$sequence->getName(),
$sequence->getAllocationSize(),
$sequence->getInitialValue(),
);
}
return parent::getDiff($quotedSchema, $connection);
}
/**

View file

@ -1,55 +0,0 @@
<?php
/**
* @copyright Copyright (c) 2016, ownCloud, Inc.
*
* @author Thomas Müller <thomas.mueller@tmit.eu>
*
* @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\Schema\Schema;
class PostgreSqlMigrator extends Migrator {
/**
* @param Schema $targetSchema
* @param \Doctrine\DBAL\Connection $connection
* @return \Doctrine\DBAL\Schema\SchemaDiff
*/
protected function getDiff(Schema $targetSchema, \Doctrine\DBAL\Connection $connection) {
$schemaDiff = parent::getDiff($targetSchema, $connection);
foreach ($schemaDiff->changedTables as $tableDiff) {
// fix default value in brackets - pg 9.4 is returning a negative default value in ()
// see https://github.com/doctrine/dbal/issues/2427
foreach ($tableDiff->changedColumns as $column) {
$column->changedProperties = array_filter($column->changedProperties, function ($changedProperties) use ($column) {
if ($changedProperties !== 'default') {
return true;
}
$fromDefault = $column->fromColumn->getDefault();
$toDefault = $column->column->getDefault();
$fromDefault = trim((string) $fromDefault, '()');
// by intention usage of !=
return $fromDefault != $toDefault;
});
}
}
return $schemaDiff;
}
}

View file

@ -24,8 +24,6 @@
namespace OC\DB;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Types\BigIntType;
use Doctrine\DBAL\Types\Type;
class SQLiteMigrator extends Migrator {
/**
@ -34,21 +32,12 @@ class SQLiteMigrator extends Migrator {
* @return \Doctrine\DBAL\Schema\SchemaDiff
*/
protected function getDiff(Schema $targetSchema, \Doctrine\DBAL\Connection $connection) {
$platform = $connection->getDatabasePlatform();
$platform->registerDoctrineTypeMapping('tinyint unsigned', 'integer');
$platform->registerDoctrineTypeMapping('smallint unsigned', 'integer');
$platform->registerDoctrineTypeMapping('varchar ', 'string');
foreach ($targetSchema->getTables() as $table) {
foreach ($table->getColumns() as $column) {
// column comments are not supported on SQLite
if ($column->getComment() !== null) {
$column->setComment(null);
}
// with sqlite autoincrement columns is of type integer
if ($column->getType() instanceof BigIntType && $column->getAutoincrement()) {
$column->setType(Type::getType('integer'));
}
}
}

View file

@ -84,7 +84,6 @@ use OC\Repair\RemoveLinkShares;
use OC\Repair\RepairDavShares;
use OC\Repair\RepairInvalidShares;
use OC\Repair\RepairMimeTypes;
use OC\Repair\SqliteAutoincrement;
use OC\Template\JSCombiner;
use Psr\Log\LoggerInterface;
use Throwable;
@ -235,14 +234,11 @@ class Repair implements IOutput {
* @return IRepairStep[]
*/
public static function getBeforeUpgradeRepairSteps() {
/** @var Connection $connection */
$connection = \OC::$server->get(Connection::class);
/** @var ConnectionAdapter $connectionAdapter */
$connectionAdapter = \OC::$server->get(ConnectionAdapter::class);
$config = \OC::$server->getConfig();
$steps = [
new Collation(\OC::$server->getConfig(), \OC::$server->get(LoggerInterface::class), $connectionAdapter, true),
new SqliteAutoincrement($connection),
new SaveAccountsTableData($connectionAdapter, $config),
new DropAccountTermsTable($connectionAdapter),
];

View file

@ -1,100 +0,0 @@
<?php
/**
* @copyright Copyright (c) 2016, ownCloud, Inc.
*
* @author Roeland Jago Douma <roeland@famdouma.nl>
* @author Thomas Müller <thomas.mueller@tmit.eu>
* @author Vincent Petry <vincent@nextcloud.com>
*
* @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\Repair;
use Doctrine\DBAL\Platforms\SqlitePlatform;
use Doctrine\DBAL\Schema\ColumnDiff;
use Doctrine\DBAL\Schema\SchemaDiff;
use Doctrine\DBAL\Schema\SchemaException;
use Doctrine\DBAL\Schema\TableDiff;
use OCP\Migration\IOutput;
use OCP\Migration\IRepairStep;
/**
* Fixes Sqlite autoincrement by forcing the SQLite table schemas to be
* altered in order to retrigger SQL schema generation through OCSqlitePlatform.
*/
class SqliteAutoincrement implements IRepairStep {
/**
* @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(IOutput $out) {
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[$columnSchema->getName()] = $columnDiff;
$schemaDiff->changedTables[] = $tableDiff;
}
} catch (SchemaException $e) {
// ignore
}
}
$this->connection->beginTransaction();
foreach ($schemaDiff->toSql($this->connection->getDatabasePlatform()) as $sql) {
$this->connection->executeQuery($sql);
}
$this->connection->commit();
}
}

View file

@ -27,6 +27,7 @@
*/
namespace OCP\DB\QueryBuilder;
use Doctrine\DBAL\ArrayParameterType;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\ParameterType;
use OCP\DB\Exception;
@ -72,11 +73,11 @@ interface IQueryBuilder {
/**
* @since 9.0.0
*/
public const PARAM_INT_ARRAY = Connection::PARAM_INT_ARRAY;
public const PARAM_INT_ARRAY = ArrayParameterType::INTEGER;
/**
* @since 9.0.0
*/
public const PARAM_STR_ARRAY = Connection::PARAM_STR_ARRAY;
public const PARAM_STR_ARRAY = ArrayParameterType::STRING;
/**
* @since 24.0.0 Indicates how many rows can be deleted at once with MySQL

View file

@ -68,6 +68,7 @@
<file name="build/stubs/imagick.php"/>
<file name="build/stubs/intl.php"/>
<file name="build/stubs/IntlChar.php"/>
<file name="build/stubs/SensitiveParameter.phpstub"/>
<file name="build/stubs/ldap.php"/>
<file name="build/stubs/memcached.php"/>
<file name="build/stubs/redis.php"/>

View file

@ -11,16 +11,12 @@ namespace Test\DB;
use Doctrine\DBAL\Exception;
use Doctrine\DBAL\ParameterType;
use Doctrine\DBAL\Platforms\MySQLPlatform;
use Doctrine\DBAL\Platforms\OraclePlatform;
use Doctrine\DBAL\Platforms\PostgreSQL94Platform;
use Doctrine\DBAL\Platforms\SqlitePlatform;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Schema\SchemaConfig;
use OC\DB\Migrator;
use OC\DB\MySQLMigrator;
use OC\DB\OracleMigrator;
use OC\DB\PostgreSqlMigrator;
use OC\DB\SQLiteMigrator;
use OCP\DB\Types;
use OCP\IConfig;
@ -67,10 +63,6 @@ class MigratorTest extends \Test\TestCase {
return new SQLiteMigrator($this->connection, $this->config, $dispatcher);
} elseif ($platform instanceof OraclePlatform) {
return new OracleMigrator($this->connection, $this->config, $dispatcher);
} elseif ($platform instanceof MySQLPlatform) {
return new MySQLMigrator($this->connection, $this->config, $dispatcher);
} elseif ($platform instanceof PostgreSQL94Platform) {
return new PostgreSqlMigrator($this->connection, $this->config, $dispatcher);
}
return new Migrator($this->connection, $this->config, $dispatcher);
}
@ -138,14 +130,6 @@ class MigratorTest extends \Test\TestCase {
return $config;
}
private function isSQLite() {
return $this->connection->getDatabasePlatform() instanceof SqlitePlatform;
}
private function isMySQL() {
return $this->connection->getDatabasePlatform() instanceof MySQLPlatform;
}
public function testUpgrade() {
[$startSchema, $endSchema] = $this->getDuplicateKeySchemas();
$migrator = $this->getMigrator();

View file

@ -1,90 +0,0 @@
<?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 Test\Repair;
use OC\DB\Connection;
use OCP\Migration\IOutput;
/**
* Tests for fixing the SQLite id recycling
*
* @group DB
*/
class RepairSqliteAutoincrementTest extends \Test\TestCase {
/**
* @var \OC\Repair\SqliteAutoincrement
*/
private $repair;
/**
* @var Connection
*/
private $connection;
/**
* @var string
*/
private $tableName;
/**
* @var \OCP\IConfig
*/
private $config;
protected function setUp(): void {
parent::setUp();
$this->connection = \OC::$server->get(\OC\DB\Connection::class);
$this->config = \OC::$server->getConfig();
if (!$this->connection->getDatabasePlatform() instanceof \Doctrine\DBAL\Platforms\SqlitePlatform) {
$this->markTestSkipped("Test only relevant on Sqlite");
}
$dbPrefix = $this->config->getSystemValueString('dbtableprefix', 'oc_');
$this->tableName = $this->getUniqueID($dbPrefix . 'autoinc_test');
$this->connection->prepare('CREATE TABLE ' . $this->tableName . '("someid" INTEGER NOT NULL, "text" VARCHAR(16), PRIMARY KEY("someid"))')->execute();
$this->repair = new \OC\Repair\SqliteAutoincrement($this->connection);
}
protected function tearDown(): void {
$this->connection->getSchemaManager()->dropTable($this->tableName);
parent::tearDown();
}
/**
* Tests whether autoincrement works
*
* @return boolean true if autoincrement works, false otherwise
*/
protected function checkAutoincrement() {
$this->connection->executeUpdate('INSERT INTO ' . $this->tableName . ' ("text") VALUES ("test")');
$insertId = $this->connection->lastInsertId();
$this->connection->executeUpdate('DELETE FROM ' . $this->tableName . ' WHERE "someid" = ?', [$insertId]);
// insert again
$this->connection->executeUpdate('INSERT INTO ' . $this->tableName . ' ("text") VALUES ("test2")');
$newInsertId = $this->connection->lastInsertId();
return ($insertId !== $newInsertId);
}
public function testConvertIdColumn() {
$this->assertFalse($this->checkAutoincrement());
/** @var IOutput | \PHPUnit\Framework\MockObject\MockObject $outputMock */
$outputMock = $this->getMockBuilder('\OCP\Migration\IOutput')
->disableOriginalConstructor()
->getMock();
$this->repair->run($outputMock);
$this->assertTrue($this->checkAutoincrement());
}
}