mirror of
https://github.com/phpbb/phpbb.git
synced 2025-05-17 04:51:35 +02:00
188 lines
4.3 KiB
PHP
188 lines
4.3 KiB
PHP
<?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\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 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 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 ($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);
|
|
}
|
|
}
|