mirror of
https://github.com/phpbb/phpbb.git
synced 2025-05-11 10:05:19 +02:00
[ticket/16741] Specific DBs fixes
MSSQL: - Fix bool type - Fix comparator - Drop Default constraint before deleting column - Rename Default constraint to use phpBB's names - Re-create the indices when changing the type of one column - Uses varchar instead of varbinary PostgreSQL: - Creates auto increment sequences by hand instead of using serial in order to use phpBB's names - Drop constraint on unique / primary indices Oracle: - Rename indices to use phpBB's names - Fix string not null behaviour - Fix broken regex in Oracle driver - Handle to long indices on Oracle - Rename auto_increment trigger and sequence - Automatically lowercase keys in assoc results PHPBB3-16741
This commit is contained in:
parent
b266ebbcef
commit
b8d555f56a
@ -10,7 +10,7 @@ services:
|
||||
dbal.conn.doctrine:
|
||||
synthetic: true
|
||||
|
||||
# ----- DB Tools -----
|
||||
# ----- DB Tools -----
|
||||
dbal.tools.factory:
|
||||
class: phpbb\db\tools\factory
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
namespace phpbb\convert\controller;
|
||||
|
||||
use Doctrine\DBAL\Connection;
|
||||
use phpbb\cache\driver\driver_interface;
|
||||
use phpbb\db\doctrine\connection_factory;
|
||||
use phpbb\exception\http_exception;
|
||||
@ -26,7 +27,6 @@ use phpbb\install\helper\navigation\navigation_provider;
|
||||
use phpbb\language\language;
|
||||
use phpbb\request\request_interface;
|
||||
use phpbb\template\template;
|
||||
use PHPUnit\DbUnit\Database\Connection;
|
||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
|
||||
/**
|
||||
|
64
phpBB/phpbb/db/doctrine/comparator.php
Normal file
64
phpBB/phpbb/db/doctrine/comparator.php
Normal file
@ -0,0 +1,64 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace phpbb\db\doctrine;
|
||||
|
||||
use Doctrine\DBAL\Schema\Table;
|
||||
|
||||
class comparator extends \Doctrine\DBAL\Schema\Comparator
|
||||
{
|
||||
/**
|
||||
* {@inerhitDoc}
|
||||
*/
|
||||
public function diffTable(Table $fromTable, Table $toTable)
|
||||
{
|
||||
$diff = parent::diffTable($fromTable, $toTable);
|
||||
|
||||
if ($diff === false)
|
||||
{
|
||||
return $diff;
|
||||
}
|
||||
|
||||
if (!is_array($diff->changedColumns))
|
||||
{
|
||||
return $diff;
|
||||
}
|
||||
|
||||
// When the type of a column changes, re-create the associated indices
|
||||
foreach ($diff->changedColumns as $columnName => $changedColumn)
|
||||
{
|
||||
if (!$changedColumn->hasChanged('type'))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($toTable->getIndexes() as $index_name => $index)
|
||||
{
|
||||
if (array_key_exists($index_name, $diff->addedIndexes) || array_key_exists($index_name, $diff->changedIndexes))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$index_columns = array_map('strtolower', $index->getUnquotedColumns());
|
||||
if (array_search($columnName, $index_columns, true) === false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$diff->changedIndexes[$index_name] = $index;
|
||||
}
|
||||
}
|
||||
|
||||
return $diff;
|
||||
}
|
||||
}
|
99
phpBB/phpbb/db/doctrine/oci8/connection.php
Normal file
99
phpBB/phpbb/db/doctrine/oci8/connection.php
Normal file
@ -0,0 +1,99 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace phpbb\db\doctrine\oci8;
|
||||
|
||||
use Doctrine\DBAL\Driver\Connection as DriverConnection;
|
||||
use Doctrine\DBAL\Driver\Result as DriverResult;
|
||||
use Doctrine\DBAL\Driver\Statement as DriverStatement;
|
||||
use Doctrine\DBAL\ParameterType;
|
||||
|
||||
class Connection implements DriverConnection
|
||||
{
|
||||
/**
|
||||
* @var DriverConnection
|
||||
*/
|
||||
private $wrapped;
|
||||
|
||||
/**
|
||||
* @param DriverConnection $wrapped
|
||||
*/
|
||||
public function __construct(DriverConnection $wrapped)
|
||||
{
|
||||
$this->wrapped = $wrapped;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function prepare(string $sql): DriverStatement
|
||||
{
|
||||
return new statement($this->wrapped->prepare($sql));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function query(string $sql): DriverResult
|
||||
{
|
||||
return new result($this->wrapped->query($sql));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function quote($value, $type = ParameterType::STRING)
|
||||
{
|
||||
return $this->wrapped->quote($value, $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function exec(string $sql): int
|
||||
{
|
||||
return $this->wrapped->exec($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function lastInsertId($name = null)
|
||||
{
|
||||
return $this->wrapped->lastInsertId($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function beginTransaction()
|
||||
{
|
||||
return $this->wrapped->beginTransaction();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function commit()
|
||||
{
|
||||
return $this->wrapped->commit();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function rollBack()
|
||||
{
|
||||
return $this->wrapped->rollBack();
|
||||
}
|
||||
}
|
65
phpBB/phpbb/db/doctrine/oci8/driver.php
Normal file
65
phpBB/phpbb/db/doctrine/oci8/driver.php
Normal file
@ -0,0 +1,65 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace phpbb\db\doctrine\oci8;
|
||||
|
||||
use Doctrine\DBAL\Connection as DoctrineConnection;
|
||||
use Doctrine\DBAL\Driver\API\ExceptionConverter;
|
||||
use Doctrine\DBAL\Platforms\AbstractPlatform;
|
||||
use Doctrine\DBAL\Driver as DoctrineDriver;
|
||||
use Doctrine\DBAL\Driver\OCI8\Driver as OCI8Driver;
|
||||
|
||||
class driver implements DoctrineDriver
|
||||
{
|
||||
/**
|
||||
* @var DoctrineDriver
|
||||
*/
|
||||
private $wrapped;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->wrapped = new OCI8Driver();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function connect(array $params)
|
||||
{
|
||||
return new connection($this->wrapped->connect($params));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getDatabasePlatform()
|
||||
{
|
||||
return $this->wrapped->getDatabasePlatform();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getSchemaManager(DoctrineConnection $conn, AbstractPlatform $platform)
|
||||
{
|
||||
return new schema_manager($conn, $platform);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getExceptionConverter(): ExceptionConverter
|
||||
{
|
||||
return $this->wrapped->getExceptionConverter();
|
||||
}
|
||||
}
|
109
phpBB/phpbb/db/doctrine/oci8/result.php
Normal file
109
phpBB/phpbb/db/doctrine/oci8/result.php
Normal file
@ -0,0 +1,109 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace phpbb\db\doctrine\oci8;
|
||||
|
||||
use Doctrine\DBAL\Driver\Result as DriverResult;
|
||||
|
||||
class result implements DriverResult
|
||||
{
|
||||
/**
|
||||
* @var DriverResult
|
||||
*/
|
||||
private $wrapped;
|
||||
|
||||
/**
|
||||
* @param DriverResult $wrapped
|
||||
*/
|
||||
public function __construct(DriverResult $wrapped)
|
||||
{
|
||||
$this->wrapped = $wrapped;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function fetchNumeric()
|
||||
{
|
||||
return $this->wrapped->fetchNumeric();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function fetchAssociative()
|
||||
{
|
||||
return array_change_key_case($this->wrapped->fetchAssociative(), CASE_LOWER);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function fetchOne()
|
||||
{
|
||||
return $this->wrapped->fetchOne();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function fetchAllNumeric(): array
|
||||
{
|
||||
return $this->wrapped->fetchAllNumeric();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function fetchAllAssociative(): array
|
||||
{
|
||||
$rows = [];
|
||||
foreach ($this->wrapped->fetchAllAssociative() as $row)
|
||||
{
|
||||
$rows[] = array_change_key_case($row, CASE_LOWER);
|
||||
}
|
||||
return $rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function fetchFirstColumn(): array
|
||||
{
|
||||
return $this->wrapped->fetchFirstColumn();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function rowCount(): int
|
||||
{
|
||||
return $this->wrapped->rowCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function columnCount(): int
|
||||
{
|
||||
return $this->wrapped->columnCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function free(): void
|
||||
{
|
||||
$this->wrapped->free();
|
||||
}
|
||||
}
|
45
phpBB/phpbb/db/doctrine/oci8/schema_manager.php
Normal file
45
phpBB/phpbb/db/doctrine/oci8/schema_manager.php
Normal file
@ -0,0 +1,45 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace phpbb\db\doctrine\oci8;
|
||||
|
||||
use Doctrine\DBAL\Platforms\OraclePlatform;
|
||||
use Doctrine\DBAL\Schema\AbstractSchemaManager;
|
||||
use Doctrine\DBAL\Schema\OracleSchemaManager;
|
||||
use Doctrine\DBAL\Schema\Table;
|
||||
|
||||
class schema_manager extends OracleSchemaManager
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* Copied from upstream to lowercase 'COMMENTS'
|
||||
*/
|
||||
public function listTableDetails($name): Table
|
||||
{
|
||||
$table = AbstractSchemaManager::listTableDetails($name);
|
||||
|
||||
$platform = $this->_platform;
|
||||
assert($platform instanceof OraclePlatform);
|
||||
$sql = $platform->getListTableCommentsSQL($name);
|
||||
|
||||
$tableOptions = $this->_conn->fetchAssociative($sql);
|
||||
|
||||
if ($tableOptions !== false)
|
||||
{
|
||||
$table->addOption('comment', $tableOptions['comments']);
|
||||
}
|
||||
|
||||
return $table;
|
||||
}
|
||||
}
|
58
phpBB/phpbb/db/doctrine/oci8/statement.php
Normal file
58
phpBB/phpbb/db/doctrine/oci8/statement.php
Normal file
@ -0,0 +1,58 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace phpbb\db\doctrine\oci8;
|
||||
|
||||
use Doctrine\DBAL\Driver\Result as DriverResult;
|
||||
use Doctrine\DBAL\Driver\Statement as DriverStatement;
|
||||
use Doctrine\DBAL\ParameterType;
|
||||
|
||||
class statement implements DriverStatement
|
||||
{
|
||||
/**
|
||||
* @var DriverStatement
|
||||
*/
|
||||
private $wrapped;
|
||||
|
||||
/**
|
||||
* @param DriverStatement $wrapped
|
||||
*/
|
||||
public function __construct(DriverStatement $wrapped)
|
||||
{
|
||||
$this->wrapped = $wrapped;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function bindValue($param, $value, $type = ParameterType::STRING)
|
||||
{
|
||||
return $this->wrapped->bindValue($param, $value, $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function bindParam($param, &$variable, $type = ParameterType::STRING, $length = null)
|
||||
{
|
||||
return $this->wrapped->bindParam($param, $variable, $type, $length);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function execute($params = null): DriverResult
|
||||
{
|
||||
return new result($this->wrapped->execute($params));
|
||||
}
|
||||
}
|
@ -14,6 +14,9 @@
|
||||
namespace phpbb\db\doctrine;
|
||||
|
||||
use Doctrine\DBAL\Platforms\OraclePlatform;
|
||||
use Doctrine\DBAL\Schema\Identifier;
|
||||
use Doctrine\DBAL\Schema\Index;
|
||||
use Doctrine\DBAL\Schema\Table;
|
||||
|
||||
/**
|
||||
* Oracle specific schema restrictions for BC.
|
||||
@ -40,4 +43,133 @@ class oracle_platform extends OraclePlatform
|
||||
{
|
||||
return parent::getVarcharTypeDeclarationSQL($column);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getCreateIndexSQL(Index $index, $table)
|
||||
{
|
||||
if ($table instanceof Table)
|
||||
{
|
||||
$table_name = $table->getName();
|
||||
}
|
||||
else
|
||||
{
|
||||
$table_name = $table;
|
||||
}
|
||||
|
||||
$index_name = $index->getName();
|
||||
if (strpos($index->getName(), $table_name) !== 0)
|
||||
{
|
||||
$index_name = $table_name . '_' . $index->getName();
|
||||
}
|
||||
|
||||
$index = new Index(
|
||||
$this->check_index_name_length($table_name, $index_name),
|
||||
$index->getColumns(),
|
||||
$index->isUnique(),
|
||||
$index->isPrimary(),
|
||||
$index->getFlags(),
|
||||
$index->getOptions()
|
||||
);
|
||||
|
||||
return parent::getCreateIndexSQL($index, $table);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the index name is too long
|
||||
*
|
||||
* @param string $table_name
|
||||
* @param string $index_name
|
||||
* @param bool $throw_error
|
||||
* @return string The index name, shortened if too long
|
||||
*/
|
||||
protected function check_index_name_length($table_name, $index_name, $throw_error = true)
|
||||
{
|
||||
$max_index_name_length = $this->getMaxIdentifierLength();
|
||||
if (strlen($index_name) > $max_index_name_length)
|
||||
{
|
||||
// Try removing the table prefix if it's at the beginning
|
||||
$table_prefix = substr(CONFIG_TABLE, 0, -6); // strlen(config)
|
||||
if (strpos($index_name, $table_prefix) === 0)
|
||||
{
|
||||
$index_name = substr($index_name, strlen($table_prefix));
|
||||
return $this->check_index_name_length($table_name, $index_name, $throw_error);
|
||||
}
|
||||
|
||||
// Try removing the remaining suffix part of table name then
|
||||
$table_suffix = substr($table_name, strlen($table_prefix));
|
||||
if (strpos($index_name, $table_suffix) === 0)
|
||||
{
|
||||
// Remove the suffix and underscore separator between table_name and index_name
|
||||
$index_name = substr($index_name, strlen($table_suffix) + 1);
|
||||
return $this->check_index_name_length($table_name, $index_name, $throw_error);
|
||||
}
|
||||
|
||||
if ($throw_error)
|
||||
{
|
||||
trigger_error("Index name '$index_name' on table '$table_name' is too long. The maximum is $max_index_name_length characters.", E_USER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
return $index_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIdentitySequenceName($tableName, $columnName)
|
||||
{
|
||||
return $tableName.'_SEQ';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getCreateAutoincrementSql($name, $table, $start = 1)
|
||||
{
|
||||
$sql = parent::getCreateAutoincrementSql($name, $table, $start);
|
||||
|
||||
return str_replace(
|
||||
$this->get_doctrine_autoincrement_identifier_name($this->doctrine_normalize_identifier($table)),
|
||||
'T_'.$table,
|
||||
$sql
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see OraclePlatform::normalizeIdentifier()
|
||||
*/
|
||||
private function doctrine_normalize_identifier($name)
|
||||
{
|
||||
$identifier = new Identifier($name);
|
||||
|
||||
return $identifier->isQuoted() ? $identifier : new Identifier(strtoupper($name));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see OraclePlatform::getAutoincrementIdentifierName()
|
||||
*/
|
||||
private function get_doctrine_autoincrement_identifier_name(Identifier $table)
|
||||
{
|
||||
$identifierName = $this->add_doctrine_Suffix($table->getName(), '_AI_PK');
|
||||
|
||||
return $table->isQuoted()
|
||||
? $this->quoteSingleIdentifier($identifierName)
|
||||
: $identifierName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see OraclePlatform::addSuffix()
|
||||
*/
|
||||
private function add_doctrine_Suffix(string $identifier, string $suffix): string
|
||||
{
|
||||
$maxPossibleLengthWithoutSuffix = $this->getMaxIdentifierLength() - strlen($suffix);
|
||||
if (strlen($identifier) > $maxPossibleLengthWithoutSuffix)
|
||||
{
|
||||
$identifier = substr($identifier, 0, $maxPossibleLengthWithoutSuffix);
|
||||
}
|
||||
|
||||
return $identifier . $suffix;
|
||||
}
|
||||
}
|
||||
|
178
phpBB/phpbb/db/doctrine/postgresql_platform.php
Normal file
178
phpBB/phpbb/db/doctrine/postgresql_platform.php
Normal file
@ -0,0 +1,178 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace phpbb\db\doctrine;
|
||||
|
||||
use Doctrine\DBAL\Platforms\AbstractPlatform;
|
||||
use Doctrine\DBAL\Platforms\PostgreSQL94Platform;
|
||||
use Doctrine\DBAL\Schema\Index;
|
||||
use Doctrine\DBAL\Schema\Sequence;
|
||||
use Doctrine\DBAL\Schema\Table;
|
||||
use Doctrine\DBAL\Types\BigIntType;
|
||||
use Doctrine\DBAL\Types\IntegerType;
|
||||
use Doctrine\DBAL\Types\SmallIntType;
|
||||
use Doctrine\DBAL\Types\Type;
|
||||
|
||||
/**
|
||||
* PostgreSQL specific schema restrictions for BC.
|
||||
*
|
||||
* Doctrine is using SERIAL which auto creates the sequences with
|
||||
* a name different from the one our driver is using. So in order
|
||||
* to stay compatible with the existing DB we have to change its
|
||||
* naming and not ours.
|
||||
*/
|
||||
class postgresql_platform extends PostgreSQL94Platform
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIdentitySequenceName($tableName, $columnName)
|
||||
{
|
||||
return $tableName . '_seq';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getIntegerTypeDeclarationSQL(array $column)
|
||||
{
|
||||
return 'INT';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getBigIntTypeDeclarationSQL(array $column)
|
||||
{
|
||||
return 'BIGINT';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getSmallIntTypeDeclarationSQL(array $column)
|
||||
{
|
||||
return 'SMALLINT';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getDefaultValueDeclarationSQL($column)
|
||||
{
|
||||
if ($this->isSerialColumn($column))
|
||||
{
|
||||
return ' DEFAULT {{placeholder_sequence}}';
|
||||
}
|
||||
|
||||
return AbstractPlatform::getDefaultValueDeclarationSQL($column);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function supportsIdentityColumns()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function _getCreateTableSQL($name, array $columns, array $options = [])
|
||||
{
|
||||
$sql = [];
|
||||
$post_sql = [];
|
||||
foreach ($columns as $column_name => $column)
|
||||
{
|
||||
if (! empty($column['autoincrement']))
|
||||
{
|
||||
$sequence = new Sequence($this->getIdentitySequenceName($name, $column_name));
|
||||
$sql[] = $this->getCreateSequenceSQL($sequence);
|
||||
$post_sql[] = 'ALTER SEQUENCE '.$sequence->getName().' OWNED BY '.$name.'.'.$column_name;
|
||||
}
|
||||
}
|
||||
$sql = array_merge($sql, parent::_getCreateTableSQL($name, $columns, $options), $post_sql);
|
||||
|
||||
foreach ($sql as $i => $query)
|
||||
{
|
||||
$sql[$i] = str_replace('{{placeholder_sequence}}', "nextval('{$name}_seq')", $query);
|
||||
}
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed[] $column
|
||||
*/
|
||||
private function isSerialColumn(array $column): bool
|
||||
{
|
||||
return isset($column['type'], $column['autoincrement'])
|
||||
&& $column['autoincrement'] === true
|
||||
&& $this->isNumericType($column['type']);
|
||||
}
|
||||
|
||||
private function isNumericType(Type $type): bool
|
||||
{
|
||||
return $type instanceof IntegerType || $type instanceof BigIntType || $type instanceof SmallIntType;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getListSequencesSQL($database)
|
||||
{
|
||||
return "SELECT sequence_name AS relname,
|
||||
sequence_schema AS schemaname,
|
||||
1 AS min_value,
|
||||
1 AS increment_by
|
||||
FROM information_schema.sequences
|
||||
WHERE sequence_schema NOT LIKE 'pg\_%'
|
||||
AND sequence_schema != 'information_schema'";
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getDropIndexSQL($index, $table = null)
|
||||
{
|
||||
// If we have a primary or a unique index, we need to drop the constraint
|
||||
// instead of the index itself or postgreSQL will reject the query.
|
||||
if ($index instanceof Index)
|
||||
{
|
||||
if ($index->isPrimary())
|
||||
{
|
||||
if ($table instanceof Table)
|
||||
{
|
||||
$table = $table->getQuotedName($this);
|
||||
}
|
||||
else if (!is_string($table))
|
||||
{
|
||||
throw new \InvalidArgumentException(
|
||||
__METHOD__ . '() expects $table parameter to be string or ' . Table::class . '.'
|
||||
);
|
||||
}
|
||||
|
||||
return 'ALTER TABLE '.$table.' DROP CONSTRAINT '.$index->getQuotedName($this);
|
||||
}
|
||||
}
|
||||
else if (! is_string($index))
|
||||
{
|
||||
throw new \InvalidArgumentException(
|
||||
__METHOD__ . '() expects $index parameter to be string or ' . Index::class . '.'
|
||||
);
|
||||
}
|
||||
|
||||
return parent::getDropIndexSQL($index, $table);
|
||||
}
|
||||
}
|
139
phpBB/phpbb/db/doctrine/sqlsrv_platform.php
Normal file
139
phpBB/phpbb/db/doctrine/sqlsrv_platform.php
Normal file
@ -0,0 +1,139 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace phpbb\db\doctrine;
|
||||
|
||||
use Doctrine\DBAL\Platforms\SQLServer2012Platform;
|
||||
use Doctrine\DBAL\Schema\Identifier;
|
||||
use Doctrine\DBAL\Schema\TableDiff;
|
||||
|
||||
/**
|
||||
* Oracle specific schema restrictions for BC.
|
||||
*/
|
||||
class sqlsrv_platform extends SQLServer2012Platform
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* Renames the default constraints to use the classic phpBB's names
|
||||
*/
|
||||
public function getDefaultConstraintDeclarationSQL($table, array $column)
|
||||
{
|
||||
$sql = parent::getDefaultConstraintDeclarationSQL($table, $column);
|
||||
|
||||
return str_replace(
|
||||
[
|
||||
$this->generate_doctrine_identifier_name($table),
|
||||
$this->generate_doctrine_identifier_name($column['name']),
|
||||
], [
|
||||
$table,
|
||||
$column['name'].'_1',
|
||||
],
|
||||
$sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* Renames the default constraints to use the classic phpBB's names
|
||||
*/
|
||||
public function getAlterTableSQL(TableDiff $diff)
|
||||
{
|
||||
$sql = [];
|
||||
|
||||
// When dropping a column, if it has a default we need to drop the default constraint first
|
||||
foreach ($diff->removedColumns as $column)
|
||||
{
|
||||
if (!$column->getAutoincrement())
|
||||
{
|
||||
$sql[] = $this->getDropConstraintSQL($this->generate_doctrine_default_constraint_name($diff->name, $column->getQuotedName($this)), $diff->name);
|
||||
}
|
||||
}
|
||||
|
||||
$sql = array_merge($sql, parent::getAlterTableSQL($diff));
|
||||
|
||||
$doctrine_names = [];
|
||||
$phpbb_names = [];
|
||||
|
||||
// OLD Table name
|
||||
$doctrine_names[] = $this->generate_doctrine_identifier_name($diff->name);
|
||||
$phpbb_names[] = $diff->name;
|
||||
|
||||
// NEW Table name if relevant
|
||||
if ($diff->getNewName() != null)
|
||||
{
|
||||
$doctrine_names[] = $this->generate_doctrine_identifier_name($diff->getNewName()->getName());
|
||||
$phpbb_names[] = $diff->getNewName()->getName();
|
||||
}
|
||||
|
||||
foreach ($diff->addedColumns as $column)
|
||||
{
|
||||
$doctrine_names[] = $this->generate_doctrine_identifier_name($column->getQuotedName($this));
|
||||
$phpbb_names[] = $column->getQuotedName($this).'_1';
|
||||
}
|
||||
|
||||
foreach ($diff->removedColumns as $column)
|
||||
{
|
||||
$doctrine_names[] = $this->generate_doctrine_identifier_name($column->getQuotedName($this));
|
||||
$phpbb_names[] = $column->getQuotedName($this).'_1';
|
||||
}
|
||||
|
||||
foreach ($diff->renamedColumns as $column)
|
||||
{
|
||||
$doctrine_names[] = $this->generate_doctrine_identifier_name($column->getQuotedName($this));
|
||||
$phpbb_names[] = $column->getQuotedName($this).'_1';
|
||||
}
|
||||
|
||||
foreach ($diff->changedColumns as $column)
|
||||
{
|
||||
$doctrine_names[] = $this->generate_doctrine_identifier_name($column->column->getQuotedName($this));
|
||||
$phpbb_names[] = $column->column->getQuotedName($this).'_1';
|
||||
|
||||
if ($column->oldColumnName != $column->column->getQuotedName($this))
|
||||
{
|
||||
$doctrine_names[] = $this->generate_doctrine_identifier_name($column->oldColumnName);
|
||||
$phpbb_names[] = $column->oldColumnName.'_1';
|
||||
}
|
||||
}
|
||||
|
||||
return str_replace($doctrine_names, $phpbb_names, $sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hash value for a given identifier.
|
||||
*
|
||||
* @param string $identifier Identifier to generate a hash value for.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function generate_doctrine_identifier_name($identifier)
|
||||
{
|
||||
// Always generate name for unquoted identifiers to ensure consistency.
|
||||
$identifier = new Identifier($identifier);
|
||||
|
||||
return strtoupper(dechex(crc32($identifier->getName())));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a unique default constraint name for a table and column.
|
||||
*
|
||||
* @param string $table Name of the table to generate the unique default constraint name for.
|
||||
* @param string $column Name of the column in the table to generate the unique default constraint name for.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function generate_doctrine_default_constraint_name($table, $column)
|
||||
{
|
||||
return 'DF_' . $this->generate_doctrine_identifier_name($table) . '_' . $this->generate_doctrine_identifier_name($column);
|
||||
}
|
||||
}
|
@ -160,7 +160,7 @@ class oracle extends \phpbb\db\driver\driver
|
||||
*/
|
||||
function _rewrite_where($where_clause)
|
||||
{
|
||||
preg_match_all('/\s*(AND|OR)?\s*([\w_.()]++)\s*(?:(=|<[=>]?|>=?|LIKE)\s*((?>\'(?>[^\']++|\'\')*+\'|[\d-.()]+))|((NOT )?IN\s*\((?>\'(?>[^\']++|\'\')*+\',? ?|[\d-.]+,? ?)*+\)))/', $where_clause, $result, PREG_SET_ORDER);
|
||||
preg_match_all('/\s*(AND|OR)?\s*([\w_.()]++)\s*(?:(=|<[=>]?|>=?|LIKE)\s*((?>\'(?>[^\']++|\'\')*+\'|[\d\-.()]+))|((NOT )?IN\s*\((?>\'(?>[^\']++|\'\')*+\',? ?|[\d\-.]+,? ?)*+\)))/', $where_clause, $result, PREG_SET_ORDER);
|
||||
$out = '';
|
||||
foreach ($result as $val)
|
||||
{
|
||||
@ -188,7 +188,7 @@ class oracle extends \phpbb\db\driver\driver
|
||||
$in_clause = array();
|
||||
$sub_exp = substr($val[5], strpos($val[5], '(') + 1, -1);
|
||||
$extra = false;
|
||||
preg_match_all('/\'(?>[^\']++|\'\')*+\'|[\d-.]++/', $sub_exp, $sub_vals, PREG_PATTERN_ORDER);
|
||||
preg_match_all('/\'(?>[^\']++|\'\')*+\'|[\d\-.]++/', $sub_exp, $sub_vals, PREG_PATTERN_ORDER);
|
||||
$i = 0;
|
||||
foreach ($sub_vals[0] as $sub_val)
|
||||
{
|
||||
@ -282,7 +282,7 @@ class oracle extends \phpbb\db\driver\driver
|
||||
{
|
||||
$cols = explode(', ', $regs[2]);
|
||||
|
||||
preg_match_all('/\'(?:[^\']++|\'\')*+\'|[\d-.]+/', $regs[3], $vals, PREG_PATTERN_ORDER);
|
||||
preg_match_all('/\'(?:[^\']++|\'\')*+\'|[\d\-.]+/', $regs[3], $vals, PREG_PATTERN_ORDER);
|
||||
|
||||
/* The code inside this comment block breaks clob handling, but does allow the
|
||||
database restore script to work. If you want to allow no posts longer than 4KB
|
||||
@ -353,13 +353,13 @@ class oracle extends \phpbb\db\driver\driver
|
||||
$query = $regs[1] . '(' . $regs[2] . ') VALUES (' . implode(', ', $inserts) . ')';
|
||||
}
|
||||
}
|
||||
else if (preg_match_all('/^(UPDATE [\\w_]++\\s+SET )([\\w_]++\\s*=\\s*(?:\'(?:[^\']++|\'\')*+\'|[\d-.]+)(?:,\\s*[\\w_]++\\s*=\\s*(?:\'(?:[^\']++|\'\')*+\'|[\d-.]+))*+)\\s+(WHERE.*)$/s', $query, $data, PREG_SET_ORDER))
|
||||
else if (preg_match_all('/^(UPDATE [\\w_]++\\s+SET )([\\w_]++\\s*=\\s*(?:\'(?:[^\']++|\'\')*+\'|[\d\-.]+)(?:,\\s*[\\w_]++\\s*=\\s*(?:\'(?:[^\']++|\'\')*+\'|[\d\-.]+))*+)\\s+(WHERE.*)$/s', $query, $data, PREG_SET_ORDER))
|
||||
{
|
||||
if (strlen($data[0][2]) > 4000)
|
||||
{
|
||||
$update = $data[0][1];
|
||||
$where = $data[0][3];
|
||||
preg_match_all('/([\\w_]++)\\s*=\\s*(\'(?:[^\']++|\'\')*+\'|[\d-.]++)/', $data[0][2], $temp, PREG_SET_ORDER);
|
||||
preg_match_all('/([\\w_]++)\\s*=\\s*(\'(?:[^\']++|\'\')*+\'|[\d\-.]++)/', $data[0][2], $temp, PREG_SET_ORDER);
|
||||
unset($data);
|
||||
|
||||
$cols = array();
|
||||
@ -385,7 +385,7 @@ class oracle extends \phpbb\db\driver\driver
|
||||
switch (substr($query, 0, 6))
|
||||
{
|
||||
case 'DELETE':
|
||||
if (preg_match('/^(DELETE FROM [\w_]++ WHERE)((?:\s*(?:AND|OR)?\s*[\w_]+\s*(?:(?:=|<>)\s*(?>\'(?>[^\']++|\'\')*+\'|[\d-.]+)|(?:NOT )?IN\s*\((?>\'(?>[^\']++|\'\')*+\',? ?|[\d-.]+,? ?)*+\)))*+)$/', $query, $regs))
|
||||
if (preg_match('/^(DELETE FROM [\w_]++ WHERE)((?:\s*(?:AND|OR)?\s*[\w_]+\s*(?:(?:=|<>)\s*(?>\'(?>[^\']++|\'\')*+\'|[\d\-.]+)|(?:NOT )?IN\s*\((?>\'(?>[^\']++|\'\')*+\',? ?|[\d\-.]+,? ?)*+\)))*+)$/', $query, $regs))
|
||||
{
|
||||
$query = $regs[1] . $this->_rewrite_where($regs[2]);
|
||||
unset($regs);
|
||||
@ -393,7 +393,7 @@ class oracle extends \phpbb\db\driver\driver
|
||||
break;
|
||||
|
||||
case 'UPDATE':
|
||||
if (preg_match('/^(UPDATE [\\w_]++\\s+SET [\\w_]+\s*=\s*(?:\'(?:[^\']++|\'\')*+\'|[\d-.]++|:\w++)(?:, [\\w_]+\s*=\s*(?:\'(?:[^\']++|\'\')*+\'|[\d-.]++|:\w++))*+\\s+WHERE)(.*)$/s', $query, $regs))
|
||||
if (preg_match('/^(UPDATE [\\w_]++\\s+SET [\\w_]+\s*=\s*(?:\'(?:[^\']++|\'\')*+\'|[\d\-.]++|:\w++)(?:, [\\w_]+\s*=\s*(?:\'(?:[^\']++|\'\')*+\'|[\d\-.]++|:\w++))*+\\s+WHERE)(.*)$/s', $query, $regs))
|
||||
{
|
||||
$query = $regs[1] . $this->_rewrite_where($regs[2]);
|
||||
unset($regs);
|
||||
@ -401,7 +401,7 @@ class oracle extends \phpbb\db\driver\driver
|
||||
break;
|
||||
|
||||
case 'SELECT':
|
||||
$query = preg_replace_callback('/([\w_.]++)\s*(?:(=|<>)\s*(?>\'(?>[^\']++|\'\')*+\'|[\d-.]++|([\w_.]++))|(?:NOT )?IN\s*\((?>\'(?>[^\']++|\'\')*+\',? ?|[\d-.]++,? ?)*+\))/', array($this, '_rewrite_col_compare'), $query);
|
||||
$query = preg_replace_callback('/([\w_.]++)\s*(?:(=|<>)\s*(?>\'(?>[^\']++|\'\')*+\'|[\d\-.]++|([\w_.]++))|(?:NOT )?IN\s*\((?>\'(?>[^\']++|\'\')*+\',? ?|[\d\-.]++,? ?)*+\))/', array($this, '_rewrite_col_compare'), $query);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,6 @@ namespace phpbb\db\tools;
|
||||
*
|
||||
* @deprecated 4.0.0-a1
|
||||
*/
|
||||
class mssql extends tools
|
||||
class mssql extends doctrine
|
||||
{
|
||||
}
|
||||
|
@ -19,6 +19,6 @@ namespace phpbb\db\tools;
|
||||
*
|
||||
* @deprecated 4.0.0-a1
|
||||
*/
|
||||
class postgres extends tools
|
||||
class postgres extends doctrine
|
||||
{
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user