Unverified Commit fcc00dee authored by Marco Pivetta's avatar Marco Pivetta Committed by GitHub

Merge pull request #2893 from simPod/master

PostgreSQL 10 support
parents 0c74527d 83b72c1d
......@@ -245,6 +245,37 @@ jobs:
addons:
postgresql: "9.6"
- stage: Test
php: 7.1
env: DB=pgsql POSTGRESQL_VERSION=10.0
sudo: required
services:
- postgresql
addons:
postgresql: "9.6"
before_script:
- bash ./tests/travis/install-postgres-10.sh
- stage: Test
php: 7.2
env: DB=pgsql POSTGRESQL_VERSION=10.0
sudo: required
services:
- postgresql
addons:
postgresql: "9.6"
before_script:
- bash ./tests/travis/install-postgres-10.sh
- stage: Test
php: nightly
env: DB=pgsql POSTGRESQL_VERSION=10.0
sudo: required
services:
- postgresql
addons:
postgresql: "9.6"
before_script:
- bash ./tests/travis/install-postgres-10.sh
- stage: Coverage
php: 7.1
env: DB=sqlite
......
......@@ -22,6 +22,7 @@ namespace Doctrine\DBAL\Driver;
use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Driver;
use Doctrine\DBAL\Exception;
use Doctrine\DBAL\Platforms\PostgreSQL100Platform;
use Doctrine\DBAL\Platforms\PostgreSQL91Platform;
use Doctrine\DBAL\Platforms\PostgreSQL92Platform;
use Doctrine\DBAL\Platforms\PostgreSQL94Platform;
......@@ -113,6 +114,8 @@ abstract class AbstractPostgreSQLDriver implements Driver, ExceptionConverterDri
$version = $majorVersion . '.' . $minorVersion . '.' . $patchVersion;
switch(true) {
case version_compare($version, '10.0', '>='):
return new PostgreSQL100Platform();
case version_compare($version, '9.4', '>='):
return new PostgreSQL94Platform();
case version_compare($version, '9.2', '>='):
......
......@@ -2223,18 +2223,18 @@ abstract class AbstractPlatform
$default = $this->getDefaultValueDeclarationSQL($field);
$charset = (isset($field['charset']) && $field['charset']) ?
' ' . $this->getColumnCharsetDeclarationSQL($field['charset']) : '';
' ' . $this->getColumnCharsetDeclarationSQL($field['charset']) : '';
$collation = (isset($field['collation']) && $field['collation']) ?
' ' . $this->getColumnCollationDeclarationSQL($field['collation']) : '';
' ' . $this->getColumnCollationDeclarationSQL($field['collation']) : '';
$notnull = (isset($field['notnull']) && $field['notnull']) ? ' NOT NULL' : '';
$unique = (isset($field['unique']) && $field['unique']) ?
' ' . $this->getUniqueFieldDeclarationSQL() : '';
' ' . $this->getUniqueFieldDeclarationSQL() : '';
$check = (isset($field['check']) && $field['check']) ?
' ' . $field['check'] : '';
' ' . $field['check'] : '';
$typeDecl = $field['type']->getSQLDeclaration($field, $this);
$columnDef = $typeDecl . $charset . $default . $notnull . $unique . $check . $collation;
......@@ -2358,8 +2358,8 @@ abstract class AbstractPlatform
}
return 'CONSTRAINT ' . $name->getQuotedName($this) . ' UNIQUE ('
. $this->getIndexFieldDeclarationListSQL($columns)
. ')' . $this->getPartialIndexSQL($index);
. $this->getIndexFieldDeclarationListSQL($columns)
. ')' . $this->getPartialIndexSQL($index);
}
/**
......@@ -2546,9 +2546,9 @@ abstract class AbstractPlatform
}
$sql .= implode(', ', $foreignKey->getQuotedLocalColumns($this))
. ') REFERENCES '
. $foreignKey->getQuotedForeignTableName($this) . ' ('
. implode(', ', $foreignKey->getQuotedForeignColumns($this)) . ')';
. ') REFERENCES '
. $foreignKey->getQuotedForeignTableName($this) . ' ('
. implode(', ', $foreignKey->getQuotedForeignColumns($this)) . ')';
return $sql;
}
......
<?php
declare(strict_types=1);
namespace Doctrine\DBAL\Platforms\Keywords;
/**
* PostgreSQL 10.0 reserved keywords list.
*/
class PostgreSQL100Keywords extends PostgreSQL94Keywords
{
/**
* {@inheritdoc}
*/
public function getName() : string
{
return 'PostgreSQL100';
}
}
<?php
declare(strict_types=1);
namespace Doctrine\DBAL\Platforms;
use Doctrine\DBAL\Platforms\Keywords\PostgreSQL100Keywords;
/**
* Provides the behavior, features and SQL dialect of the PostgreSQL 10.0 database platform.
*/
class PostgreSQL100Platform extends PostgreSQL94Platform
{
/**
* {@inheritdoc}
*/
protected function getReservedKeywordsClass() : string
{
return PostgreSQL100Keywords::class;
}
public function getListSequencesSQL($database) : string
{
return "SELECT sequence_name AS relname,
sequence_schema AS schemaname,
minimum_value AS min_value,
increment AS increment_by
FROM information_schema.sequences
WHERE sequence_catalog = " . $this->quoteStringLiteral($database) . "
AND sequence_schema NOT LIKE 'pg\_%'
AND sequence_schema != 'information_schema'";
}
}
......@@ -692,10 +692,10 @@ class PostgreSqlPlatform extends AbstractPlatform
public function getCreateSequenceSQL(Sequence $sequence)
{
return 'CREATE SEQUENCE ' . $sequence->getQuotedName($this) .
' INCREMENT BY ' . $sequence->getAllocationSize() .
' MINVALUE ' . $sequence->getInitialValue() .
' START ' . $sequence->getInitialValue() .
$this->getSequenceCacheSQL($sequence);
' INCREMENT BY ' . $sequence->getAllocationSize() .
' MINVALUE ' . $sequence->getInitialValue() .
' START ' . $sequence->getInitialValue() .
$this->getSequenceCacheSQL($sequence);
}
/**
......@@ -704,8 +704,8 @@ class PostgreSqlPlatform extends AbstractPlatform
public function getAlterSequenceSQL(Sequence $sequence)
{
return 'ALTER SEQUENCE ' . $sequence->getQuotedName($this) .
' INCREMENT BY ' . $sequence->getAllocationSize() .
$this->getSequenceCacheSQL($sequence);
' INCREMENT BY ' . $sequence->getAllocationSize() .
$this->getSequenceCacheSQL($sequence);
}
/**
......@@ -915,7 +915,7 @@ class PostgreSqlPlatform extends AbstractPlatform
public function getSetTransactionIsolationSQL($level)
{
return 'SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL '
. $this->_getTransactionIsolationLevelSQL($level);
. $this->_getTransactionIsolationLevelSQL($level);
}
/**
......@@ -1020,7 +1020,7 @@ class PostgreSqlPlatform extends AbstractPlatform
protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed)
{
return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(255)')
: ($length ? 'VARCHAR(' . $length . ')' : 'VARCHAR(255)');
: ($length ? 'VARCHAR(' . $length . ')' : 'VARCHAR(255)');
}
/**
......
......@@ -283,15 +283,18 @@ class PostgreSqlSchemaManager extends AbstractSchemaManager
*/
protected function _getPortableSequenceDefinition($sequence)
{
if ($sequence['schemaname'] != 'public') {
if ($sequence['schemaname'] !== 'public') {
$sequenceName = $sequence['schemaname'] . "." . $sequence['relname'];
} else {
$sequenceName = $sequence['relname'];
}
$data = $this->_conn->fetchAll('SELECT min_value, increment_by FROM ' . $this->_platform->quoteIdentifier($sequenceName));
if ( ! isset($sequence['increment_by'], $sequence['min_value'])) {
$data = $this->_conn->fetchAssoc('SELECT min_value, increment_by FROM ' . $this->_platform->quoteIdentifier($sequenceName));
$sequence += $data;
}
return new Sequence($sequenceName, $data[0]['increment_by'], $data[0]['min_value']);
return new Sequence($sequenceName, $sequence['increment_by'], $sequence['min_value']);
}
/**
......
......@@ -3,6 +3,7 @@
namespace Doctrine\Tests\DBAL\Driver;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Platforms\PostgreSQL100Platform;
use Doctrine\DBAL\Platforms\PostgreSqlPlatform;
use Doctrine\DBAL\Schema\PostgreSqlSchemaManager;
......@@ -67,7 +68,7 @@ class AbstractPostgreSQLDriverTest extends AbstractDriverTest
array('9.4', 'Doctrine\DBAL\Platforms\PostgreSQL94Platform'),
array('9.4.0', 'Doctrine\DBAL\Platforms\PostgreSQL94Platform'),
array('9.4.1', 'Doctrine\DBAL\Platforms\PostgreSQL94Platform'),
array('10', 'Doctrine\DBAL\Platforms\PostgreSQL94Platform'),
array('10', PostgreSQL100Platform::class),
);
}
......
......@@ -273,4 +273,9 @@ class OracleSchemaManagerTest extends SchemaManagerFunctionalTestCase
self::assertSame('datetime', $columns['col_datetime']->getType()->getName());
self::assertSame('datetimetz', $columns['col_datetimetz']->getType()->getName());
}
public function testCreateAndListSequences() : void
{
self::markTestSkipped("Skipped for uppercase letters are contained in sequences' names. Fix the schema manager in 3.0.");
}
}
......@@ -8,6 +8,7 @@ use Doctrine\DBAL\Platforms\OraclePlatform;
use Doctrine\DBAL\Schema\Column;
use Doctrine\DBAL\Schema\ColumnDiff;
use Doctrine\DBAL\Schema\Comparator;
use Doctrine\DBAL\Schema\Sequence;
use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Schema\TableDiff;
use Doctrine\DBAL\Types\Type;
......@@ -1360,4 +1361,40 @@ class SchemaManagerFunctionalTestCase extends \Doctrine\Tests\DbalFunctionalTest
'valid with extra opening brackets' => ['(DC2Type:should((.stop)).before)', 'should((.stop', $currentType],
];
}
public function testCreateAndListSequences() : void
{
if ( ! $this->_sm->getDatabasePlatform()->supportsSequences()) {
self::markTestSkipped('This test is only supported on platforms that support sequences.');
}
$sequence1Name = 'sequence_1';
$sequence1AllocationSize = 1;
$sequence1InitialValue = 2;
$sequence2Name = 'sequence_2';
$sequence2AllocationSize = 3;
$sequence2InitialValue = 4;
$sequence1 = new Sequence($sequence1Name, $sequence1AllocationSize, $sequence1InitialValue);
$sequence2 = new Sequence($sequence2Name, $sequence2AllocationSize, $sequence2InitialValue);
$this->_sm->createSequence($sequence1);
$this->_sm->createSequence($sequence2);
/** @var Sequence[] $actualSequences */
$actualSequences = [];
foreach ($this->_sm->listSequences() as $sequence) {
$actualSequences[$sequence->getName()] = $sequence;
}
$actualSequence1 = $actualSequences[$sequence1Name];
$actualSequence2 = $actualSequences[$sequence2Name];
self::assertSame($sequence1Name, $actualSequence1->getName());
self::assertEquals($sequence1AllocationSize, $actualSequence1->getAllocationSize());
self::assertEquals($sequence1InitialValue, $actualSequence1->getInitialValue());
self::assertSame($sequence2Name, $actualSequence2->getName());
self::assertEquals($sequence2AllocationSize, $actualSequence2->getAllocationSize());
self::assertEquals($sequence2InitialValue, $actualSequence2->getInitialValue());
}
}
<?php
declare(strict_types=1);
namespace Doctrine\Tests\DBAL\Platforms;
use Doctrine\DBAL\Platforms\PostgreSQL100Platform;
class PostgreSQL100PlatformTest extends PostgreSQL94PlatformTest
{
/**
* {@inheritdoc}
*/
public function createPlatform() : PostgreSQL100Platform
{
return new PostgreSQL100Platform();
}
public function testGetListSequencesSQL() : void
{
self::assertSame(
"SELECT sequence_name AS relname,
sequence_schema AS schemaname,
minimum_value AS min_value,
increment AS increment_by
FROM information_schema.sequences
WHERE sequence_catalog = 'test_db'
AND sequence_schema NOT LIKE 'pg\_%'
AND sequence_schema != 'information_schema'",
$this->_platform->getListSequencesSQL('test_db')
);
}
}
<?php
namespace Doctrine\Tests\DBAL\Schema;
use Doctrine\DBAL\Configuration;
use Doctrine\DBAL\Schema\PostgreSqlSchemaManager;
use Doctrine\DBAL\Schema\Sequence;
class PostgreSQLSchemaManagerTest extends \PHPUnit\Framework\TestCase
{
/**
* @var \Doctrine\DBAL\Schema\PostgreSQLSchemaManager
*/
private $schemaManager;
/**
* @var \Doctrine\DBAL\Connection|\PHPUnit_Framework_MockObject_MockObject
*/
private $connection;
protected function setUp()
{
$driverMock = $this->createMock('Doctrine\DBAL\Driver');
$platform = $this->createMock('Doctrine\DBAL\Platforms\PostgreSqlPlatform');
$this->connection = $this->getMockBuilder('Doctrine\DBAL\Connection')
->setConstructorArgs([['platform' => $platform], $driverMock])
->getMock();
$this->schemaManager = new PostgreSqlSchemaManager($this->connection, $platform);
}
/**
* @group DBAL-474
*/
public function testFiltersSequences()
{
$configuration = new Configuration();
$configuration->setFilterSchemaAssetsExpression('/^schema/');
$sequences = [
['relname' => 'foo', 'schemaname' => 'schema'],
['relname' => 'bar', 'schemaname' => 'schema'],
['relname' => 'baz', 'schemaname' => ''],
['relname' => 'bloo', 'schemaname' => 'bloo_schema'],
];
$this->connection->expects($this->any())
->method('getConfiguration')
->will($this->returnValue($configuration));
$this->connection->expects($this->at(0))
->method('fetchAll')
->will($this->returnValue($sequences));
$this->connection->expects($this->at(1))
->method('fetchAll')
->will($this->returnValue([['min_value' => 1, 'increment_by' => 1]]));
$this->connection->expects($this->at(2))
->method('fetchAll')
->will($this->returnValue([['min_value' => 2, 'increment_by' => 2]]));
$this->connection->expects($this->exactly(3))
->method('fetchAll');
self::assertEquals(
[
new Sequence('schema.foo', 2, 2),
new Sequence('schema.bar', 1, 1),
],
$this->schemaManager->listSequences('database')
);
}
}
#!/usr/bin/env bash
set -ex
echo "Installing Postgres 10"
sudo service postgresql stop
sudo apt-get remove -q 'postgresql-*'
sudo apt-get update -q
sudo apt-get install -q postgresql-10 postgresql-client-10
sudo cp /etc/postgresql/{9.6,10}/main/pg_hba.conf
echo "Restarting Postgres 10"
sudo service postgresql restart
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment