mirror of
https://github.com/phpbb/phpbb.git
synced 2025-08-20 15:31:42 +02:00
[ticket/17530] Use Doctrine driver middleware instead of 'platform' parameter
PHPBB-17530
This commit is contained in:
@@ -15,6 +15,8 @@ namespace phpbb\db\doctrine;
|
||||
|
||||
use Doctrine\DBAL\Platforms\AbstractPlatform;
|
||||
use Doctrine\DBAL\Types\Type;
|
||||
use phpbb\db\middleware\postgresql\phpbb_postgresql_platform;
|
||||
use phpbb\db\middleware\oracle\phpbb_oracle_platform;
|
||||
|
||||
/**
|
||||
* Case-insensitive string type (only supported by Postgres).
|
||||
@@ -28,7 +30,7 @@ class case_insensitive_string extends Type
|
||||
*/
|
||||
public function getSQLDeclaration(array $column, AbstractPlatform $platform): string
|
||||
{
|
||||
if ($platform instanceof postgresql_platform)
|
||||
if ($platform instanceof phpbb_postgresql_platform)
|
||||
{
|
||||
return 'varchar_ci';
|
||||
}
|
||||
@@ -37,7 +39,7 @@ class case_insensitive_string extends Type
|
||||
// we used 3 times larger capacity for strings on oracle for unicode strings
|
||||
// as on other platforms. This is not the case with varchar_ci, which uses
|
||||
// the same length as other platforms.
|
||||
if ($platform instanceof oracle_platform)
|
||||
if ($platform instanceof phpbb_oracle_platform)
|
||||
{
|
||||
return $platform->getAsciiStringTypeDeclarationSQL($column);
|
||||
}
|
||||
|
@@ -13,12 +13,17 @@
|
||||
|
||||
namespace phpbb\db\doctrine;
|
||||
|
||||
use Doctrine\DBAL\Configuration;
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\DriverManager;
|
||||
use Doctrine\DBAL\Exception;
|
||||
use Doctrine\DBAL\Types\Type;
|
||||
use InvalidArgumentException;
|
||||
use phpbb\config_php_file;
|
||||
use phpbb\db\middleware\mysql\phpbb_mysql_middleware;
|
||||
use phpbb\db\middleware\oracle\phpbb_oracle_middleware;
|
||||
use phpbb\db\middleware\postgresql\phpbb_postgresql_middleware;
|
||||
use phpbb\db\middleware\sqlsrv\phpbb_sqlsrv_middleware;
|
||||
use phpbb\exception\runtime_exception;
|
||||
|
||||
/**
|
||||
@@ -94,9 +99,21 @@ class connection_factory
|
||||
$port
|
||||
);
|
||||
|
||||
$middleware = match($driver)
|
||||
{
|
||||
'pdo_mysql', 'mysqli' => [new phpbb_mysql_middleware()],
|
||||
'pdo_oci', 'oci8' => [new phpbb_oracle_middleware()],
|
||||
'pdo_pgsql', 'pgsql' => [new phpbb_postgresql_middleware()],
|
||||
'pdo_sqlsrv', 'sqlsrv' => [new phpbb_sqlsrv_middleware()],
|
||||
default => [],
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
$connection = DriverManager::getConnection($params);
|
||||
$connection_config = new Configuration();
|
||||
$connection_config->setMiddlewares($middleware);
|
||||
|
||||
$connection = DriverManager::getConnection($params, $connection_config);
|
||||
if (!Type::hasType(case_insensitive_string::CASE_INSENSITIVE_STRING))
|
||||
{
|
||||
Type::addType(case_insensitive_string::CASE_INSENSITIVE_STRING, case_insensitive_string::class);
|
||||
|
@@ -14,7 +14,6 @@
|
||||
namespace phpbb\db\doctrine;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use phpbb\db\doctrine\oci8\driver as oci8_driver;
|
||||
|
||||
/**
|
||||
* Helper class to generate Doctrine DBAL configuration.
|
||||
@@ -146,37 +145,17 @@ class connection_parameter_factory
|
||||
*/
|
||||
private static function enrich_parameters(array $params) : array
|
||||
{
|
||||
$enrichment_tags = [
|
||||
'pdo_mysql' => [
|
||||
'charset' => 'UTF8',
|
||||
'platform' => new mysql_platform(),
|
||||
],
|
||||
'oci8' => [
|
||||
'charset' => 'UTF8',
|
||||
'platform' => new oracle_platform(),
|
||||
'driverClass' => oci8_driver::class,
|
||||
],
|
||||
'pdo_pgsql' => [
|
||||
'charset' => 'UTF8',
|
||||
'platform' => new postgresql_platform(),
|
||||
],
|
||||
'pdo_sqlsrv' => [
|
||||
'platform' => new sqlsrv_platform(),
|
||||
],
|
||||
];
|
||||
if (in_array($params['driver'], ['mysqli', 'pdo_mysql', 'pgsql', 'pdo_pgsql', 'oci8', 'pdo_oci']))
|
||||
{
|
||||
$params['charset'] = 'UTF8';
|
||||
}
|
||||
|
||||
if ($params['driver'] === 'pdo_mysql' && extension_loaded('pdo_mysql'))
|
||||
{
|
||||
$enrichment_tags['pdo_mysql'][\PDO::MYSQL_ATTR_FOUND_ROWS] = true;
|
||||
$params[\PDO::MYSQL_ATTR_FOUND_ROWS] = true;
|
||||
}
|
||||
|
||||
$driver = $params['driver'];
|
||||
if (!array_key_exists($driver, $enrichment_tags))
|
||||
{
|
||||
return $params;
|
||||
}
|
||||
|
||||
return array_merge($params, $enrichment_tags[$driver]);
|
||||
return $params;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@@ -1,62 +0,0 @@
|
||||
<?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\AbstractMySQLPlatform;
|
||||
use Doctrine\DBAL\Schema\TableDiff;
|
||||
|
||||
/**
|
||||
* MySQL specific schema handling.
|
||||
*
|
||||
* While adding auto_increment column to MySQL, it must be indexed.
|
||||
* If it's indexed as primary key, it should be declared as NOT NULL
|
||||
* because MySQL primary key columns cannot be NULL.
|
||||
*/
|
||||
class mysql_platform extends AbstractMySQLPlatform
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getAlterTableSQL(TableDiff $diff)
|
||||
{
|
||||
$sql = parent::getAlterTableSQL($diff);
|
||||
$table = $diff->getOldTable();
|
||||
$columns = $diff->getAddedColumns();
|
||||
|
||||
foreach ($columns as $column)
|
||||
{
|
||||
$column_name = $column->getName();
|
||||
if (!empty($column->getAutoincrement()) && $table)
|
||||
{
|
||||
foreach ($sql as $i => $query)
|
||||
{
|
||||
if (stripos($query, "add $column_name"))
|
||||
{
|
||||
if (!$table->getPrimaryKey())
|
||||
{
|
||||
$sql[$i] = str_replace(' DEFAULT NULL', '', $sql[$i]);
|
||||
$sql[$i] .= ' PRIMARY KEY';
|
||||
}
|
||||
else
|
||||
{
|
||||
$sql[$i] .= ", ADD KEY ($column_name)";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $sql;
|
||||
}
|
||||
}
|
@@ -1,99 +0,0 @@
|
||||
<?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(): bool
|
||||
{
|
||||
return $this->wrapped->beginTransaction();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function commit(): bool
|
||||
{
|
||||
return $this->wrapped->commit();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function rollBack(): bool
|
||||
{
|
||||
return $this->wrapped->rollBack();
|
||||
}
|
||||
}
|
@@ -1,65 +0,0 @@
|
||||
<?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();
|
||||
}
|
||||
}
|
@@ -1,109 +0,0 @@
|
||||
<?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();
|
||||
}
|
||||
}
|
@@ -1,45 +0,0 @@
|
||||
<?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;
|
||||
}
|
||||
}
|
@@ -1,58 +0,0 @@
|
||||
<?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): bool
|
||||
{
|
||||
return $this->wrapped->bindValue($param, $value, $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function bindParam($param, &$variable, $type = ParameterType::STRING, $length = null): bool
|
||||
{
|
||||
return $this->wrapped->bindParam($param, $variable, $type, $length);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function execute($params = null): DriverResult
|
||||
{
|
||||
return new result($this->wrapped->execute($params));
|
||||
}
|
||||
}
|
@@ -1,177 +0,0 @@
|
||||
<?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\OraclePlatform;
|
||||
use Doctrine\DBAL\Schema\Identifier;
|
||||
use Doctrine\DBAL\Schema\Index;
|
||||
use Doctrine\DBAL\Schema\Table;
|
||||
|
||||
/**
|
||||
* Oracle specific schema restrictions for BC.
|
||||
*/
|
||||
class oracle_platform extends OraclePlatform
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getVarcharTypeDeclarationSQL(array $column): string
|
||||
{
|
||||
if (array_key_exists('length', $column) && is_int($column['length']))
|
||||
{
|
||||
$column['length'] *= 3;
|
||||
}
|
||||
|
||||
return parent::getVarcharTypeDeclarationSQL($column);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getAsciiStringTypeDeclarationSQL(array $column): string
|
||||
{
|
||||
return parent::getVarcharTypeDeclarationSQL($column);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getCreateIndexSQL(Index $index, $table): string
|
||||
{
|
||||
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(string $table_name, string $index_name, bool $throw_error = true): string
|
||||
{
|
||||
$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)
|
||||
{
|
||||
throw new \InvalidArgumentException(
|
||||
"Index name '$index_name' on table '$table_name' is too long. The maximum is $max_index_name_length characters."
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $index_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIdentitySequenceName($tableName, $columnName): string
|
||||
{
|
||||
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
|
||||
{
|
||||
$identifier = new Identifier($name);
|
||||
|
||||
return $identifier->isQuoted() ? $identifier : new Identifier(strtoupper($name));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see OraclePlatform::getAutoincrementIdentifierName()
|
||||
*/
|
||||
private function get_doctrine_autoincrement_identifier_name(Identifier $table): string
|
||||
{
|
||||
$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;
|
||||
}
|
||||
}
|
@@ -1,205 +0,0 @@
|
||||
<?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\PostgreSQLPlatform;
|
||||
use Doctrine\DBAL\Schema\Sequence;
|
||||
use Doctrine\DBAL\Schema\Table;
|
||||
use Doctrine\DBAL\Schema\TableDiff;
|
||||
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 PostgreSQLPlatform
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIdentitySequenceName($tableName, $columnName): string
|
||||
{
|
||||
return $tableName . '_seq';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getIntegerTypeDeclarationSQL(array $column): string
|
||||
{
|
||||
return 'INT';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getBigIntTypeDeclarationSQL(array $column): string
|
||||
{
|
||||
return 'BIGINT';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getSmallIntTypeDeclarationSQL(array $column): string
|
||||
{
|
||||
return 'SMALLINT';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getDefaultValueDeclarationSQL($column): string
|
||||
{
|
||||
if ($this->isSerialColumn($column))
|
||||
{
|
||||
return ' DEFAULT {{placeholder_sequence}}';
|
||||
}
|
||||
|
||||
return AbstractPlatform::getDefaultValueDeclarationSQL($column);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getAlterTableSQL(TableDiff $diff)
|
||||
{
|
||||
$sql = parent::getAlterTableSQL($diff);
|
||||
$table_name = $diff->getOldTable()->getName();
|
||||
$columns = $diff->getAddedColumns();
|
||||
$post_sql = $sequence_sql = [];
|
||||
|
||||
foreach ($columns as $column)
|
||||
{
|
||||
$column_name = $column->getName();
|
||||
if (!empty($column->getAutoincrement()))
|
||||
{
|
||||
$sequence = new Sequence($this->getIdentitySequenceName($table_name, $column_name));
|
||||
$sequence_sql[] = $this->getCreateSequenceSQL($sequence);
|
||||
$post_sql[] = 'ALTER SEQUENCE ' . $sequence->getName() . ' OWNED BY ' . $table_name . '.' . $column_name;
|
||||
}
|
||||
}
|
||||
$sql = array_merge($sequence_sql, $sql, $post_sql);
|
||||
|
||||
foreach ($sql as $i => $query)
|
||||
{
|
||||
$sql[$i] = str_replace('{{placeholder_sequence}}', "nextval('{$table_name}_seq')", $query);
|
||||
}
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function supportsIdentityColumns(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function _getCreateTableSQL($name, array $columns, array $options = []): array
|
||||
{
|
||||
$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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return if column is a "serial" column, i.e. type supporting auto-increment
|
||||
*
|
||||
* @param array $column Column data
|
||||
* @return bool
|
||||
*/
|
||||
private function isSerialColumn(array $column): bool
|
||||
{
|
||||
return isset($column['type'], $column['autoincrement'])
|
||||
&& $column['autoincrement'] === true
|
||||
&& $this->isNumericType($column['type']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return if supplied type is of numeric type
|
||||
*
|
||||
* @param Type $type
|
||||
* @return bool
|
||||
*/
|
||||
private function isNumericType(Type $type): bool
|
||||
{
|
||||
return $type instanceof IntegerType || $type instanceof BigIntType || $type instanceof SmallIntType;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getListSequencesSQL($database): string
|
||||
{
|
||||
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): string
|
||||
{
|
||||
// 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 (is_string($index) && $table !== null && $index === $this->tableName($table) . '_pkey')
|
||||
{
|
||||
return $this->getDropConstraintSQL($index, $this->tableName($table));
|
||||
}
|
||||
|
||||
return parent::getDropIndexSQL($index, $table);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
private function tableName($table)
|
||||
{
|
||||
return $table instanceof Table ? $table->getName() : (string) $table;
|
||||
}
|
||||
}
|
@@ -1,149 +0,0 @@
|
||||
<?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\SQLServerPlatform;
|
||||
use Doctrine\DBAL\Schema\Identifier;
|
||||
use Doctrine\DBAL\Schema\TableDiff;
|
||||
|
||||
/**
|
||||
* SQLServer specific schema restrictions for BC.
|
||||
*/
|
||||
class sqlsrv_platform extends SQLServerPlatform
|
||||
{
|
||||
/**
|
||||
* {@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);
|
||||
}
|
||||
}
|
||||
|
||||
// When dropping a primary key, the constraint needs to be dropped
|
||||
foreach ($diff->removedIndexes as $key => $index)
|
||||
{
|
||||
if ($index->isPrimary())
|
||||
{
|
||||
unset($diff->removedIndexes[$key]);
|
||||
$sql[] = $this->getDropConstraintSQL($index->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() !== false)
|
||||
{
|
||||
$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(string $identifier): string
|
||||
{
|
||||
// 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(string $table, string $column): string
|
||||
{
|
||||
return 'DF_' . $this->generate_doctrine_identifier_name($table) . '_' . $this->generate_doctrine_identifier_name($column);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user