Unverified Commit 96365135 authored by Michael Moravec's avatar Michael Moravec Committed by Sergei Morozov

Drop support for SQL Anywhere <16

parent b1ad5280
# Upgrade to 3.0 # Upgrade to 3.0
## BC BREAK: Removed support for SQL Anywhere 12 and older
DBAL now requires SQL Anywhere 16 or newer, support for unmaintained versions has been dropped.
If you are using any of the legacy versions, you have to upgrade to newer SQL Anywhere version (16+).
`Doctrine\DBAL\Platforms\SQLAnywherePlatform` and `Doctrine\DBAL\Platforms\Keywords\SQLAnywhereKeywords` now represent the SQL Anywhere 16.
The following classes have been removed:
* `Doctrine\DBAL\Platforms\SQLAnywhere11Platform`
* `Doctrine\DBAL\Platforms\SQLAnywhere12Platform`
* `Doctrine\DBAL\Platforms\SQLAnywhere16Platform`
* `Doctrine\DBAL\Platforms\Keywords\SQLAnywhere11Keywords`
* `Doctrine\DBAL\Platforms\Keywords\SQLAnywhere12Keywords`
* `Doctrine\DBAL\Platforms\Keywords\SQLAnywhere16Keywords`
## BC BREAK: Removed support for SQL Server 2005 and older ## BC BREAK: Removed support for SQL Server 2005 and older
DBAL now requires SQL Server 2008 or newer, support for unmaintained versions has been dropped. DBAL now requires SQL Server 2008 or newer, support for unmaintained versions has been dropped.
......
...@@ -310,14 +310,9 @@ sqlanywhere ...@@ -310,14 +310,9 @@ sqlanywhere
Depending on the used underlying platform version, you can specify Depending on the used underlying platform version, you can specify
any other connection parameter that is supported by the particular any other connection parameter that is supported by the particular
platform version via the ``driverOptions`` option. platform version via the ``driverOptions`` option.
You can find a list of supported connection parameters for each You can find a list of supported connection parameters for the
platform version here: currently supported platform here:
- `SQL Anywhere 10.0.1 <http://dcx.sybase.com/index.html#1001/en/dbdaen10/da-conmean.html>`_
- `SQL Anywhere 11.0.0 <http://dcx.sybase.com/index.html#1100/en/dbadmin_en11/conmean.html>`_
- `SQL Anywhere 11.0.1 <http://dcx.sybase.com/index.html#1101/en/dbadmin_en11/conmean.html>`_
- `SQL Anywhere 12.0.0 <http://dcx.sybase.com/index.html#1200/en/dbadmin/da-conparm.html>`_
- `SQL Anywhere 12.0.1 <http://dcx.sybase.com/index.html#1201/en/dbadmin/da-conparm.html>`_
- `SAP Sybase SQL Anywhere 16.0 <http://dcx.sybase.com/index.html#sa160/en/dbadmin/da-conparm.html>`_ - `SAP Sybase SQL Anywhere 16.0 <http://dcx.sybase.com/index.html#sa160/en/dbadmin/da-conparm.html>`_
Automatic platform version detection Automatic platform version detection
......
...@@ -701,9 +701,7 @@ Please also notice the mapping specific footnotes for additional information. ...@@ -701,9 +701,7 @@ Please also notice the mapping specific footnotes for additional information.
| | +--------------------------+ | | | | +--------------------------+ | |
| | | **Oracle** | | | | | | **Oracle** | | |
| | +--------------------------+---------+----------------------------------------------------------+ | | +--------------------------+---------+----------------------------------------------------------+
| | | **SQL Anywhere** | < 12 | ``DATETIME`` [14]_ [15]_ | | | | **SQL Anywhere** | "all" | ``TIMESTAMP WITH TIME ZONE`` |
| | | +---------+----------------------------------------------------------+
| | | | >= 12 | ``TIMESTAMP WITH TIME ZONE`` |
+-------------------+---------------+--------------------------+---------+----------------------------------------------------------+ +-------------------+---------------+--------------------------+---------+----------------------------------------------------------+
| **time** | ``\DateTime`` | **MySQL** | *all* | ``TIME`` | | **time** | ``\DateTime`` | **MySQL** | *all* | ``TIME`` |
| | +--------------------------+ | | | | +--------------------------+ | |
......
...@@ -6,14 +6,10 @@ use Doctrine\DBAL\Connection; ...@@ -6,14 +6,10 @@ use Doctrine\DBAL\Connection;
use Doctrine\DBAL\DBALException; use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Driver; use Doctrine\DBAL\Driver;
use Doctrine\DBAL\Exception; use Doctrine\DBAL\Exception;
use Doctrine\DBAL\Platforms\SQLAnywhere11Platform;
use Doctrine\DBAL\Platforms\SQLAnywhere12Platform;
use Doctrine\DBAL\Platforms\SQLAnywhere16Platform;
use Doctrine\DBAL\Platforms\SQLAnywherePlatform; use Doctrine\DBAL\Platforms\SQLAnywherePlatform;
use Doctrine\DBAL\Schema\SQLAnywhereSchemaManager; use Doctrine\DBAL\Schema\SQLAnywhereSchemaManager;
use Doctrine\DBAL\VersionAwarePlatformDriver; use Doctrine\DBAL\VersionAwarePlatformDriver;
use function preg_match; use function preg_match;
use function version_compare;
/** /**
* Abstract base implementation of the {@link Doctrine\DBAL\Driver} interface for SAP Sybase SQL Anywhere based drivers. * Abstract base implementation of the {@link Doctrine\DBAL\Driver} interface for SAP Sybase SQL Anywhere based drivers.
...@@ -81,19 +77,7 @@ abstract class AbstractSQLAnywhereDriver implements Driver, ExceptionConverterDr ...@@ -81,19 +77,7 @@ abstract class AbstractSQLAnywhereDriver implements Driver, ExceptionConverterDr
); );
} }
$majorVersion = $versionParts['major'];
$minorVersion = $versionParts['minor'] ?? 0;
$patchVersion = $versionParts['patch'] ?? 0;
$buildVersion = $versionParts['build'] ?? 0;
$version = $majorVersion . '.' . $minorVersion . '.' . $patchVersion . '.' . $buildVersion;
switch (true) { switch (true) {
case version_compare($version, '16', '>='):
return new SQLAnywhere16Platform();
case version_compare($version, '12', '>='):
return new SQLAnywhere12Platform();
case version_compare($version, '11', '>='):
return new SQLAnywhere11Platform();
default: default:
return new SQLAnywherePlatform(); return new SQLAnywherePlatform();
} }
...@@ -114,7 +98,7 @@ abstract class AbstractSQLAnywhereDriver implements Driver, ExceptionConverterDr ...@@ -114,7 +98,7 @@ abstract class AbstractSQLAnywhereDriver implements Driver, ExceptionConverterDr
*/ */
public function getDatabasePlatform() public function getDatabasePlatform()
{ {
return new SQLAnywhere12Platform(); return new SQLAnywherePlatform();
} }
/** /**
......
<?php
namespace Doctrine\DBAL\Platforms\Keywords;
use function array_diff;
use function array_merge;
/**
* SAP Sybase SQL Anywhere 11 reserved keywords list.
*/
class SQLAnywhere11Keywords extends SQLAnywhereKeywords
{
/**
* {@inheritdoc}
*/
public function getName()
{
return 'SQLAnywhere11';
}
/**
* {@inheritdoc}
*
* @link http://dcx.sybase.com/1100/en/dbreference_en11/alhakeywords.html
*/
protected function getKeywords()
{
return array_merge(
array_diff(
parent::getKeywords(),
['IQ']
),
[
'MERGE',
'OPENSTRING',
]
);
}
}
<?php
namespace Doctrine\DBAL\Platforms\Keywords;
use function array_diff;
use function array_merge;
/**
* SAP Sybase SQL Anywhere 12 reserved keywords list.
*/
class SQLAnywhere12Keywords extends SQLAnywhere11Keywords
{
/**
* {@inheritdoc}
*/
public function getName()
{
return 'SQLAnywhere12';
}
/**
* {@inheritdoc}
*
* @link http://dcx.sybase.com/1200/en/dbreference/alhakeywords.html
*/
protected function getKeywords()
{
return array_merge(
array_diff(
parent::getKeywords(),
[
'INDEX_LPAREN',
'SYNTAX_ERROR',
'WITH_CUBE',
'WITH_LPAREN',
'WITH_ROLLUP',
]
),
[
'DATETIMEOFFSET',
'LIMIT',
'OPENXML',
'SPATIAL',
'TREAT',
]
);
}
}
<?php
namespace Doctrine\DBAL\Platforms\Keywords;
use function array_merge;
/**
* SAP Sybase SQL Anywhere 16 reserved keywords list.
*/
class SQLAnywhere16Keywords extends SQLAnywhere12Keywords
{
/**
* {@inheritdoc}
*/
public function getName()
{
return 'SQLAnywhere16';
}
/**
* {@inheritdoc}
*
* @link http://dcx.sybase.com/index.html#sa160/en/dbreference/alhakeywords.html
*/
protected function getKeywords()
{
return array_merge(
parent::getKeywords(),
[
'ARRAY',
'JSON',
'ROW',
'ROWTYPE',
'UNNEST',
'VARRAY',
]
);
}
}
...@@ -28,6 +28,7 @@ class SQLAnywhereKeywords extends KeywordList ...@@ -28,6 +28,7 @@ class SQLAnywhereKeywords extends KeywordList
'ALTER', 'ALTER',
'AND', 'AND',
'ANY', 'ANY',
'ARRAY',
'AS', 'AS',
'ASC', 'ASC',
'ATTACH', 'ATTACH',
...@@ -68,6 +69,7 @@ class SQLAnywhereKeywords extends KeywordList ...@@ -68,6 +69,7 @@ class SQLAnywhereKeywords extends KeywordList
'CURRENT_USER', 'CURRENT_USER',
'CURSOR', 'CURSOR',
'DATE', 'DATE',
'DATETIMEOFFSET',
'DBSPACE', 'DBSPACE',
'DEALLOCATE', 'DEALLOCATE',
'DEC', 'DEC',
...@@ -114,7 +116,6 @@ class SQLAnywhereKeywords extends KeywordList ...@@ -114,7 +116,6 @@ class SQLAnywhereKeywords extends KeywordList
'IF', 'IF',
'IN', 'IN',
'INDEX', 'INDEX',
'INDEX_LPAREN',
'INNER', 'INNER',
'INOUT', 'INOUT',
'INSENSITIVE', 'INSENSITIVE',
...@@ -127,20 +128,22 @@ class SQLAnywhereKeywords extends KeywordList ...@@ -127,20 +128,22 @@ class SQLAnywhereKeywords extends KeywordList
'INTEGRATED', 'INTEGRATED',
'INTERSECT', 'INTERSECT',
'INTO', 'INTO',
'IQ',
'IS', 'IS',
'ISOLATION', 'ISOLATION',
'JOIN', 'JOIN',
'JSON',
'KERBEROS', 'KERBEROS',
'KEY', 'KEY',
'LATERAL', 'LATERAL',
'LEFT', 'LEFT',
'LIKE', 'LIKE',
'LIMIT',
'LOCK', 'LOCK',
'LOGIN', 'LOGIN',
'LONG', 'LONG',
'MATCH', 'MATCH',
'MEMBERSHIP', 'MEMBERSHIP',
'MERGE',
'MESSAGE', 'MESSAGE',
'MODE', 'MODE',
'MODIFY', 'MODIFY',
...@@ -158,6 +161,8 @@ class SQLAnywhereKeywords extends KeywordList ...@@ -158,6 +161,8 @@ class SQLAnywhereKeywords extends KeywordList
'OFF', 'OFF',
'ON', 'ON',
'OPEN', 'OPEN',
'OPENSTRING',
'OPENXML',
'OPTION', 'OPTION',
'OPTIONS', 'OPTIONS',
'OR', 'OR',
...@@ -194,6 +199,8 @@ class SQLAnywhereKeywords extends KeywordList ...@@ -194,6 +199,8 @@ class SQLAnywhereKeywords extends KeywordList
'RIGHT', 'RIGHT',
'ROLLBACK', 'ROLLBACK',
'ROLLUP', 'ROLLUP',
'ROW',
'ROWTYPE',
'SAVE', 'SAVE',
'SAVEPOINT', 'SAVEPOINT',
'SCROLL', 'SCROLL',
...@@ -205,6 +212,7 @@ class SQLAnywhereKeywords extends KeywordList ...@@ -205,6 +212,7 @@ class SQLAnywhereKeywords extends KeywordList
'SHARE', 'SHARE',
'SMALLINT', 'SMALLINT',
'SOME', 'SOME',
'SPATIAL',
'SQLCODE', 'SQLCODE',
'SQLSTATE', 'SQLSTATE',
'START', 'START',
...@@ -212,7 +220,6 @@ class SQLAnywhereKeywords extends KeywordList ...@@ -212,7 +220,6 @@ class SQLAnywhereKeywords extends KeywordList
'SUBTRANS', 'SUBTRANS',
'SUBTRANSACTION', 'SUBTRANSACTION',
'SYNCHRONIZE', 'SYNCHRONIZE',
'SYNTAX_ERROR',
'TABLE', 'TABLE',
'TEMPORARY', 'TEMPORARY',
'THEN', 'THEN',
...@@ -222,6 +229,7 @@ class SQLAnywhereKeywords extends KeywordList ...@@ -222,6 +229,7 @@ class SQLAnywhereKeywords extends KeywordList
'TO', 'TO',
'TOP', 'TOP',
'TRAN', 'TRAN',
'TREAT',
'TRIGGER', 'TRIGGER',
'TRUNCATE', 'TRUNCATE',
'TSEQUAL', 'TSEQUAL',
...@@ -230,6 +238,7 @@ class SQLAnywhereKeywords extends KeywordList ...@@ -230,6 +238,7 @@ class SQLAnywhereKeywords extends KeywordList
'UNIQUE', 'UNIQUE',
'UNIQUEIDENTIFIER', 'UNIQUEIDENTIFIER',
'UNKNOWN', 'UNKNOWN',
'UNNEST',
'UNSIGNED', 'UNSIGNED',
'UPDATE', 'UPDATE',
'UPDATING', 'UPDATING',
...@@ -241,6 +250,7 @@ class SQLAnywhereKeywords extends KeywordList ...@@ -241,6 +250,7 @@ class SQLAnywhereKeywords extends KeywordList
'VARBIT', 'VARBIT',
'VARCHAR', 'VARCHAR',
'VARIABLE', 'VARIABLE',
'VARRAY',
'VARYING', 'VARYING',
'VIEW', 'VIEW',
'WAIT', 'WAIT',
...@@ -250,9 +260,6 @@ class SQLAnywhereKeywords extends KeywordList ...@@ -250,9 +260,6 @@ class SQLAnywhereKeywords extends KeywordList
'WHILE', 'WHILE',
'WINDOW', 'WINDOW',
'WITH', 'WITH',
'WITH_CUBE',
'WITH_LPAREN',
'WITH_ROLLUP',
'WITHIN', 'WITHIN',
'WORK', 'WORK',
'WRITETEXT', 'WRITETEXT',
......
<?php
namespace Doctrine\DBAL\Platforms;
/**
* The SQLAnywhere11Platform provides the behavior, features and SQL dialect of the
* SAP Sybase SQL Anywhere 11 database platform.
*/
class SQLAnywhere11Platform extends SQLAnywherePlatform
{
/**
* {@inheritdoc}
*/
public function getRegexpExpression()
{
return 'REGEXP';
}
/**
* {@inheritdoc}
*/
protected function getReservedKeywordsClass()
{
return Keywords\SQLAnywhere11Keywords::class;
}
}
<?php
namespace Doctrine\DBAL\Platforms;
use Doctrine\DBAL\Schema\Index;
use Doctrine\DBAL\Schema\Sequence;
/**
* The SQLAnywhere12Platform provides the behavior, features and SQL dialect of the
* SAP Sybase SQL Anywhere 12 database platform.
*/
class SQLAnywhere12Platform extends SQLAnywhere11Platform
{
/**
* {@inheritdoc}
*/
public function getCreateSequenceSQL(Sequence $sequence)
{
return 'CREATE SEQUENCE ' . $sequence->getQuotedName($this) .
' INCREMENT BY ' . $sequence->getAllocationSize() .
' START WITH ' . $sequence->getInitialValue() .
' MINVALUE ' . $sequence->getInitialValue();
}
/**
* {@inheritdoc}
*/
public function getAlterSequenceSQL(Sequence $sequence)
{
return 'ALTER SEQUENCE ' . $sequence->getQuotedName($this) .
' INCREMENT BY ' . $sequence->getAllocationSize();
}
/**
* {@inheritdoc}
*/
public function getDateTimeTzFormatString()
{
return 'Y-m-d H:i:s.uP';
}
/**
* {@inheritdoc}
*/
public function getDateTimeTzTypeDeclarationSQL(array $fieldDeclaration)
{
return 'TIMESTAMP WITH TIME ZONE';
}
/**
* {@inheritdoc}
*/
public function getDropSequenceSQL($sequence)
{
if ($sequence instanceof Sequence) {
$sequence = $sequence->getQuotedName($this);
}
return 'DROP SEQUENCE ' . $sequence;
}
/**
* {@inheritdoc}
*/
public function getListSequencesSQL($database)
{
return 'SELECT sequence_name, increment_by, start_with, min_value FROM SYS.SYSSEQUENCE';
}
/**
* {@inheritdoc}
*/
public function getSequenceNextValSQL($sequenceName)
{
return 'SELECT ' . $sequenceName . '.NEXTVAL';
}
/**
* {@inheritdoc}
*/
public function supportsSequences()
{
return true;
}
/**
* {@inheritdoc}
*/
protected function getAdvancedIndexOptionsSQL(Index $index)
{
if (! $index->isPrimary() && $index->isUnique() && $index->hasFlag('with_nulls_not_distinct')) {
return ' WITH NULLS NOT DISTINCT' . parent::getAdvancedIndexOptionsSQL($index);
}
return parent::getAdvancedIndexOptionsSQL($index);
}
/**
* {@inheritdoc}
*/
protected function getReservedKeywordsClass()
{
return Keywords\SQLAnywhere12Keywords::class;
}
/**
* {@inheritDoc}
*/
protected function initializeDoctrineTypeMappings()
{
parent::initializeDoctrineTypeMappings();
$this->doctrineTypeMapping['timestamp with time zone'] = 'datetime';
}
}
<?php
namespace Doctrine\DBAL\Platforms;
use Doctrine\DBAL\Schema\Index;
use UnexpectedValueException;
/**
* The SQLAnywhere16Platform provides the behavior, features and SQL dialect of the
* SAP Sybase SQL Anywhere 16 database platform.
*/
class SQLAnywhere16Platform extends SQLAnywhere12Platform
{
/**
* {@inheritdoc}
*/
protected function getAdvancedIndexOptionsSQL(Index $index)
{
if ($index->hasFlag('with_nulls_distinct') && $index->hasFlag('with_nulls_not_distinct')) {
throw new UnexpectedValueException(
'An Index can either have a "with_nulls_distinct" or "with_nulls_not_distinct" flag but not both.'
);
}
if (! $index->isPrimary() && $index->isUnique() && $index->hasFlag('with_nulls_distinct')) {
return ' WITH NULLS DISTINCT' . parent::getAdvancedIndexOptionsSQL($index);
}
return parent::getAdvancedIndexOptionsSQL($index);
}
/**
* {@inheritdoc}
*/
protected function getReservedKeywordsClass()
{
return Keywords\SQLAnywhere16Keywords::class;
}
}
...@@ -10,10 +10,12 @@ use Doctrine\DBAL\Schema\Constraint; ...@@ -10,10 +10,12 @@ use Doctrine\DBAL\Schema\Constraint;
use Doctrine\DBAL\Schema\ForeignKeyConstraint; use Doctrine\DBAL\Schema\ForeignKeyConstraint;
use Doctrine\DBAL\Schema\Identifier; use Doctrine\DBAL\Schema\Identifier;
use Doctrine\DBAL\Schema\Index; use Doctrine\DBAL\Schema\Index;
use Doctrine\DBAL\Schema\Sequence;
use Doctrine\DBAL\Schema\Table; use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Schema\TableDiff; use Doctrine\DBAL\Schema\TableDiff;
use Doctrine\DBAL\TransactionIsolationLevel; use Doctrine\DBAL\TransactionIsolationLevel;
use InvalidArgumentException; use InvalidArgumentException;
use UnexpectedValueException;
use function array_merge; use function array_merge;
use function array_unique; use function array_unique;
use function array_values; use function array_values;
...@@ -32,7 +34,7 @@ use function substr; ...@@ -32,7 +34,7 @@ use function substr;
/** /**
* The SQLAnywherePlatform provides the behavior, features and SQL dialect of the * The SQLAnywherePlatform provides the behavior, features and SQL dialect of the
* SAP Sybase SQL Anywhere 10 database platform. * SAP Sybase SQL Anywhere 12 database platform.
*/ */
class SQLAnywherePlatform extends AbstractPlatform class SQLAnywherePlatform extends AbstractPlatform
{ {
...@@ -508,7 +510,7 @@ class SQLAnywherePlatform extends AbstractPlatform ...@@ -508,7 +510,7 @@ class SQLAnywherePlatform extends AbstractPlatform
*/ */
public function getDateTimeTzFormatString() public function getDateTimeTzFormatString()
{ {
return $this->getDateTimeFormatString(); return 'Y-m-d H:i:s.uP';
} }
/** /**
...@@ -996,6 +998,14 @@ SQL ...@@ -996,6 +998,14 @@ SQL
return 'HASH(' . $column . ", 'MD5')"; return 'HASH(' . $column . ", 'MD5')";
} }
/**
* {@inheritdoc}
*/
public function getRegexpExpression()
{
return 'REGEXP';
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
...@@ -1158,6 +1168,70 @@ SQL ...@@ -1158,6 +1168,70 @@ SQL
return 'TRUNCATE TABLE ' . $tableIdentifier->getQuotedName($this); return 'TRUNCATE TABLE ' . $tableIdentifier->getQuotedName($this);
} }
/**
* {@inheritdoc}
*/
public function getCreateSequenceSQL(Sequence $sequence)
{
return 'CREATE SEQUENCE ' . $sequence->getQuotedName($this) .
' INCREMENT BY ' . $sequence->getAllocationSize() .
' START WITH ' . $sequence->getInitialValue() .
' MINVALUE ' . $sequence->getInitialValue();
}
/**
* {@inheritdoc}
*/
public function getAlterSequenceSQL(Sequence $sequence)
{
return 'ALTER SEQUENCE ' . $sequence->getQuotedName($this) .
' INCREMENT BY ' . $sequence->getAllocationSize();
}
/**
* {@inheritdoc}
*/
public function getDropSequenceSQL($sequence)
{
if ($sequence instanceof Sequence) {
$sequence = $sequence->getQuotedName($this);
}
return 'DROP SEQUENCE ' . $sequence;
}
/**
* {@inheritdoc}
*/
public function getListSequencesSQL($database)
{
return 'SELECT sequence_name, increment_by, start_with, min_value FROM SYS.SYSSEQUENCE';
}
/**
* {@inheritdoc}
*/
public function getSequenceNextValSQL($sequenceName)
{
return 'SELECT ' . $sequenceName . '.NEXTVAL';
}
/**
* {@inheritdoc}
*/
public function supportsSequences()
{
return true;
}
/**
* {@inheritdoc}
*/
public function getDateTimeTzTypeDeclarationSQL(array $fieldDeclaration)
{
return 'TIMESTAMP WITH TIME ZONE';
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
...@@ -1321,12 +1395,26 @@ SQL ...@@ -1321,12 +1395,26 @@ SQL
*/ */
protected function getAdvancedIndexOptionsSQL(Index $index) protected function getAdvancedIndexOptionsSQL(Index $index)
{ {
if ($index->hasFlag('with_nulls_distinct') && $index->hasFlag('with_nulls_not_distinct')) {
throw new UnexpectedValueException(
'An Index can either have a "with_nulls_distinct" or "with_nulls_not_distinct" flag but not both.'
);
}
$sql = ''; $sql = '';
if (! $index->isPrimary() && $index->hasFlag('for_olap_workload')) { if (! $index->isPrimary() && $index->hasFlag('for_olap_workload')) {
$sql .= ' FOR OLAP WORKLOAD'; $sql .= ' FOR OLAP WORKLOAD';
} }
if (! $index->isPrimary() && $index->isUnique() && $index->hasFlag('with_nulls_not_distinct')) {
return ' WITH NULLS NOT DISTINCT' . $sql;
}
if (! $index->isPrimary() && $index->isUnique() && $index->hasFlag('with_nulls_distinct')) {
return ' WITH NULLS DISTINCT' . $sql;
}
return $sql; return $sql;
} }
...@@ -1478,6 +1566,7 @@ SQL ...@@ -1478,6 +1566,7 @@ SQL
'smalldatetime' => 'datetime', 'smalldatetime' => 'datetime',
'time' => 'time', 'time' => 'time',
'timestamp' => 'datetime', 'timestamp' => 'datetime',
'timestamp with time zone' => 'datetime',
'binary' => 'binary', 'binary' => 'binary',
'image' => 'blob', 'image' => 'blob',
'long binary' => 'blob', 'long binary' => 'blob',
......
...@@ -12,9 +12,6 @@ use Doctrine\DBAL\Platforms\Keywords\PostgreSQL100Keywords; ...@@ -12,9 +12,6 @@ use Doctrine\DBAL\Platforms\Keywords\PostgreSQL100Keywords;
use Doctrine\DBAL\Platforms\Keywords\PostgreSQL94Keywords; use Doctrine\DBAL\Platforms\Keywords\PostgreSQL94Keywords;
use Doctrine\DBAL\Platforms\Keywords\PostgreSQLKeywords; use Doctrine\DBAL\Platforms\Keywords\PostgreSQLKeywords;
use Doctrine\DBAL\Platforms\Keywords\ReservedKeywordsValidator; use Doctrine\DBAL\Platforms\Keywords\ReservedKeywordsValidator;
use Doctrine\DBAL\Platforms\Keywords\SQLAnywhere11Keywords;
use Doctrine\DBAL\Platforms\Keywords\SQLAnywhere12Keywords;
use Doctrine\DBAL\Platforms\Keywords\SQLAnywhere16Keywords;
use Doctrine\DBAL\Platforms\Keywords\SQLAnywhereKeywords; use Doctrine\DBAL\Platforms\Keywords\SQLAnywhereKeywords;
use Doctrine\DBAL\Platforms\Keywords\SQLiteKeywords; use Doctrine\DBAL\Platforms\Keywords\SQLiteKeywords;
use Doctrine\DBAL\Platforms\Keywords\SQLServer2012Keywords; use Doctrine\DBAL\Platforms\Keywords\SQLServer2012Keywords;
...@@ -45,9 +42,6 @@ class ReservedWordsCommand extends Command ...@@ -45,9 +42,6 @@ class ReservedWordsCommand extends Command
'oracle' => OracleKeywords::class, 'oracle' => OracleKeywords::class,
'db2' => DB2Keywords::class, 'db2' => DB2Keywords::class,
'sqlanywhere' => SQLAnywhereKeywords::class, 'sqlanywhere' => SQLAnywhereKeywords::class,
'sqlanywhere11' => SQLAnywhere11Keywords::class,
'sqlanywhere12' => SQLAnywhere12Keywords::class,
'sqlanywhere16' => SQLAnywhere16Keywords::class,
]; ];
/** /**
...@@ -105,9 +99,6 @@ The following keyword lists are currently shipped with Doctrine: ...@@ -105,9 +99,6 @@ The following keyword lists are currently shipped with Doctrine:
* sqlserver * sqlserver
* sqlserver2012 * sqlserver2012
* sqlanywhere * sqlanywhere
* sqlanywhere11
* sqlanywhere12
* sqlanywhere16
* db2 (Not checked by default) * db2 (Not checked by default)
EOT EOT
); );
......
...@@ -4,9 +4,6 @@ namespace Doctrine\Tests\DBAL\Driver; ...@@ -4,9 +4,6 @@ namespace Doctrine\Tests\DBAL\Driver;
use Doctrine\DBAL\Connection; use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Driver\AbstractSQLAnywhereDriver; use Doctrine\DBAL\Driver\AbstractSQLAnywhereDriver;
use Doctrine\DBAL\Platforms\SQLAnywhere11Platform;
use Doctrine\DBAL\Platforms\SQLAnywhere12Platform;
use Doctrine\DBAL\Platforms\SQLAnywhere16Platform;
use Doctrine\DBAL\Platforms\SQLAnywherePlatform; use Doctrine\DBAL\Platforms\SQLAnywherePlatform;
use Doctrine\DBAL\Schema\SQLAnywhereSchemaManager; use Doctrine\DBAL\Schema\SQLAnywhereSchemaManager;
...@@ -19,7 +16,7 @@ class AbstractSQLAnywhereDriverTest extends AbstractDriverTest ...@@ -19,7 +16,7 @@ class AbstractSQLAnywhereDriverTest extends AbstractDriverTest
protected function createPlatform() protected function createPlatform()
{ {
return new SQLAnywhere12Platform(); return new SQLAnywherePlatform();
} }
protected function createSchemaManager(Connection $connection) protected function createSchemaManager(Connection $connection)
...@@ -30,35 +27,13 @@ class AbstractSQLAnywhereDriverTest extends AbstractDriverTest ...@@ -30,35 +27,13 @@ class AbstractSQLAnywhereDriverTest extends AbstractDriverTest
protected function getDatabasePlatformsForVersions() protected function getDatabasePlatformsForVersions()
{ {
return [ return [
['10', SQLAnywherePlatform::class], ['16', SQLAnywherePlatform::class],
['10.0', SQLAnywherePlatform::class], ['16.0', SQLAnywherePlatform::class],
['10.0.0', SQLAnywherePlatform::class], ['16.0.0', SQLAnywherePlatform::class],
['10.0.0.0', SQLAnywherePlatform::class], ['16.0.0.0', SQLAnywherePlatform::class],
['10.1.2.3', SQLAnywherePlatform::class], ['16.1.2.3', SQLAnywherePlatform::class],
['10.9.9.9', SQLAnywherePlatform::class], ['16.9.9.9', SQLAnywherePlatform::class],
['11', SQLAnywhere11Platform::class], ['17', SQLAnywherePlatform::class],
['11.0', SQLAnywhere11Platform::class],
['11.0.0', SQLAnywhere11Platform::class],
['11.0.0.0', SQLAnywhere11Platform::class],
['11.1.2.3', SQLAnywhere11Platform::class],
['11.9.9.9', SQLAnywhere11Platform::class],
['12', SQLAnywhere12Platform::class],
['12.0', SQLAnywhere12Platform::class],
['12.0.0', SQLAnywhere12Platform::class],
['12.0.0.0', SQLAnywhere12Platform::class],
['12.1.2.3', SQLAnywhere12Platform::class],
['12.9.9.9', SQLAnywhere12Platform::class],
['13', SQLAnywhere12Platform::class],
['14', SQLAnywhere12Platform::class],
['15', SQLAnywhere12Platform::class],
['15.9.9.9', SQLAnywhere12Platform::class],
['16', SQLAnywhere16Platform::class],
['16.0', SQLAnywhere16Platform::class],
['16.0.0', SQLAnywhere16Platform::class],
['16.0.0.0', SQLAnywhere16Platform::class],
['16.1.2.3', SQLAnywhere16Platform::class],
['16.9.9.9', SQLAnywhere16Platform::class],
['17', SQLAnywhere16Platform::class],
]; ];
} }
......
<?php
namespace Doctrine\Tests\DBAL\Platforms;
use Doctrine\DBAL\Platforms\SQLAnywhere11Platform;
class SQLAnywhere11PlatformTest extends SQLAnywherePlatformTest
{
/** @var SQLAnywhere11Platform */
protected $platform;
public function createPlatform()
{
return new SQLAnywhere11Platform();
}
public function testDoesNotSupportRegexp()
{
$this->markTestSkipped('This version of the platform now supports regular expressions.');
}
public function testGeneratesRegularExpressionSQLSnippet()
{
self::assertEquals('REGEXP', $this->platform->getRegexpExpression());
}
}
<?php
namespace Doctrine\Tests\DBAL\Platforms;
use Doctrine\DBAL\Platforms\SQLAnywhere12Platform;
use Doctrine\DBAL\Schema\Index;
use Doctrine\DBAL\Schema\Sequence;
class SQLAnywhere12PlatformTest extends SQLAnywhere11PlatformTest
{
/** @var SQLAnywhere12Platform */
protected $platform;
public function createPlatform()
{
return new SQLAnywhere12Platform();
}
public function testDoesNotSupportSequences()
{
$this->markTestSkipped('This version of the platform now supports sequences.');
}
public function testSupportsSequences()
{
self::assertTrue($this->platform->supportsSequences());
}
public function testGeneratesSequenceSqlCommands()
{
$sequence = new Sequence('myseq', 20, 1);
self::assertEquals(
'CREATE SEQUENCE myseq INCREMENT BY 20 START WITH 1 MINVALUE 1',
$this->platform->getCreateSequenceSQL($sequence)
);
self::assertEquals(
'ALTER SEQUENCE myseq INCREMENT BY 20',
$this->platform->getAlterSequenceSQL($sequence)
);
self::assertEquals(
'DROP SEQUENCE myseq',
$this->platform->getDropSequenceSQL('myseq')
);
self::assertEquals(
'DROP SEQUENCE myseq',
$this->platform->getDropSequenceSQL($sequence)
);
self::assertEquals(
'SELECT myseq.NEXTVAL',
$this->platform->getSequenceNextValSQL('myseq')
);
self::assertEquals(
'SELECT sequence_name, increment_by, start_with, min_value FROM SYS.SYSSEQUENCE',
$this->platform->getListSequencesSQL(null)
);
}
public function testGeneratesDateTimeTzColumnTypeDeclarationSQL()
{
self::assertEquals(
'TIMESTAMP WITH TIME ZONE',
$this->platform->getDateTimeTzTypeDeclarationSQL([
'length' => 10,
'fixed' => true,
'unsigned' => true,
'autoincrement' => true,
])
);
}
public function testHasCorrectDateTimeTzFormatString()
{
self::assertEquals('Y-m-d H:i:s.uP', $this->platform->getDateTimeTzFormatString());
}
public function testInitializesDateTimeTzTypeMapping()
{
self::assertTrue($this->platform->hasDoctrineTypeMappingFor('timestamp with time zone'));
self::assertEquals('datetime', $this->platform->getDoctrineTypeMapping('timestamp with time zone'));
}
public function testGeneratesCreateIndexWithAdvancedPlatformOptionsSQL()
{
self::assertEquals(
'CREATE VIRTUAL UNIQUE CLUSTERED INDEX fooindex ON footable (a, b) WITH NULLS NOT DISTINCT FOR OLAP WORKLOAD',
$this->platform->getCreateIndexSQL(
new Index(
'fooindex',
['a', 'b'],
true,
false,
['virtual', 'clustered', 'with_nulls_not_distinct', 'for_olap_workload']
),
'footable'
)
);
self::assertEquals(
'CREATE VIRTUAL CLUSTERED INDEX fooindex ON footable (a, b) FOR OLAP WORKLOAD',
$this->platform->getCreateIndexSQL(
new Index(
'fooindex',
['a', 'b'],
false,
false,
['virtual', 'clustered', 'with_nulls_not_distinct', 'for_olap_workload']
),
'footable'
)
);
// WITH NULLS NOT DISTINCT clause not available on primary indexes.
self::assertEquals(
'ALTER TABLE footable ADD PRIMARY KEY (a, b)',
$this->platform->getCreateIndexSQL(
new Index(
'fooindex',
['a', 'b'],
false,
true,
['with_nulls_not_distinct']
),
'footable'
)
);
// WITH NULLS NOT DISTINCT clause not available on non-unique indexes.
self::assertEquals(
'CREATE INDEX fooindex ON footable (a, b)',
$this->platform->getCreateIndexSQL(
new Index(
'fooindex',
['a', 'b'],
false,
false,
['with_nulls_not_distinct']
),
'footable'
)
);
}
}
<?php
namespace Doctrine\Tests\DBAL\Platforms;
use Doctrine\DBAL\Platforms\SQLAnywhere16Platform;
use Doctrine\DBAL\Schema\Index;
class SQLAnywhere16PlatformTest extends SQLAnywhere12PlatformTest
{
public function createPlatform()
{
return new SQLAnywhere16Platform();
}
public function testGeneratesCreateIndexWithAdvancedPlatformOptionsSQL()
{
self::assertEquals(
'CREATE UNIQUE INDEX fooindex ON footable (a, b) WITH NULLS DISTINCT',
$this->platform->getCreateIndexSQL(
new Index(
'fooindex',
['a', 'b'],
true,
false,
['with_nulls_distinct']
),
'footable'
)
);
// WITH NULLS DISTINCT clause not available on primary indexes.
self::assertEquals(
'ALTER TABLE footable ADD PRIMARY KEY (a, b)',
$this->platform->getCreateIndexSQL(
new Index(
'fooindex',
['a', 'b'],
false,
true,
['with_nulls_distinct']
),
'footable'
)
);
// WITH NULLS DISTINCT clause not available on non-unique indexes.
self::assertEquals(
'CREATE INDEX fooindex ON footable (a, b)',
$this->platform->getCreateIndexSQL(
new Index(
'fooindex',
['a', 'b'],
false,
false,
['with_nulls_distinct']
),
'footable'
)
);
parent::testGeneratesCreateIndexWithAdvancedPlatformOptionsSQL();
}
public function testThrowsExceptionOnInvalidWithNullsNotDistinctIndexOptions()
{
$this->expectException('UnexpectedValueException');
$this->platform->getCreateIndexSQL(
new Index(
'fooindex',
['a', 'b'],
false,
false,
['with_nulls_distinct', 'with_nulls_not_distinct']
),
'footable'
);
}
}
...@@ -13,6 +13,7 @@ use Doctrine\DBAL\Schema\Comparator; ...@@ -13,6 +13,7 @@ use Doctrine\DBAL\Schema\Comparator;
use Doctrine\DBAL\Schema\Constraint; use Doctrine\DBAL\Schema\Constraint;
use Doctrine\DBAL\Schema\ForeignKeyConstraint; use Doctrine\DBAL\Schema\ForeignKeyConstraint;
use Doctrine\DBAL\Schema\Index; use Doctrine\DBAL\Schema\Index;
use Doctrine\DBAL\Schema\Sequence;
use Doctrine\DBAL\Schema\Table; use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Schema\TableDiff; use Doctrine\DBAL\Schema\TableDiff;
use Doctrine\DBAL\Schema\UniqueConstraint; use Doctrine\DBAL\Schema\UniqueConstraint;
...@@ -453,20 +454,123 @@ class SQLAnywherePlatformTest extends AbstractPlatformTestCase ...@@ -453,20 +454,123 @@ class SQLAnywherePlatformTest extends AbstractPlatformTestCase
public function testGeneratesCreateIndexWithAdvancedPlatformOptionsSQL() public function testGeneratesCreateIndexWithAdvancedPlatformOptionsSQL()
{ {
self::assertEquals( self::assertEquals(
'CREATE VIRTUAL UNIQUE CLUSTERED INDEX fooindex ON footable (a, b) FOR OLAP WORKLOAD', 'CREATE UNIQUE INDEX fooindex ON footable (a, b) WITH NULLS DISTINCT',
$this->platform->getCreateIndexSQL( $this->platform->getCreateIndexSQL(
new Index( new Index(
'fooindex', 'fooindex',
['a', 'b'], ['a', 'b'],
true, true,
false, false,
['virtual', 'clustered', 'for_olap_workload'] ['with_nulls_distinct']
),
'footable'
)
);
// WITH NULLS DISTINCT clause not available on primary indexes.
self::assertEquals(
'ALTER TABLE footable ADD PRIMARY KEY (a, b)',
$this->platform->getCreateIndexSQL(
new Index(
'fooindex',
['a', 'b'],
false,
true,
['with_nulls_distinct']
),
'footable'
)
);
// WITH NULLS DISTINCT clause not available on non-unique indexes.
self::assertEquals(
'CREATE INDEX fooindex ON footable (a, b)',
$this->platform->getCreateIndexSQL(
new Index(
'fooindex',
['a', 'b'],
false,
false,
['with_nulls_distinct']
),
'footable'
)
);
self::assertEquals(
'CREATE VIRTUAL UNIQUE CLUSTERED INDEX fooindex ON footable (a, b) WITH NULLS NOT DISTINCT FOR OLAP WORKLOAD',
$this->platform->getCreateIndexSQL(
new Index(
'fooindex',
['a', 'b'],
true,
false,
['virtual', 'clustered', 'with_nulls_not_distinct', 'for_olap_workload']
),
'footable'
)
);
self::assertEquals(
'CREATE VIRTUAL CLUSTERED INDEX fooindex ON footable (a, b) FOR OLAP WORKLOAD',
$this->platform->getCreateIndexSQL(
new Index(
'fooindex',
['a', 'b'],
false,
false,
['virtual', 'clustered', 'with_nulls_not_distinct', 'for_olap_workload']
),
'footable'
)
);
// WITH NULLS NOT DISTINCT clause not available on primary indexes.
self::assertEquals(
'ALTER TABLE footable ADD PRIMARY KEY (a, b)',
$this->platform->getCreateIndexSQL(
new Index(
'fooindex',
['a', 'b'],
false,
true,
['with_nulls_not_distinct']
),
'footable'
)
);
// WITH NULLS NOT DISTINCT clause not available on non-unique indexes.
self::assertEquals(
'CREATE INDEX fooindex ON footable (a, b)',
$this->platform->getCreateIndexSQL(
new Index(
'fooindex',
['a', 'b'],
false,
false,
['with_nulls_not_distinct']
), ),
'footable' 'footable'
) )
); );
} }
public function testThrowsExceptionOnInvalidWithNullsNotDistinctIndexOptions()
{
$this->expectException('UnexpectedValueException');
$this->platform->getCreateIndexSQL(
new Index(
'fooindex',
['a', 'b'],
false,
false,
['with_nulls_distinct', 'with_nulls_not_distinct']
),
'footable'
);
}
public function testDoesNotSupportIndexDeclarationInCreateAlterTableStatements() public function testDoesNotSupportIndexDeclarationInCreateAlterTableStatements()
{ {
$this->expectException(DBALException::class); $this->expectException(DBALException::class);
...@@ -574,19 +678,28 @@ class SQLAnywherePlatformTest extends AbstractPlatformTestCase ...@@ -574,19 +678,28 @@ class SQLAnywherePlatformTest extends AbstractPlatformTestCase
); );
} }
public function testDoesNotSupportRegexp() public function testHasCorrectDateTimeTzFormatString()
{ {
$this->expectException(DBALException::class); self::assertEquals('Y-m-d H:i:s.uP', $this->platform->getDateTimeTzFormatString());
}
$this->platform->getRegexpExpression(); public function testGeneratesDateTimeTzColumnTypeDeclarationSQL()
{
self::assertEquals(
'TIMESTAMP WITH TIME ZONE',
$this->platform->getDateTimeTzTypeDeclarationSQL([
'length' => 10,
'fixed' => true,
'unsigned' => true,
'autoincrement' => true,
])
);
} }
public function testHasCorrectDateTimeTzFormatString() public function testInitializesDateTimeTzTypeMapping()
{ {
// Date time type with timezone is not supported before version 12. self::assertTrue($this->platform->hasDoctrineTypeMappingFor('timestamp with time zone'));
// For versions before we have to ensure that the date time with timezone format self::assertEquals('datetime', $this->platform->getDoctrineTypeMapping('timestamp with time zone'));
// equals the normal date time format so that it corresponds to the declaration SQL equality (datetimetz -> datetime).
self::assertEquals($this->platform->getDateTimeFormatString(), $this->platform->getDateTimeTzFormatString());
} }
public function testHasCorrectDefaultTransactionIsolationLevel() public function testHasCorrectDefaultTransactionIsolationLevel()
...@@ -737,7 +850,41 @@ class SQLAnywherePlatformTest extends AbstractPlatformTestCase ...@@ -737,7 +850,41 @@ class SQLAnywherePlatformTest extends AbstractPlatformTestCase
public function testDoesNotSupportSequences() public function testDoesNotSupportSequences()
{ {
self::assertFalse($this->platform->supportsSequences()); self::markTestSkipped('This version of the platform now supports sequences.');
}
public function testSupportsSequences()
{
self::assertTrue($this->platform->supportsSequences());
}
public function testGeneratesSequenceSqlCommands()
{
$sequence = new Sequence('myseq', 20, 1);
self::assertEquals(
'CREATE SEQUENCE myseq INCREMENT BY 20 START WITH 1 MINVALUE 1',
$this->platform->getCreateSequenceSQL($sequence)
);
self::assertEquals(
'ALTER SEQUENCE myseq INCREMENT BY 20',
$this->platform->getAlterSequenceSQL($sequence)
);
self::assertEquals(
'DROP SEQUENCE myseq',
$this->platform->getDropSequenceSQL('myseq')
);
self::assertEquals(
'DROP SEQUENCE myseq',
$this->platform->getDropSequenceSQL($sequence)
);
self::assertEquals(
'SELECT myseq.NEXTVAL',
$this->platform->getSequenceNextValSQL('myseq')
);
self::assertEquals(
'SELECT sequence_name, increment_by, start_with, min_value FROM SYS.SYSSEQUENCE',
$this->platform->getListSequencesSQL(null)
);
} }
public function testDoesNotSupportInlineColumnComments() public function testDoesNotSupportInlineColumnComments()
......
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