diff --git a/.scrutinizer.yml b/.scrutinizer.yml
index f51cf15b63f..e03fc0f0cf8 100644
--- a/.scrutinizer.yml
+++ b/.scrutinizer.yml
@@ -3,7 +3,7 @@ build:
analysis:
environment:
php:
- version: 7.1
+ version: 7.2
cache:
disabled: false
directories:
@@ -21,7 +21,7 @@ before_commands:
tools:
external_code_coverage:
timeout: 3600
- runs: 27 # 23x Travis (jobs with COVERAGE=yes) + 3x AppVeyor (jobs with coverage=yes) + 1x ContinuousPHP
+ runs: 26 # 22x Travis (jobs with COVERAGE=yes) + 3x AppVeyor (jobs with coverage=yes) + 1x ContinuousPHP
filter:
excluded_paths:
diff --git a/.travis.yml b/.travis.yml
index de5c5dcd9b8..297d9caf726 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -8,7 +8,6 @@ cache:
- $HOME/.composer/cache
php:
- - 7.1
- 7.2
- 7.3
- nightly
@@ -57,11 +56,11 @@ jobs:
- env: DB=pgsql POSTGRESQL_VERSION=11.0
exclude:
- - php: 7.1
+ - php: 7.2
env: DB=sqlite
- - php: 7.1
+ - php: 7.2
env: DB=mysql
- - php: 7.1
+ - php: 7.2
env: DB=mysqli
- php: 7.2
env: DB=sqlite
@@ -79,10 +78,6 @@ jobs:
env: DB=mysqli
include:
- - stage: Test
- php: 7.1
- env: DB=sqlite
-
- stage: Test
php: 7.2
env: DB=sqlite COVERAGE=yes
@@ -95,12 +90,6 @@ jobs:
php: 7.2
env: DB=mysqli COVERAGE=yes
- - stage: Test
- php: 7.1
- env: DB=mysql MYSQL_VERSION=5.7
- sudo: required
- before_script:
- - bash ./tests/travis/install-mysql-5.7.sh
- stage: Test
php: 7.2
env: DB=mysql MYSQL_VERSION=5.7 COVERAGE=yes
@@ -120,12 +109,6 @@ jobs:
before_script:
- bash ./tests/travis/install-mysql-5.7.sh
- - stage: Test
- php: 7.1
- env: DB=mysqli MYSQL_VERSION=5.7
- sudo: required
- before_script:
- - bash ./tests/travis/install-mysql-5.7.sh
- stage: Test
php: 7.2
env: DB=mysqli MYSQL_VERSION=5.7 COVERAGE=yes
@@ -181,12 +164,6 @@ jobs:
addons:
mariadb: 10.2
- - stage: Test
- php: 7.1
- env: DB=mariadb MARIADB_VERSION=10.3
- addons:
- mariadb: 10.3
-
- stage: Test
php: 7.2
env: DB=mariadb MARIADB_VERSION=10.3 COVERAGE=yes
@@ -205,12 +182,6 @@ jobs:
addons:
mariadb: 10.3
- - stage: Test
- php: 7.1
- env: DB=mariadb.mysqli MARIADB_VERSION=10.3
- addons:
- mariadb: 10.3
-
- stage: Test
php: 7.2
env: DB=mariadb.mysqli MARIADB_VERSION=10.3 COVERAGE=yes
@@ -229,14 +200,6 @@ jobs:
addons:
mariadb: 10.3
- - stage: Test
- php: 7.2
- env: DB=pgsql POSTGRESQL_VERSION=9.2 COVERAGE=yes
- services:
- - postgresql
- addons:
- postgresql: "9.2"
-
- stage: Test
php: 7.2
env: DB=pgsql POSTGRESQL_VERSION=9.3 COVERAGE=yes
@@ -280,14 +243,6 @@ jobs:
before_script:
- bash ./tests/travis/install-postgres-10.sh
- - stage: Test
- php: 7.1
- env: DB=pgsql POSTGRESQL_VERSION=11.0
- sudo: required
- services:
- - docker
- before_script:
- - bash ./tests/travis/install-postgres-11.sh
- stage: Test
php: 7.2
env: DB=pgsql POSTGRESQL_VERSION=11.0 COVERAGE=yes
@@ -313,15 +268,6 @@ jobs:
before_script:
- bash ./tests/travis/install-postgres-11.sh
- - stage: Test
- php: 7.1
- env: DB=sqlsrv
- sudo: required
- services:
- - docker
- before_script:
- - bash ./tests/travis/install-mssql-$DB.sh
- - bash ./tests/travis/install-mssql.sh
- stage: Test
php: 7.2
env: DB=sqlsrv COVERAGE=yes
@@ -350,15 +296,6 @@ jobs:
- bash ./tests/travis/install-mssql-$DB.sh
- bash ./tests/travis/install-mssql.sh
- - stage: Test
- php: 7.1
- env: DB=pdo_sqlsrv
- sudo: required
- services:
- - docker
- before_script:
- - bash ./tests/travis/install-mssql-$DB.sh
- - bash ./tests/travis/install-mssql.sh
- stage: Test
php: 7.2
env: DB=pdo_sqlsrv COVERAGE=yes
@@ -387,15 +324,6 @@ jobs:
- bash ./tests/travis/install-mssql-$DB.sh
- bash ./tests/travis/install-mssql.sh
- - stage: Test
- php: 7.1
- env: DB=ibm_db2
- sudo: required
- services:
- - docker
- before_script:
- - bash ./tests/travis/install-db2.sh
- - bash ./tests/travis/install-db2-$DB.sh
- stage: Test
php: 7.2
env: DB=ibm_db2 COVERAGE=yes
@@ -406,12 +334,6 @@ jobs:
- bash ./tests/travis/install-db2.sh
- bash ./tests/travis/install-db2-$DB.sh
- - stage: Test
- php: 7.1
- env: DB=sqlite DEPENDENCIES=low
- install:
- - travis_retry composer update --prefer-dist --prefer-lowest
-
- stage: Test
if: type = cron
php: 7.2
diff --git a/UPGRADE.md b/UPGRADE.md
index bf079383657..d3836188cf9 100644
--- a/UPGRADE.md
+++ b/UPGRADE.md
@@ -1,3 +1,143 @@
+# Upgrade to 3.0
+
+## BC BREAK `Statement::execute()` with redundant parameters.
+
+Similarly to the drivers based on `pdo_pgsql` and `pdo_sqlsrv`, `OCI8Statement::execute()` and `MySQLiStatement::execute()` do not longer ignore redundant parameters.
+
+## BC BREAK: `Doctrine\DBAL\Types\Type::getDefaultLength()` removed
+
+The `Doctrine\DBAL\Types\Type::getDefaultLength()` method has been removed as it served no purpose.
+
+## BC BREAK: `Doctrine\DBAL\Types\Type::__toString()` removed
+
+Relying on string representation was discouraged and has been removed.
+
+## BC BREAK: The `NULL` value of `$offset` in LIMIT queries is not allowed
+
+The `NULL` value of the `$offset` argument in `AbstractPlatform::(do)?ModifyLimitQuery()` methods is no longer allowed. The absence of the offset should be indicated with a `0` which is now the default value.
+
+## BC BREAK: Removed dbal:import CLI command
+
+The `dbal:import` CLI command has been removed since it only worked with PDO-based drivers by relying on a non-documented behavior of the extension, and it was impossible to make it work with other drivers.
+Please use other database client applications for import, e.g.:
+
+ * For MySQL and MariaDB: `mysql [dbname] < data.sql`.
+ * For PostgreSQL: `psql [dbname] < data.sql`.
+ * For SQLite: `sqlite3 /path/to/file.db < data.sql`.
+
+## BC BREAK: Removed support for DB-generated UUIDs
+
+The support for DB-generated UUIDs was removed as non-portable.
+Please generate UUIDs on the application side (e.g. using [ramsey/uuid](https://packagist.org/packages/ramsey/uuid)).
+
+## BC BREAK: Removed MsSQLKeywords class
+
+The `Doctrine\DBAL\Platforms\MsSQLKeywords` has been removed.
+Please use `Doctrine\DBAL\Platforms\SQLServerPlatform `instead.
+
+## BC BREAK: Removed PDO DB2 driver
+
+This PDO-based IBM DB2 driver (built on top of pdo_ibm extension) has already been unsupported as of 2.5, it has now been now removed.
+
+The following class has been removed:
+
+ * `Doctrine\DBAL\Driver\PDOIbm\Driver`
+
+## 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
+
+DBAL now requires SQL Server 2008 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 Server version (2012+ is recommended).
+`Doctrine\DBAL\Platforms\SQLServerPlatform` and `Doctrine\DBAL\Platforms\Keywords\SQLServerKeywords` now represent the SQL Server 2008.
+
+The following classes have been removed:
+
+ * `Doctrine\DBAL\Platforms\SQLServer2005Platform`
+ * `Doctrine\DBAL\Platforms\SQLServer2008Platform`
+ * `Doctrine\DBAL\Platforms\Keywords\SQLServer2005Keywords`
+ * `Doctrine\DBAL\Platforms\Keywords\SQLServer2008Keywords`
+
+## BC BREAK: Removed support for PostgreSQL 9.2 and older
+
+DBAL now requires PostgeSQL 9.3 or newer, support for unmaintained versions has been dropped.
+If you are using any of the legacy versions, you have to upgrade to newer PostgreSQL version (9.6+ is recommended).
+`Doctrine\DBAL\Platforms\PostgreSqlPlatform` and `Doctrine\DBAL\Platforms\Keywords\PostgreSQLKeywords` now represent the PostgreSQL 9.3.
+
+The following classes have been removed:
+
+ * `Doctrine\DBAL\Platforms\PostgreSQL91Platform`
+ * `Doctrine\DBAL\Platforms\PostgreSQL92Platform`
+ * `Doctrine\DBAL\Platforms\Keywords\PostgreSQL91Keywords`
+ * `Doctrine\DBAL\Platforms\Keywords\PostgreSQL92Keywords`
+
+## BC BREAK: Removed Doctrine\DBAL\Version
+
+The Doctrine\DBAL\Version class is no longer available: please refrain from checking the DBAL version at runtime.
+
+## BC BREAK: the PDO symbols are no longer part of the DBAL API
+
+1. The support of `PDO::PARAM_*`, `PDO::FETCH_*`, `PDO::CASE_*` and `PDO::PARAM_INPUT_OUTPUT` constants in the DBAL API is removed.
+2. `\Doctrine\DBAL\Driver\PDOConnection` does not extend `\PDO` anymore. Please use `\Doctrine\DBAL\Driver\PDOConnection::getWrappedConnection()` to access the underlying `PDO` object.
+3. `\Doctrine\DBAL\Driver\PDOStatement` does not extend `\PDOStatement` anymore.
+
+Before:
+
+ use Doctrine\DBAL\Portability\Connection;
+
+ $params = array(
+ 'wrapperClass' => Connection::class,
+ 'fetch_case' => PDO::CASE_LOWER,
+ );
+
+ $stmt->bindValue(1, 1, PDO::PARAM_INT);
+ $stmt->fetchAll(PDO::FETCH_COLUMN);
+
+After:
+
+ use Doctrine\DBAL\ColumnCase;
+ use Doctrine\DBAL\FetchMode;
+ use Doctrine\DBAL\ParameterType;
+ use Doctrine\DBAL\Portability\Connection;
+
+ $params = array(
+ 'wrapperClass' => Connection::class,
+ 'fetch_case' => ColumnCase::LOWER,
+ );
+
+ $stmt->bindValue(1, 1, ParameterType::INTEGER);
+ $stmt->fetchAll(FetchMode::COLUMN);
+
+## BC BREAK: Removed Drizzle support
+
+The Drizzle project is abandoned and is therefore not supported by Doctrine DBAL anymore.
+
+## BC BREAK: SQLLogger changes
+
+- The `SQLLogger` interface has changed; the methods are the same but use scalar type hints, return types, and non-nullable arrays.
+- `SQLLogger` implementations: `DebugStack`, `EchoSQLLogger`, `LoggerChain` are now final.
+- `Configuration::getSQLLogger()` does not return `null` anymore, but a `NullLogger` implementation.
+- `Configuration::setSQLLogger()` does not allow `null` anymore.
+
+## BC BREAK: Changes to handling binary fields
+
+- Binary fields whose length exceeds the maximum field size on a given platform are no longer represented as `BLOB`s.
+ Use binary fields of a size which fits all target platforms, or use blob explicitly instead.
+- Binary fields are no longer represented as streams in PHP. They are represented as strings.
+
# Upgrade to 2.9
## Deprecated `Configuration::getFilterSchemaAssetsExpression()`, `::setFilterSchemaAssetsExpression()` and `AbstractSchemaManager::getFilterSchemaAssetsExpression()`.
diff --git a/build.properties b/build.properties
index 309e0e2105c..e69de29bb2d 100644
--- a/build.properties
+++ b/build.properties
@@ -1,3 +0,0 @@
-# Version class and file
-project.version_class = Doctrine\\DBAL\\Version
-project.version_file = lib/Doctrine/DBAL/Version.php
diff --git a/build.xml b/build.xml
index 064a6084e7e..95f80d42398 100644
--- a/build.xml
+++ b/build.xml
@@ -38,29 +38,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/composer.json b/composer.json
index 9d5f610c2b8..27c6a6c5816 100644
--- a/composer.json
+++ b/composer.json
@@ -21,10 +21,10 @@
{"name": "Jonathan Wage", "email": "jonwage@gmail.com"}
],
"require": {
- "php": "^7.1",
- "ext-pdo": "*",
+ "php": "^7.2",
"doctrine/cache": "^1.0",
- "doctrine/event-manager": "^1.0"
+ "doctrine/event-manager": "^1.0",
+ "ocramius/package-versions": "^1.2"
},
"require-dev": {
"doctrine/coding-standard": "^5.0",
diff --git a/composer.lock b/composer.lock
index 0c15627967d..7a658c5c312 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "1147a9427c03f98ca063806250633645",
+ "content-hash": "aa8c419d7e09c6754e7f58789037136f",
"packages": [
{
"name": "doctrine/cache",
@@ -153,6 +153,55 @@
"eventmanager"
],
"time": "2018-06-11T11:59:03+00:00"
+ },
+ {
+ "name": "ocramius/package-versions",
+ "version": "1.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Ocramius/PackageVersions.git",
+ "reference": "4489d5002c49d55576fa0ba786f42dbb009be46f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Ocramius/PackageVersions/zipball/4489d5002c49d55576fa0ba786f42dbb009be46f",
+ "reference": "4489d5002c49d55576fa0ba786f42dbb009be46f",
+ "shasum": ""
+ },
+ "require": {
+ "composer-plugin-api": "^1.0.0",
+ "php": "^7.1.0"
+ },
+ "require-dev": {
+ "composer/composer": "^1.6.3",
+ "ext-zip": "*",
+ "infection/infection": "^0.7.1",
+ "phpunit/phpunit": "^7.0.0"
+ },
+ "type": "composer-plugin",
+ "extra": {
+ "class": "PackageVersions\\Installer",
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "PackageVersions\\": "src/PackageVersions"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Marco Pivetta",
+ "email": "ocramius@gmail.com"
+ }
+ ],
+ "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)",
+ "time": "2018-02-05T13:05:30+00:00"
}
],
"packages-dev": [
@@ -1048,55 +1097,6 @@
],
"time": "2018-06-03T11:33:10+00:00"
},
- {
- "name": "ocramius/package-versions",
- "version": "1.3.0",
- "source": {
- "type": "git",
- "url": "https://github.com/Ocramius/PackageVersions.git",
- "reference": "4489d5002c49d55576fa0ba786f42dbb009be46f"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/Ocramius/PackageVersions/zipball/4489d5002c49d55576fa0ba786f42dbb009be46f",
- "reference": "4489d5002c49d55576fa0ba786f42dbb009be46f",
- "shasum": ""
- },
- "require": {
- "composer-plugin-api": "^1.0.0",
- "php": "^7.1.0"
- },
- "require-dev": {
- "composer/composer": "^1.6.3",
- "ext-zip": "*",
- "infection/infection": "^0.7.1",
- "phpunit/phpunit": "^7.0.0"
- },
- "type": "composer-plugin",
- "extra": {
- "class": "PackageVersions\\Installer",
- "branch-alias": {
- "dev-master": "2.0.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "PackageVersions\\": "src/PackageVersions"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Marco Pivetta",
- "email": "ocramius@gmail.com"
- }
- ],
- "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)",
- "time": "2018-02-05T13:05:30+00:00"
- },
{
"name": "phar-io/manifest",
"version": "1.0.3",
@@ -2959,8 +2959,7 @@
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
- "php": "^7.1",
- "ext-pdo": "*"
+ "php": "^7.2"
},
"platform-dev": []
}
diff --git a/docs/en/reference/configuration.rst b/docs/en/reference/configuration.rst
index 4fa8991ec33..a4fba806a0c 100644
--- a/docs/en/reference/configuration.rst
+++ b/docs/en/reference/configuration.rst
@@ -73,12 +73,8 @@ full driver name::
pdo-mysql://localhost:4486/foo?charset=UTF-8
-If you wanted to use the ``drizzle_pdo__mysql`` driver instead::
-
- drizzle-pdo-mysql://localhost:4486/foo?charset=UTF-8
-
-In the last two examples above, mind the dashes instead of the
-underscores in the URL schemes.
+In the example above, mind the dashes instead of the
+underscores in the URL scheme.
For connecting to an SQLite database, the authority portion of the
URL is obviously irrelevant and thus can be omitted. The path part
@@ -128,8 +124,6 @@ interfaces to use. It can be configured in one of three ways:
- ``pdo_mysql``: A MySQL driver that uses the pdo_mysql PDO
extension.
- - ``drizzle_pdo_mysql``: A Drizzle driver that uses pdo_mysql PDO
- extension.
- ``mysqli``: A MySQL driver that uses the mysqli extension.
- ``pdo_sqlite``: An SQLite driver that uses the pdo_sqlite PDO
extension.
@@ -197,23 +191,6 @@ pdo_mysql
- ``charset`` (string): The charset used when connecting to the
database.
-drizzle_pdo_mysql
-^^^^^^^^^^^^^^^^^
-
-**Requires** drizzle plugin ``mysql_protocol`` or ``mysql_unix_socket_protocol`` to be enabled.
-On Ubuntu this can be done by editing ``/etc/drizzle/conf.d/mysql-protocol.cnf``
-or ``/etc/drizzle/conf.d/mysql-unix-socket-protocol.cnf`` and restarting the drizzled daemon.
-
-- ``user`` (string): Username to use when connecting to the
- database. Only needed if authentication is configured for drizzled.
-- ``password`` (string): Password to use when connecting to the
- database. Only needed if authentication is configured for drizzled.
-- ``host`` (string): Hostname of the database to connect to.
-- ``port`` (integer): Port of the database to connect to.
-- ``dbname`` (string): Name of the database/schema to connect to.
-- ``unix_socket`` (string): Name of the socket used to connect to
- the database.
-
mysqli
^^^^^^
@@ -252,20 +229,20 @@ pdo_pgsql
- ``sslmode`` (string): Determines whether or with what priority
a SSL TCP/IP connection will be negotiated with the server.
See the list of available modes:
- `http://www.postgresql.org/docs/9.1/static/libpq-connect.html#LIBPQ-CONNECT-SSLMODE`
+ `https://www.postgresql.org/docs/9.3/static/libpq-connect.html#LIBPQ-CONNECT-SSLMODE`
- ``sslrootcert`` (string): specifies the name of a file containing
SSL certificate authority (CA) certificate(s). If the file exists,
the server's certificate will be verified to be signed by one of these
authorities.
- See http://www.postgresql.org/docs/9.0/static/libpq-connect.html#LIBPQ-CONNECT-SSLROOTCERT
+ See https://www.postgresql.org/docs/9.3/static/libpq-connect.html#LIBPQ-CONNECT-SSLROOTCERT
- ``sslcert`` (string): specifies the file name of the client SSL certificate.
- See `https://www.postgresql.org/docs/9.1/static/libpq-connect.html#LIBPQ-CONNECT-SSLCERT`
+ See `https://www.postgresql.org/docs/9.3/static/libpq-connect.html#LIBPQ-CONNECT-SSLCERT`
- ``sslkey`` (string): specifies the location for the secret key used for the
client certificate.
- See `https://www.postgresql.org/docs/9.1/static/libpq-connect.html#LIBPQ-CONNECT-SSLKEY`
+ See `https://www.postgresql.org/docs/9.3/static/libpq-connect.html#LIBPQ-CONNECT-SSLKEY`
- ``sslcrl`` (string): specifies the file name of the SSL certificate
revocation list (CRL).
- See `https://www.postgresql.org/docs/9.1/static/libpq-connect.html#LIBPQ-CONNECT-SSLCRL`
+ See `https://www.postgresql.org/docs/9.3/static/libpq-connect.html#LIBPQ-CONNECT-SSLCRL`
- ``application_name`` (string): Name of the application that is
connecting to database. Optional. It will be displayed at ``pg_stat_activity``.
@@ -333,14 +310,9 @@ sqlanywhere
Depending on the used underlying platform version, you can specify
any other connection parameter that is supported by the particular
platform version via the ``driverOptions`` option.
-You can find a list of supported connection parameters for each
-platform version here:
-
-- `SQL Anywhere 10.0.1 `_
-- `SQL Anywhere 11.0.0 `_
-- `SQL Anywhere 11.0.1 `_
-- `SQL Anywhere 12.0.0 `_
-- `SQL Anywhere 12.0.1 `_
+You can find a list of supported connection parameters for the
+currently supported platform here:
+
- `SAP Sybase SQL Anywhere 16.0 `_
Automatic platform version detection
diff --git a/docs/en/reference/introduction.rst b/docs/en/reference/introduction.rst
index ae495ea9815..5318303a7c6 100644
--- a/docs/en/reference/introduction.rst
+++ b/docs/en/reference/introduction.rst
@@ -21,7 +21,6 @@ The following database vendors are currently supported:
- PostgreSQL
- SAP Sybase SQL Anywhere
- SQLite
-- Drizzle
The Doctrine 2 database layer can be used independently of the
object-relational mapper. In order to use the DBAL all you need is
diff --git a/docs/en/reference/platforms.rst b/docs/en/reference/platforms.rst
index 32ef74304ea..12e292eec11 100644
--- a/docs/en/reference/platforms.rst
+++ b/docs/en/reference/platforms.rst
@@ -50,18 +50,15 @@ Oracle
Microsoft SQL Server
^^^^^^^^^^^^^^^^^^^^
-- ``SQLServerPlatform`` for version 2000 and above.
-- ``SQLServer2005Platform`` for version 2005 and above.
-- ``SQLServer2008Platform`` for version 2008 and above.
+- ``SQLServerPlatform`` for version 2008 and above.
- ``SQLServer2012Platform`` for version 2012 and above.
PostgreSQL
^^^^^^^^^^
- ``PostgreSqlPlatform`` for all versions.
-- ``PostgreSQL91Platform`` for version 9.1 and above.
-- ``PostgreSQL92Platform`` for version 9.2 and above.
- ``PostgreSQL94Platform`` for version 9.4 and above.
+- ``PostgreSQL100Platform`` for version 10.0 and above.
SAP Sybase SQL Anywhere
^^^^^^^^^^^^^^^^^^^^^^^
@@ -76,11 +73,6 @@ SQLite
- ``SqlitePlatform`` for all versions.
-Drizzle
-^^^^^^
-
-- ``DrizzlePlatform`` for all versions.
-
It is highly encouraged to use the platform class that matches your
database vendor and version best. Otherwise it is not guaranteed
that the compatibility in terms of SQL dialect and feature support
diff --git a/docs/en/reference/schema-representation.rst b/docs/en/reference/schema-representation.rst
index b250a5c5109..381a997e321 100644
--- a/docs/en/reference/schema-representation.rst
+++ b/docs/en/reference/schema-representation.rst
@@ -115,10 +115,10 @@ The following options are not completely portable but are supported by most of t
vendors:
- **unsigned** (boolean): Whether a ``smallint``, ``integer`` or ``bigint`` Doctrine
- type column should allow unsigned values only. Supported by MySQL, SQL Anywhere
- and Drizzle. Defaults to ``false``.
+ type column should allow unsigned values only. Supported by MySQL and SQL Anywhere.
+ Defaults to ``false``.
- **comment** (integer|string): The column comment. Supported by MySQL, PostgreSQL,
- Oracle, SQL Server, SQL Anywhere and Drizzle. Defaults to ``null``.
+ Oracle, SQL Server and SQL Anywhere. Defaults to ``null``.
Vendor specific options
^^^^^^^^^^^^^^^^^^^^^^^
@@ -133,8 +133,8 @@ The following options are completely vendor specific and absolutely not portable
supported by some vendors but not portable:
- **charset** (string): The character set to use for the column. Currently only supported
- on MySQL and Drizzle.
+ on MySQL.
- **collation** (string): The collation to use for the column. Supported by MySQL, PostgreSQL,
- Sqlite, SQL Server and Drizzle.
+ Sqlite and SQL Server.
- **check** (string): The check constraint clause to add to the column.
Defaults to ``null``.
diff --git a/docs/en/reference/types.rst b/docs/en/reference/types.rst
index f4916a69672..dd733f33a51 100644
--- a/docs/en/reference/types.rst
+++ b/docs/en/reference/types.rst
@@ -517,8 +517,6 @@ Please also notice the mapping specific footnotes for additional information.
+===================+===============+==========================+=========+==========================================================+
| **smallint** | ``integer`` | **MySQL** | *all* | ``SMALLINT`` ``UNSIGNED`` [10]_ ``AUTO_INCREMENT`` [11]_ |
| | +--------------------------+---------+----------------------------------------------------------+
-| | | **Drizzle** | *all* | ``INT`` ``UNSIGNED`` [10]_ ``AUTO_INCREMENT`` [11]_ |
-| | +--------------------------+---------+----------------------------------------------------------+
| | | **PostgreSQL** | *all* | ``SMALLINT`` |
| | +--------------------------+---------+----------------------------------------------------------+
| | | **Oracle** | *all* | ``NUMBER(5)`` |
@@ -527,11 +525,9 @@ Please also notice the mapping specific footnotes for additional information.
| | +--------------------------+---------+----------------------------------------------------------+
| | | **SQL Anywhere** | *all* | ``UNSIGNED`` [10]_ ``SMALLINT`` ``IDENTITY`` [11]_ |
| | +--------------------------+---------+----------------------------------------------------------+
-| | | **SQLite** | *all* | ``INTEGER`` [16]_ |
+| | | **SQLite** | *all* | ``INTEGER`` [15]_ |
+-------------------+---------------+--------------------------+---------+----------------------------------------------------------+
| **integer** | ``integer`` | **MySQL** | *all* | ``INT`` ``UNSIGNED`` [10]_ ``AUTO_INCREMENT`` [11]_ |
-| | +--------------------------+ | |
-| | | **Drizzle** | | |
| | +--------------------------+---------+----------------------------------------------------------+
| | | **PostgreSQL** | *all* | ``INT`` [12]_ |
| | | | +----------------------------------------------------------+
@@ -543,12 +539,10 @@ Please also notice the mapping specific footnotes for additional information.
| | +--------------------------+---------+----------------------------------------------------------+
| | | **SQL Anywhere** | *all* | ``UNSIGNED`` [10]_ ``INT`` ``IDENTITY`` [11]_ |
| | +--------------------------+---------+----------------------------------------------------------+
-| | | **SQLite** | *all* | ``INTEGER`` [16]_ |
+| | | **SQLite** | *all* | ``INTEGER`` [15]_ |
+-------------------+---------------+--------------------------+---------+----------------------------------------------------------+
| **bigint** | ``string`` | **MySQL** | *all* | ``BIGINT`` ``UNSIGNED`` [10]_ ``AUTO_INCREMENT`` [11]_ |
-| | [8]_ +--------------------------+ | |
-| | | **Drizzle** | | |
-| | +--------------------------+---------+----------------------------------------------------------+
+| | [8]_ +--------------------------+---------+----------------------------------------------------------+
| | | **PostgreSQL** | *all* | ``BIGINT`` [12]_ |
| | | | +----------------------------------------------------------+
| | | | | ``BIGSERIAL`` [11]_ |
@@ -559,7 +553,7 @@ Please also notice the mapping specific footnotes for additional information.
| | +--------------------------+---------+----------------------------------------------------------+
| | | **SQL Anywhere** | *all* | ``UNSIGNED`` [10]_ ``BIGINT`` ``IDENTITY`` [11]_ |
| | +--------------------------+---------+----------------------------------------------------------+
-| | | **SQLite** | *all* | ``INTEGER`` [16]_ |
+| | | **SQLite** | *all* | ``INTEGER`` [15]_ |
+-------------------+---------------+--------------------------+---------+----------------------------------------------------------+
| **decimal** [7]_ | ``string`` | **MySQL** | *all* | ``NUMERIC(p, s)`` ``UNSIGNED`` [10]_ |
| | [9]_ +--------------------------+---------+----------------------------------------------------------+
@@ -572,8 +566,6 @@ Please also notice the mapping specific footnotes for additional information.
| | | **SQL Anywhere** | | |
| | +--------------------------+ | |
| | | **SQLite** | | |
-| | +--------------------------+ | |
-| | | **Drizzle** | | |
+-------------------+---------------+--------------------------+---------+----------------------------------------------------------+
| **float** | ``float`` | **MySQL** | *all* | ``DOUBLE PRECISION`` ``UNSIGNED`` [10]_ |
| | +--------------------------+---------+----------------------------------------------------------+
@@ -586,8 +578,6 @@ Please also notice the mapping specific footnotes for additional information.
| | | **SQL Anywhere** | | |
| | +--------------------------+ | |
| | | **SQLite** | | |
-| | +--------------------------+ | |
-| | | **Drizzle** | | |
+-------------------+---------------+--------------------------+---------+----------------------------------------------------------+
| **string** | ``string`` | **MySQL** | *all* | ``VARCHAR(n)`` [3]_ |
| [2]_ [5]_ | +--------------------------+ | |
@@ -597,8 +587,6 @@ Please also notice the mapping specific footnotes for additional information.
| | +--------------------------+ | |
| | | **SQLite** | | |
| | +--------------------------+---------+----------------------------------------------------------+
-| | | **Drizzle** | *all* | ``VARCHAR(n)`` |
-| | +--------------------------+---------+----------------------------------------------------------+
| | | **Oracle** | *all* | ``VARCHAR2(n)`` [3]_ |
| | | | +----------------------------------------------------------+
| | | | | ``CHAR(n)`` [4]_ |
@@ -607,19 +595,17 @@ Please also notice the mapping specific footnotes for additional information.
| | | | +----------------------------------------------------------+
| | | | | ``NCHAR(n)`` [4]_ |
+-------------------+---------------+--------------------------+---------+----------------------------------------------------------+
-| **text** | ``string`` | **MySQL** | *all* | ``TINYTEXT`` [17]_ |
+| **text** | ``string`` | **MySQL** | *all* | ``TINYTEXT`` [16]_ |
| | | | +----------------------------------------------------------+
-| | | | | ``TEXT`` [18]_ |
+| | | | | ``TEXT`` [17]_ |
| | | | +----------------------------------------------------------+
-| | | | | ``MEDIUMTEXT`` [19]_ |
+| | | | | ``MEDIUMTEXT`` [18]_ |
| | | | +----------------------------------------------------------+
-| | | | | ``LONGTEXT`` [20]_ |
+| | | | | ``LONGTEXT`` [19]_ |
| | +--------------------------+---------+----------------------------------------------------------+
| | | **PostgreSQL** | *all* | ``TEXT`` |
| | +--------------------------+ | |
| | | **SQL Anywhere** | | |
-| | +--------------------------+ | |
-| | | **Drizzle** | | |
| | +--------------------------+---------+----------------------------------------------------------+
| | | **Oracle** | *all* | ``CLOB`` |
| | +--------------------------+ | |
@@ -632,8 +618,6 @@ Please also notice the mapping specific footnotes for additional information.
| | | **Oracle** | | |
| | +--------------------------+ | |
| | | **SQLite** | | |
-| | +--------------------------+ | |
-| | | **Drizzle** | | |
| | +--------------------------+---------+----------------------------------------------------------+
| | | **SQL Server** | *all* | ``UNIQUEIDENTIFIER`` |
| | +--------------------------+ | |
@@ -647,27 +631,23 @@ Please also notice the mapping specific footnotes for additional information.
| | +--------------------------+ | ``BINARY(n)`` [4]_ |
| | | **SQL Anywhere** | | |
| | +--------------------------+---------+----------------------------------------------------------+
-| | | **Drizzle** | *all* | ``VARBINARY(n)`` |
-| | +--------------------------+---------+----------------------------------------------------------+
| | | **Oracle** | *all* | ``RAW(n)`` |
| | +--------------------------+---------+----------------------------------------------------------+
-| | | **PostgreSQL** | *all* | ``BYTEA`` [16]_ |
+| | | **PostgreSQL** | *all* | ``BYTEA`` [15]_ |
| | +--------------------------+---------+----------------------------------------------------------+
-| | | **SQLite** | *all* | ``BLOB`` [16]_ |
+| | | **SQLite** | *all* | ``BLOB`` [15]_ |
+-------------------+---------------+--------------------------+---------+----------------------------------------------------------+
-| **blob** | ``resource`` | **MySQL** | *all* | ``TINYBLOB`` [17]_ |
+| **blob** | ``resource`` | **MySQL** | *all* | ``TINYBLOB`` [16]_ |
| | | | +----------------------------------------------------------+
-| | | | | ``BLOB`` [18]_ |
+| | | | | ``BLOB`` [17]_ |
| | | | +----------------------------------------------------------+
-| | | | | ``MEDIUMBLOB`` [19]_ |
+| | | | | ``MEDIUMBLOB`` [18]_ |
| | | | +----------------------------------------------------------+
-| | | | | ``LONGBLOB`` [20]_ |
+| | | | | ``LONGBLOB`` [19]_ |
| | +--------------------------+---------+----------------------------------------------------------+
| | | **Oracle** | *all* | ``BLOB`` |
| | +--------------------------+ | |
| | | **SQLite** | | |
-| | +--------------------------+ | |
-| | | **Drizzle** | | |
| | +--------------------------+---------+----------------------------------------------------------+
| | | **SQL Server** | *all* | ``VARBINARY(MAX)`` |
| | +--------------------------+---------+----------------------------------------------------------+
@@ -680,8 +660,6 @@ Please also notice the mapping specific footnotes for additional information.
| | | **PostgreSQL** | *all* | ``BOOLEAN`` |
| | +--------------------------+ | |
| | | **SQLite** | | |
-| | +--------------------------+ | |
-| | | **Drizzle** | | |
| | +--------------------------+---------+----------------------------------------------------------+
| | | **SQL Server** | *all* | ``BIT`` |
| | +--------------------------+ | |
@@ -698,16 +676,10 @@ Please also notice the mapping specific footnotes for additional information.
| | | **SQL Anywhere** | | |
| | +--------------------------+ | |
| | | **SQLite** | | |
-| | +--------------------------+ | |
-| | | **Drizzle** | | |
| | +--------------------------+---------+ |
-| | | **SQL Server** | >= 2008 | |
-| | | +---------+----------------------------------------------------------+
-| | | | < 2008 | ``DATETIME`` [16]_ |
+| | | **SQL Server** | "all" | |
+-------------------+---------------+--------------------------+---------+----------------------------------------------------------+
| **datetime** | ``\DateTime`` | **MySQL** | *all* | ``DATETIME`` [13]_ |
-| | +--------------------------+ +----------------------------------------------------------+
-| | | **Drizzle** | | ``TIMESTAMP`` [14]_ |
| | +--------------------------+---------+----------------------------------------------------------+
| | | **SQL Server** | *all* | ``DATETIME`` |
| | +--------------------------+ | |
@@ -719,53 +691,41 @@ Please also notice the mapping specific footnotes for additional information.
| | +--------------------------+---------+----------------------------------------------------------+
| | | **Oracle** | *all* | ``TIMESTAMP(0)`` |
+-------------------+---------------+--------------------------+---------+----------------------------------------------------------+
-| **datetimetz** | ``\DateTime`` | **MySQL** | *all* | ``DATETIME`` [15]_ [16]_ |
-| | +--------------------------+ | |
-| | | **Drizzle** | | |
+| **datetimetz** | ``\DateTime`` | **MySQL** | *all* | ``DATETIME`` [14]_ [15]_ |
| | +--------------------------+ | |
| | | **SQLite** | | |
| | +--------------------------+---------+ |
-| | | **SQL Server** | < 2008 | |
-| | | +---------+----------------------------------------------------------+
-| | | | >= 2008 | ``DATETIMEOFFSET(6)`` |
+| | | **SQL Server** | "all" | |
| | +--------------------------+---------+----------------------------------------------------------+
| | | **PostgreSQL** | *all* | ``TIMESTAMP(0) WITH TIME ZONE`` |
| | +--------------------------+ | |
| | | **Oracle** | | |
| | +--------------------------+---------+----------------------------------------------------------+
-| | | **SQL Anywhere** | < 12 | ``DATETIME`` [15]_ [16]_ |
-| | | +---------+----------------------------------------------------------+
-| | | | >= 12 | ``TIMESTAMP WITH TIME ZONE`` |
+| | | **SQL Anywhere** | "all" | ``TIMESTAMP WITH TIME ZONE`` |
+-------------------+---------------+--------------------------+---------+----------------------------------------------------------+
| **time** | ``\DateTime`` | **MySQL** | *all* | ``TIME`` |
| | +--------------------------+ | |
| | | **SQL Anywhere** | | |
| | +--------------------------+ | |
| | | **SQLite** | | |
-| | +--------------------------+ | |
-| | | **Drizzle** | | |
| | +--------------------------+---------+----------------------------------------------------------+
| | | **PostgreSQL** | *all* | ``TIME(0) WITHOUT TIME ZONE`` |
| | +--------------------------+---------+----------------------------------------------------------+
-| | | **Oracle** | *all* | ``DATE`` [16]_ |
+| | | **Oracle** | *all* | ``DATE`` [15]_ |
| | +--------------------------+---------+----------------------------------------------------------+
-| | | **SQL Server** | < 2008 | ``DATETIME`` [16]_ |
-| | | +---------+----------------------------------------------------------+
-| | | | >= 2008 | ``TIME(0)`` |
+| | | **SQL Server** | "all" | ``TIME(0)`` |
+-------------------+---------------+--------------------------+---------+----------------------------------------------------------+
-| **array** [1]_ | ``array`` | **MySQL** | *all* | ``TINYTEXT`` [17]_ |
+| **array** [1]_ | ``array`` | **MySQL** | *all* | ``TINYTEXT`` [16]_ |
+-------------------+ | | +----------------------------------------------------------+
-| **simple array** | | | | ``TEXT`` [18]_ |
+| **simple array** | | | | ``TEXT`` [17]_ |
| [1]_ | | | +----------------------------------------------------------+
-| | | | | ``MEDIUMTEXT`` [19]_ |
+| | | | | ``MEDIUMTEXT`` [18]_ |
| | | | +----------------------------------------------------------+
-| | | | | ``LONGTEXT`` [20]_ |
+| | | | | ``LONGTEXT`` [19]_ |
| | +--------------------------+---------+----------------------------------------------------------+
| | | **PostgreSQL** | *all* | ``TEXT`` |
| | +--------------------------+ | |
| | | **SQL Anywhere** | | |
-| | +--------------------------+ | |
-| | | **Drizzle** | | |
| | +--------------------------+---------+----------------------------------------------------------+
| | | **Oracle** | *all* | ``CLOB`` |
| | +--------------------------+ | |
@@ -773,25 +733,21 @@ Please also notice the mapping specific footnotes for additional information.
| | +--------------------------+---------+----------------------------------------------------------+
| | | **SQL Server** | *all* | ``VARCHAR(MAX)`` |
+-------------------+---------------+--------------------------+---------+----------------------------------------------------------+
-| **json_array** | ``array`` | **MySQL** [1]_ | *all* | ``TINYTEXT`` [17]_ |
+| **json_array** | ``array`` | **MySQL** [1]_ | *all* | ``TINYTEXT`` [16]_ |
| | | | +----------------------------------------------------------+
-| | | | | ``TEXT`` [18]_ |
+| | | | | ``TEXT`` [17]_ |
| | | | +----------------------------------------------------------+
-| | | | | ``MEDIUMTEXT`` [19]_ |
+| | | | | ``MEDIUMTEXT`` [18]_ |
| | | | +----------------------------------------------------------+
-| | | | | ``LONGTEXT`` [20]_ |
+| | | | | ``LONGTEXT`` [19]_ |
| | +--------------------------+---------+----------------------------------------------------------+
-| | | **PostgreSQL** | < 9.2 | ``TEXT`` [1]_ |
-| | | +---------+----------------------------------------------------------+
-| | | | < 9.4 | ``JSON`` |
+| | | **PostgreSQL** | < 9.4 | ``JSON`` |
| | | +---------+----------------------------------------------------------+
-| | | | >= 9.4 | ``JSON`` [21]_ |
+| | | | >= 9.4 | ``JSON`` [20]_ |
| | | | +----------------------------------------------------------+
-| | | | | ``JSONB`` [22]_ |
+| | | | | ``JSONB`` [21]_ |
| | +--------------------------+---------+----------------------------------------------------------+
| | | **SQL Anywhere** | *all* | ``TEXT`` [1]_ |
-| | +--------------------------+ | |
-| | | **Drizzle** | | |
| | +--------------------------+---------+----------------------------------------------------------+
| | | **Oracle** | *all* | ``CLOB`` [1]_ |
| | +--------------------------+ | |
@@ -799,19 +755,17 @@ Please also notice the mapping specific footnotes for additional information.
| | +--------------------------+---------+----------------------------------------------------------+
| | | **SQL Server** | *all* | ``VARCHAR(MAX)`` [1]_ |
+-------------------+---------------+--------------------------+---------+----------------------------------------------------------+
-| **object** [1]_ | ``object`` | **MySQL** | *all* | ``TINYTEXT`` [17]_ |
+| **object** [1]_ | ``object`` | **MySQL** | *all* | ``TINYTEXT`` [16]_ |
| | | | +----------------------------------------------------------+
-| | | | | ``TEXT`` [18]_ |
+| | | | | ``TEXT`` [17]_ |
| | | | +----------------------------------------------------------+
-| | | | | ``MEDIUMTEXT`` [19]_ |
+| | | | | ``MEDIUMTEXT`` [18]_ |
| | | | +----------------------------------------------------------+
-| | | | | ``LONGTEXT`` [20]_ |
+| | | | | ``LONGTEXT`` [19]_ |
| | +--------------------------+---------+----------------------------------------------------------+
| | | **PostgreSQL** | *all* | ``TEXT`` |
| | +--------------------------+ | |
| | | **SQL Anywhere** | | |
-| | +--------------------------+ | |
-| | | **Drizzle** | | |
| | +--------------------------+---------+----------------------------------------------------------+
| | | **Oracle** | *all* | ``CLOB`` |
| | +--------------------------+ | |
@@ -827,10 +781,10 @@ Please also notice the mapping specific footnotes for additional information.
.. [4] Chosen if the column definition has the **fixed** attribute set to ``true``.
.. [5] Silently maps to the vendor specific ``text`` type if the given **length** attribute for
**n** exceeds the maximum length the related platform allows. If this is the case, please
- see [16]_.
+ see [15]_.
.. [6] Silently maps to the vendor specific ``blob`` type if the given **length** attribute for
**n** exceeds the maximum length the related platform allows. If this is the case, please
- see [16]_.
+ see [15]_.
.. [7] **p** is the precision and **s** the scale set in the column definition.
The precision defaults to ``10`` and the scale to ``0`` if not set.
.. [8] Returns PHP ``string`` type value instead of ``integer`` because of maximum integer value
@@ -842,22 +796,20 @@ Please also notice the mapping specific footnotes for additional information.
.. [12] Chosen if the column definition has the **autoincrement** attribute set to ``false`` (default).
.. [13] Chosen if the column definition does not contain the **version** option inside the **platformOptions**
attribute array or is set to ``false`` which marks it as a non-locking information column.
-.. [14] Chosen if the column definition contains the **version** option inside the **platformOptions**
- attribute array and is set to ``true`` which marks it as a locking information column.
-.. [15] Fallback type as the vendor does not support a native date time type with timezone information.
+.. [14] Fallback type as the vendor does not support a native date time type with timezone information.
This means that the timezone information gets lost when storing a value.
-.. [16] Cannot be safely reverse engineered to the same Doctrine type as the vendor does not have a
+.. [15] Cannot be safely reverse engineered to the same Doctrine type as the vendor does not have a
native distinct data type for this mapping. Using this type with this vendor can therefore
have implications on schema comparison (*online* vs *offline* schema) and PHP type safety
(data conversion from database to PHP value) because it silently falls back to its
appropriate Doctrine type.
-.. [17] Chosen if the column length is less or equal to **2 ^ 8 - 1 = 255**.
-.. [18] Chosen if the column length is less or equal to **2 ^ 16 - 1 = 65535**.
-.. [19] Chosen if the column length is less or equal to **2 ^ 24 - 1 = 16777215**.
-.. [20] Chosen if the column length is less or equal to **2 ^ 32 - 1 = 4294967295** or empty.
-.. [21] Chosen if the column definition does not contain the **jsonb** option inside the **platformOptions**
+.. [16] Chosen if the column length is less or equal to **2 ^ 8 - 1 = 255**.
+.. [17] Chosen if the column length is less or equal to **2 ^ 16 - 1 = 65535**.
+.. [18] Chosen if the column length is less or equal to **2 ^ 24 - 1 = 16777215**.
+.. [19] Chosen if the column length is less or equal to **2 ^ 32 - 1 = 4294967295** or empty.
+.. [20] Chosen if the column definition does not contain the **jsonb** option inside the **platformOptions**
attribute array or is set to ``false``.
-.. [22] Chosen if the column definition contains the **jsonb** option inside the **platformOptions**
+.. [21] Chosen if the column definition contains the **jsonb** option inside the **platformOptions**
attribute array and is set to ``true``.
Detection of Database Types
diff --git a/lib/Doctrine/DBAL/Cache/ArrayStatement.php b/lib/Doctrine/DBAL/Cache/ArrayStatement.php
index 449a220a2af..494876c935e 100644
--- a/lib/Doctrine/DBAL/Cache/ArrayStatement.php
+++ b/lib/Doctrine/DBAL/Cache/ArrayStatement.php
@@ -7,7 +7,6 @@
use Doctrine\DBAL\FetchMode;
use InvalidArgumentException;
use IteratorAggregate;
-use PDO;
use function array_merge;
use function array_values;
use function count;
@@ -59,9 +58,9 @@ public function columnCount()
/**
* {@inheritdoc}
*/
- public function setFetchMode($fetchMode, $arg2 = null, $arg3 = null)
+ public function setFetchMode($fetchMode, ...$args)
{
- if ($arg2 !== null || $arg3 !== null) {
+ if (count($args) > 0) {
throw new InvalidArgumentException('Caching layer does not support 2nd/3rd argument to setFetchMode()');
}
@@ -83,7 +82,7 @@ public function getIterator()
/**
* {@inheritdoc}
*/
- public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEXT, $cursorOffset = 0)
+ public function fetch($fetchMode = null, ...$args)
{
if (! isset($this->data[$this->num])) {
return false;
@@ -114,10 +113,10 @@ public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEX
/**
* {@inheritdoc}
*/
- public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = null)
+ public function fetchAll($fetchMode = null, ...$args)
{
$rows = [];
- while ($row = $this->fetch($fetchMode)) {
+ while ($row = $this->fetch($fetchMode, ...$args)) {
$rows[] = $row;
}
diff --git a/lib/Doctrine/DBAL/Cache/ResultCacheStatement.php b/lib/Doctrine/DBAL/Cache/ResultCacheStatement.php
index 872f3e71fc9..b3f324f7136 100644
--- a/lib/Doctrine/DBAL/Cache/ResultCacheStatement.php
+++ b/lib/Doctrine/DBAL/Cache/ResultCacheStatement.php
@@ -9,7 +9,6 @@
use Doctrine\DBAL\FetchMode;
use InvalidArgumentException;
use IteratorAggregate;
-use PDO;
use function array_merge;
use function array_values;
use function reset;
@@ -104,7 +103,7 @@ public function columnCount()
/**
* {@inheritdoc}
*/
- public function setFetchMode($fetchMode, $arg2 = null, $arg3 = null)
+ public function setFetchMode($fetchMode, ...$args)
{
$this->defaultFetchMode = $fetchMode;
@@ -124,7 +123,7 @@ public function getIterator()
/**
* {@inheritdoc}
*/
- public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEXT, $cursorOffset = 0)
+ public function fetch($fetchMode = null, ...$args)
{
if ($this->data === null) {
$this->data = [];
@@ -164,9 +163,9 @@ public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEX
/**
* {@inheritdoc}
*/
- public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = null)
+ public function fetchAll($fetchMode = null, ...$args)
{
- return $this->statement->fetchAll($fetchMode, $fetchArgument, $ctorArgs);
+ return $this->statement->fetchAll($fetchMode, ...$args);
}
/**
@@ -191,7 +190,7 @@ public function fetchColumn($columnIndex = 0)
*
* @return int The number of rows.
*/
- public function rowCount()
+ public function rowCount() : int
{
return $this->statement->rowCount();
}
diff --git a/lib/Doctrine/DBAL/ColumnCase.php b/lib/Doctrine/DBAL/ColumnCase.php
index 872d3ede873..c78ad372e65 100644
--- a/lib/Doctrine/DBAL/ColumnCase.php
+++ b/lib/Doctrine/DBAL/ColumnCase.php
@@ -2,8 +2,6 @@
namespace Doctrine\DBAL;
-use PDO;
-
/**
* Contains portable column case conversions.
*/
@@ -14,14 +12,14 @@ final class ColumnCase
*
* @see \PDO::CASE_UPPER
*/
- public const UPPER = PDO::CASE_UPPER;
+ public const UPPER = 1;
/**
* Convert column names to lower case.
*
* @see \PDO::CASE_LOWER
*/
- public const LOWER = PDO::CASE_LOWER;
+ public const LOWER = 2;
/**
* This class cannot be instantiated.
diff --git a/lib/Doctrine/DBAL/Configuration.php b/lib/Doctrine/DBAL/Configuration.php
index 9b7b21fb21e..a1ec0e97dfd 100644
--- a/lib/Doctrine/DBAL/Configuration.php
+++ b/lib/Doctrine/DBAL/Configuration.php
@@ -3,6 +3,7 @@
namespace Doctrine\DBAL;
use Doctrine\Common\Cache\Cache;
+use Doctrine\DBAL\Logging\NullLogger;
use Doctrine\DBAL\Logging\SQLLogger;
use Doctrine\DBAL\Schema\AbstractAsset;
use function preg_match;
@@ -24,23 +25,19 @@ class Configuration
protected $_attributes = [];
/**
- * Sets the SQL logger to use. Defaults to NULL which means SQL logging is disabled.
- *
- * @return void
+ * Sets the SQL logger to use.
*/
- public function setSQLLogger(?SQLLogger $logger = null)
+ public function setSQLLogger(?SQLLogger $logger) : void
{
$this->_attributes['sqlLogger'] = $logger;
}
/**
* Gets the SQL logger that is used.
- *
- * @return SQLLogger|null
*/
- public function getSQLLogger()
+ public function getSQLLogger() : SQLLogger
{
- return $this->_attributes['sqlLogger'] ?? null;
+ return $this->_attributes['sqlLogger'] ?? $this->_attributes['sqlLogger'] = new NullLogger();
}
/**
diff --git a/lib/Doctrine/DBAL/Connection.php b/lib/Doctrine/DBAL/Connection.php
index 85761fcca9b..0d7246ff600 100644
--- a/lib/Doctrine/DBAL/Connection.php
+++ b/lib/Doctrine/DBAL/Connection.php
@@ -24,7 +24,6 @@
use function array_key_exists;
use function array_merge;
use function assert;
-use function func_get_args;
use function implode;
use function is_int;
use function is_string;
@@ -846,18 +845,16 @@ public function fetchAll($sql, array $params = [], $types = [])
/**
* Prepares an SQL statement.
*
- * @param string $statement The SQL statement to prepare.
- *
- * @return DriverStatement The prepared statement.
+ * @param string $sql The SQL statement to prepare.
*
* @throws DBALException
*/
- public function prepare($statement)
+ public function prepare(string $sql) : DriverStatement
{
try {
- $stmt = new Statement($statement, $this);
+ $stmt = new Statement($sql, $this);
} catch (Throwable $ex) {
- throw DBALException::driverExceptionDuringQuery($this->_driver, $ex, $statement);
+ throw DBALException::driverExceptionDuringQuery($this->_driver, $ex, $sql);
}
$stmt->setFetchMode($this->defaultFetchMode);
@@ -873,14 +870,14 @@ public function prepare($statement)
*
* @param string $query The SQL query to execute.
* @param mixed[] $params The parameters to bind to the query, if any.
- * @param int[]|string[] $types The types the previous parameters are in.
+ * @param int[]|string[]|Type[] $types The types the previous parameters are in.
* @param QueryCacheProfile|null $qcp The query cache profile, optional.
*
* @return ResultStatement The executed statement.
*
* @throws DBALException
*/
- public function executeQuery($query, array $params = [], $types = [], ?QueryCacheProfile $qcp = null)
+ public function executeQuery(string $query, array $params = [], $types = [], ?QueryCacheProfile $qcp = null) : ResultStatement
{
if ($qcp !== null) {
return $this->executeCacheQuery($query, $params, $types, $qcp);
@@ -889,9 +886,7 @@ public function executeQuery($query, array $params = [], $types = [], ?QueryCach
$this->connect();
$logger = $this->_config->getSQLLogger();
- if ($logger) {
- $logger->startQuery($query, $params, $types);
- }
+ $logger->startQuery($query, $params, $types);
try {
if ($params) {
@@ -913,9 +908,7 @@ public function executeQuery($query, array $params = [], $types = [], ?QueryCach
$stmt->setFetchMode($this->defaultFetchMode);
- if ($logger) {
- $logger->stopQuery();
- }
+ $logger->stopQuery();
return $stmt;
}
@@ -923,16 +916,14 @@ public function executeQuery($query, array $params = [], $types = [], ?QueryCach
/**
* Executes a caching query.
*
- * @param string $query The SQL query to execute.
- * @param mixed[] $params The parameters to bind to the query, if any.
- * @param int[]|string[] $types The types the previous parameters are in.
- * @param QueryCacheProfile $qcp The query cache profile.
- *
- * @return ResultStatement
+ * @param string $query The SQL query to execute.
+ * @param mixed[] $params The parameters to bind to the query, if any.
+ * @param int[]|string[]|Type[] $types The types the previous parameters are in.
+ * @param QueryCacheProfile $qcp The query cache profile.
*
* @throws CacheException
*/
- public function executeCacheQuery($query, $params, $types, QueryCacheProfile $qcp)
+ public function executeCacheQuery($query, $params, $types, QueryCacheProfile $qcp) : ResultStatement
{
$resultCache = $qcp->getResultCacheDriver() ?: $this->_config->getResultCacheImpl();
if (! $resultCache) {
@@ -989,34 +980,24 @@ public function project($query, array $params, Closure $function)
}
/**
- * Executes an SQL statement, returning a result set as a Statement object.
- *
- * @return \Doctrine\DBAL\Driver\Statement
- *
- * @throws DBALException
+ * {@inheritDoc}
*/
- public function query()
+ public function query(string $sql) : ResultStatement
{
$this->connect();
- $args = func_get_args();
-
$logger = $this->_config->getSQLLogger();
- if ($logger) {
- $logger->startQuery($args[0]);
- }
+ $logger->startQuery($sql);
try {
- $statement = $this->_conn->query(...$args);
+ $statement = $this->_conn->query($sql);
} catch (Throwable $ex) {
- throw DBALException::driverExceptionDuringQuery($this->_driver, $ex, $args[0]);
+ throw DBALException::driverExceptionDuringQuery($this->_driver, $ex, $sql);
}
$statement->setFetchMode($this->defaultFetchMode);
- if ($logger) {
- $logger->stopQuery();
- }
+ $logger->stopQuery();
return $statement;
}
@@ -1027,22 +1008,18 @@ public function query()
*
* This method supports PDO binding types as well as DBAL mapping types.
*
- * @param string $query The SQL query.
- * @param mixed[] $params The query parameters.
- * @param int[]|string[] $types The parameter types.
- *
- * @return int The number of affected rows.
+ * @param string $query The SQL query.
+ * @param mixed[] $params The query parameters.
+ * @param int[]|string[]|Type[] $types The parameter types.
*
* @throws DBALException
*/
- public function executeUpdate($query, array $params = [], array $types = [])
+ public function executeUpdate(string $query, array $params = [], array $types = []) : int
{
$this->connect();
$logger = $this->_config->getSQLLogger();
- if ($logger) {
- $logger->startQuery($query, $params, $types);
- }
+ $logger->startQuery($query, $params, $types);
try {
if ($params) {
@@ -1063,30 +1040,20 @@ public function executeUpdate($query, array $params = [], array $types = [])
throw DBALException::driverExceptionDuringQuery($this->_driver, $ex, $query, $this->resolveParams($params, $types));
}
- if ($logger) {
- $logger->stopQuery();
- }
+ $logger->stopQuery();
return $result;
}
/**
- * Executes an SQL statement and return the number of affected rows.
- *
- * @param string $statement
- *
- * @return int The number of affected rows.
- *
- * @throws DBALException
+ * {@inheritDoc}
*/
- public function exec($statement)
+ public function exec(string $statement) : int
{
$this->connect();
$logger = $this->_config->getSQLLogger();
- if ($logger) {
- $logger->startQuery($statement);
- }
+ $logger->startQuery($statement);
try {
$result = $this->_conn->exec($statement);
@@ -1094,9 +1061,7 @@ public function exec($statement)
throw DBALException::driverExceptionDuringQuery($this->_driver, $ex, $statement);
}
- if ($logger) {
- $logger->stopQuery();
- }
+ $logger->stopQuery();
return $result;
}
@@ -1164,7 +1129,6 @@ public function lastInsertId($seqName = null)
*
* @return mixed The value returned by $func
*
- * @throws Exception
* @throws Throwable
*/
public function transactional(Closure $func)
@@ -1174,9 +1138,6 @@ public function transactional(Closure $func)
$res = $func($this);
$this->commit();
return $res;
- } catch (Exception $e) {
- $this->rollBack();
- throw $e;
} catch (Throwable $e) {
$this->rollBack();
throw $e;
@@ -1240,21 +1201,13 @@ public function beginTransaction()
$logger = $this->_config->getSQLLogger();
if ($this->transactionNestingLevel === 1) {
- if ($logger) {
- $logger->startQuery('"START TRANSACTION"');
- }
+ $logger->startQuery('"START TRANSACTION"');
$this->_conn->beginTransaction();
- if ($logger) {
- $logger->stopQuery();
- }
+ $logger->stopQuery();
} elseif ($this->nestTransactionsWithSavepoints) {
- if ($logger) {
- $logger->startQuery('"SAVEPOINT"');
- }
+ $logger->startQuery('"SAVEPOINT"');
$this->createSavepoint($this->_getNestedTransactionSavePointName());
- if ($logger) {
- $logger->stopQuery();
- }
+ $logger->stopQuery();
}
}
@@ -1280,21 +1233,13 @@ public function commit()
$logger = $this->_config->getSQLLogger();
if ($this->transactionNestingLevel === 1) {
- if ($logger) {
- $logger->startQuery('"COMMIT"');
- }
+ $logger->startQuery('"COMMIT"');
$this->_conn->commit();
- if ($logger) {
- $logger->stopQuery();
- }
+ $logger->stopQuery();
} elseif ($this->nestTransactionsWithSavepoints) {
- if ($logger) {
- $logger->startQuery('"RELEASE SAVEPOINT"');
- }
+ $logger->startQuery('"RELEASE SAVEPOINT"');
$this->releaseSavepoint($this->_getNestedTransactionSavePointName());
- if ($logger) {
- $logger->stopQuery();
- }
+ $logger->stopQuery();
}
--$this->transactionNestingLevel;
@@ -1340,28 +1285,20 @@ public function rollBack()
$logger = $this->_config->getSQLLogger();
if ($this->transactionNestingLevel === 1) {
- if ($logger) {
- $logger->startQuery('"ROLLBACK"');
- }
+ $logger->startQuery('"ROLLBACK"');
$this->transactionNestingLevel = 0;
$this->_conn->rollBack();
$this->isRollbackOnly = false;
- if ($logger) {
- $logger->stopQuery();
- }
+ $logger->stopQuery();
if ($this->autoCommit === false) {
$this->beginTransaction();
}
} elseif ($this->nestTransactionsWithSavepoints) {
- if ($logger) {
- $logger->startQuery('"ROLLBACK TO SAVEPOINT"');
- }
+ $logger->startQuery('"ROLLBACK TO SAVEPOINT"');
$this->rollbackSavepoint($this->_getNestedTransactionSavePointName());
--$this->transactionNestingLevel;
- if ($logger) {
- $logger->stopQuery();
- }
+ $logger->stopQuery();
} else {
$this->isRollbackOnly = true;
--$this->transactionNestingLevel;
@@ -1520,13 +1457,11 @@ public function convertToPHPValue($value, $type)
* @internal Duck-typing used on the $stmt parameter to support driver statements as well as
* raw PDOStatement instances.
*
- * @param \Doctrine\DBAL\Driver\Statement $stmt The statement to bind the values to.
- * @param mixed[] $params The map/list of named/positional parameters.
- * @param int[]|string[] $types The parameter types (PDO binding types or DBAL mapping types).
- *
- * @return void
+ * @param DriverStatement $stmt The statement to bind the values to.
+ * @param mixed[] $params The map/list of named/positional parameters.
+ * @param int[]|string[]|Type[] $types The parameter types.
*/
- private function _bindTypedValues($stmt, array $params, array $types)
+ private function _bindTypedValues(DriverStatement $stmt, array $params, array $types) : void
{
// Check whether parameters are positional or named. Mixing is not allowed, just like in PDO.
if (is_int(key($params))) {
diff --git a/lib/Doctrine/DBAL/Connections/MasterSlaveConnection.php b/lib/Doctrine/DBAL/Connections/MasterSlaveConnection.php
index e9864d6df90..247996bf54c 100644
--- a/lib/Doctrine/DBAL/Connections/MasterSlaveConnection.php
+++ b/lib/Doctrine/DBAL/Connections/MasterSlaveConnection.php
@@ -7,12 +7,13 @@
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Driver;
use Doctrine\DBAL\Driver\Connection as DriverConnection;
+use Doctrine\DBAL\Driver\ResultStatement;
+use Doctrine\DBAL\Driver\Statement;
use Doctrine\DBAL\Event\ConnectionEventArgs;
use Doctrine\DBAL\Events;
use InvalidArgumentException;
use function array_rand;
use function count;
-use function func_get_args;
/**
* Master-Slave Connection
@@ -218,7 +219,7 @@ protected function chooseConnectionConfiguration($connectionName, $params)
/**
* {@inheritDoc}
*/
- public function executeUpdate($query, array $params = [], array $types = [])
+ public function executeUpdate(string $query, array $params = [], array $types = []) : int
{
$this->connect('master');
@@ -301,7 +302,7 @@ public function insert($tableName, array $data, array $types = [])
/**
* {@inheritDoc}
*/
- public function exec($statement)
+ public function exec(string $statement) : int
{
$this->connect('master');
@@ -341,22 +342,16 @@ public function rollbackSavepoint($savepoint)
/**
* {@inheritDoc}
*/
- public function query()
+ public function query(string $sql) : ResultStatement
{
$this->connect('master');
- $args = func_get_args();
-
$logger = $this->getConfiguration()->getSQLLogger();
- if ($logger) {
- $logger->startQuery($args[0]);
- }
+ $logger->startQuery($sql);
- $statement = $this->_conn->query(...$args);
+ $statement = $this->_conn->query($sql);
- if ($logger) {
- $logger->stopQuery();
- }
+ $logger->stopQuery();
return $statement;
}
@@ -364,10 +359,10 @@ public function query()
/**
* {@inheritDoc}
*/
- public function prepare($statement)
+ public function prepare(string $sql) : Statement
{
$this->connect('master');
- return parent::prepare($statement);
+ return parent::prepare($sql);
}
}
diff --git a/lib/Doctrine/DBAL/Driver/AbstractDriverException.php b/lib/Doctrine/DBAL/Driver/AbstractDriverException.php
deleted file mode 100644
index d9af92d1744..00000000000
--- a/lib/Doctrine/DBAL/Driver/AbstractDriverException.php
+++ /dev/null
@@ -1,54 +0,0 @@
-errorCode = $errorCode;
- $this->sqlState = $sqlState;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getErrorCode()
- {
- return $this->errorCode;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getSQLState()
- {
- return $this->sqlState;
- }
-}
diff --git a/lib/Doctrine/DBAL/Driver/AbstractPostgreSQLDriver.php b/lib/Doctrine/DBAL/Driver/AbstractPostgreSQLDriver.php
index 916d924980c..bdfd6cd894b 100644
--- a/lib/Doctrine/DBAL/Driver/AbstractPostgreSQLDriver.php
+++ b/lib/Doctrine/DBAL/Driver/AbstractPostgreSQLDriver.php
@@ -7,8 +7,6 @@
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;
use Doctrine\DBAL\Platforms\PostgreSqlPlatform;
use Doctrine\DBAL\Schema\PostgreSqlSchemaManager;
@@ -101,10 +99,6 @@ public function createDatabasePlatformForVersion($version)
return new PostgreSQL100Platform();
case version_compare($version, '9.4', '>='):
return new PostgreSQL94Platform();
- case version_compare($version, '9.2', '>='):
- return new PostgreSQL92Platform();
- case version_compare($version, '9.1', '>='):
- return new PostgreSQL91Platform();
default:
return new PostgreSqlPlatform();
}
diff --git a/lib/Doctrine/DBAL/Driver/AbstractSQLAnywhereDriver.php b/lib/Doctrine/DBAL/Driver/AbstractSQLAnywhereDriver.php
index 88f26ce7def..f93b576e202 100644
--- a/lib/Doctrine/DBAL/Driver/AbstractSQLAnywhereDriver.php
+++ b/lib/Doctrine/DBAL/Driver/AbstractSQLAnywhereDriver.php
@@ -6,14 +6,10 @@
use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Driver;
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\Schema\SQLAnywhereSchemaManager;
use Doctrine\DBAL\VersionAwarePlatformDriver;
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.
@@ -81,19 +77,7 @@ public function createDatabasePlatformForVersion($version)
);
}
- $majorVersion = $versionParts['major'];
- $minorVersion = $versionParts['minor'] ?? 0;
- $patchVersion = $versionParts['patch'] ?? 0;
- $buildVersion = $versionParts['build'] ?? 0;
- $version = $majorVersion . '.' . $minorVersion . '.' . $patchVersion . '.' . $buildVersion;
-
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:
return new SQLAnywherePlatform();
}
@@ -114,7 +98,7 @@ public function getDatabase(Connection $conn)
*/
public function getDatabasePlatform()
{
- return new SQLAnywhere12Platform();
+ return new SQLAnywherePlatform();
}
/**
diff --git a/lib/Doctrine/DBAL/Driver/AbstractSQLServerDriver.php b/lib/Doctrine/DBAL/Driver/AbstractSQLServerDriver.php
index 421d82b3951..280f72544e0 100644
--- a/lib/Doctrine/DBAL/Driver/AbstractSQLServerDriver.php
+++ b/lib/Doctrine/DBAL/Driver/AbstractSQLServerDriver.php
@@ -5,8 +5,6 @@
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Driver;
-use Doctrine\DBAL\Platforms\SQLServer2005Platform;
-use Doctrine\DBAL\Platforms\SQLServer2008Platform;
use Doctrine\DBAL\Platforms\SQLServer2012Platform;
use Doctrine\DBAL\Platforms\SQLServerPlatform;
use Doctrine\DBAL\Schema\SQLServerSchemaManager;
@@ -44,10 +42,6 @@ public function createDatabasePlatformForVersion($version)
switch (true) {
case version_compare($version, '11.00.2100', '>='):
return new SQLServer2012Platform();
- case version_compare($version, '10.00.1600', '>='):
- return new SQLServer2008Platform();
- case version_compare($version, '9.00.1399', '>='):
- return new SQLServer2005Platform();
default:
return new SQLServerPlatform();
}
@@ -68,7 +62,7 @@ public function getDatabase(Connection $conn)
*/
public function getDatabasePlatform()
{
- return new SQLServer2008Platform();
+ return new SQLServerPlatform();
}
/**
diff --git a/lib/Doctrine/DBAL/Driver/Connection.php b/lib/Doctrine/DBAL/Driver/Connection.php
index 1574581c2ad..f55b23a4dd6 100644
--- a/lib/Doctrine/DBAL/Driver/Connection.php
+++ b/lib/Doctrine/DBAL/Driver/Connection.php
@@ -15,18 +15,16 @@ interface Connection
/**
* Prepares a statement for execution and returns a Statement object.
*
- * @param string $prepareString
- *
- * @return Statement
+ * @throws DriverException If an error occurs.
*/
- public function prepare($prepareString);
+ public function prepare(string $sql) : Statement;
/**
* Executes an SQL statement, returning a result set as a Statement object.
*
- * @return Statement
+ * @throws DriverException If an error occurs.
*/
- public function query();
+ public function query(string $sql) : ResultStatement;
/**
* Quotes a string for use in a query.
@@ -41,11 +39,9 @@ public function quote($input, $type = ParameterType::STRING);
/**
* Executes an SQL statement and return the number of affected rows.
*
- * @param string $statement
- *
- * @return int
+ * @throws DriverException If an error occurs.
*/
- public function exec($statement);
+ public function exec(string $statement) : int;
/**
* Returns the ID of the last inserted row or sequence value.
@@ -53,6 +49,8 @@ public function exec($statement);
* @param string|null $name
*
* @return string
+ *
+ * @throws DriverException If an error occurs.
*/
public function lastInsertId($name = null);
@@ -60,6 +58,8 @@ public function lastInsertId($name = null);
* Initiates a transaction.
*
* @return bool TRUE on success or FALSE on failure.
+ *
+ * @throws DriverException If an error occurs.
*/
public function beginTransaction();
@@ -67,6 +67,8 @@ public function beginTransaction();
* Commits a transaction.
*
* @return bool TRUE on success or FALSE on failure.
+ *
+ * @throws DriverException If an error occurs.
*/
public function commit();
@@ -74,6 +76,8 @@ public function commit();
* Rolls back the current transaction, as initiated by beginTransaction().
*
* @return bool TRUE on success or FALSE on failure.
+ *
+ * @throws DriverException If an error occurs.
*/
public function rollBack();
diff --git a/lib/Doctrine/DBAL/Driver/DriverException.php b/lib/Doctrine/DBAL/Driver/DriverException.php
index 79480ac72be..38c7a481619 100644
--- a/lib/Doctrine/DBAL/Driver/DriverException.php
+++ b/lib/Doctrine/DBAL/Driver/DriverException.php
@@ -2,39 +2,67 @@
namespace Doctrine\DBAL\Driver;
+use Exception;
use Throwable;
/**
- * Contract for a driver exception.
+ * A driver exception.
*
* Driver exceptions provide the SQLSTATE of the driver
* and the driver specific error code at the time the error occurred.
*/
-interface DriverException extends Throwable
+class DriverException extends Exception
{
/**
- * Returns the driver specific error code if available.
+ * The driver specific error code.
*
- * Returns null if no driver specific error code is available
- * for the error raised by the driver.
+ * @var int|string|null
+ */
+ private $errorCode;
+
+ /**
+ * The SQLSTATE of the driver.
*
- * @return int|string|null
+ * @var string|null
+ */
+ private $sqlState;
+
+ /**
+ * @param string $message The driver error message.
+ * @param string|null $sqlState The SQLSTATE the driver is in at the time the error occurred, if any.
+ * @param int|string|null $errorCode The driver specific error code if any.
+ * @param Throwable|null $previous The previous throwable used for the exception chaining.
*/
- public function getErrorCode();
+ public function __construct(string $message, ?string $sqlState = null, $errorCode = null, ?Throwable $previous = null)
+ {
+ parent::__construct($message, 0, $previous);
+
+ $this->errorCode = $errorCode;
+ $this->sqlState = $sqlState;
+ }
/**
- * Returns the driver error message.
+ * Returns the driver specific error code if available.
+ *
+ * Returns null if no driver specific error code is available
+ * for the error raised by the driver.
*
- * @return string
+ * @return int|string|null The error code.
*/
- public function getMessage();
+ public function getErrorCode()
+ {
+ return $this->errorCode;
+ }
/**
* Returns the SQLSTATE the driver was in at the time the error occurred.
*
* Returns null if the driver does not provide a SQLSTATE for the error occurred.
*
- * @return string|null
+ * @return string|null The SQLSTATE, or null if not available.
*/
- public function getSQLState();
+ public function getSQLState() : ?string
+ {
+ return $this->sqlState;
+ }
}
diff --git a/lib/Doctrine/DBAL/Driver/DrizzlePDOMySql/Connection.php b/lib/Doctrine/DBAL/Driver/DrizzlePDOMySql/Connection.php
deleted file mode 100644
index 4089ab26e11..00000000000
--- a/lib/Doctrine/DBAL/Driver/DrizzlePDOMySql/Connection.php
+++ /dev/null
@@ -1,21 +0,0 @@
-constructPdoDsn($params),
- $username,
- $password,
- $driverOptions
- );
- }
-
- /**
- * {@inheritdoc}
- */
- public function createDatabasePlatformForVersion($version)
- {
- return $this->getDatabasePlatform();
- }
-
- /**
- * {@inheritdoc}
- */
- public function getDatabasePlatform()
- {
- return new DrizzlePlatform();
- }
-
- /**
- * {@inheritdoc}
- */
- public function getSchemaManager(\Doctrine\DBAL\Connection $conn)
- {
- return new DrizzleSchemaManager($conn);
- }
-
- /**
- * {@inheritdoc}
- */
- public function getName()
- {
- return 'drizzle_pdo_mysql';
- }
-}
diff --git a/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Connection.php b/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Connection.php
index bd80e6e49a7..0a56426e218 100644
--- a/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Connection.php
+++ b/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Connection.php
@@ -3,7 +3,10 @@
namespace Doctrine\DBAL\Driver\IBMDB2;
use Doctrine\DBAL\Driver\Connection;
+use Doctrine\DBAL\Driver\DriverException;
+use Doctrine\DBAL\Driver\ResultStatement;
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
+use Doctrine\DBAL\Driver\Statement as DriverStatement;
use Doctrine\DBAL\ParameterType;
use stdClass;
use const DB2_AUTOCOMMIT_OFF;
@@ -22,7 +25,6 @@
use function db2_rollback;
use function db2_server_info;
use function db2_stmt_errormsg;
-use function func_get_args;
class DB2Connection implements Connection, ServerInfoAwareConnection
{
@@ -35,7 +37,7 @@ class DB2Connection implements Connection, ServerInfoAwareConnection
* @param string $password
* @param mixed[] $driverOptions
*
- * @throws DB2Exception
+ * @throws DriverException
*/
public function __construct(array $params, $username, $password, $driverOptions = [])
{
@@ -47,7 +49,7 @@ public function __construct(array $params, $username, $password, $driverOptions
$this->conn = db2_connect($params['dbname'], $username, $password, $driverOptions);
}
if (! $this->conn) {
- throw new DB2Exception(db2_conn_errormsg());
+ throw new DriverException(db2_conn_errormsg());
}
}
@@ -73,11 +75,11 @@ public function requiresQueryForServerVersion()
/**
* {@inheritdoc}
*/
- public function prepare($sql)
+ public function prepare(string $sql) : DriverStatement
{
$stmt = @db2_prepare($this->conn, $sql);
if (! $stmt) {
- throw new DB2Exception(db2_stmt_errormsg());
+ throw new DriverException(db2_stmt_errormsg());
}
return new DB2Statement($stmt);
@@ -86,10 +88,8 @@ public function prepare($sql)
/**
* {@inheritdoc}
*/
- public function query()
+ public function query(string $sql) : ResultStatement
{
- $args = func_get_args();
- $sql = $args[0];
$stmt = $this->prepare($sql);
$stmt->execute();
@@ -113,12 +113,12 @@ public function quote($input, $type = ParameterType::STRING)
/**
* {@inheritdoc}
*/
- public function exec($statement)
+ public function exec(string $statement) : int
{
$stmt = @db2_exec($this->conn, $statement);
if ($stmt === false) {
- throw new DB2Exception(db2_stmt_errormsg());
+ throw new DriverException(db2_stmt_errormsg());
}
return db2_num_rows($stmt);
@@ -146,7 +146,7 @@ public function beginTransaction()
public function commit()
{
if (! db2_commit($this->conn)) {
- throw new DB2Exception(db2_conn_errormsg($this->conn));
+ throw new DriverException(db2_conn_errormsg($this->conn));
}
db2_autocommit($this->conn, DB2_AUTOCOMMIT_ON);
}
@@ -157,7 +157,7 @@ public function commit()
public function rollBack()
{
if (! db2_rollback($this->conn)) {
- throw new DB2Exception(db2_conn_errormsg($this->conn));
+ throw new DriverException(db2_conn_errormsg($this->conn));
}
db2_autocommit($this->conn, DB2_AUTOCOMMIT_ON);
}
diff --git a/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Exception.php b/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Exception.php
deleted file mode 100644
index b01c4552a23..00000000000
--- a/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Exception.php
+++ /dev/null
@@ -1,9 +0,0 @@
-bindParam[$parameter] =& $variable;
if (! db2_bind_param($this->stmt, $parameter, 'variable', $parameterType, $dataType)) {
- throw new DB2Exception(db2_stmt_errormsg());
+ throw new DriverException(db2_stmt_errormsg());
}
}
@@ -230,7 +229,7 @@ public function execute($params = null)
$this->lobs = [];
if ($retval === false) {
- throw new DB2Exception(db2_stmt_errormsg());
+ throw new DriverException(db2_stmt_errormsg());
}
$this->result = true;
@@ -241,11 +240,17 @@ public function execute($params = null)
/**
* {@inheritdoc}
*/
- public function setFetchMode($fetchMode, $arg2 = null, $arg3 = null)
+ public function setFetchMode($fetchMode, ...$args)
{
- $this->defaultFetchMode = $fetchMode;
- $this->defaultFetchClass = $arg2 ?: $this->defaultFetchClass;
- $this->defaultFetchClassCtorArgs = $arg3 ? (array) $arg3 : $this->defaultFetchClassCtorArgs;
+ $this->defaultFetchMode = $fetchMode;
+
+ if (isset($args[0])) {
+ $this->defaultFetchClass = $args[0];
+ }
+
+ if (isset($args[1])) {
+ $this->defaultFetchClassCtorArgs = (array) $args[2];
+ }
return true;
}
@@ -261,7 +266,7 @@ public function getIterator()
/**
* {@inheritdoc}
*/
- public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEXT, $cursorOffset = 0)
+ public function fetch($fetchMode = null, ...$args)
{
// do not try fetching from the statement if it's not expected to contain result
// in order to prevent exceptional situation
@@ -284,10 +289,9 @@ public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEX
$className = $this->defaultFetchClass;
$ctorArgs = $this->defaultFetchClassCtorArgs;
- if (func_num_args() >= 2) {
- $args = func_get_args();
- $className = $args[1];
- $ctorArgs = $args[2] ?? [];
+ if (count($args) > 0) {
+ $className = $args[0];
+ $ctorArgs = $args[1] ?? [];
}
$result = db2_fetch_object($this->stmt);
@@ -305,20 +309,20 @@ public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEX
return db2_fetch_object($this->stmt);
default:
- throw new DB2Exception('Given Fetch-Style ' . $fetchMode . ' is not supported.');
+ throw new DriverException('Given Fetch-Style ' . $fetchMode . ' is not supported.');
}
}
/**
* {@inheritdoc}
*/
- public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = null)
+ public function fetchAll($fetchMode = null, ...$args)
{
$rows = [];
switch ($fetchMode) {
case FetchMode::CUSTOM_OBJECT:
- while (($row = $this->fetch(...func_get_args())) !== false) {
+ while (($row = $this->fetch($fetchMode, ...$args)) !== false) {
$rows[] = $row;
}
break;
@@ -353,7 +357,7 @@ public function fetchColumn($columnIndex = 0)
/**
* {@inheritdoc}
*/
- public function rowCount()
+ public function rowCount() : int
{
return @db2_num_rows($this->stmt) ? : 0;
}
@@ -367,13 +371,13 @@ public function rowCount()
*
* @return object
*
- * @throws DB2Exception
+ * @throws DriverException
*/
private function castObject(stdClass $sourceObject, $destinationClass, array $ctorArgs = [])
{
if (! is_string($destinationClass)) {
if (! is_object($destinationClass)) {
- throw new DB2Exception(sprintf(
+ throw new DriverException(sprintf(
'Destination class has to be of type string or object, %s given.',
gettype($destinationClass)
));
@@ -426,14 +430,14 @@ private function castObject(stdClass $sourceObject, $destinationClass, array $ct
/**
* @return resource
*
- * @throws DB2Exception
+ * @throws DriverException
*/
private function createTemporaryFile()
{
$handle = @tmpfile();
if ($handle === false) {
- throw new DB2Exception('Could not create temporary file: ' . error_get_last()['message']);
+ throw new DriverException('Could not create temporary file: ' . error_get_last()['message']);
}
return $handle;
@@ -443,24 +447,24 @@ private function createTemporaryFile()
* @param resource $source
* @param resource $target
*
- * @throws DB2Exception
+ * @throws DriverException
*/
private function copyStreamToStream($source, $target) : void
{
if (@stream_copy_to_stream($source, $target) === false) {
- throw new DB2Exception('Could not copy source stream to temporary file: ' . error_get_last()['message']);
+ throw new DriverException('Could not copy source stream to temporary file: ' . error_get_last()['message']);
}
}
/**
* @param resource $target
*
- * @throws DB2Exception
+ * @throws DriverException
*/
private function writeStringToStream(string $string, $target) : void
{
if (@fwrite($target, $string) === false) {
- throw new DB2Exception('Could not write string to temporary file: ' . error_get_last()['message']);
+ throw new DriverException('Could not write string to temporary file: ' . error_get_last()['message']);
}
}
}
diff --git a/lib/Doctrine/DBAL/Driver/Mysqli/Driver.php b/lib/Doctrine/DBAL/Driver/Mysqli/Driver.php
index aaf4f2bd9fd..0909d7db7a4 100644
--- a/lib/Doctrine/DBAL/Driver/Mysqli/Driver.php
+++ b/lib/Doctrine/DBAL/Driver/Mysqli/Driver.php
@@ -4,6 +4,7 @@
use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Driver\AbstractMySQLDriver;
+use Doctrine\DBAL\Driver\DriverException;
class Driver extends AbstractMySQLDriver
{
@@ -14,7 +15,7 @@ public function connect(array $params, $username = null, $password = null, array
{
try {
return new MysqliConnection($params, $username, $password, $driverOptions);
- } catch (MysqliException $e) {
+ } catch (DriverException $e) {
throw DBALException::driverException($this, $e);
}
}
diff --git a/lib/Doctrine/DBAL/Driver/Mysqli/MysqliConnection.php b/lib/Doctrine/DBAL/Driver/Mysqli/MysqliConnection.php
index 1f1a1d218c3..b0349f9145d 100644
--- a/lib/Doctrine/DBAL/Driver/Mysqli/MysqliConnection.php
+++ b/lib/Doctrine/DBAL/Driver/Mysqli/MysqliConnection.php
@@ -3,8 +3,11 @@
namespace Doctrine\DBAL\Driver\Mysqli;
use Doctrine\DBAL\Driver\Connection;
+use Doctrine\DBAL\Driver\DriverException;
use Doctrine\DBAL\Driver\PingableConnection;
+use Doctrine\DBAL\Driver\ResultStatement;
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
+use Doctrine\DBAL\Driver\Statement as DriverStatement;
use Doctrine\DBAL\ParameterType;
use mysqli;
use const MYSQLI_INIT_COMMAND;
@@ -15,7 +18,6 @@
use const MYSQLI_SERVER_PUBLIC_KEY;
use function defined;
use function floor;
-use function func_get_args;
use function in_array;
use function ini_get;
use function mysqli_errno;
@@ -43,7 +45,7 @@ class MysqliConnection implements Connection, PingableConnection, ServerInfoAwar
* @param string $password
* @param mixed[] $driverOptions
*
- * @throws MysqliException
+ * @throws DriverException
*/
public function __construct(array $params, $username, $password, array $driverOptions = [])
{
@@ -68,7 +70,7 @@ public function __construct(array $params, $username, $password, array $driverOp
});
try {
if (! $this->conn->real_connect($params['host'], $username, $password, $dbname, $port, $socket, $flags)) {
- throw new MysqliException($this->conn->connect_error, $this->conn->sqlstate ?? 'HY000', $this->conn->connect_errno);
+ throw new DriverException($this->conn->connect_error, $this->conn->sqlstate ?? 'HY000', $this->conn->connect_errno);
}
} finally {
restore_error_handler();
@@ -126,18 +128,16 @@ public function requiresQueryForServerVersion()
/**
* {@inheritdoc}
*/
- public function prepare($prepareString)
+ public function prepare(string $sql) : DriverStatement
{
- return new MysqliStatement($this->conn, $prepareString);
+ return new MysqliStatement($this->conn, $sql);
}
/**
* {@inheritdoc}
*/
- public function query()
+ public function query(string $sql) : ResultStatement
{
- $args = func_get_args();
- $sql = $args[0];
$stmt = $this->prepare($sql);
$stmt->execute();
@@ -155,10 +155,10 @@ public function quote($input, $type = ParameterType::STRING)
/**
* {@inheritdoc}
*/
- public function exec($statement)
+ public function exec(string $statement) : int
{
if ($this->conn->query($statement) === false) {
- throw new MysqliException($this->conn->error, $this->conn->sqlstate, $this->conn->errno);
+ throw new DriverException($this->conn->error, $this->conn->sqlstate, $this->conn->errno);
}
return $this->conn->affected_rows;
@@ -191,7 +191,7 @@ public function commit()
}
/**
- * {@inheritdoc}non-PHPdoc)
+ * {@inheritdoc}
*/
public function rollBack()
{
@@ -219,8 +219,8 @@ public function errorInfo()
*
* @param mixed[] $driverOptions
*
- * @throws MysqliException When one of of the options is not supported.
- * @throws MysqliException When applying doesn't work - e.g. due to incorrect value.
+ * @throws DriverException When one of of the options is not supported.
+ * @throws DriverException When applying doesn't work - e.g. due to incorrect value.
*/
private function setDriverOptions(array $driverOptions = [])
{
@@ -244,7 +244,7 @@ private function setDriverOptions(array $driverOptions = [])
}
if (! in_array($option, $supportedDriverOptions, true)) {
- throw new MysqliException(
+ throw new DriverException(
sprintf($exceptionMsg, 'Unsupported', $option, $value)
);
}
@@ -256,7 +256,7 @@ private function setDriverOptions(array $driverOptions = [])
$msg = sprintf($exceptionMsg, 'Failed to set', $option, $value);
$msg .= sprintf(', error: %s (%d)', mysqli_error($this->conn), mysqli_errno($this->conn));
- throw new MysqliException(
+ throw new DriverException(
$msg,
$this->conn->sqlstate,
$this->conn->errno
@@ -279,7 +279,7 @@ public function ping()
*
* @param mixed[] $params
*
- * @throws MysqliException
+ * @throws DriverException
*/
private function setSecureConnection(array $params)
{
diff --git a/lib/Doctrine/DBAL/Driver/Mysqli/MysqliException.php b/lib/Doctrine/DBAL/Driver/Mysqli/MysqliException.php
deleted file mode 100644
index 1fa0c900fbd..00000000000
--- a/lib/Doctrine/DBAL/Driver/Mysqli/MysqliException.php
+++ /dev/null
@@ -1,12 +0,0 @@
-_conn = $conn;
$this->_stmt = $conn->prepare($prepareString);
if ($this->_stmt === false) {
- throw new MysqliException($this->_conn->error, $this->_conn->sqlstate, $this->_conn->errno);
+ throw new DriverException($this->_conn->error, $this->_conn->sqlstate, $this->_conn->errno);
}
$paramCount = $this->_stmt->param_count;
@@ -100,7 +100,7 @@ public function bindParam($column, &$variable, $type = ParameterType::STRING, $l
$type = 's';
} else {
if (! isset(self::$_paramTypeMap[$type])) {
- throw new MysqliException(sprintf("Unknown type: '%s'", $type));
+ throw new DriverException(sprintf("Unknown type: '%s'", $type));
}
$type = self::$_paramTypeMap[$type];
@@ -121,7 +121,7 @@ public function bindValue($param, $value, $type = ParameterType::STRING)
$type = 's';
} else {
if (! isset(self::$_paramTypeMap[$type])) {
- throw new MysqliException(sprintf("Unknown type: '%s'", $type));
+ throw new DriverException(sprintf("Unknown type: '%s'", $type));
}
$type = self::$_paramTypeMap[$type];
@@ -139,22 +139,22 @@ public function bindValue($param, $value, $type = ParameterType::STRING)
*/
public function execute($params = null)
{
- if ($this->_bindedValues !== null) {
- if ($params !== null) {
- if (! $this->_bindValues($params)) {
- throw new MysqliException($this->_stmt->error, $this->_stmt->errno);
- }
- } else {
- [$types, $values, $streams] = $this->separateBoundValues();
- if (! $this->_stmt->bind_param($types, ...$values)) {
- throw new MysqliException($this->_stmt->error, $this->_stmt->sqlstate, $this->_stmt->errno);
- }
- $this->sendLongData($streams);
+ if ($params !== null && count($params) > 0) {
+ if (! $this->_bindValues($params)) {
+ throw new DriverException($this->_stmt->error, $this->_stmt->errno);
}
+ } else {
+ [$types, $values, $streams] = $this->separateBoundValues();
+
+ if (count($values) > 0 && ! $this->_stmt->bind_param($types, ...$values)) {
+ throw new DriverException($this->_stmt->error, $this->_stmt->sqlstate, $this->_stmt->errno);
+ }
+
+ $this->sendLongData($streams);
}
if (! $this->_stmt->execute()) {
- throw new MysqliException($this->_stmt->error, $this->_stmt->sqlstate, $this->_stmt->errno);
+ throw new DriverException($this->_stmt->error, $this->_stmt->sqlstate, $this->_stmt->errno);
}
if ($this->_columnNames === null) {
@@ -197,7 +197,7 @@ public function execute($params = null)
}
if (! $this->_stmt->bind_result(...$refs)) {
- throw new MysqliException($this->_stmt->error, $this->_stmt->sqlstate, $this->_stmt->errno);
+ throw new DriverException($this->_stmt->error, $this->_stmt->sqlstate, $this->_stmt->errno);
}
}
@@ -244,7 +244,7 @@ private function separateBoundValues()
/**
* Handle $this->_longData after regular query parameters have been bound
*
- * @throws MysqliException
+ * @throws DriverException
*/
private function sendLongData($streams)
{
@@ -253,11 +253,11 @@ private function sendLongData($streams)
$chunk = fread($stream, 8192);
if ($chunk === false) {
- throw new MysqliException("Failed reading the stream resource for parameter offset ${paramNr}.");
+ throw new DriverException("Failed reading the stream resource for parameter offset ${paramNr}.");
}
if (! $this->_stmt->send_long_data($paramNr - 1, $chunk)) {
- throw new MysqliException($this->_stmt->error, $this->_stmt->sqlstate, $this->_stmt->errno);
+ throw new DriverException($this->_stmt->error, $this->_stmt->sqlstate, $this->_stmt->errno);
}
}
}
@@ -304,7 +304,7 @@ private function _fetch()
/**
* {@inheritdoc}
*/
- public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEXT, $cursorOffset = 0)
+ public function fetch($fetchMode = null, ...$args)
{
// do not try fetching from the statement if it's not expected to contain result
// in order to prevent exceptional situation
@@ -324,7 +324,7 @@ public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEX
}
if ($values === false) {
- throw new MysqliException($this->_stmt->error, $this->_stmt->sqlstate, $this->_stmt->errno);
+ throw new DriverException($this->_stmt->error, $this->_stmt->sqlstate, $this->_stmt->errno);
}
switch ($fetchMode) {
@@ -351,14 +351,14 @@ public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEX
return $ret;
default:
- throw new MysqliException(sprintf("Unknown fetch type '%s'", $fetchMode));
+ throw new DriverException(sprintf("Unknown fetch type '%s'", $fetchMode));
}
}
/**
* {@inheritdoc}
*/
- public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = null)
+ public function fetchAll($fetchMode = null, ...$args)
{
$fetchMode = $fetchMode ?: $this->_defaultFetchMode;
@@ -421,7 +421,7 @@ public function closeCursor()
/**
* {@inheritdoc}
*/
- public function rowCount()
+ public function rowCount() : int
{
if ($this->_columnNames === false) {
return $this->_stmt->affected_rows;
@@ -441,7 +441,7 @@ public function columnCount()
/**
* {@inheritdoc}
*/
- public function setFetchMode($fetchMode, $arg2 = null, $arg3 = null)
+ public function setFetchMode($fetchMode, ...$args)
{
$this->_defaultFetchMode = $fetchMode;
diff --git a/lib/Doctrine/DBAL/Driver/OCI8/Driver.php b/lib/Doctrine/DBAL/Driver/OCI8/Driver.php
index 872582d80b7..c061fec8594 100644
--- a/lib/Doctrine/DBAL/Driver/OCI8/Driver.php
+++ b/lib/Doctrine/DBAL/Driver/OCI8/Driver.php
@@ -4,6 +4,7 @@
use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Driver\AbstractOracleDriver;
+use Doctrine\DBAL\Driver\DriverException;
use const OCI_DEFAULT;
/**
@@ -25,7 +26,7 @@ public function connect(array $params, $username = null, $password = null, array
$params['sessionMode'] ?? OCI_DEFAULT,
$params['persistent'] ?? false
);
- } catch (OCI8Exception $e) {
+ } catch (DriverException $e) {
throw DBALException::driverException($this, $e);
}
}
diff --git a/lib/Doctrine/DBAL/Driver/OCI8/OCI8Connection.php b/lib/Doctrine/DBAL/Driver/OCI8/OCI8Connection.php
index 5ebc877a898..23bab52f4a8 100644
--- a/lib/Doctrine/DBAL/Driver/OCI8/OCI8Connection.php
+++ b/lib/Doctrine/DBAL/Driver/OCI8/OCI8Connection.php
@@ -3,7 +3,10 @@
namespace Doctrine\DBAL\Driver\OCI8;
use Doctrine\DBAL\Driver\Connection;
+use Doctrine\DBAL\Driver\DriverException;
+use Doctrine\DBAL\Driver\ResultStatement;
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
+use Doctrine\DBAL\Driver\Statement as DriverStatement;
use Doctrine\DBAL\ParameterType;
use UnexpectedValueException;
use const OCI_COMMIT_ON_SUCCESS;
@@ -12,7 +15,6 @@
use function addcslashes;
use function define;
use function defined;
-use function func_get_args;
use function is_float;
use function is_int;
use function oci_commit;
@@ -46,7 +48,7 @@ class OCI8Connection implements Connection, ServerInfoAwareConnection
* @param int $sessionMode
* @param bool $persistent
*
- * @throws OCI8Exception
+ * @throws DriverException
*/
public function __construct($username, $password, $db, $charset = null, $sessionMode = OCI_DEFAULT, $persistent = false)
{
@@ -59,7 +61,7 @@ public function __construct($username, $password, $db, $charset = null, $session
: @oci_connect($username, $password, $db, $charset, $sessionMode);
if (! $this->dbh) {
- throw OCI8Exception::fromErrorInfo(oci_error());
+ throw self::exceptionFromErrorInfo(oci_error());
}
}
@@ -95,19 +97,16 @@ public function requiresQueryForServerVersion()
/**
* {@inheritdoc}
*/
- public function prepare($prepareString)
+ public function prepare(string $sql) : DriverStatement
{
- return new OCI8Statement($this->dbh, $prepareString, $this);
+ return new OCI8Statement($this->dbh, $sql, $this);
}
/**
* {@inheritdoc}
*/
- public function query()
+ public function query(string $sql) : ResultStatement
{
- $args = func_get_args();
- $sql = $args[0];
- //$fetchMode = $args[1];
$stmt = $this->prepare($sql);
$stmt->execute();
@@ -130,7 +129,7 @@ public function quote($value, $type = ParameterType::STRING)
/**
* {@inheritdoc}
*/
- public function exec($statement)
+ public function exec(string $statement) : int
{
$stmt = $this->prepare($statement);
$stmt->execute();
@@ -144,7 +143,7 @@ public function exec($statement)
public function lastInsertId($name = null)
{
if ($name === null) {
- return false;
+ throw new DriverException('A sequence name must be provided.');
}
$sql = 'SELECT ' . $name . '.CURRVAL FROM DUAL';
@@ -152,7 +151,7 @@ public function lastInsertId($name = null)
$result = $stmt->fetchColumn();
if ($result === false) {
- throw new OCI8Exception('lastInsertId failed: Query was executed but no result was returned.');
+ throw new DriverException('lastInsertId failed: Query was executed but no result was returned.');
}
return (int) $result;
@@ -184,7 +183,7 @@ public function beginTransaction()
public function commit()
{
if (! oci_commit($this->dbh)) {
- throw OCI8Exception::fromErrorInfo($this->errorInfo());
+ throw self::exceptionFromErrorInfo($this->errorInfo());
}
$this->executeMode = OCI_COMMIT_ON_SUCCESS;
@@ -197,7 +196,7 @@ public function commit()
public function rollBack()
{
if (! oci_rollback($this->dbh)) {
- throw OCI8Exception::fromErrorInfo($this->errorInfo());
+ throw self::exceptionFromErrorInfo($this->errorInfo());
}
$this->executeMode = OCI_COMMIT_ON_SUCCESS;
@@ -224,4 +223,12 @@ public function errorInfo()
{
return oci_error($this->dbh);
}
+
+ /**
+ * @param mixed[] $error The return value of an oci_error() call.
+ */
+ public static function exceptionFromErrorInfo(array $error) : DriverException
+ {
+ return new DriverException($error['message'], null, $error['code']);
+ }
}
diff --git a/lib/Doctrine/DBAL/Driver/OCI8/OCI8Exception.php b/lib/Doctrine/DBAL/Driver/OCI8/OCI8Exception.php
deleted file mode 100644
index 9d61ad42d08..00000000000
--- a/lib/Doctrine/DBAL/Driver/OCI8/OCI8Exception.php
+++ /dev/null
@@ -1,18 +0,0 @@
- the statement value (string), [1] => the paramMap value (array).
*
- * @throws OCI8Exception
+ * @throws DriverException
*
* @todo extract into utility class in Doctrine\DBAL\Util namespace
* @todo review and test for lost spaces. we experienced missing spaces with oci8 in some sql statements.
@@ -147,7 +147,7 @@ public static function convertPositionalToNamedPlaceholders($statement)
} while ($result);
if ($currentLiteralDelimiter) {
- throw new OCI8Exception(sprintf(
+ throw new DriverException(sprintf(
'The statement contains non-terminated string literal starting at offset %d',
$tokenOffset - 1
));
@@ -360,16 +360,20 @@ public function execute($params = null)
$hasZeroIndex = array_key_exists(0, $params);
foreach ($params as $key => $val) {
if ($hasZeroIndex && is_numeric($key)) {
- $this->bindValue($key + 1, $val);
+ $param = $key + 1;
} else {
- $this->bindValue($key, $val);
+ $param = $key;
+ }
+
+ if (! $this->bindValue($param, $val)) {
+ throw OCI8Connection::exceptionFromErrorInfo($this->errorInfo());
}
}
}
$ret = @oci_execute($this->_sth, $this->_conn->getExecuteMode());
if (! $ret) {
- throw OCI8Exception::fromErrorInfo($this->errorInfo());
+ throw OCI8Connection::exceptionFromErrorInfo($this->errorInfo());
}
$this->result = true;
@@ -380,7 +384,7 @@ public function execute($params = null)
/**
* {@inheritdoc}
*/
- public function setFetchMode($fetchMode, $arg2 = null, $arg3 = null)
+ public function setFetchMode($fetchMode, ...$args)
{
$this->_defaultFetchMode = $fetchMode;
@@ -398,7 +402,7 @@ public function getIterator()
/**
* {@inheritdoc}
*/
- public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEXT, $cursorOffset = 0)
+ public function fetch($fetchMode = null, ...$args)
{
// do not try fetching from the statement if it's not expected to contain result
// in order to prevent exceptional situation
@@ -429,7 +433,7 @@ public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEX
/**
* {@inheritdoc}
*/
- public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = null)
+ public function fetchAll($fetchMode = null, ...$args)
{
$fetchMode = $fetchMode ?: $this->_defaultFetchMode;
@@ -503,7 +507,7 @@ public function fetchColumn($columnIndex = 0)
/**
* {@inheritdoc}
*/
- public function rowCount()
+ public function rowCount() : int
{
return oci_num_rows($this->_sth);
}
diff --git a/lib/Doctrine/DBAL/Driver/PDOConnection.php b/lib/Doctrine/DBAL/Driver/PDOConnection.php
index 3368c0d94dc..a1b8e1a8bbc 100644
--- a/lib/Doctrine/DBAL/Driver/PDOConnection.php
+++ b/lib/Doctrine/DBAL/Driver/PDOConnection.php
@@ -4,43 +4,45 @@
use Doctrine\DBAL\ParameterType;
use PDO;
-use function count;
-use function func_get_args;
+use PDOException;
/**
* PDO implementation of the Connection interface.
+ *
* Used by all PDO-based drivers.
*/
-class PDOConnection extends PDO implements Connection, ServerInfoAwareConnection
+class PDOConnection implements Connection, ServerInfoAwareConnection
{
+ /** @var PDO */
+ private $connection;
+
/**
* @param string $dsn
* @param string|null $user
* @param string|null $password
* @param mixed[]|null $options
*
- * @throws PDOException In case of an error.
+ * @throws DriverException In case of an error.
*/
public function __construct($dsn, $user = null, $password = null, ?array $options = null)
{
try {
- parent::__construct($dsn, $user, $password, $options);
- $this->setAttribute(PDO::ATTR_STATEMENT_CLASS, [PDOStatement::class, []]);
- $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
- } catch (\PDOException $exception) {
- throw new PDOException($exception);
+ $this->connection = new PDO($dsn, $user, $password, $options);
+ $this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+ } catch (PDOException $exception) {
+ throw self::exceptionFromPDOException($exception);
}
}
/**
* {@inheritdoc}
*/
- public function exec($statement)
+ public function exec(string $statement) : int
{
try {
- return parent::exec($statement);
- } catch (\PDOException $exception) {
- throw new PDOException($exception);
+ return $this->connection->exec($statement);
+ } catch (PDOException $exception) {
+ throw self::exceptionFromPDOException($exception);
}
}
@@ -49,45 +51,34 @@ public function exec($statement)
*/
public function getServerVersion()
{
- return PDO::getAttribute(PDO::ATTR_SERVER_VERSION);
+ return $this->connection->getAttribute(PDO::ATTR_SERVER_VERSION);
}
/**
* {@inheritdoc}
*/
- public function prepare($prepareString, $driverOptions = [])
+ public function prepare(string $sql) : Statement
{
try {
- return parent::prepare($prepareString, $driverOptions);
- } catch (\PDOException $exception) {
- throw new PDOException($exception);
+ return $this->createStatement(
+ $this->connection->prepare($sql)
+ );
+ } catch (PDOException $exception) {
+ throw self::exceptionFromPDOException($exception);
}
}
/**
* {@inheritdoc}
*/
- public function query()
+ public function query(string $sql) : ResultStatement
{
- $args = func_get_args();
- $argsCount = count($args);
-
try {
- if ($argsCount === 4) {
- return parent::query($args[0], $args[1], $args[2], $args[3]);
- }
-
- if ($argsCount === 3) {
- return parent::query($args[0], $args[1], $args[2]);
- }
-
- if ($argsCount === 2) {
- return parent::query($args[0], $args[1]);
- }
-
- return parent::query($args[0]);
- } catch (\PDOException $exception) {
- throw new PDOException($exception);
+ return $this->createStatement(
+ $this->connection->query($sql)
+ );
+ } catch (PDOException $exception) {
+ throw self::exceptionFromPDOException($exception);
}
}
@@ -96,7 +87,7 @@ public function query()
*/
public function quote($input, $type = ParameterType::STRING)
{
- return parent::quote($input, $type);
+ return $this->connection->quote($input, $type);
}
/**
@@ -104,7 +95,7 @@ public function quote($input, $type = ParameterType::STRING)
*/
public function lastInsertId($name = null)
{
- return parent::lastInsertId($name);
+ return $this->connection->lastInsertId($name);
}
/**
@@ -114,4 +105,70 @@ public function requiresQueryForServerVersion()
{
return false;
}
+
+ /**
+ * Creates a wrapped statement
+ */
+ protected function createStatement(\PDOStatement $stmt) : PDOStatement
+ {
+ return new PDOStatement($stmt);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function beginTransaction()
+ {
+ return $this->connection->beginTransaction();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function commit()
+ {
+ return $this->connection->commit();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function rollBack()
+ {
+ return $this->connection->rollBack();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function errorCode()
+ {
+ return $this->connection->errorCode();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function errorInfo()
+ {
+ return $this->connection->errorInfo();
+ }
+
+ public function getWrappedConnection() : PDO
+ {
+ return $this->connection;
+ }
+
+ /**
+ * Creates a DriverException from a PDOException.
+ */
+ public static function exceptionFromPDOException(PDOException $exception) : DriverException
+ {
+ return new DriverException(
+ $exception->getMessage(),
+ $exception->errorInfo[0] ?? $exception->getCode(),
+ $exception->errorInfo[1] ?? $exception->getCode(),
+ $exception
+ );
+ }
}
diff --git a/lib/Doctrine/DBAL/Driver/PDOException.php b/lib/Doctrine/DBAL/Driver/PDOException.php
deleted file mode 100644
index 277d7a62500..00000000000
--- a/lib/Doctrine/DBAL/Driver/PDOException.php
+++ /dev/null
@@ -1,52 +0,0 @@
-getMessage(), 0, $exception);
-
- $this->code = $exception->getCode();
- $this->errorInfo = $exception->errorInfo;
- $this->errorCode = $exception->errorInfo[1] ?? $exception->getCode();
- $this->sqlState = $exception->errorInfo[0] ?? $exception->getCode();
- }
-
- /**
- * {@inheritdoc}
- */
- public function getErrorCode()
- {
- return $this->errorCode;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getSQLState()
- {
- return $this->sqlState;
- }
-}
diff --git a/lib/Doctrine/DBAL/Driver/PDOIbm/Driver.php b/lib/Doctrine/DBAL/Driver/PDOIbm/Driver.php
deleted file mode 100644
index 4291e1e17f0..00000000000
--- a/lib/Doctrine/DBAL/Driver/PDOIbm/Driver.php
+++ /dev/null
@@ -1,57 +0,0 @@
-_constructPdoDsn($params),
- $username,
- $password,
- $driverOptions
- );
- }
-
- /**
- * Constructs the IBM PDO DSN.
- *
- * @param mixed[] $params
- *
- * @return string The DSN.
- */
- private function _constructPdoDsn(array $params)
- {
- $dsn = 'ibm:';
- if (isset($params['host'])) {
- $dsn .= 'HOSTNAME=' . $params['host'] . ';';
- }
- if (isset($params['port'])) {
- $dsn .= 'PORT=' . $params['port'] . ';';
- }
- $dsn .= 'PROTOCOL=TCPIP;';
- if (isset($params['dbname'])) {
- $dsn .= 'DATABASE=' . $params['dbname'] . ';';
- }
-
- return $dsn;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getName()
- {
- return 'pdo_ibm';
- }
-}
diff --git a/lib/Doctrine/DBAL/Driver/PDOMySql/Driver.php b/lib/Doctrine/DBAL/Driver/PDOMySql/Driver.php
index 59d27d3844f..fa8e4b845bf 100644
--- a/lib/Doctrine/DBAL/Driver/PDOMySql/Driver.php
+++ b/lib/Doctrine/DBAL/Driver/PDOMySql/Driver.php
@@ -4,8 +4,8 @@
use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Driver\AbstractMySQLDriver;
+use Doctrine\DBAL\Driver\DriverException;
use Doctrine\DBAL\Driver\PDOConnection;
-use PDOException;
/**
* PDO MySql driver.
@@ -24,7 +24,7 @@ public function connect(array $params, $username = null, $password = null, array
$password,
$driverOptions
);
- } catch (PDOException $e) {
+ } catch (DriverException $e) {
throw DBALException::driverException($this, $e);
}
diff --git a/lib/Doctrine/DBAL/Driver/PDOOracle/Driver.php b/lib/Doctrine/DBAL/Driver/PDOOracle/Driver.php
index f1239eafbd4..ba3a3a90c7a 100644
--- a/lib/Doctrine/DBAL/Driver/PDOOracle/Driver.php
+++ b/lib/Doctrine/DBAL/Driver/PDOOracle/Driver.php
@@ -4,8 +4,8 @@
use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Driver\AbstractOracleDriver;
+use Doctrine\DBAL\Driver\DriverException;
use Doctrine\DBAL\Driver\PDOConnection;
-use PDOException;
/**
* PDO Oracle driver.
@@ -29,7 +29,7 @@ public function connect(array $params, $username = null, $password = null, array
$password,
$driverOptions
);
- } catch (PDOException $e) {
+ } catch (DriverException $e) {
throw DBALException::driverException($this, $e);
}
}
diff --git a/lib/Doctrine/DBAL/Driver/PDOPgSql/Driver.php b/lib/Doctrine/DBAL/Driver/PDOPgSql/Driver.php
index 972dbadcd5d..68d4ee76661 100644
--- a/lib/Doctrine/DBAL/Driver/PDOPgSql/Driver.php
+++ b/lib/Doctrine/DBAL/Driver/PDOPgSql/Driver.php
@@ -4,9 +4,9 @@
use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Driver\AbstractPostgreSQLDriver;
+use Doctrine\DBAL\Driver\DriverException;
use Doctrine\DBAL\Driver\PDOConnection;
use PDO;
-use PDOException;
use function defined;
/**
@@ -20,7 +20,7 @@ class Driver extends AbstractPostgreSQLDriver
public function connect(array $params, $username = null, $password = null, array $driverOptions = [])
{
try {
- $pdo = new PDOConnection(
+ $connection = new PDOConnection(
$this->_constructPdoDsn($params),
$username,
$password,
@@ -32,7 +32,7 @@ public function connect(array $params, $username = null, $password = null, array
|| $driverOptions[PDO::PGSQL_ATTR_DISABLE_PREPARES] === true
)
) {
- $pdo->setAttribute(PDO::PGSQL_ATTR_DISABLE_PREPARES, true);
+ $connection->getWrappedConnection()->setAttribute(PDO::PGSQL_ATTR_DISABLE_PREPARES, true);
}
/* defining client_encoding via SET NAMES to avoid inconsistent DSN support
@@ -40,11 +40,11 @@ public function connect(array $params, $username = null, $password = null, array
* - passing client_encoding via the 'options' param breaks pgbouncer support
*/
if (isset($params['charset'])) {
- $pdo->exec('SET NAMES \'' . $params['charset'] . '\'');
+ $connection->exec('SET NAMES \'' . $params['charset'] . '\'');
}
- return $pdo;
- } catch (PDOException $e) {
+ return $connection;
+ } catch (DriverException $e) {
throw DBALException::driverException($this, $e);
}
}
diff --git a/lib/Doctrine/DBAL/Driver/PDOSqlite/Driver.php b/lib/Doctrine/DBAL/Driver/PDOSqlite/Driver.php
index 7a28b831027..5cc3f16665d 100644
--- a/lib/Doctrine/DBAL/Driver/PDOSqlite/Driver.php
+++ b/lib/Doctrine/DBAL/Driver/PDOSqlite/Driver.php
@@ -4,9 +4,9 @@
use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Driver\AbstractSQLiteDriver;
+use Doctrine\DBAL\Driver\DriverException;
use Doctrine\DBAL\Driver\PDOConnection;
use Doctrine\DBAL\Platforms\SqlitePlatform;
-use PDOException;
use function array_merge;
/**
@@ -35,21 +35,23 @@ public function connect(array $params, $username = null, $password = null, array
}
try {
- $pdo = new PDOConnection(
+ $connection = new PDOConnection(
$this->_constructPdoDsn($params),
$username,
$password,
$driverOptions
);
- } catch (PDOException $ex) {
+ } catch (DriverException $ex) {
throw DBALException::driverException($this, $ex);
}
+ $pdo = $connection->getWrappedConnection();
+
foreach ($this->_userDefinedFunctions as $fn => $data) {
$pdo->sqliteCreateFunction($fn, $data['callback'], $data['numArgs']);
}
- return $pdo;
+ return $connection;
}
/**
diff --git a/lib/Doctrine/DBAL/Driver/PDOSqlsrv/Connection.php b/lib/Doctrine/DBAL/Driver/PDOSqlsrv/Connection.php
index 86ad9aedf29..8d3601f3b98 100644
--- a/lib/Doctrine/DBAL/Driver/PDOSqlsrv/Connection.php
+++ b/lib/Doctrine/DBAL/Driver/PDOSqlsrv/Connection.php
@@ -3,8 +3,8 @@
namespace Doctrine\DBAL\Driver\PDOSqlsrv;
use Doctrine\DBAL\Driver\PDOConnection;
+use Doctrine\DBAL\Driver\PDOStatement;
use Doctrine\DBAL\ParameterType;
-use PDO;
use function strpos;
use function substr;
@@ -13,15 +13,6 @@
*/
class Connection extends PDOConnection implements \Doctrine\DBAL\Driver\Connection
{
- /**
- * {@inheritdoc}
- */
- public function __construct($dsn, $user = null, $password = null, ?array $options = null)
- {
- parent::__construct($dsn, $user, $password, $options);
- $this->setAttribute(PDO::ATTR_STATEMENT_CLASS, [Statement::class, []]);
- }
-
/**
* {@inheritDoc}
*/
@@ -51,4 +42,12 @@ public function quote($value, $type = ParameterType::STRING)
return $val;
}
+
+ /**
+ * {@inheritDoc}
+ */
+ protected function createStatement(\PDOStatement $stmt) : PDOStatement
+ {
+ return new Statement($stmt);
+ }
}
diff --git a/lib/Doctrine/DBAL/Driver/PDOStatement.php b/lib/Doctrine/DBAL/Driver/PDOStatement.php
index 2aed89fbf07..d639219d982 100644
--- a/lib/Doctrine/DBAL/Driver/PDOStatement.php
+++ b/lib/Doctrine/DBAL/Driver/PDOStatement.php
@@ -4,7 +4,9 @@
use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\ParameterType;
+use IteratorAggregate;
use PDO;
+use PDOException;
use const E_USER_DEPRECATED;
use function sprintf;
use function trigger_error;
@@ -13,7 +15,7 @@
* The PDO implementation of the Statement interface.
* Used by all PDO-based drivers.
*/
-class PDOStatement extends \PDOStatement implements Statement
+class PDOStatement implements IteratorAggregate, Statement
{
private const PARAM_TYPE_MAP = [
ParameterType::NULL => PDO::PARAM_NULL,
@@ -33,36 +35,25 @@ class PDOStatement extends \PDOStatement implements Statement
FetchMode::CUSTOM_OBJECT => PDO::FETCH_CLASS,
];
- /**
- * Protected constructor.
- */
- protected function __construct()
+ /** @var \PDOStatement */
+ private $stmt;
+
+ public function __construct(\PDOStatement $stmt)
{
+ $this->stmt = $stmt;
}
/**
* {@inheritdoc}
*/
- public function setFetchMode($fetchMode, $arg2 = null, $arg3 = null)
+ public function setFetchMode($fetchMode, ...$args)
{
$fetchMode = $this->convertFetchMode($fetchMode);
- // This thin wrapper is necessary to shield against the weird signature
- // of PDOStatement::setFetchMode(): even if the second and third
- // parameters are optional, PHP will not let us remove it from this
- // declaration.
try {
- if ($arg2 === null && $arg3 === null) {
- return parent::setFetchMode($fetchMode);
- }
-
- if ($arg3 === null) {
- return parent::setFetchMode($fetchMode, $arg2);
- }
-
- return parent::setFetchMode($fetchMode, $arg2, $arg3);
- } catch (\PDOException $exception) {
- throw new PDOException($exception);
+ return $this->stmt->setFetchMode($fetchMode, ...$args);
+ } catch (PDOException $exception) {
+ throw PDOConnection::exceptionFromPDOException($exception);
}
}
@@ -74,9 +65,9 @@ public function bindValue($param, $value, $type = ParameterType::STRING)
$type = $this->convertParamType($type);
try {
- return parent::bindValue($param, $value, $type);
- } catch (\PDOException $exception) {
- throw new PDOException($exception);
+ return $this->stmt->bindValue($param, $value, $type);
+ } catch (PDOException $exception) {
+ throw PDOConnection::exceptionFromPDOException($exception);
}
}
@@ -88,9 +79,9 @@ public function bindParam($column, &$variable, $type = ParameterType::STRING, $l
$type = $this->convertParamType($type);
try {
- return parent::bindParam($column, $variable, $type, $length, $driverOptions);
- } catch (\PDOException $exception) {
- throw new PDOException($exception);
+ return $this->stmt->bindParam($column, $variable, $type, $length, $driverOptions);
+ } catch (PDOException $exception) {
+ throw PDOConnection::exceptionFromPDOException($exception);
}
}
@@ -100,75 +91,91 @@ public function bindParam($column, &$variable, $type = ParameterType::STRING, $l
public function closeCursor()
{
try {
- return parent::closeCursor();
- } catch (\PDOException $exception) {
+ return $this->stmt->closeCursor();
+ } catch (PDOException $exception) {
// Exceptions not allowed by the interface.
// In case driver implementations do not adhere to the interface, silence exceptions here.
return true;
}
}
+ /**
+ * {@inheritdoc}
+ */
+ public function columnCount()
+ {
+ return $this->stmt->columnCount();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function errorCode()
+ {
+ return $this->stmt->errorCode();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function errorInfo()
+ {
+ return $this->stmt->errorInfo();
+ }
+
/**
* {@inheritdoc}
*/
public function execute($params = null)
{
try {
- return parent::execute($params);
- } catch (\PDOException $exception) {
- throw new PDOException($exception);
+ return $this->stmt->execute($params);
+ } catch (PDOException $exception) {
+ throw PDOConnection::exceptionFromPDOException($exception);
}
}
/**
* {@inheritdoc}
*/
- public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEXT, $cursorOffset = 0)
+ public function rowCount() : int
+ {
+ return $this->stmt->rowCount();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function fetch($fetchMode = null, ...$args)
{
$fetchMode = $this->convertFetchMode($fetchMode);
try {
- if ($fetchMode === null && $cursorOrientation === PDO::FETCH_ORI_NEXT && $cursorOffset === 0) {
- return parent::fetch();
- }
-
- if ($cursorOrientation === PDO::FETCH_ORI_NEXT && $cursorOffset === 0) {
- return parent::fetch($fetchMode);
- }
-
- if ($cursorOffset === 0) {
- return parent::fetch($fetchMode, $cursorOrientation);
+ if ($fetchMode === null) {
+ return $this->stmt->fetch();
}
- return parent::fetch($fetchMode, $cursorOrientation, $cursorOffset);
- } catch (\PDOException $exception) {
- throw new PDOException($exception);
+ return $this->stmt->fetch($fetchMode, ...$args);
+ } catch (PDOException $exception) {
+ throw PDOConnection::exceptionFromPDOException($exception);
}
}
/**
* {@inheritdoc}
*/
- public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = null)
+ public function fetchAll($fetchMode = null, ...$args)
{
$fetchMode = $this->convertFetchMode($fetchMode);
try {
- if ($fetchMode === null && $fetchArgument === null && $ctorArgs === null) {
- return parent::fetchAll();
- }
-
- if ($fetchArgument === null && $ctorArgs === null) {
- return parent::fetchAll($fetchMode);
+ if ($fetchMode === null) {
+ return $this->stmt->fetchAll();
}
- if ($ctorArgs === null) {
- return parent::fetchAll($fetchMode, $fetchArgument);
- }
-
- return parent::fetchAll($fetchMode, $fetchArgument, $ctorArgs);
- } catch (\PDOException $exception) {
- throw new PDOException($exception);
+ return $this->stmt->fetchAll($fetchMode, ...$args);
+ } catch (PDOException $exception) {
+ throw PDOConnection::exceptionFromPDOException($exception);
}
}
@@ -178,9 +185,9 @@ public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = n
public function fetchColumn($columnIndex = 0)
{
try {
- return parent::fetchColumn($columnIndex);
- } catch (\PDOException $exception) {
- throw new PDOException($exception);
+ return $this->stmt->fetchColumn($columnIndex);
+ } catch (PDOException $exception) {
+ throw PDOConnection::exceptionFromPDOException($exception);
}
}
@@ -228,4 +235,12 @@ private function convertFetchMode(?int $fetchMode) : ?int
return self::FETCH_MODE_MAP[$fetchMode];
}
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getIterator()
+ {
+ yield from $this->stmt;
+ }
}
diff --git a/lib/Doctrine/DBAL/Driver/ResultStatement.php b/lib/Doctrine/DBAL/Driver/ResultStatement.php
index 1e6df0269b8..20deaee46ec 100644
--- a/lib/Doctrine/DBAL/Driver/ResultStatement.php
+++ b/lib/Doctrine/DBAL/Driver/ResultStatement.php
@@ -2,7 +2,6 @@
namespace Doctrine\DBAL\Driver;
-use PDO;
use Traversable;
/**
@@ -29,62 +28,47 @@ public function columnCount();
/**
* Sets the fetch mode to use while iterating this statement.
*
- * @param int $fetchMode The fetch mode must be one of the {@link \Doctrine\DBAL\FetchMode} constants.
- * @param mixed $arg2
- * @param mixed $arg3
+ * @param int $fetchMode Controls how the next row will be returned to the caller.
+ * The value must be one of the {@link \Doctrine\DBAL\FetchMode} constants.
+ * @param mixed[] ...$args Optional mode-specific arguments (see {@link self::fetchAll()}).
*
* @return bool
*/
- public function setFetchMode($fetchMode, $arg2 = null, $arg3 = null);
+ public function setFetchMode($fetchMode, ...$args);
/**
* Returns the next row of a result set.
*
- * @param int|null $fetchMode Controls how the next row will be returned to the caller.
- * The value must be one of the {@link \Doctrine\DBAL\FetchMode} constants,
- * defaulting to {@link \Doctrine\DBAL\FetchMode::MIXED}.
- * @param int $cursorOrientation For a ResultStatement object representing a scrollable cursor,
- * this value determines which row will be returned to the caller.
- * This value must be one of the \PDO::FETCH_ORI_* constants,
- * defaulting to \PDO::FETCH_ORI_NEXT. To request a scrollable
- * cursor for your ResultStatement object, you must set the \PDO::ATTR_CURSOR
- * attribute to \PDO::CURSOR_SCROLL when you prepare the SQL statement with
- * \PDO::prepare().
- * @param int $cursorOffset For a ResultStatement object representing a scrollable cursor for which the
- * cursorOrientation parameter is set to \PDO::FETCH_ORI_ABS, this value
- * specifies the absolute number of the row in the result set that shall be
- * fetched.
- * For a ResultStatement object representing a scrollable cursor for which the
- * cursorOrientation parameter is set to \PDO::FETCH_ORI_REL, this value
- * specifies the row to fetch relative to the cursor position before
- * ResultStatement::fetch() was called.
+ * @param int|null $fetchMode Controls how the next row will be returned to the caller.
+ * The value must be one of the {@link \Doctrine\DBAL\FetchMode} constants,
+ * defaulting to {@link \Doctrine\DBAL\FetchMode::MIXED}.
+ * @param mixed[] ...$args Optional mode-specific arguments (see {@link self::fetchAll()}).
*
* @return mixed The return value of this method on success depends on the fetch mode. In all cases, FALSE is
* returned on failure.
+ *
+ * @throws DriverException If an error occurs.
*/
- public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEXT, $cursorOffset = 0);
+ public function fetch($fetchMode = null, ...$args);
/**
* Returns an array containing all of the result set rows.
*
- * @param int|null $fetchMode Controls how the next row will be returned to the caller.
- * The value must be one of the {@link \Doctrine\DBAL\FetchMode} constants,
- * defaulting to {@link \Doctrine\DBAL\FetchMode::MIXED}.
- * @param int|null $fetchArgument This argument has a different meaning depending on the value of the $fetchMode parameter:
- * * {@link \Doctrine\DBAL\FetchMode::COLUMN}:
- * Returns the indicated 0-indexed column.
- * * {@link \Doctrine\DBAL\FetchMode::CUSTOM_OBJECT}:
- * Returns instances of the specified class, mapping the columns of each row
- * to named properties in the class.
- * * \PDO::FETCH_FUNC: Returns the results of calling the specified function, using each row's
- * columns as parameters in the call.
- * @param mixed[]|null $ctorArgs Controls how the next row will be returned to the caller.
- * The value must be one of the {@link \Doctrine\DBAL\FetchMode} constants,
- * defaulting to {@link \Doctrine\DBAL\FetchMode::MIXED}.
+ * @param int|null $fetchMode Controls how the next row will be returned to the caller.
+ * The value must be one of the {@link \Doctrine\DBAL\FetchMode} constants,
+ * defaulting to {@link \Doctrine\DBAL\FetchMode::MIXED}.
+ * @param mixed[] ...$args Optional mode-specific arguments. Supported modes:
+ * * {@link \Doctrine\DBAL\FetchMode::COLUMN}
+ * 1. The 0-indexed column to be returned.
+ * * {@link \Doctrine\DBAL\FetchMode::CUSTOM_OBJECT}
+ * 1. The classname of the object to be created,
+ * 2. Array of constructor arguments
*
* @return mixed[]
+ *
+ * @throws DriverException If an error occurs.
*/
- public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = null);
+ public function fetchAll($fetchMode = null, ...$args);
/**
* Returns a single column from the next row of a result set or FALSE if there are no more rows.
@@ -93,6 +77,8 @@ public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = n
* If no value is supplied, fetches the first column.
*
* @return mixed|false A single column in the next row of a result set, or FALSE if there are no more rows.
+ *
+ * @throws DriverException If an error occurs.
*/
public function fetchColumn($columnIndex = 0);
}
diff --git a/lib/Doctrine/DBAL/Driver/SQLAnywhere/Driver.php b/lib/Doctrine/DBAL/Driver/SQLAnywhere/Driver.php
index 294d5c7a5e9..de397466f90 100644
--- a/lib/Doctrine/DBAL/Driver/SQLAnywhere/Driver.php
+++ b/lib/Doctrine/DBAL/Driver/SQLAnywhere/Driver.php
@@ -4,6 +4,7 @@
use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Driver\AbstractSQLAnywhereDriver;
+use Doctrine\DBAL\Driver\DriverException;
use function array_keys;
use function array_map;
use function implode;
@@ -33,7 +34,7 @@ public function connect(array $params, $username = null, $password = null, array
),
$params['persistent'] ?? false
);
- } catch (SQLAnywhereException $e) {
+ } catch (DriverException $e) {
throw DBALException::driverException($this, $e);
}
}
diff --git a/lib/Doctrine/DBAL/Driver/SQLAnywhere/SQLAnywhereConnection.php b/lib/Doctrine/DBAL/Driver/SQLAnywhere/SQLAnywhereConnection.php
index 00295a2af1a..73db8f320dc 100644
--- a/lib/Doctrine/DBAL/Driver/SQLAnywhere/SQLAnywhereConnection.php
+++ b/lib/Doctrine/DBAL/Driver/SQLAnywhere/SQLAnywhereConnection.php
@@ -3,10 +3,13 @@
namespace Doctrine\DBAL\Driver\SQLAnywhere;
use Doctrine\DBAL\Driver\Connection;
+use Doctrine\DBAL\Driver\DriverException;
+use Doctrine\DBAL\Driver\ResultStatement;
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
+use Doctrine\DBAL\Driver\Statement as DriverStatement;
use Doctrine\DBAL\ParameterType;
+use InvalidArgumentException;
use function assert;
-use function func_get_args;
use function is_float;
use function is_int;
use function is_resource;
@@ -37,41 +40,39 @@ class SQLAnywhereConnection implements Connection, ServerInfoAwareConnection
* @param string $dsn The connection string.
* @param bool $persistent Whether or not to establish a persistent connection.
*
- * @throws SQLAnywhereException
+ * @throws DriverException
*/
public function __construct($dsn, $persistent = false)
{
$this->connection = $persistent ? @sasql_pconnect($dsn) : @sasql_connect($dsn);
if (! is_resource($this->connection)) {
- throw SQLAnywhereException::fromSQLAnywhereError();
+ throw self::exceptionFromSQLAnywhereError();
}
// Disable PHP warnings on error.
if (! sasql_set_option($this->connection, 'verbose_errors', false)) {
- throw SQLAnywhereException::fromSQLAnywhereError($this->connection);
+ throw self::exceptionFromSQLAnywhereError($this->connection);
}
// Enable auto committing by default.
if (! sasql_set_option($this->connection, 'auto_commit', 'on')) {
- throw SQLAnywhereException::fromSQLAnywhereError($this->connection);
+ throw self::exceptionFromSQLAnywhereError($this->connection);
}
// Enable exact, non-approximated row count retrieval.
if (! sasql_set_option($this->connection, 'row_counts', true)) {
- throw SQLAnywhereException::fromSQLAnywhereError($this->connection);
+ throw self::exceptionFromSQLAnywhereError($this->connection);
}
}
/**
* {@inheritdoc}
- *
- * @throws SQLAnywhereException
*/
public function beginTransaction()
{
if (! sasql_set_option($this->connection, 'auto_commit', 'off')) {
- throw SQLAnywhereException::fromSQLAnywhereError($this->connection);
+ throw self::exceptionFromSQLAnywhereError($this->connection);
}
return true;
@@ -79,13 +80,11 @@ public function beginTransaction()
/**
* {@inheritdoc}
- *
- * @throws SQLAnywhereException
*/
public function commit()
{
if (! sasql_commit($this->connection)) {
- throw SQLAnywhereException::fromSQLAnywhereError($this->connection);
+ throw self::exceptionFromSQLAnywhereError($this->connection);
}
$this->endTransaction();
@@ -112,10 +111,10 @@ public function errorInfo()
/**
* {@inheritdoc}
*/
- public function exec($statement)
+ public function exec(string $statement) : int
{
if (sasql_real_query($this->connection, $statement) === false) {
- throw SQLAnywhereException::fromSQLAnywhereError($this->connection);
+ throw self::exceptionFromSQLAnywhereError($this->connection);
}
return sasql_affected_rows($this->connection);
@@ -148,19 +147,17 @@ public function lastInsertId($name = null)
/**
* {@inheritdoc}
*/
- public function prepare($prepareString)
+ public function prepare(string $sql) : DriverStatement
{
- return new SQLAnywhereStatement($this->connection, $prepareString);
+ return new SQLAnywhereStatement($this->connection, $sql);
}
/**
* {@inheritdoc}
*/
- public function query()
+ public function query(string $sql) : ResultStatement
{
- $args = func_get_args();
- $stmt = $this->prepare($args[0]);
-
+ $stmt = $this->prepare($sql);
$stmt->execute();
return $stmt;
@@ -188,13 +185,11 @@ public function requiresQueryForServerVersion()
/**
* {@inheritdoc}
- *
- * @throws SQLAnywhereException
*/
public function rollBack()
{
if (! sasql_rollback($this->connection)) {
- throw SQLAnywhereException::fromSQLAnywhereError($this->connection);
+ throw self::exceptionFromSQLAnywhereError($this->connection);
}
$this->endTransaction();
@@ -207,14 +202,74 @@ public function rollBack()
*
* @return bool Whether or not ending transactional mode succeeded.
*
- * @throws SQLAnywhereException
+ * @throws DriverException
*/
private function endTransaction()
{
if (! sasql_set_option($this->connection, 'auto_commit', 'on')) {
- throw SQLAnywhereException::fromSQLAnywhereError($this->connection);
+ throw self::exceptionFromSQLAnywhereError($this->connection);
}
return true;
}
+
+ /**
+ * Helper method to turn SQL Anywhere error into exception.
+ *
+ * @param resource|null $conn The SQL Anywhere connection resource to retrieve the last error from.
+ * @param resource|null $stmt The SQL Anywhere statement resource to retrieve the last error from.
+ *
+ * @throws InvalidArgumentException
+ */
+ public static function exceptionFromSQLAnywhereError($conn = null, $stmt = null) : DriverException
+ {
+ if ($conn !== null && ! is_resource($conn)) {
+ throw new InvalidArgumentException('Invalid SQL Anywhere connection resource given: ' . $conn);
+ }
+
+ if ($stmt !== null && ! is_resource($stmt)) {
+ throw new InvalidArgumentException('Invalid SQL Anywhere statement resource given: ' . $stmt);
+ }
+
+ $state = $conn ? sasql_sqlstate($conn) : sasql_sqlstate();
+ $code = null;
+ $message = null;
+
+ /**
+ * Try retrieving the last error from statement resource if given
+ */
+ if ($stmt) {
+ $code = sasql_stmt_errno($stmt);
+ $message = sasql_stmt_error($stmt);
+ }
+
+ /**
+ * Try retrieving the last error from the connection resource
+ * if either the statement resource is not given or the statement
+ * resource is given but the last error could not be retrieved from it (fallback).
+ * Depending on the type of error, it is sometimes necessary to retrieve
+ * it from the connection resource even though it occurred during
+ * a prepared statement.
+ */
+ if ($conn && ! $code) {
+ $code = sasql_errorcode($conn);
+ $message = sasql_error($conn);
+ }
+
+ /**
+ * Fallback mode if either no connection resource is given
+ * or the last error could not be retrieved from the given
+ * connection / statement resource.
+ */
+ if (! $conn || ! $code) {
+ $code = sasql_errorcode();
+ $message = sasql_error();
+ }
+
+ if ($message) {
+ return new DriverException('SQLSTATE [' . $state . '] [' . $code . '] ' . $message, $state, $code);
+ }
+
+ return new DriverException('SQL Anywhere error occurred but no error message was retrieved from driver.', $state, $code);
+ }
}
diff --git a/lib/Doctrine/DBAL/Driver/SQLAnywhere/SQLAnywhereException.php b/lib/Doctrine/DBAL/Driver/SQLAnywhere/SQLAnywhereException.php
deleted file mode 100644
index 9f8aac0608d..00000000000
--- a/lib/Doctrine/DBAL/Driver/SQLAnywhere/SQLAnywhereException.php
+++ /dev/null
@@ -1,80 +0,0 @@
-conn = $conn;
$this->stmt = sasql_prepare($conn, $sql);
if (! is_resource($this->stmt)) {
- throw SQLAnywhereException::fromSQLAnywhereError($conn);
+ throw SQLAnywhereConnection::exceptionFromSQLAnywhereError($conn);
}
}
/**
* {@inheritdoc}
*
- * @throws SQLAnywhereException
+ * @throws DriverException
*/
public function bindParam($column, &$variable, $type = ParameterType::STRING, $length = null)
{
@@ -105,11 +105,11 @@ public function bindParam($column, &$variable, $type = ParameterType::STRING, $l
break;
default:
- throw new SQLAnywhereException('Unknown type: ' . $type);
+ throw new DriverException('Unknown type: ' . $type);
}
if (! sasql_stmt_bind_param_ex($this->stmt, $column - 1, $variable, $type, $variable === null)) {
- throw SQLAnywhereException::fromSQLAnywhereError($this->conn, $this->stmt);
+ throw SQLAnywhereConnection::exceptionFromSQLAnywhereError($this->conn, $this->stmt);
}
return true;
@@ -126,12 +126,12 @@ public function bindValue($param, $value, $type = ParameterType::STRING)
/**
* {@inheritdoc}
*
- * @throws SQLAnywhereException
+ * @throws DriverException
*/
public function closeCursor()
{
if (! sasql_stmt_reset($this->stmt)) {
- throw SQLAnywhereException::fromSQLAnywhereError($this->conn, $this->stmt);
+ throw SQLAnywhereConnection::exceptionFromSQLAnywhereError($this->conn, $this->stmt);
}
return true;
@@ -164,7 +164,7 @@ public function errorInfo()
/**
* {@inheritdoc}
*
- * @throws SQLAnywhereException
+ * @throws DriverException
*/
public function execute($params = null)
{
@@ -179,7 +179,7 @@ public function execute($params = null)
}
if (! sasql_stmt_execute($this->stmt)) {
- throw SQLAnywhereException::fromSQLAnywhereError($this->conn, $this->stmt);
+ throw SQLAnywhereConnection::exceptionFromSQLAnywhereError($this->conn, $this->stmt);
}
$this->result = sasql_stmt_result_metadata($this->stmt);
@@ -190,9 +190,9 @@ public function execute($params = null)
/**
* {@inheritdoc}
*
- * @throws SQLAnywhereException
+ * @throws DriverException
*/
- public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEXT, $cursorOffset = 0)
+ public function fetch($fetchMode = null, ...$args)
{
if (! is_resource($this->result)) {
return false;
@@ -214,10 +214,9 @@ public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEX
$className = $this->defaultFetchClass;
$ctorArgs = $this->defaultFetchClassCtorArgs;
- if (func_num_args() >= 2) {
- $args = func_get_args();
- $className = $args[1];
- $ctorArgs = $args[2] ?? [];
+ if (count($args) > 0) {
+ $className = $args[0];
+ $ctorArgs = $args[1] ?? [];
}
$result = sasql_fetch_object($this->result);
@@ -235,32 +234,32 @@ public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEX
return sasql_fetch_object($this->result);
default:
- throw new SQLAnywhereException('Fetch mode is not supported: ' . $fetchMode);
+ throw new DriverException('Fetch mode is not supported: ' . $fetchMode);
}
}
/**
* {@inheritdoc}
*/
- public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = null)
+ public function fetchAll($fetchMode = null, ...$args)
{
$rows = [];
switch ($fetchMode) {
case FetchMode::CUSTOM_OBJECT:
- while ($row = $this->fetch(...func_get_args())) {
+ while (($row = $this->fetch(...func_get_args())) !== false) {
$rows[] = $row;
}
break;
case FetchMode::COLUMN:
- while ($row = $this->fetchColumn()) {
+ while (($row = $this->fetchColumn()) !== false) {
$rows[] = $row;
}
break;
default:
- while ($row = $this->fetch($fetchMode)) {
+ while (($row = $this->fetch($fetchMode)) !== false) {
$rows[] = $row;
}
}
@@ -293,7 +292,7 @@ public function getIterator()
/**
* {@inheritdoc}
*/
- public function rowCount()
+ public function rowCount() : int
{
return sasql_stmt_affected_rows($this->stmt);
}
@@ -301,11 +300,19 @@ public function rowCount()
/**
* {@inheritdoc}
*/
- public function setFetchMode($fetchMode, $arg2 = null, $arg3 = null)
+ public function setFetchMode($fetchMode, ...$args)
{
- $this->defaultFetchMode = $fetchMode;
- $this->defaultFetchClass = $arg2 ?: $this->defaultFetchClass;
- $this->defaultFetchClassCtorArgs = $arg3 ? (array) $arg3 : $this->defaultFetchClassCtorArgs;
+ $this->defaultFetchMode = $fetchMode;
+
+ if (isset($args[0])) {
+ $this->defaultFetchClass = $args[0];
+ }
+
+ if (! isset($args[1])) {
+ return;
+ }
+
+ $this->defaultFetchClassCtorArgs = (array) $args[1];
}
/**
@@ -317,13 +324,13 @@ public function setFetchMode($fetchMode, $arg2 = null, $arg3 = null)
*
* @return object
*
- * @throws SQLAnywhereException
+ * @throws DriverException
*/
private function castObject(stdClass $sourceObject, $destinationClass, array $ctorArgs = [])
{
if (! is_string($destinationClass)) {
if (! is_object($destinationClass)) {
- throw new SQLAnywhereException(sprintf(
+ throw new DriverException(sprintf(
'Destination class has to be of type string or object, %s given.',
gettype($destinationClass)
));
diff --git a/lib/Doctrine/DBAL/Driver/SQLSrv/Driver.php b/lib/Doctrine/DBAL/Driver/SQLSrv/Driver.php
index a9be26e9dea..c71b014be6b 100644
--- a/lib/Doctrine/DBAL/Driver/SQLSrv/Driver.php
+++ b/lib/Doctrine/DBAL/Driver/SQLSrv/Driver.php
@@ -3,6 +3,7 @@
namespace Doctrine\DBAL\Driver\SQLSrv;
use Doctrine\DBAL\Driver\AbstractSQLServerDriver;
+use Doctrine\DBAL\Driver\DriverException;
/**
* Driver for ext/sqlsrv.
@@ -15,7 +16,7 @@ class Driver extends AbstractSQLServerDriver
public function connect(array $params, $username = null, $password = null, array $driverOptions = [])
{
if (! isset($params['host'])) {
- throw new SQLSrvException("Missing 'host' in configuration for sqlsrv driver.");
+ throw new DriverException("Missing 'host' in configuration for sqlsrv driver.");
}
$serverName = $params['host'];
diff --git a/lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvConnection.php b/lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvConnection.php
index f1f9ddd1d79..f5ddf1c835e 100644
--- a/lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvConnection.php
+++ b/lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvConnection.php
@@ -3,12 +3,15 @@
namespace Doctrine\DBAL\Driver\SQLSrv;
use Doctrine\DBAL\Driver\Connection;
+use Doctrine\DBAL\Driver\DriverException;
+use Doctrine\DBAL\Driver\ResultStatement;
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
+use Doctrine\DBAL\Driver\Statement as DriverStatement;
use Doctrine\DBAL\ParameterType;
use const SQLSRV_ERR_ERRORS;
-use function func_get_args;
use function is_float;
use function is_int;
+use function rtrim;
use function sprintf;
use function sqlsrv_begin_transaction;
use function sqlsrv_commit;
@@ -36,17 +39,17 @@ class SQLSrvConnection implements Connection, ServerInfoAwareConnection
* @param string $serverName
* @param mixed[] $connectionOptions
*
- * @throws SQLSrvException
+ * @throws DriverException
*/
public function __construct($serverName, $connectionOptions)
{
if (! sqlsrv_configure('WarningsReturnAsErrors', 0)) {
- throw SQLSrvException::fromSqlSrvErrors();
+ throw self::exceptionFromSqlSrvErrors();
}
$this->conn = sqlsrv_connect($serverName, $connectionOptions);
if (! $this->conn) {
- throw SQLSrvException::fromSqlSrvErrors();
+ throw self::exceptionFromSqlSrvErrors();
}
$this->lastInsertId = new LastInsertId();
}
@@ -72,7 +75,7 @@ public function requiresQueryForServerVersion()
/**
* {@inheritDoc}
*/
- public function prepare($sql)
+ public function prepare(string $sql) : DriverStatement
{
return new SQLSrvStatement($this->conn, $sql, $this->lastInsertId);
}
@@ -80,10 +83,8 @@ public function prepare($sql)
/**
* {@inheritDoc}
*/
- public function query()
+ public function query(string $sql) : ResultStatement
{
- $args = func_get_args();
- $sql = $args[0];
$stmt = $this->prepare($sql);
$stmt->execute();
@@ -107,12 +108,12 @@ public function quote($value, $type = ParameterType::STRING)
/**
* {@inheritDoc}
*/
- public function exec($statement)
+ public function exec(string $statement) : int
{
$stmt = sqlsrv_query($this->conn, $statement);
if ($stmt === false) {
- throw SQLSrvException::fromSqlSrvErrors();
+ throw self::exceptionFromSqlSrvErrors();
}
return sqlsrv_rows_affected($stmt);
@@ -139,7 +140,7 @@ public function lastInsertId($name = null)
public function beginTransaction()
{
if (! sqlsrv_begin_transaction($this->conn)) {
- throw SQLSrvException::fromSqlSrvErrors();
+ throw self::exceptionFromSqlSrvErrors();
}
}
@@ -149,7 +150,7 @@ public function beginTransaction()
public function commit()
{
if (! sqlsrv_commit($this->conn)) {
- throw SQLSrvException::fromSqlSrvErrors();
+ throw self::exceptionFromSqlSrvErrors();
}
}
@@ -159,7 +160,7 @@ public function commit()
public function rollBack()
{
if (! sqlsrv_rollback($this->conn)) {
- throw SQLSrvException::fromSqlSrvErrors();
+ throw self::exceptionFromSqlSrvErrors();
}
}
@@ -183,4 +184,34 @@ public function errorInfo()
{
return sqlsrv_errors(SQLSRV_ERR_ERRORS);
}
+
+ /**
+ * Helper method to turn sql server errors into exception.
+ */
+ public static function exceptionFromSqlSrvErrors() : DriverException
+ {
+ $errors = sqlsrv_errors(SQLSRV_ERR_ERRORS);
+ $message = '';
+ $sqlState = null;
+ $errorCode = null;
+
+ foreach ($errors as $error) {
+ $message .= 'SQLSTATE [' . $error['SQLSTATE'] . ', ' . $error['code'] . ']: ' . $error['message'] . "\n";
+
+ if ($sqlState === null) {
+ $sqlState = $error['SQLSTATE'];
+ }
+
+ if ($errorCode !== null) {
+ continue;
+ }
+
+ $errorCode = $error['code'];
+ }
+ if (! $message) {
+ $message = 'SQL Server error occurred but no error message was retrieved from driver.';
+ }
+
+ return new DriverException(rtrim($message), $sqlState, $errorCode);
+ }
}
diff --git a/lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvException.php b/lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvException.php
deleted file mode 100644
index 796f5d129d4..00000000000
--- a/lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvException.php
+++ /dev/null
@@ -1,43 +0,0 @@
-variables[$column] =& $variable;
@@ -242,7 +241,7 @@ public function execute($params = null)
}
if (! sqlsrv_execute($this->stmt)) {
- throw SQLSrvException::fromSqlSrvErrors();
+ throw SQLSrvConnection::exceptionFromSqlSrvErrors();
}
if ($this->lastInsertId) {
@@ -259,7 +258,7 @@ public function execute($params = null)
*
* @return resource
*
- * @throws SQLSrvException
+ * @throws DriverException
*/
private function prepare()
{
@@ -293,7 +292,7 @@ private function prepare()
$stmt = sqlsrv_prepare($this->conn, $this->sql, $params);
if (! $stmt) {
- throw SQLSrvException::fromSqlSrvErrors();
+ throw SQLSrvConnection::exceptionFromSqlSrvErrors();
}
return $stmt;
@@ -302,11 +301,17 @@ private function prepare()
/**
* {@inheritdoc}
*/
- public function setFetchMode($fetchMode, $arg2 = null, $arg3 = null)
+ public function setFetchMode($fetchMode, ...$args)
{
- $this->defaultFetchMode = $fetchMode;
- $this->defaultFetchClass = $arg2 ?: $this->defaultFetchClass;
- $this->defaultFetchClassCtorArgs = $arg3 ? (array) $arg3 : $this->defaultFetchClassCtorArgs;
+ $this->defaultFetchMode = $fetchMode;
+
+ if (isset($args[0])) {
+ $this->defaultFetchClass = $args[0];
+ }
+
+ if (isset($args[1])) {
+ $this->defaultFetchClassCtorArgs = (array) $args[1];
+ }
return true;
}
@@ -322,9 +327,9 @@ public function getIterator()
/**
* {@inheritdoc}
*
- * @throws SQLSrvException
+ * @throws DriverException
*/
- public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEXT, $cursorOffset = 0)
+ public function fetch($fetchMode = null, ...$args)
{
// do not try fetching from the statement if it's not expected to contain result
// in order to prevent exceptional situation
@@ -332,7 +337,6 @@ public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEX
return false;
}
- $args = func_get_args();
$fetchMode = $fetchMode ?: $this->defaultFetchMode;
if ($fetchMode === FetchMode::COLUMN) {
@@ -347,27 +351,27 @@ public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEX
$className = $this->defaultFetchClass;
$ctorArgs = $this->defaultFetchClassCtorArgs;
- if (count($args) >= 2) {
- $className = $args[1];
- $ctorArgs = $args[2] ?? [];
+ if (count($args) > 0) {
+ $className = $args[0];
+ $ctorArgs = $args[1] ?? [];
}
return sqlsrv_fetch_object($this->stmt, $className, $ctorArgs) ?: false;
}
- throw new SQLSrvException('Fetch mode is not supported!');
+ throw new DriverException('Fetch mode is not supported!');
}
/**
* {@inheritdoc}
*/
- public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = null)
+ public function fetchAll($fetchMode = null, ...$args)
{
$rows = [];
switch ($fetchMode) {
case FetchMode::CUSTOM_OBJECT:
- while (($row = $this->fetch(...func_get_args())) !== false) {
+ while (($row = $this->fetch($fetchMode, ...$args)) !== false) {
$rows[] = $row;
}
break;
@@ -404,7 +408,7 @@ public function fetchColumn($columnIndex = 0)
/**
* {@inheritdoc}
*/
- public function rowCount()
+ public function rowCount() : int
{
return sqlsrv_rows_affected($this->stmt);
}
diff --git a/lib/Doctrine/DBAL/Driver/Statement.php b/lib/Doctrine/DBAL/Driver/Statement.php
index a3ea74a4df5..b859740bd6b 100644
--- a/lib/Doctrine/DBAL/Driver/Statement.php
+++ b/lib/Doctrine/DBAL/Driver/Statement.php
@@ -49,8 +49,7 @@ public function bindValue($param, $value, $type = ParameterType::STRING);
* question mark placeholders, this will be the 1-indexed position of the parameter.
* @param mixed $variable Name of the PHP variable to bind to the SQL statement parameter.
* @param int|null $type Explicit data type for the parameter using the {@link \Doctrine\DBAL\ParameterType}
- * constants. To return an INOUT parameter from a stored procedure, use the bitwise
- * OR operator to set the PDO::PARAM_INPUT_OUTPUT bits for the data_type parameter.
+ * constants.
* @param int|null $length You must specify maxlength when using an OUT bind
* so that PHP allocates enough memory to hold the returned value.
*
@@ -101,5 +100,5 @@ public function execute($params = null);
*
* @return int The number of rows.
*/
- public function rowCount();
+ public function rowCount() : int;
}
diff --git a/lib/Doctrine/DBAL/DriverManager.php b/lib/Doctrine/DBAL/DriverManager.php
index 658123199c0..2f599015d62 100644
--- a/lib/Doctrine/DBAL/DriverManager.php
+++ b/lib/Doctrine/DBAL/DriverManager.php
@@ -3,7 +3,6 @@
namespace Doctrine\DBAL;
use Doctrine\Common\EventManager;
-use Doctrine\DBAL\Driver\DrizzlePDOMySql\Driver as DrizzlePDOMySQLDriver;
use Doctrine\DBAL\Driver\IBMDB2\DB2Driver;
use Doctrine\DBAL\Driver\Mysqli\Driver as MySQLiDriver;
use Doctrine\DBAL\Driver\OCI8\Driver as OCI8Driver;
@@ -42,17 +41,16 @@ final class DriverManager
* @var string[]
*/
private static $_driverMap = [
- 'pdo_mysql' => PDOMySQLDriver::class,
- 'pdo_sqlite' => PDOSQLiteDriver::class,
- 'pdo_pgsql' => PDOPgSQLDriver::class,
- 'pdo_oci' => PDOOCIDriver::class,
- 'oci8' => OCI8Driver::class,
- 'ibm_db2' => DB2Driver::class,
- 'pdo_sqlsrv' => PDOSQLSrvDriver::class,
- 'mysqli' => MySQLiDriver::class,
- 'drizzle_pdo_mysql' => DrizzlePDOMySQLDriver::class,
- 'sqlanywhere' => SQLAnywhereDriver::class,
- 'sqlsrv' => SQLSrvDriver::class,
+ 'pdo_mysql' => PDOMySQLDriver::class,
+ 'pdo_sqlite' => PDOSQLiteDriver::class,
+ 'pdo_pgsql' => PDOPgSQLDriver::class,
+ 'pdo_oci' => PDOOCIDriver::class,
+ 'oci8' => OCI8Driver::class,
+ 'ibm_db2' => DB2Driver::class,
+ 'pdo_sqlsrv' => PDOSQLSrvDriver::class,
+ 'mysqli' => MySQLiDriver::class,
+ 'sqlanywhere' => SQLAnywhereDriver::class,
+ 'sqlsrv' => SQLSrvDriver::class,
];
/**
@@ -98,7 +96,6 @@ private function __construct()
* sqlanywhere
* sqlsrv
* ibm_db2 (unstable)
- * drizzle_pdo_mysql
*
* OR 'driverClass' that contains the full class name (with namespace) of the
* driver class to instantiate.
diff --git a/lib/Doctrine/DBAL/FetchMode.php b/lib/Doctrine/DBAL/FetchMode.php
index b3fe42f4ceb..65af014f1e0 100644
--- a/lib/Doctrine/DBAL/FetchMode.php
+++ b/lib/Doctrine/DBAL/FetchMode.php
@@ -2,8 +2,6 @@
namespace Doctrine\DBAL;
-use PDO;
-
/**
* Contains statement fetch modes.
*/
@@ -17,7 +15,7 @@ final class FetchMode
*
* @see \PDO::FETCH_ASSOC
*/
- public const ASSOCIATIVE = PDO::FETCH_ASSOC;
+ public const ASSOCIATIVE = 2;
/**
* Specifies that the fetch method shall return each row as an array indexed
@@ -26,7 +24,7 @@ final class FetchMode
*
* @see \PDO::FETCH_NUM
*/
- public const NUMERIC = PDO::FETCH_NUM;
+ public const NUMERIC = 3;
/**
* Specifies that the fetch method shall return each row as an array indexed
@@ -35,7 +33,7 @@ final class FetchMode
*
* @see \PDO::FETCH_BOTH
*/
- public const MIXED = PDO::FETCH_BOTH;
+ public const MIXED = 4;
/**
* Specifies that the fetch method shall return each row as an object with
@@ -44,7 +42,7 @@ final class FetchMode
*
* @see \PDO::FETCH_OBJ
*/
- public const STANDARD_OBJECT = PDO::FETCH_OBJ;
+ public const STANDARD_OBJECT = 5;
/**
* Specifies that the fetch method shall return only a single requested
@@ -52,7 +50,7 @@ final class FetchMode
*
* @see \PDO::FETCH_COLUMN
*/
- public const COLUMN = PDO::FETCH_COLUMN;
+ public const COLUMN = 7;
/**
* Specifies that the fetch method shall return a new instance of the
@@ -60,7 +58,7 @@ final class FetchMode
*
* @see \PDO::FETCH_CLASS
*/
- public const CUSTOM_OBJECT = PDO::FETCH_CLASS;
+ public const CUSTOM_OBJECT = 8;
/**
* This class cannot be instantiated.
diff --git a/lib/Doctrine/DBAL/Logging/DebugStack.php b/lib/Doctrine/DBAL/Logging/DebugStack.php
index e1ccaad6ba0..bd1358f321d 100644
--- a/lib/Doctrine/DBAL/Logging/DebugStack.php
+++ b/lib/Doctrine/DBAL/Logging/DebugStack.php
@@ -7,7 +7,7 @@
/**
* Includes executed SQLs in a Debug Stack.
*/
-class DebugStack implements SQLLogger
+final class DebugStack implements SQLLogger
{
/**
* Executed SQL queries.
@@ -32,7 +32,7 @@ class DebugStack implements SQLLogger
/**
* {@inheritdoc}
*/
- public function startQuery($sql, ?array $params = null, ?array $types = null)
+ public function startQuery(string $sql, array $params = [], array $types = []) : void
{
if (! $this->enabled) {
return;
@@ -45,7 +45,7 @@ public function startQuery($sql, ?array $params = null, ?array $types = null)
/**
* {@inheritdoc}
*/
- public function stopQuery()
+ public function stopQuery() : void
{
if (! $this->enabled) {
return;
diff --git a/lib/Doctrine/DBAL/Logging/EchoSQLLogger.php b/lib/Doctrine/DBAL/Logging/EchoSQLLogger.php
index 657abb4d378..cfca9dd7c90 100644
--- a/lib/Doctrine/DBAL/Logging/EchoSQLLogger.php
+++ b/lib/Doctrine/DBAL/Logging/EchoSQLLogger.php
@@ -8,12 +8,12 @@
/**
* A SQL logger that logs to the standard output using echo/var_dump.
*/
-class EchoSQLLogger implements SQLLogger
+final class EchoSQLLogger implements SQLLogger
{
/**
* {@inheritdoc}
*/
- public function startQuery($sql, ?array $params = null, ?array $types = null)
+ public function startQuery(string $sql, array $params = [], array $types = []) : void
{
echo $sql . PHP_EOL;
@@ -31,7 +31,7 @@ public function startQuery($sql, ?array $params = null, ?array $types = null)
/**
* {@inheritdoc}
*/
- public function stopQuery()
+ public function stopQuery() : void
{
}
}
diff --git a/lib/Doctrine/DBAL/Logging/LoggerChain.php b/lib/Doctrine/DBAL/Logging/LoggerChain.php
index 2b5404b25c7..226faae83da 100644
--- a/lib/Doctrine/DBAL/Logging/LoggerChain.php
+++ b/lib/Doctrine/DBAL/Logging/LoggerChain.php
@@ -5,17 +5,15 @@
/**
* Chains multiple SQLLogger.
*/
-class LoggerChain implements SQLLogger
+final class LoggerChain implements SQLLogger
{
/** @var SQLLogger[] */
private $loggers = [];
/**
* Adds a logger in the chain.
- *
- * @return void
*/
- public function addLogger(SQLLogger $logger)
+ public function addLogger(SQLLogger $logger) : void
{
$this->loggers[] = $logger;
}
@@ -23,7 +21,7 @@ public function addLogger(SQLLogger $logger)
/**
* {@inheritdoc}
*/
- public function startQuery($sql, ?array $params = null, ?array $types = null)
+ public function startQuery(string $sql, array $params = [], array $types = []) : void
{
foreach ($this->loggers as $logger) {
$logger->startQuery($sql, $params, $types);
@@ -33,7 +31,7 @@ public function startQuery($sql, ?array $params = null, ?array $types = null)
/**
* {@inheritdoc}
*/
- public function stopQuery()
+ public function stopQuery() : void
{
foreach ($this->loggers as $logger) {
$logger->stopQuery();
diff --git a/lib/Doctrine/DBAL/Logging/NullLogger.php b/lib/Doctrine/DBAL/Logging/NullLogger.php
new file mode 100644
index 00000000000..3a925f13ca0
--- /dev/null
+++ b/lib/Doctrine/DBAL/Logging/NullLogger.php
@@ -0,0 +1,25 @@
+getBinaryMaxLength();
-
- if ($field['length'] > $maxLength) {
- if ($maxLength > 0) {
- @trigger_error(sprintf(
- 'Binary field length %d is greater than supported by the platform (%d). Reduce the field length or use a BLOB field instead.',
- $field['length'],
- $maxLength
- ), E_USER_DEPRECATED);
- }
-
- return $this->getBlobTypeDeclarationSQL($field);
- }
-
return $this->getBinaryTypeDeclarationSQLSnippet($field['length'], $fixed);
}
@@ -631,20 +614,6 @@ public function getRegexpExpression()
throw DBALException::notSupported(__METHOD__);
}
- /**
- * Returns the global unique identifier expression.
- *
- * @deprecated Use application-generated UUIDs instead
- *
- * @return string
- *
- * @throws DBALException If not supported on this platform.
- */
- public function getGuidExpression()
- {
- throw DBALException::notSupported(__METHOD__);
- }
-
/**
* Returns the SQL snippet to get the average value of a column.
*
@@ -1534,15 +1503,30 @@ public function getCreateTableSQL(Table $table, $createFlags = self::CREATE_INDE
$options['indexes'] = [];
$options['primary'] = [];
- if (($createFlags&self::CREATE_INDEXES) > 0) {
+ if (($createFlags & self::CREATE_INDEXES) > 0) {
foreach ($table->getIndexes() as $index) {
/** @var $index Index */
- if ($index->isPrimary()) {
- $options['primary'] = $index->getQuotedColumns($this);
- $options['primary_index'] = $index;
- } else {
+ if (! $index->isPrimary()) {
$options['indexes'][$index->getQuotedName($this)] = $index;
+
+ continue;
}
+
+ $options['primary'] = $index->getQuotedColumns($this);
+ $options['primary_index'] = $index;
+ }
+
+ foreach ($table->getUniqueConstraints() as $uniqueConstraint) {
+ /** @var UniqueConstraint $uniqueConstraint */
+ $options['uniqueConstraints'][$uniqueConstraint->getQuotedName($this)] = $uniqueConstraint;
+ }
+ }
+
+ if (($createFlags & self::CREATE_FOREIGNKEYS) > 0) {
+ $options['foreignKeys'] = [];
+
+ foreach ($table->getForeignKeys() as $fkConstraint) {
+ $options['foreignKeys'][] = $fkConstraint;
}
}
@@ -1551,7 +1535,6 @@ public function getCreateTableSQL(Table $table, $createFlags = self::CREATE_INDE
foreach ($table->getColumns() as $column) {
/** @var Column $column */
-
if ($this->_eventManager !== null && $this->_eventManager->hasListeners(Events::onSchemaCreateTableColumn)) {
$eventArgs = new SchemaCreateTableColumnEventArgs($column, $table, $this);
$this->_eventManager->dispatchEvent(Events::onSchemaCreateTableColumn, $eventArgs);
@@ -1579,13 +1562,6 @@ public function getCreateTableSQL(Table $table, $createFlags = self::CREATE_INDE
$columns[$columnData['name']] = $columnData;
}
- if (($createFlags&self::CREATE_FOREIGNKEYS) > 0) {
- $options['foreignKeys'] = [];
- foreach ($table->getForeignKeys() as $fkConstraint) {
- $options['foreignKeys'][] = $fkConstraint;
- }
- }
-
if ($this->_eventManager !== null && $this->_eventManager->hasListeners(Events::onSchemaCreateTable)) {
$eventArgs = new SchemaCreateTableEventArgs($table, $columns, $options, $this);
$this->_eventManager->dispatchEvent(Events::onSchemaCreateTable, $eventArgs);
@@ -2330,25 +2306,33 @@ public function getCheckDeclarationSQL(array $definition)
* Obtains DBMS specific SQL code portion needed to set a unique
* constraint declaration to be used in statements like CREATE TABLE.
*
- * @param string $name The name of the unique constraint.
- * @param Index $index The index definition.
+ * @param string $name The name of the unique constraint.
+ * @param UniqueConstraint $constraint The unique constraint definition.
*
* @return string DBMS specific SQL code portion needed to set a constraint.
*
* @throws InvalidArgumentException
*/
- public function getUniqueConstraintDeclarationSQL($name, Index $index)
+ public function getUniqueConstraintDeclarationSQL($name, UniqueConstraint $constraint)
{
- $columns = $index->getColumns();
+ $columns = $constraint->getColumns();
$name = new Identifier($name);
if (count($columns) === 0) {
throw new InvalidArgumentException("Incomplete definition. 'columns' required.");
}
- return 'CONSTRAINT ' . $name->getQuotedName($this) . ' UNIQUE ('
- . $this->getIndexFieldDeclarationListSQL($index)
- . ')' . $this->getPartialIndexSQL($index);
+ $flags = ['UNIQUE'];
+
+ if ($constraint->hasFlag('clustered')) {
+ $flags[] = 'CLUSTERED';
+ }
+
+ $constraintName = $name->getQuotedName($this);
+ $constraintName = ! empty($constraintName) ? $constraintName . ' ' : '';
+ $columnListNames = $this->getIndexFieldDeclarationListSQL($columns);
+
+ return sprintf('CONSTRAINT %s%s (%s)', $constraintName, implode(' ', $flags), $columnListNames);
}
/**
@@ -3044,6 +3028,26 @@ public function usesSequenceEmulatedIdentityColumns()
return false;
}
+ /**
+ * Gets the sequence name prefix based on table information.
+ *
+ * @param string $tableName
+ * @param string|null $schemaName
+ *
+ * @return string
+ */
+ public function getSequencePrefix($tableName, $schemaName = null)
+ {
+ if (! $schemaName) {
+ return $tableName;
+ }
+
+ // Prepend the schema name to the table name if there is one
+ return ! $this->supportsSchemas() && $this->canEmulateSchemas()
+ ? $schemaName . '__' . $tableName
+ : $schemaName . '.' . $tableName;
+ }
+
/**
* Returns the name of the sequence for a particular identity column in a particular table.
*
@@ -3334,22 +3338,10 @@ public function getTimeFormatString()
/**
* Adds an driver-specific LIMIT clause to the query.
*
- * @param string $query
- * @param int|null $limit
- * @param int|null $offset
- *
- * @return string
- *
* @throws DBALException
*/
- final public function modifyLimitQuery($query, $limit, $offset = null)
+ final public function modifyLimitQuery(string $query, ?int $limit, int $offset = 0) : string
{
- if ($limit !== null) {
- $limit = (int) $limit;
- }
-
- $offset = (int) $offset;
-
if ($offset < 0) {
throw new DBALException(sprintf(
'Offset must be a positive integer or zero, %d given',
@@ -3369,21 +3361,15 @@ final public function modifyLimitQuery($query, $limit, $offset = null)
/**
* Adds an platform-specific LIMIT clause to the query.
- *
- * @param string $query
- * @param int|null $limit
- * @param int|null $offset
- *
- * @return string
*/
- protected function doModifyLimitQuery($query, $limit, $offset)
+ protected function doModifyLimitQuery(string $query, ?int $limit, int $offset) : string
{
if ($limit !== null) {
- $query .= ' LIMIT ' . $limit;
+ $query .= sprintf(' LIMIT %d', $limit);
}
if ($offset > 0) {
- $query .= ' OFFSET ' . $offset;
+ $query .= sprintf(' OFFSET %d', $offset);
}
return $query;
@@ -3467,13 +3453,9 @@ public function getTruncateTableSQL($tableName, $cascade = false)
/**
* This is for test reasons, many vendors have special requirements for dummy statements.
- *
- * @return string
*/
- public function getDummySelectSQL()
+ public function getDummySelectSQL(string $expression = '1') : string
{
- $expression = func_num_args() > 0 ? func_get_arg(0) : '1';
-
return sprintf('SELECT %s', $expression);
}
diff --git a/lib/Doctrine/DBAL/Platforms/DB2Platform.php b/lib/Doctrine/DBAL/Platforms/DB2Platform.php
index 605122115d4..5d85dfec485 100644
--- a/lib/Doctrine/DBAL/Platforms/DB2Platform.php
+++ b/lib/Doctrine/DBAL/Platforms/DB2Platform.php
@@ -13,8 +13,6 @@
use function count;
use function current;
use function explode;
-use function func_get_arg;
-use function func_num_args;
use function implode;
use function sprintf;
use function strpos;
@@ -74,21 +72,21 @@ public function getBlobTypeDeclarationSQL(array $field)
public function initializeDoctrineTypeMappings()
{
$this->doctrineTypeMapping = [
- 'smallint' => 'smallint',
- 'bigint' => 'bigint',
- 'integer' => 'integer',
- 'time' => 'time',
- 'date' => 'date',
- 'varchar' => 'string',
- 'character' => 'string',
- 'varbinary' => 'binary',
- 'binary' => 'binary',
- 'clob' => 'text',
- 'blob' => 'blob',
- 'decimal' => 'decimal',
- 'double' => 'float',
- 'real' => 'float',
- 'timestamp' => 'datetime',
+ 'bigint' => 'bigint',
+ 'binary' => 'binary',
+ 'blob' => 'blob',
+ 'character' => 'string',
+ 'clob' => 'text',
+ 'date' => 'date',
+ 'decimal' => 'decimal',
+ 'double' => 'float',
+ 'integer' => 'integer',
+ 'real' => 'float',
+ 'smallint' => 'smallint',
+ 'time' => 'time',
+ 'timestamp' => 'datetime',
+ 'varbinary' => 'binary',
+ 'varchar' => 'string',
];
}
@@ -782,7 +780,7 @@ public function getTemporaryTableName($tableName)
/**
* {@inheritDoc}
*/
- protected function doModifyLimitQuery($query, $limit, $offset = null)
+ protected function doModifyLimitQuery(string $query, ?int $limit, int $offset) : string
{
$where = [];
@@ -867,10 +865,8 @@ public function getForUpdateSQL()
/**
* {@inheritDoc}
*/
- public function getDummySelectSQL()
+ public function getDummySelectSQL(string $expression = '1') : string
{
- $expression = func_num_args() > 0 ? func_get_arg(0) : '1';
-
return sprintf('SELECT %s FROM sysibm.sysdummy1', $expression);
}
diff --git a/lib/Doctrine/DBAL/Platforms/DrizzlePlatform.php b/lib/Doctrine/DBAL/Platforms/DrizzlePlatform.php
deleted file mode 100644
index 2ba8c03b3b3..00000000000
--- a/lib/Doctrine/DBAL/Platforms/DrizzlePlatform.php
+++ /dev/null
@@ -1,623 +0,0 @@
-_getCommonIntegerTypeDeclarationSQL($field);
- }
-
- /**
- * {@inheritDoc}
- */
- protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef)
- {
- $autoinc = '';
- if (! empty($columnDef['autoincrement'])) {
- $autoinc = ' AUTO_INCREMENT';
- }
-
- return $autoinc;
- }
-
- /**
- * {@inheritDoc}
- */
- public function getBigIntTypeDeclarationSQL(array $field)
- {
- return 'BIGINT' . $this->_getCommonIntegerTypeDeclarationSQL($field);
- }
-
- /**
- * {@inheritDoc}
- */
- public function getSmallIntTypeDeclarationSQL(array $field)
- {
- return 'INT' . $this->_getCommonIntegerTypeDeclarationSQL($field);
- }
-
- /**
- * {@inheritDoc}
- */
- protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed)
- {
- return $length ? 'VARCHAR(' . $length . ')' : 'VARCHAR(255)';
- }
-
- /**
- * {@inheritdoc}
- */
- protected function getBinaryTypeDeclarationSQLSnippet($length, $fixed)
- {
- return 'VARBINARY(' . ($length ?: 255) . ')';
- }
-
- /**
- * {@inheritDoc}
- */
- protected function initializeDoctrineTypeMappings()
- {
- $this->doctrineTypeMapping = [
- 'boolean' => 'boolean',
- 'varchar' => 'string',
- 'varbinary' => 'binary',
- 'integer' => 'integer',
- 'blob' => 'blob',
- 'decimal' => 'decimal',
- 'datetime' => 'datetime',
- 'date' => 'date',
- 'time' => 'time',
- 'text' => 'text',
- 'timestamp' => 'datetime',
- 'double' => 'float',
- 'bigint' => 'bigint',
- ];
- }
-
- /**
- * {@inheritDoc}
- */
- public function getClobTypeDeclarationSQL(array $field)
- {
- return 'TEXT';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getBlobTypeDeclarationSQL(array $field)
- {
- return 'BLOB';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getCreateDatabaseSQL($name)
- {
- return 'CREATE DATABASE ' . $name;
- }
-
- /**
- * {@inheritDoc}
- */
- public function getDropDatabaseSQL($name)
- {
- return 'DROP DATABASE ' . $name;
- }
-
- /**
- * {@inheritDoc}
- */
- protected function _getCreateTableSQL($tableName, array $columns, array $options = [])
- {
- $queryFields = $this->getColumnDeclarationListSQL($columns);
-
- if (isset($options['uniqueConstraints']) && ! empty($options['uniqueConstraints'])) {
- foreach ($options['uniqueConstraints'] as $index => $definition) {
- $queryFields .= ', ' . $this->getUniqueConstraintDeclarationSQL($index, $definition);
- }
- }
-
- // add all indexes
- if (isset($options['indexes']) && ! empty($options['indexes'])) {
- foreach ($options['indexes'] as $index => $definition) {
- $queryFields .= ', ' . $this->getIndexDeclarationSQL($index, $definition);
- }
- }
-
- // attach all primary keys
- if (isset($options['primary']) && ! empty($options['primary'])) {
- $keyColumns = array_unique(array_values($options['primary']));
- $queryFields .= ', PRIMARY KEY(' . implode(', ', $keyColumns) . ')';
- }
-
- $query = 'CREATE ';
-
- if (! empty($options['temporary'])) {
- $query .= 'TEMPORARY ';
- }
-
- $query .= 'TABLE ' . $tableName . ' (' . $queryFields . ') ';
- $query .= $this->buildTableOptions($options);
- $query .= $this->buildPartitionOptions($options);
-
- $sql = [$query];
-
- if (isset($options['foreignKeys'])) {
- foreach ((array) $options['foreignKeys'] as $definition) {
- $sql[] = $this->getCreateForeignKeySQL($definition, $tableName);
- }
- }
-
- return $sql;
- }
-
- /**
- * Build SQL for table options
- *
- * @param mixed[] $options
- *
- * @return string
- */
- private function buildTableOptions(array $options)
- {
- if (isset($options['table_options'])) {
- return $options['table_options'];
- }
-
- $tableOptions = [];
-
- // Collate
- if (! isset($options['collate'])) {
- $options['collate'] = 'utf8_unicode_ci';
- }
-
- $tableOptions[] = sprintf('COLLATE %s', $options['collate']);
-
- // Engine
- if (! isset($options['engine'])) {
- $options['engine'] = 'InnoDB';
- }
-
- $tableOptions[] = sprintf('ENGINE = %s', $options['engine']);
-
- // Auto increment
- if (isset($options['auto_increment'])) {
- $tableOptions[] = sprintf('AUTO_INCREMENT = %s', $options['auto_increment']);
- }
-
- // Comment
- if (isset($options['comment'])) {
- $comment = trim($options['comment'], " '");
-
- $tableOptions[] = sprintf('COMMENT = %s ', $this->quoteStringLiteral($comment));
- }
-
- // Row format
- if (isset($options['row_format'])) {
- $tableOptions[] = sprintf('ROW_FORMAT = %s', $options['row_format']);
- }
-
- return implode(' ', $tableOptions);
- }
-
- /**
- * Build SQL for partition options.
- *
- * @param mixed[] $options
- *
- * @return string
- */
- private function buildPartitionOptions(array $options)
- {
- return isset($options['partition_options'])
- ? ' ' . $options['partition_options']
- : '';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getListDatabasesSQL()
- {
- return "SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE CATALOG_NAME='LOCAL'";
- }
-
- /**
- * {@inheritDoc}
- */
- protected function getReservedKeywordsClass()
- {
- return Keywords\DrizzleKeywords::class;
- }
-
- /**
- * {@inheritDoc}
- */
- public function getListTablesSQL()
- {
- return "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE' AND TABLE_SCHEMA=DATABASE()";
- }
-
- /**
- * {@inheritDoc}
- */
- public function getListTableColumnsSQL($table, $database = null)
- {
- if ($database) {
- $databaseSQL = $this->quoteStringLiteral($database);
- } else {
- $databaseSQL = 'DATABASE()';
- }
-
- return 'SELECT COLUMN_NAME, DATA_TYPE, COLUMN_COMMENT, IS_NULLABLE, IS_AUTO_INCREMENT, CHARACTER_MAXIMUM_LENGTH, COLUMN_DEFAULT,' .
- ' NUMERIC_PRECISION, NUMERIC_SCALE, COLLATION_NAME' .
- ' FROM DATA_DICTIONARY.COLUMNS' .
- ' WHERE TABLE_SCHEMA=' . $databaseSQL . ' AND TABLE_NAME = ' . $this->quoteStringLiteral($table);
- }
-
- /**
- * {@inheritDoc}
- */
- public function getListTableForeignKeysSQL($table, $database = null)
- {
- if ($database) {
- $databaseSQL = $this->quoteStringLiteral($database);
- } else {
- $databaseSQL = 'DATABASE()';
- }
-
- return 'SELECT CONSTRAINT_NAME, CONSTRAINT_COLUMNS, REFERENCED_TABLE_NAME, REFERENCED_TABLE_COLUMNS, UPDATE_RULE, DELETE_RULE' .
- ' FROM DATA_DICTIONARY.FOREIGN_KEYS' .
- ' WHERE CONSTRAINT_SCHEMA=' . $databaseSQL . ' AND CONSTRAINT_TABLE=' . $this->quoteStringLiteral($table);
- }
-
- /**
- * {@inheritDoc}
- */
- public function getListTableIndexesSQL($table, $database = null)
- {
- if ($database) {
- $databaseSQL = $this->quoteStringLiteral($database);
- } else {
- $databaseSQL = 'DATABASE()';
- }
-
- return "SELECT INDEX_NAME AS 'key_name', COLUMN_NAME AS 'column_name', IS_USED_IN_PRIMARY AS 'primary', IS_UNIQUE=0 AS 'non_unique'" .
- ' FROM DATA_DICTIONARY.INDEX_PARTS' .
- ' WHERE TABLE_SCHEMA=' . $databaseSQL . ' AND TABLE_NAME=' . $this->quoteStringLiteral($table);
- }
-
- /**
- * {@inheritDoc}
- */
- public function prefersIdentityColumns()
- {
- return true;
- }
-
- /**
- * {@inheritDoc}
- */
- public function supportsIdentityColumns()
- {
- return true;
- }
-
- /**
- * {@inheritDoc}
- */
- public function supportsInlineColumnComments()
- {
- return true;
- }
-
- /**
- * {@inheritDoc}
- */
- public function supportsViews()
- {
- return false;
- }
-
- /**
- * {@inheritdoc}
- */
- public function supportsColumnCollation()
- {
- return true;
- }
-
- /**
- * {@inheritDoc}
- */
- public function getDropIndexSQL($index, $table = null)
- {
- if ($index instanceof Index) {
- $indexName = $index->getQuotedName($this);
- } elseif (is_string($index)) {
- $indexName = $index;
- } else {
- throw new InvalidArgumentException('DrizzlePlatform::getDropIndexSQL() expects $index parameter to be string or \Doctrine\DBAL\Schema\Index.');
- }
-
- if ($table instanceof Table) {
- $table = $table->getQuotedName($this);
- } elseif (! is_string($table)) {
- throw new InvalidArgumentException('DrizzlePlatform::getDropIndexSQL() expects $table parameter to be string or \Doctrine\DBAL\Schema\Table.');
- }
-
- if ($index instanceof Index && $index->isPrimary()) {
- // drizzle primary keys are always named "PRIMARY",
- // so we cannot use them in statements because of them being keyword.
- return $this->getDropPrimaryKeySQL($table);
- }
-
- return 'DROP INDEX ' . $indexName . ' ON ' . $table;
- }
-
- /**
- * {@inheritDoc}
- */
- protected function getDropPrimaryKeySQL($table)
- {
- return 'ALTER TABLE ' . $table . ' DROP PRIMARY KEY';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration)
- {
- if (isset($fieldDeclaration['version']) && $fieldDeclaration['version'] === true) {
- return 'TIMESTAMP';
- }
-
- return 'DATETIME';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getTimeTypeDeclarationSQL(array $fieldDeclaration)
- {
- return 'TIME';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getDateTypeDeclarationSQL(array $fieldDeclaration)
- {
- return 'DATE';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getAlterTableSQL(TableDiff $diff)
- {
- $columnSql = [];
- $queryParts = [];
-
- if ($diff->newName !== false) {
- $queryParts[] = 'RENAME TO ' . $diff->getNewName()->getQuotedName($this);
- }
-
- foreach ($diff->addedColumns as $column) {
- if ($this->onSchemaAlterTableAddColumn($column, $diff, $columnSql)) {
- continue;
- }
-
- $columnArray = $column->toArray();
- $columnArray['comment'] = $this->getColumnComment($column);
- $queryParts[] = 'ADD ' . $this->getColumnDeclarationSQL($column->getQuotedName($this), $columnArray);
- }
-
- foreach ($diff->removedColumns as $column) {
- if ($this->onSchemaAlterTableRemoveColumn($column, $diff, $columnSql)) {
- continue;
- }
-
- $queryParts[] = 'DROP ' . $column->getQuotedName($this);
- }
-
- foreach ($diff->changedColumns as $columnDiff) {
- if ($this->onSchemaAlterTableChangeColumn($columnDiff, $diff, $columnSql)) {
- continue;
- }
-
- /** @var ColumnDiff $columnDiff */
- $column = $columnDiff->column;
- $columnArray = $column->toArray();
-
- // Do not generate column alteration clause if type is binary and only fixed property has changed.
- // Drizzle only supports binary type columns with variable length.
- // Avoids unnecessary table alteration statements.
- if ($columnArray['type'] instanceof BinaryType &&
- $columnDiff->hasChanged('fixed') &&
- count($columnDiff->changedProperties) === 1
- ) {
- continue;
- }
-
- $columnArray['comment'] = $this->getColumnComment($column);
- $queryParts[] = 'CHANGE ' . ($columnDiff->getOldColumnName()->getQuotedName($this)) . ' '
- . $this->getColumnDeclarationSQL($column->getQuotedName($this), $columnArray);
- }
-
- foreach ($diff->renamedColumns as $oldColumnName => $column) {
- if ($this->onSchemaAlterTableRenameColumn($oldColumnName, $column, $diff, $columnSql)) {
- continue;
- }
-
- $oldColumnName = new Identifier($oldColumnName);
-
- $columnArray = $column->toArray();
- $columnArray['comment'] = $this->getColumnComment($column);
- $queryParts[] = 'CHANGE ' . $oldColumnName->getQuotedName($this) . ' '
- . $this->getColumnDeclarationSQL($column->getQuotedName($this), $columnArray);
- }
-
- $sql = [];
- $tableSql = [];
-
- if (! $this->onSchemaAlterTable($diff, $tableSql)) {
- if (count($queryParts) > 0) {
- $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . implode(', ', $queryParts);
- }
- $sql = array_merge(
- $this->getPreAlterTableIndexForeignKeySQL($diff),
- $sql,
- $this->getPostAlterTableIndexForeignKeySQL($diff)
- );
- }
-
- return array_merge($sql, $tableSql, $columnSql);
- }
-
- /**
- * {@inheritDoc}
- */
- public function getDropTemporaryTableSQL($table)
- {
- if ($table instanceof Table) {
- $table = $table->getQuotedName($this);
- } elseif (! is_string($table)) {
- throw new InvalidArgumentException('getDropTableSQL() expects $table parameter to be string or \Doctrine\DBAL\Schema\Table.');
- }
-
- return 'DROP TEMPORARY TABLE ' . $table;
- }
-
- /**
- * {@inheritDoc}
- */
- public function convertBooleans($item)
- {
- if (is_array($item)) {
- foreach ($item as $key => $value) {
- if (! is_bool($value) && ! is_numeric($item)) {
- continue;
- }
-
- $item[$key] = $value ? 'true' : 'false';
- }
- } elseif (is_bool($item) || is_numeric($item)) {
- $item = $item ? 'true' : 'false';
- }
-
- return $item;
- }
-
- /**
- * {@inheritDoc}
- */
- public function getLocateExpression($str, $substr, $startPos = false)
- {
- if ($startPos === false) {
- return 'LOCATE(' . $substr . ', ' . $str . ')';
- }
-
- return 'LOCATE(' . $substr . ', ' . $str . ', ' . $startPos . ')';
- }
-
- /**
- * {@inheritDoc}
- *
- * @deprecated Use application-generated UUIDs instead
- */
- public function getGuidExpression()
- {
- return 'UUID()';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getRegexpExpression()
- {
- return 'RLIKE';
- }
-}
diff --git a/lib/Doctrine/DBAL/Platforms/Keywords/DB2Keywords.php b/lib/Doctrine/DBAL/Platforms/Keywords/DB2Keywords.php
index 8533f579d71..db577d30207 100644
--- a/lib/Doctrine/DBAL/Platforms/Keywords/DB2Keywords.php
+++ b/lib/Doctrine/DBAL/Platforms/Keywords/DB2Keywords.php
@@ -27,24 +27,6 @@ protected function getKeywords()
'ALIAS',
'ALL',
'ALLOCATE',
- 'DOCUMENT',
- 'DOUBLE',
- 'DROP',
- 'DSSIZE',
- 'DYNAMIC',
- 'EACH',
- 'LOCK',
- 'LOCKMAX',
- 'LOCKSIZE',
- 'LONG',
- 'LOOP',
- 'MAINTAINED',
- 'ROUND_CEILING',
- 'ROUND_DOWN',
- 'ROUND_FLOOR',
- 'ROUND_HALF_DOWN',
- 'ROUND_HALF_EVEN',
- 'ROUND_HALF_UP',
'ALLOW',
'ALTER',
'AND',
@@ -112,6 +94,38 @@ protected function getKeywords()
'DATABASE',
'DATAPARTITIONNAME',
'DATAPARTITIONNUM',
+ 'DATE',
+ 'DAY',
+ 'DAYS',
+ 'DB2GENERAL',
+ 'DB2GENRL',
+ 'DB2SQL',
+ 'DBINFO',
+ 'DBPARTITIONNAME',
+ 'DBPARTITIONNUM',
+ 'DEALLOCATE',
+ 'DECLARE',
+ 'DEFAULT',
+ 'DEFAULTS',
+ 'DEFINITION',
+ 'DELETE',
+ 'DENSE_RANK',
+ 'DENSERANK',
+ 'DESCRIBE',
+ 'DESCRIPTOR',
+ 'DETERMINISTIC',
+ 'DIAGNOSTICS',
+ 'DISABLE',
+ 'DISALLOW',
+ 'DISCONNECT',
+ 'DISTINCT',
+ 'DO',
+ 'DOCUMENT',
+ 'DOUBLE',
+ 'DROP',
+ 'DSSIZE',
+ 'DYNAMIC',
+ 'EACH',
'EDITPROC',
'ELSE',
'ELSEIF',
@@ -179,6 +193,38 @@ protected function getKeywords()
'INSENSITIVE',
'INSERT',
'INTEGRITY',
+ 'INTERSECT',
+ 'INTO',
+ 'IS',
+ 'ISOBID',
+ 'ISOLATION',
+ 'ITERATE',
+ 'JAR',
+ 'JAVA',
+ 'JOIN',
+ 'KEEP',
+ 'KEY',
+ 'LABEL',
+ 'LANGUAGE',
+ 'LATERAL',
+ 'LC_CTYPE',
+ 'LEAVE',
+ 'LEFT',
+ 'LIKE',
+ 'LINKTYPE',
+ 'LOCAL',
+ 'LOCALDATE',
+ 'LOCALE',
+ 'LOCALTIME',
+ 'LOCALTIMESTAMP RIGHT',
+ 'LOCATOR',
+ 'LOCATORS',
+ 'LOCK',
+ 'LOCKMAX',
+ 'LOCKSIZE',
+ 'LONG',
+ 'LOOP',
+ 'MAINTAINED',
'MATERIALIZED',
'MAXVALUE',
'MICROSECOND',
@@ -246,6 +292,37 @@ protected function getKeywords()
'PROCEDURE',
'PROGRAM',
'PSID',
+ 'PUBLIC',
+ 'QUERY',
+ 'QUERYNO',
+ 'RANGE',
+ 'RANK',
+ 'READ',
+ 'READS',
+ 'RECOVERY',
+ 'REFERENCES',
+ 'REFERENCING',
+ 'REFRESH',
+ 'RELEASE',
+ 'RENAME',
+ 'REPEAT',
+ 'RESET',
+ 'RESIGNAL',
+ 'RESTART',
+ 'RESTRICT',
+ 'RESULT',
+ 'RESULT_SET_LOCATOR WLM',
+ 'RETURN',
+ 'RETURNS',
+ 'REVOKE',
+ 'ROLE',
+ 'ROLLBACK',
+ 'ROUND_CEILING',
+ 'ROUND_DOWN',
+ 'ROUND_FLOOR',
+ 'ROUND_HALF_DOWN',
+ 'ROUND_HALF_EVEN',
+ 'ROUND_HALF_UP',
'ROUND_UP',
'ROUTINE',
'ROW',
@@ -313,107 +390,30 @@ protected function getKeywords()
'UNIQUE',
'UNTIL',
'UPDATE',
- 'DATE',
- 'DAY',
- 'DAYS',
- 'DB2GENERAL',
- 'DB2GENRL',
- 'DB2SQL',
- 'DBINFO',
- 'DBPARTITIONNAME',
- 'DBPARTITIONNUM',
- 'DEALLOCATE',
- 'DECLARE',
- 'DEFAULT',
- 'DEFAULTS',
- 'DEFINITION',
- 'DELETE',
- 'DENSE_RANK',
- 'DENSERANK',
- 'DESCRIBE',
- 'DESCRIPTOR',
- 'DETERMINISTIC',
- 'DIAGNOSTICS',
- 'DISABLE',
- 'DISALLOW',
- 'DISCONNECT',
- 'DISTINCT',
- 'DO',
- 'INTERSECT',
- 'PUBLIC',
'USAGE',
- 'INTO',
- 'QUERY',
'USER',
- 'IS',
- 'QUERYNO',
'USING',
- 'ISOBID',
- 'RANGE',
'VALIDPROC',
- 'ISOLATION',
- 'RANK',
'VALUE',
- 'ITERATE',
- 'READ',
'VALUES',
- 'JAR',
- 'READS',
'VARIABLE',
- 'JAVA',
- 'RECOVERY',
'VARIANT',
- 'JOIN',
- 'REFERENCES',
'VCAT',
- 'KEEP',
- 'REFERENCING',
'VERSION',
- 'KEY',
- 'REFRESH',
'VIEW',
- 'LABEL',
- 'RELEASE',
'VOLATILE',
- 'LANGUAGE',
- 'RENAME',
'VOLUMES',
- 'LATERAL',
- 'REPEAT',
'WHEN',
- 'LC_CTYPE',
- 'RESET',
'WHENEVER',
- 'LEAVE',
- 'RESIGNAL',
'WHERE',
- 'LEFT',
- 'RESTART',
'WHILE',
- 'LIKE',
- 'RESTRICT',
'WITH',
- 'LINKTYPE',
- 'RESULT',
'WITHOUT',
- 'LOCAL',
- 'RESULT_SET_LOCATOR WLM',
- 'LOCALDATE',
- 'RETURN',
'WRITE',
- 'LOCALE',
- 'RETURNS',
'XMLELEMENT',
- 'LOCALTIME',
- 'REVOKE',
'XMLEXISTS',
- 'LOCALTIMESTAMP RIGHT',
'XMLNAMESPACES',
- 'LOCATOR',
- 'ROLE',
'YEAR',
- 'LOCATORS',
- 'ROLLBACK',
'YEARS',
];
}
diff --git a/lib/Doctrine/DBAL/Platforms/Keywords/DrizzleKeywords.php b/lib/Doctrine/DBAL/Platforms/Keywords/DrizzleKeywords.php
deleted file mode 100644
index 70f69f44b0b..00000000000
--- a/lib/Doctrine/DBAL/Platforms/Keywords/DrizzleKeywords.php
+++ /dev/null
@@ -1,326 +0,0 @@
-getColumnDeclarationListSQL($columns);
if (isset($options['uniqueConstraints']) && ! empty($options['uniqueConstraints'])) {
- foreach ($options['uniqueConstraints'] as $index => $definition) {
- $queryFields .= ', ' . $this->getUniqueConstraintDeclarationSQL($index, $definition);
+ foreach ($options['uniqueConstraints'] as $name => $definition) {
+ $queryFields .= ', ' . $this->getUniqueConstraintDeclarationSQL($name, $definition);
}
}
@@ -1025,36 +1015,36 @@ public function getReadLockSQL()
protected function initializeDoctrineTypeMappings()
{
$this->doctrineTypeMapping = [
- 'tinyint' => 'boolean',
- 'smallint' => 'smallint',
- 'mediumint' => 'integer',
- 'int' => 'integer',
- 'integer' => 'integer',
- 'bigint' => 'bigint',
- 'tinytext' => 'text',
- 'mediumtext' => 'text',
- 'longtext' => 'text',
- 'text' => 'text',
- 'varchar' => 'string',
- 'string' => 'string',
- 'char' => 'string',
- 'date' => 'date',
- 'datetime' => 'datetime',
- 'timestamp' => 'datetime',
- 'time' => 'time',
- 'float' => 'float',
- 'double' => 'float',
- 'real' => 'float',
- 'decimal' => 'decimal',
- 'numeric' => 'decimal',
- 'year' => 'date',
- 'longblob' => 'blob',
- 'blob' => 'blob',
- 'mediumblob' => 'blob',
- 'tinyblob' => 'blob',
- 'binary' => 'binary',
- 'varbinary' => 'binary',
- 'set' => 'simple_array',
+ 'bigint' => 'bigint',
+ 'binary' => 'binary',
+ 'blob' => 'blob',
+ 'char' => 'string',
+ 'date' => 'date',
+ 'datetime' => 'datetime',
+ 'decimal' => 'decimal',
+ 'double' => 'float',
+ 'float' => 'float',
+ 'int' => 'integer',
+ 'integer' => 'integer',
+ 'longblob' => 'blob',
+ 'longtext' => 'text',
+ 'mediumblob' => 'blob',
+ 'mediumint' => 'integer',
+ 'mediumtext' => 'text',
+ 'numeric' => 'decimal',
+ 'real' => 'float',
+ 'set' => 'simple_array',
+ 'smallint' => 'smallint',
+ 'string' => 'string',
+ 'text' => 'text',
+ 'time' => 'time',
+ 'timestamp' => 'datetime',
+ 'tinyblob' => 'blob',
+ 'tinyint' => 'boolean',
+ 'tinytext' => 'text',
+ 'varbinary' => 'binary',
+ 'varchar' => 'string',
+ 'year' => 'date',
];
}
diff --git a/lib/Doctrine/DBAL/Platforms/OraclePlatform.php b/lib/Doctrine/DBAL/Platforms/OraclePlatform.php
index 1d249e9aa10..36990ed1dcb 100644
--- a/lib/Doctrine/DBAL/Platforms/OraclePlatform.php
+++ b/lib/Doctrine/DBAL/Platforms/OraclePlatform.php
@@ -16,8 +16,6 @@
use function array_merge;
use function count;
use function explode;
-use function func_get_arg;
-use function func_num_args;
use function implode;
use function preg_match;
use function sprintf;
@@ -85,16 +83,6 @@ public function getLocateExpression($str, $substr, $startPos = false)
return 'INSTR(' . $str . ', ' . $substr . ', ' . $startPos . ')';
}
- /**
- * {@inheritDoc}
- *
- * @deprecated Use application-generated UUIDs instead
- */
- public function getGuidExpression()
- {
- return 'SYS_GUID()';
- }
-
/**
* {@inheritdoc}
*/
@@ -373,11 +361,11 @@ public function getListSequencesSQL($database)
/**
* {@inheritDoc}
*/
- protected function _getCreateTableSQL($table, array $columns, array $options = [])
+ protected function _getCreateTableSQL($tableName, array $columns, array $options = [])
{
$indexes = $options['indexes'] ?? [];
$options['indexes'] = [];
- $sql = parent::_getCreateTableSQL($table, $columns, $options);
+ $sql = parent::_getCreateTableSQL($tableName, $columns, $options);
foreach ($columns as $name => $column) {
if (isset($column['sequence'])) {
@@ -389,12 +377,12 @@ protected function _getCreateTableSQL($table, array $columns, array $options = [
continue;
}
- $sql = array_merge($sql, $this->getCreateAutoincrementSql($name, $table));
+ $sql = array_merge($sql, $this->getCreateAutoincrementSql($name, $tableName));
}
if (isset($indexes) && ! empty($indexes)) {
foreach ($indexes as $index) {
- $sql[] = $this->getCreateIndexSQL($index, $table);
+ $sql[] = $this->getCreateIndexSQL($index, $tableName);
}
}
@@ -981,7 +969,7 @@ public function getName()
/**
* {@inheritDoc}
*/
- protected function doModifyLimitQuery($query, $limit, $offset = null)
+ protected function doModifyLimitQuery(string $query, ?int $limit, int $offset) : string
{
if ($limit === null && $offset <= 0) {
return $query;
@@ -1112,10 +1100,8 @@ public function getTruncateTableSQL($tableName, $cascade = false)
/**
* {@inheritDoc}
*/
- public function getDummySelectSQL()
+ public function getDummySelectSQL(string $expression = '1') : string
{
- $expression = func_num_args() > 0 ? func_get_arg(0) : '1';
-
return sprintf('SELECT %s FROM DUAL', $expression);
}
@@ -1125,29 +1111,29 @@ public function getDummySelectSQL()
protected function initializeDoctrineTypeMappings()
{
$this->doctrineTypeMapping = [
- 'integer' => 'integer',
- 'number' => 'integer',
- 'pls_integer' => 'boolean',
- 'binary_integer' => 'boolean',
- 'varchar' => 'string',
- 'varchar2' => 'string',
- 'nvarchar2' => 'string',
- 'char' => 'string',
- 'nchar' => 'string',
- 'date' => 'date',
- 'timestamp' => 'datetime',
- 'timestamptz' => 'datetimetz',
- 'float' => 'float',
- 'binary_float' => 'float',
- 'binary_double' => 'float',
- 'long' => 'string',
- 'clob' => 'text',
- 'nclob' => 'text',
- 'raw' => 'binary',
- 'long raw' => 'blob',
- 'rowid' => 'string',
- 'urowid' => 'string',
- 'blob' => 'blob',
+ 'binary_double' => 'float',
+ 'binary_float' => 'float',
+ 'binary_integer' => 'boolean',
+ 'blob' => 'blob',
+ 'char' => 'string',
+ 'clob' => 'text',
+ 'date' => 'date',
+ 'float' => 'float',
+ 'integer' => 'integer',
+ 'long' => 'string',
+ 'long raw' => 'blob',
+ 'nchar' => 'string',
+ 'nclob' => 'text',
+ 'number' => 'integer',
+ 'nvarchar2' => 'string',
+ 'pls_integer' => 'boolean',
+ 'raw' => 'binary',
+ 'rowid' => 'string',
+ 'timestamp' => 'datetime',
+ 'timestamptz' => 'datetimetz',
+ 'urowid' => 'string',
+ 'varchar' => 'string',
+ 'varchar2' => 'string',
];
}
diff --git a/lib/Doctrine/DBAL/Platforms/PostgreSQL91Platform.php b/lib/Doctrine/DBAL/Platforms/PostgreSQL91Platform.php
deleted file mode 100644
index f558409831c..00000000000
--- a/lib/Doctrine/DBAL/Platforms/PostgreSQL91Platform.php
+++ /dev/null
@@ -1,46 +0,0 @@
-quoteSingleIdentifier($collation);
- }
-
- /**
- * {@inheritDoc}
- */
- public function getListTableColumnsSQL($table, $database = null)
- {
- $sql = parent::getListTableColumnsSQL($table, $database);
- $parts = explode('AS complete_type,', $sql, 2);
-
- return $parts[0] . 'AS complete_type, (SELECT tc.collcollate FROM pg_catalog.pg_collation tc WHERE tc.oid = a.attcollation) AS collation,' . $parts[1];
- }
-}
diff --git a/lib/Doctrine/DBAL/Platforms/PostgreSQL92Platform.php b/lib/Doctrine/DBAL/Platforms/PostgreSQL92Platform.php
deleted file mode 100644
index b302c0ceb83..00000000000
--- a/lib/Doctrine/DBAL/Platforms/PostgreSQL92Platform.php
+++ /dev/null
@@ -1,69 +0,0 @@
-doctrineTypeMapping['json'] = Type::JSON;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getCloseActiveDatabaseConnectionsSQL($database)
- {
- return sprintf(
- 'SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = %s',
- $this->quoteStringLiteral($database)
- );
- }
-}
diff --git a/lib/Doctrine/DBAL/Platforms/PostgreSQL94Platform.php b/lib/Doctrine/DBAL/Platforms/PostgreSQL94Platform.php
index 9db0ecbbd2a..8cb65542e3b 100644
--- a/lib/Doctrine/DBAL/Platforms/PostgreSQL94Platform.php
+++ b/lib/Doctrine/DBAL/Platforms/PostgreSQL94Platform.php
@@ -7,7 +7,7 @@
/**
* Provides the behavior, features and SQL dialect of the PostgreSQL 9.4 database platform.
*/
-class PostgreSQL94Platform extends PostgreSQL92Platform
+class PostgreSQL94Platform extends PostgreSqlPlatform
{
/**
* {@inheritdoc}
diff --git a/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php b/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php
index cb4603f5199..c9389a7aa7a 100644
--- a/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php
+++ b/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php
@@ -33,7 +33,7 @@
use function trim;
/**
- * PostgreSqlPlatform.
+ * Provides the behavior, features and SQL dialect of the PostgreSQL 9.4+ database platform.
*
* @todo Rename: PostgreSQLPlatform
*/
@@ -392,6 +392,7 @@ public function getListTableColumnsSQL($table, $database = null)
quote_ident(a.attname) AS field,
t.typname AS type,
format_type(a.atttypid, a.atttypmod) AS complete_type,
+ (SELECT tc.collcollate FROM pg_catalog.pg_collation tc WHERE tc.oid = a.attcollation) AS collation,
(SELECT t1.typname FROM pg_catalog.pg_type t1 WHERE t1.oid = t.typbasetype) AS domain_type,
(SELECT format_type(t2.typbasetype, t2.typtypmod) FROM
pg_catalog.pg_type t2 WHERE t2.typtype = 'd' AND t2.oid = a.atttypid) AS domain_complete_type,
@@ -452,7 +453,7 @@ public function getDisallowDatabaseConnectionsSQL($database)
*/
public function getCloseActiveDatabaseConnectionsSQL($database)
{
- return 'SELECT pg_terminate_backend(procpid) FROM pg_stat_activity WHERE datname = '
+ return 'SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = '
. $this->quoteStringLiteral($database);
}
@@ -967,6 +968,10 @@ public function getBigIntTypeDeclarationSQL(array $field)
*/
public function getSmallIntTypeDeclarationSQL(array $field)
{
+ if (! empty($field['autoincrement'])) {
+ return 'SMALLSERIAL';
+ }
+
return 'SMALLINT';
}
@@ -1010,16 +1015,6 @@ public function getTimeTypeDeclarationSQL(array $fieldDeclaration)
return 'TIME(0) WITHOUT TIME ZONE';
}
- /**
- * {@inheritDoc}
- *
- * @deprecated Use application-generated UUIDs instead
- */
- public function getGuidExpression()
- {
- return 'UUID_GENERATE_V4()';
- }
-
/**
* {@inheritDoc}
*/
@@ -1116,45 +1111,46 @@ public function getReadLockSQL()
protected function initializeDoctrineTypeMappings()
{
$this->doctrineTypeMapping = [
- 'smallint' => 'smallint',
- 'int2' => 'smallint',
- 'serial' => 'integer',
- 'serial4' => 'integer',
- 'int' => 'integer',
- 'int4' => 'integer',
- 'integer' => 'integer',
- 'bigserial' => 'bigint',
- 'serial8' => 'bigint',
- 'bigint' => 'bigint',
- 'int8' => 'bigint',
- 'bool' => 'boolean',
- 'boolean' => 'boolean',
- 'text' => 'text',
- 'tsvector' => 'text',
- 'varchar' => 'string',
- 'interval' => 'string',
- '_varchar' => 'string',
- 'char' => 'string',
- 'bpchar' => 'string',
- 'inet' => 'string',
- 'date' => 'date',
- 'datetime' => 'datetime',
- 'timestamp' => 'datetime',
- 'timestamptz' => 'datetimetz',
- 'time' => 'time',
- 'timetz' => 'time',
- 'float' => 'float',
- 'float4' => 'float',
- 'float8' => 'float',
- 'double' => 'float',
+ 'bigint' => 'bigint',
+ 'bigserial' => 'bigint',
+ 'bool' => 'boolean',
+ 'boolean' => 'boolean',
+ 'bpchar' => 'string',
+ 'bytea' => 'blob',
+ 'char' => 'string',
+ 'date' => 'date',
+ 'datetime' => 'datetime',
+ 'decimal' => 'decimal',
+ 'double' => 'float',
'double precision' => 'float',
- 'real' => 'float',
- 'decimal' => 'decimal',
- 'money' => 'decimal',
- 'numeric' => 'decimal',
- 'year' => 'date',
- 'uuid' => 'guid',
- 'bytea' => 'blob',
+ 'float' => 'float',
+ 'float4' => 'float',
+ 'float8' => 'float',
+ 'inet' => 'string',
+ 'int' => 'integer',
+ 'int2' => 'smallint',
+ 'int4' => 'integer',
+ 'int8' => 'bigint',
+ 'integer' => 'integer',
+ 'interval' => 'string',
+ 'json' => Type::JSON,
+ 'money' => 'decimal',
+ 'numeric' => 'decimal',
+ 'serial' => 'integer',
+ 'serial4' => 'integer',
+ 'serial8' => 'bigint',
+ 'real' => 'float',
+ 'smallint' => 'smallint',
+ 'text' => 'text',
+ 'time' => 'time',
+ 'timestamp' => 'datetime',
+ 'timestamptz' => 'datetimetz',
+ 'timetz' => 'time',
+ 'tsvector' => 'text',
+ 'uuid' => 'guid',
+ 'varchar' => 'string',
+ 'year' => 'date',
+ '_varchar' => 'string',
];
}
@@ -1182,6 +1178,14 @@ public function getBinaryDefaultLength()
return 0;
}
+ /**
+ * {@inheritdoc}
+ */
+ public function hasNativeJsonType()
+ {
+ return true;
+ }
+
/**
* {@inheritDoc}
*/
@@ -1210,6 +1214,30 @@ public function getDefaultValueDeclarationSQL($field)
return parent::getDefaultValueDeclarationSQL($field);
}
+ /**
+ * {@inheritdoc}
+ */
+ public function supportsColumnCollation()
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getColumnCollationDeclarationSQL($collation)
+ {
+ return 'COLLATE ' . $this->quoteSingleIdentifier($collation);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getJsonTypeDeclarationSQL(array $field)
+ {
+ return 'JSON';
+ }
+
/**
* @param mixed[] $field
*/
diff --git a/lib/Doctrine/DBAL/Platforms/SQLAnywhere11Platform.php b/lib/Doctrine/DBAL/Platforms/SQLAnywhere11Platform.php
deleted file mode 100644
index a46ae9352c4..00000000000
--- a/lib/Doctrine/DBAL/Platforms/SQLAnywhere11Platform.php
+++ /dev/null
@@ -1,26 +0,0 @@
-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';
- }
-}
diff --git a/lib/Doctrine/DBAL/Platforms/SQLAnywhere16Platform.php b/lib/Doctrine/DBAL/Platforms/SQLAnywhere16Platform.php
deleted file mode 100644
index 35d4238e4a3..00000000000
--- a/lib/Doctrine/DBAL/Platforms/SQLAnywhere16Platform.php
+++ /dev/null
@@ -1,39 +0,0 @@
-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;
- }
-}
diff --git a/lib/Doctrine/DBAL/Platforms/SQLAnywherePlatform.php b/lib/Doctrine/DBAL/Platforms/SQLAnywherePlatform.php
index b1105e90faa..d33477e8c51 100644
--- a/lib/Doctrine/DBAL/Platforms/SQLAnywherePlatform.php
+++ b/lib/Doctrine/DBAL/Platforms/SQLAnywherePlatform.php
@@ -10,10 +10,12 @@
use Doctrine\DBAL\Schema\ForeignKeyConstraint;
use Doctrine\DBAL\Schema\Identifier;
use Doctrine\DBAL\Schema\Index;
+use Doctrine\DBAL\Schema\Sequence;
use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Schema\TableDiff;
use Doctrine\DBAL\TransactionIsolationLevel;
use InvalidArgumentException;
+use UnexpectedValueException;
use function array_merge;
use function array_unique;
use function array_values;
@@ -32,7 +34,7 @@
/**
* 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
{
@@ -508,7 +510,7 @@ public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration)
*/
public function getDateTimeTzFormatString()
{
- return $this->getDateTimeFormatString();
+ return 'Y-m-d H:i:s.uP';
}
/**
@@ -663,16 +665,6 @@ public function getForUpdateSQL()
return '';
}
- /**
- * {@inheritdoc}
- *
- * @deprecated Use application-generated UUIDs instead
- */
- public function getGuidExpression()
- {
- return 'NEWID()';
- }
-
/**
* {@inheritdoc}
*/
@@ -996,6 +988,14 @@ public function getMd5Expression($column)
return 'HASH(' . $column . ", 'MD5')";
}
+ /**
+ * {@inheritdoc}
+ */
+ public function getRegexpExpression()
+ {
+ return 'REGEXP';
+ }
+
/**
* {@inheritdoc}
*/
@@ -1161,22 +1161,65 @@ public function getTruncateTableSQL($tableName, $cascade = false)
/**
* {@inheritdoc}
*/
- public function getUniqueConstraintDeclarationSQL($name, Index $index)
+ public function getCreateSequenceSQL(Sequence $sequence)
{
- if ($index->isPrimary()) {
- throw new InvalidArgumentException(
- 'Cannot create primary key constraint declarations with getUniqueConstraintDeclarationSQL().'
- );
- }
+ return 'CREATE SEQUENCE ' . $sequence->getQuotedName($this) .
+ ' INCREMENT BY ' . $sequence->getAllocationSize() .
+ ' START WITH ' . $sequence->getInitialValue() .
+ ' MINVALUE ' . $sequence->getInitialValue();
+ }
- if (! $index->isUnique()) {
- throw new InvalidArgumentException(
- 'Can only create unique constraint declarations, no common index declarations with ' .
- 'getUniqueConstraintDeclarationSQL().'
- );
+ /**
+ * {@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 $this->getTableConstraintDeclarationSQL($index, $name);
+ 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';
}
/**
@@ -1309,16 +1352,16 @@ protected function _getTransactionIsolationLevelSQL($level)
/**
* {@inheritdoc}
*/
- protected function doModifyLimitQuery($query, $limit, $offset)
+ protected function doModifyLimitQuery(string $query, ?int $limit, int $offset) : string
{
$limitOffsetClause = '';
- if ($limit > 0) {
+ if ($limit !== null) {
$limitOffsetClause = 'TOP ' . $limit . ' ';
}
if ($offset > 0) {
- if ($limit === 0) {
+ if ($limit === null) {
$limitOffsetClause = 'TOP ALL ';
}
@@ -1342,12 +1385,26 @@ protected function doModifyLimitQuery($query, $limit, $offset)
*/
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 = '';
if (! $index->isPrimary() && $index->hasFlag('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;
}
@@ -1466,44 +1523,45 @@ protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed)
protected function initializeDoctrineTypeMappings()
{
$this->doctrineTypeMapping = [
- 'char' => 'string',
- 'long nvarchar' => 'text',
- 'long varchar' => 'text',
- 'nchar' => 'string',
- 'ntext' => 'text',
- 'nvarchar' => 'string',
- 'text' => 'text',
- 'uniqueidentifierstr' => 'guid',
- 'varchar' => 'string',
- 'xml' => 'text',
- 'bigint' => 'bigint',
- 'unsigned bigint' => 'bigint',
- 'bit' => 'boolean',
- 'decimal' => 'decimal',
- 'double' => 'float',
- 'float' => 'float',
- 'int' => 'integer',
- 'integer' => 'integer',
- 'unsigned int' => 'integer',
- 'numeric' => 'decimal',
- 'smallint' => 'smallint',
- 'unsigned smallint' => 'smallint',
- 'tinyint' => 'smallint',
- 'unsigned tinyint' => 'smallint',
- 'money' => 'decimal',
- 'smallmoney' => 'decimal',
- 'long varbit' => 'text',
- 'varbit' => 'string',
- 'date' => 'date',
- 'datetime' => 'datetime',
- 'smalldatetime' => 'datetime',
- 'time' => 'time',
- 'timestamp' => 'datetime',
- 'binary' => 'binary',
- 'image' => 'blob',
- 'long binary' => 'blob',
- 'uniqueidentifier' => 'guid',
- 'varbinary' => 'binary',
+ 'bigint' => 'bigint',
+ 'binary' => 'binary',
+ 'bit' => 'boolean',
+ 'char' => 'string',
+ 'decimal' => 'decimal',
+ 'date' => 'date',
+ 'datetime' => 'datetime',
+ 'double' => 'float',
+ 'float' => 'float',
+ 'image' => 'blob',
+ 'int' => 'integer',
+ 'integer' => 'integer',
+ 'long binary' => 'blob',
+ 'long nvarchar' => 'text',
+ 'long varbit' => 'text',
+ 'long varchar' => 'text',
+ 'money' => 'decimal',
+ 'nchar' => 'string',
+ 'ntext' => 'text',
+ 'numeric' => 'decimal',
+ 'nvarchar' => 'string',
+ 'smalldatetime' => 'datetime',
+ 'smallint' => 'smallint',
+ 'smallmoney' => 'decimal',
+ 'text' => 'text',
+ 'time' => 'time',
+ 'timestamp' => 'datetime',
+ 'timestamp with time zone' => 'datetime',
+ 'tinyint' => 'smallint',
+ 'uniqueidentifier' => 'guid',
+ 'uniqueidentifierstr' => 'guid',
+ 'unsigned bigint' => 'bigint',
+ 'unsigned int' => 'integer',
+ 'unsigned smallint' => 'smallint',
+ 'unsigned tinyint' => 'smallint',
+ 'varbinary' => 'binary',
+ 'varbit' => 'string',
+ 'varchar' => 'string',
+ 'xml' => 'text',
];
}
}
diff --git a/lib/Doctrine/DBAL/Platforms/SQLAzurePlatform.php b/lib/Doctrine/DBAL/Platforms/SQLAzurePlatform.php
index a104848f84e..c95d93c9a86 100644
--- a/lib/Doctrine/DBAL/Platforms/SQLAzurePlatform.php
+++ b/lib/Doctrine/DBAL/Platforms/SQLAzurePlatform.php
@@ -11,7 +11,7 @@
*
* - Create tables with the FEDERATED ON syntax.
*/
-class SQLAzurePlatform extends SQLServer2008Platform
+class SQLAzurePlatform extends SQLServerPlatform
{
/**
* {@inheritDoc}
diff --git a/lib/Doctrine/DBAL/Platforms/SQLServer2005Platform.php b/lib/Doctrine/DBAL/Platforms/SQLServer2005Platform.php
deleted file mode 100644
index 1026a934f00..00000000000
--- a/lib/Doctrine/DBAL/Platforms/SQLServer2005Platform.php
+++ /dev/null
@@ -1,46 +0,0 @@
-doctrineTypeMapping['datetime2'] = 'datetime';
- $this->doctrineTypeMapping['date'] = 'date';
- $this->doctrineTypeMapping['time'] = 'time';
- $this->doctrineTypeMapping['datetimeoffset'] = 'datetimetz';
- }
-
- /**
- * {@inheritdoc}
- *
- * Returns Microsoft SQL Server 2008 specific keywords class
- */
- protected function getReservedKeywordsClass()
- {
- return Keywords\SQLServer2008Keywords::class;
- }
-
- protected function getLikeWildcardCharacters() : string
- {
- return parent::getLikeWildcardCharacters() . '[]^';
- }
-}
diff --git a/lib/Doctrine/DBAL/Platforms/SQLServer2012Platform.php b/lib/Doctrine/DBAL/Platforms/SQLServer2012Platform.php
index 009a37d33b0..afc6a32b060 100644
--- a/lib/Doctrine/DBAL/Platforms/SQLServer2012Platform.php
+++ b/lib/Doctrine/DBAL/Platforms/SQLServer2012Platform.php
@@ -6,6 +6,7 @@
use const PREG_OFFSET_CAPTURE;
use function preg_match;
use function preg_match_all;
+use function sprintf;
use function substr_count;
/**
@@ -14,7 +15,7 @@
* Differences to SQL Server 2008 and before are that sequences are introduced,
* and support for the new OFFSET... FETCH syntax for result pagination has been added.
*/
-class SQLServer2012Platform extends SQLServer2008Platform
+class SQLServer2012Platform extends SQLServerPlatform
{
/**
* {@inheritdoc}
@@ -92,7 +93,7 @@ protected function getReservedKeywordsClass()
/**
* {@inheritdoc}
*/
- protected function doModifyLimitQuery($query, $limit, $offset = null)
+ protected function doModifyLimitQuery(string $query, ?int $limit, int $offset) : string
{
if ($limit === null && $offset <= 0) {
return $query;
@@ -125,17 +126,13 @@ protected function doModifyLimitQuery($query, $limit, $offset = null)
}
}
- if ($offset === null) {
- $offset = 0;
- }
-
// This looks somewhat like MYSQL, but limit/offset are in inverse positions
// Supposedly SQL:2008 core standard.
// Per TSQL spec, FETCH NEXT n ROWS ONLY is not valid without OFFSET n ROWS.
- $query .= ' OFFSET ' . (int) $offset . ' ROWS';
+ $query .= sprintf(' OFFSET %d ROWS', $offset);
if ($limit !== null) {
- $query .= ' FETCH NEXT ' . (int) $limit . ' ROWS ONLY';
+ $query .= sprintf(' FETCH NEXT %d ROWS ONLY', $limit);
}
return $query;
diff --git a/lib/Doctrine/DBAL/Platforms/SQLServerPlatform.php b/lib/Doctrine/DBAL/Platforms/SQLServerPlatform.php
index 88578690d77..77751f0fd99 100644
--- a/lib/Doctrine/DBAL/Platforms/SQLServerPlatform.php
+++ b/lib/Doctrine/DBAL/Platforms/SQLServerPlatform.php
@@ -387,18 +387,6 @@ public function getDefaultConstraintDeclarationSQL($table, array $column)
' FOR ' . $columnName->getQuotedName($this);
}
- /**
- * {@inheritDoc}
- */
- public function getUniqueConstraintDeclarationSQL($name, Index $index)
- {
- $constraint = parent::getUniqueConstraintDeclarationSQL($name, $index);
-
- $constraint = $this->_appendUniqueConstraintDefinition($constraint, $index);
-
- return $constraint;
- }
-
/**
* {@inheritDoc}
*/
@@ -886,7 +874,7 @@ public function getListTablesSQL()
{
// "sysdiagrams" table must be ignored as it's internal SQL Server table for Database Diagrams
// Category 2 must be ignored as it is "MS SQL Server 'pseudo-system' object[s]" for replication
- return "SELECT name FROM sysobjects WHERE type = 'U' AND name != 'sysdiagrams' AND category != 2 ORDER BY name";
+ return "SELECT name, SCHEMA_NAME (uid) AS schema_name FROM sysobjects WHERE type = 'U' AND name != 'sysdiagrams' AND category != 2 ORDER BY name";
}
/**
@@ -1014,16 +1002,6 @@ public function getDropViewSQL($name)
return 'DROP VIEW ' . $name;
}
- /**
- * {@inheritDoc}
- *
- * @deprecated Use application-generated UUIDs instead
- */
- public function getGuidExpression()
- {
- return 'NEWID()';
- }
-
/**
* {@inheritDoc}
*/
@@ -1174,6 +1152,14 @@ public function getGuidTypeDeclarationSQL(array $field)
return 'UNIQUEIDENTIFIER';
}
+ /**
+ * {@inheritDoc}
+ */
+ public function getDateTimeTzTypeDeclarationSQL(array $fieldDeclaration)
+ {
+ return 'DATETIMEOFFSET(6)';
+ }
+
/**
* {@inheritDoc}
*/
@@ -1219,7 +1205,9 @@ protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef)
*/
public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration)
{
- return 'DATETIME';
+ // 3 - microseconds precision length
+ // http://msdn.microsoft.com/en-us/library/ms187819.aspx
+ return 'DATETIME2(6)';
}
/**
@@ -1227,7 +1215,7 @@ public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration)
*/
public function getDateTypeDeclarationSQL(array $fieldDeclaration)
{
- return 'DATETIME';
+ return 'DATE';
}
/**
@@ -1235,7 +1223,7 @@ public function getDateTypeDeclarationSQL(array $fieldDeclaration)
*/
public function getTimeTypeDeclarationSQL(array $fieldDeclaration)
{
- return 'DATETIME';
+ return 'TIME(0)';
}
/**
@@ -1249,7 +1237,7 @@ public function getBooleanTypeDeclarationSQL(array $field)
/**
* {@inheritDoc}
*/
- protected function doModifyLimitQuery($query, $limit, $offset = null)
+ protected function doModifyLimitQuery(string $query, ?int $limit, int $offset) : string
{
$where = [];
@@ -1381,7 +1369,7 @@ private function isOrderByInTopNSubquery($query, $currentPosition)
*/
public function supportsLimitOffset()
{
- return false;
+ return true;
}
/**
@@ -1425,7 +1413,7 @@ public function getTemporaryTableName($tableName)
*/
public function getDateTimeFormatString()
{
- return 'Y-m-d H:i:s.000';
+ return 'Y-m-d H:i:s.u';
}
/**
@@ -1433,7 +1421,7 @@ public function getDateTimeFormatString()
*/
public function getDateFormatString()
{
- return 'Y-m-d H:i:s.000';
+ return 'Y-m-d';
}
/**
@@ -1441,7 +1429,7 @@ public function getDateFormatString()
*/
public function getTimeFormatString()
{
- return 'Y-m-d H:i:s.000';
+ return 'H:i:s';
}
/**
@@ -1449,7 +1437,7 @@ public function getTimeFormatString()
*/
public function getDateTimeTzFormatString()
{
- return $this->getDateTimeFormatString();
+ return 'Y-m-d H:i:s.u P';
}
/**
@@ -1466,31 +1454,35 @@ public function getName()
protected function initializeDoctrineTypeMappings()
{
$this->doctrineTypeMapping = [
- 'bigint' => 'bigint',
- 'numeric' => 'decimal',
- 'bit' => 'boolean',
- 'smallint' => 'smallint',
- 'decimal' => 'decimal',
- 'smallmoney' => 'integer',
- 'int' => 'integer',
- 'tinyint' => 'smallint',
- 'money' => 'integer',
- 'float' => 'float',
- 'real' => 'float',
- 'double' => 'float',
+ 'bigint' => 'bigint',
+ 'binary' => 'binary',
+ 'bit' => 'boolean',
+ 'char' => 'string',
+ 'date' => 'date',
+ 'datetime' => 'datetime',
+ 'datetime2' => 'datetime',
+ 'datetimeoffset' => 'datetimetz',
+ 'decimal' => 'decimal',
+ 'double' => 'float',
'double precision' => 'float',
- 'smalldatetime' => 'datetime',
- 'datetime' => 'datetime',
- 'char' => 'string',
- 'varchar' => 'string',
- 'text' => 'text',
- 'nchar' => 'string',
- 'nvarchar' => 'string',
- 'ntext' => 'text',
- 'binary' => 'binary',
- 'varbinary' => 'binary',
- 'image' => 'blob',
+ 'float' => 'float',
+ 'image' => 'blob',
+ 'int' => 'integer',
+ 'money' => 'integer',
+ 'nchar' => 'string',
+ 'ntext' => 'text',
+ 'numeric' => 'decimal',
+ 'nvarchar' => 'string',
+ 'real' => 'float',
+ 'smalldatetime' => 'datetime',
+ 'smallint' => 'smallint',
+ 'smallmoney' => 'integer',
+ 'text' => 'text',
+ 'time' => 'time',
+ 'tinyint' => 'smallint',
'uniqueidentifier' => 'guid',
+ 'varbinary' => 'binary',
+ 'varchar' => 'string',
];
}
@@ -1651,6 +1643,14 @@ public function getColumnDeclarationSQL($name, array $field)
return $name . ' ' . $columnDef;
}
+ /**
+ * {@inheritdoc}
+ */
+ protected function getLikeWildcardCharacters() : string
+ {
+ return parent::getLikeWildcardCharacters() . '[]^';
+ }
+
/**
* Returns a unique default constraint name for a table and column.
*
diff --git a/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php b/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php
index 819421d3469..7ae69a515ad 100644
--- a/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php
+++ b/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php
@@ -40,19 +40,6 @@ public function getRegexpExpression()
return 'REGEXP';
}
- /**
- * {@inheritDoc}
- *
- * @deprecated Use application-generated UUIDs instead
- */
- public function getGuidExpression()
- {
- return "HEX(RANDOMBLOB(4)) || '-' || HEX(RANDOMBLOB(2)) || '-4' || "
- . "SUBSTR(HEX(RANDOMBLOB(2)), 2) || '-' || "
- . "SUBSTR('89AB', 1 + (ABS(RANDOM()) % 4), 1) || "
- . "SUBSTR(HEX(RANDOMBLOB(2)), 2) || '-' || HEX(RANDOMBLOB(6))";
- }
-
/**
* {@inheritDoc}
*/
@@ -313,9 +300,9 @@ public function getForeignKeyDeclarationSQL(ForeignKeyConstraint $foreignKey)
/**
* {@inheritDoc}
*/
- protected function _getCreateTableSQL($name, array $columns, array $options = [])
+ protected function _getCreateTableSQL($tableName, array $columns, array $options = [])
{
- $name = str_replace('.', '__', $name);
+ $tableName = str_replace('.', '__', $tableName);
$queryFields = $this->getColumnDeclarationListSQL($columns);
if (isset($options['uniqueConstraints']) && ! empty($options['uniqueConstraints'])) {
@@ -332,7 +319,7 @@ protected function _getCreateTableSQL($name, array $columns, array $options = []
}
}
- $query = ['CREATE TABLE ' . $name . ' (' . $queryFields . ')'];
+ $query = ['CREATE TABLE ' . $tableName . ' (' . $queryFields . ')'];
if (isset($options['alter']) && $options['alter'] === true) {
return $query;
@@ -340,13 +327,13 @@ protected function _getCreateTableSQL($name, array $columns, array $options = []
if (isset($options['indexes']) && ! empty($options['indexes'])) {
foreach ($options['indexes'] as $indexDef) {
- $query[] = $this->getCreateIndexSQL($indexDef, $name);
+ $query[] = $this->getCreateIndexSQL($indexDef, $tableName);
}
}
if (isset($options['unique']) && ! empty($options['unique'])) {
foreach ($options['unique'] as $indexDef) {
- $query[] = $this->getCreateIndexSQL($indexDef, $name);
+ $query[] = $this->getCreateIndexSQL($indexDef, $tableName);
}
}
@@ -381,8 +368,9 @@ private function getNonAutoincrementPrimaryKeyDefinition(array $columns, array $
*/
protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed)
{
- return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(255)')
- : ($length ? 'VARCHAR(' . $length . ')' : 'TEXT');
+ return $fixed
+ ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(255)')
+ : ($length ? 'VARCHAR(' . $length . ')' : 'TEXT');
}
/**
@@ -611,38 +599,39 @@ public function getInlineColumnCommentSQL($comment)
protected function initializeDoctrineTypeMappings()
{
$this->doctrineTypeMapping = [
- 'boolean' => 'boolean',
- 'tinyint' => 'boolean',
- 'smallint' => 'smallint',
- 'mediumint' => 'integer',
- 'int' => 'integer',
- 'integer' => 'integer',
- 'serial' => 'integer',
'bigint' => 'bigint',
'bigserial' => 'bigint',
- 'clob' => 'text',
- 'tinytext' => 'text',
- 'mediumtext' => 'text',
- 'longtext' => 'text',
- 'text' => 'text',
- 'varchar' => 'string',
- 'longvarchar' => 'string',
- 'varchar2' => 'string',
- 'nvarchar' => 'string',
- 'image' => 'string',
- 'ntext' => 'string',
+ 'blob' => 'blob',
+ 'boolean' => 'boolean',
'char' => 'string',
+ 'clob' => 'text',
'date' => 'date',
'datetime' => 'datetime',
- 'timestamp' => 'datetime',
- 'time' => 'time',
- 'float' => 'float',
+ 'decimal' => 'decimal',
'double' => 'float',
'double precision' => 'float',
- 'real' => 'float',
- 'decimal' => 'decimal',
+ 'float' => 'float',
+ 'image' => 'string',
+ 'int' => 'integer',
+ 'integer' => 'integer',
+ 'longtext' => 'text',
+ 'longvarchar' => 'string',
+ 'mediumint' => 'integer',
+ 'mediumtext' => 'text',
+ 'ntext' => 'string',
'numeric' => 'decimal',
- 'blob' => 'blob',
+ 'nvarchar' => 'string',
+ 'real' => 'float',
+ 'serial' => 'integer',
+ 'smallint' => 'smallint',
+ 'string' => 'string',
+ 'text' => 'text',
+ 'time' => 'time',
+ 'timestamp' => 'datetime',
+ 'tinyint' => 'boolean',
+ 'tinytext' => 'text',
+ 'varchar' => 'string',
+ 'varchar2' => 'string',
];
}
@@ -700,10 +689,10 @@ protected function getPostAlterTableIndexForeignKeySQL(TableDiff $diff)
/**
* {@inheritDoc}
*/
- protected function doModifyLimitQuery($query, $limit, $offset)
+ protected function doModifyLimitQuery(string $query, ?int $limit, int $offset) : string
{
if ($limit === null && $offset > 0) {
- return $query . ' LIMIT -1 OFFSET ' . $offset;
+ $limit = -1;
}
return parent::doModifyLimitQuery($query, $limit, $offset);
@@ -893,10 +882,11 @@ public function getAlterTableSQL(TableDiff $diff)
$sql = [];
$tableSql = [];
+
if (! $this->onSchemaAlterTable($diff, $tableSql)) {
$dataTable = new Table('__temp__' . $table->getName());
- $newTable = new Table($table->getQuotedName($this), $columns, $this->getPrimaryIndexInAlteredTable($diff), $this->getForeignKeysInAlteredTable($diff), 0, $table->getOptions());
+ $newTable = new Table($table->getQuotedName($this), $columns, $this->getPrimaryIndexInAlteredTable($diff), [], $this->getForeignKeysInAlteredTable($diff), $table->getOptions());
$newTable->addOption('alter', true);
$sql = $this->getPreAlterTableIndexForeignKeySQL($diff);
diff --git a/lib/Doctrine/DBAL/Portability/Connection.php b/lib/Doctrine/DBAL/Portability/Connection.php
index 32186dcb0ec..0fac1a9dffd 100644
--- a/lib/Doctrine/DBAL/Portability/Connection.php
+++ b/lib/Doctrine/DBAL/Portability/Connection.php
@@ -5,10 +5,11 @@
use Doctrine\DBAL\Cache\QueryCacheProfile;
use Doctrine\DBAL\ColumnCase;
use Doctrine\DBAL\Driver\PDOConnection;
+use Doctrine\DBAL\Driver\ResultStatement;
+use Doctrine\DBAL\Driver\Statement as DriverStatement;
use PDO;
use const CASE_LOWER;
use const CASE_UPPER;
-use function func_get_args;
/**
* Portability wrapper for a Connection.
@@ -26,7 +27,6 @@ class Connection extends \Doctrine\DBAL\Connection
public const PORTABILITY_POSTGRESQL = 13;
public const PORTABILITY_SQLITE = 13;
public const PORTABILITY_OTHERVENDORS = 12;
- public const PORTABILITY_DRIZZLE = 13;
public const PORTABILITY_SQLANYWHERE = 13;
public const PORTABILITY_SQLSRV = 13;
@@ -51,8 +51,6 @@ public function connect()
$params['portability'] &= self::PORTABILITY_POSTGRESQL;
} elseif ($this->getDatabasePlatform()->getName() === 'sqlite') {
$params['portability'] &= self::PORTABILITY_SQLITE;
- } elseif ($this->getDatabasePlatform()->getName() === 'drizzle') {
- $params['portability'] &= self::PORTABILITY_DRIZZLE;
} elseif ($this->getDatabasePlatform()->getName() === 'sqlanywhere') {
$params['portability'] &= self::PORTABILITY_SQLANYWHERE;
} elseif ($this->getDatabasePlatform()->getName() === 'db2') {
@@ -68,7 +66,7 @@ public function connect()
if (isset($params['fetch_case']) && $this->portability & self::PORTABILITY_FIX_CASE) {
if ($this->_conn instanceof PDOConnection) {
// make use of c-level support for case handling
- $this->_conn->setAttribute(PDO::ATTR_CASE, $params['fetch_case']);
+ $this->_conn->getWrappedConnection()->setAttribute(PDO::ATTR_CASE, $params['fetch_case']);
} else {
$this->case = $params['fetch_case'] === ColumnCase::LOWER ? CASE_LOWER : CASE_UPPER;
}
@@ -97,7 +95,7 @@ public function getFetchCase()
/**
* {@inheritdoc}
*/
- public function executeQuery($query, array $params = [], $types = [], ?QueryCacheProfile $qcp = null)
+ public function executeQuery(string $query, array $params = [], $types = [], ?QueryCacheProfile $qcp = null) : ResultStatement
{
$stmt = new Statement(parent::executeQuery($query, $params, $types, $qcp), $this);
$stmt->setFetchMode($this->defaultFetchMode);
@@ -108,9 +106,9 @@ public function executeQuery($query, array $params = [], $types = [], ?QueryCach
/**
* {@inheritdoc}
*/
- public function prepare($statement)
+ public function prepare(string $sql) : DriverStatement
{
- $stmt = new Statement(parent::prepare($statement), $this);
+ $stmt = new Statement(parent::prepare($sql), $this);
$stmt->setFetchMode($this->defaultFetchMode);
return $stmt;
@@ -119,11 +117,11 @@ public function prepare($statement)
/**
* {@inheritdoc}
*/
- public function query()
+ public function query(string $sql) : ResultStatement
{
$this->connect();
- $stmt = $this->_conn->query(...func_get_args());
+ $stmt = $this->_conn->query($sql);
$stmt = new Statement($stmt, $this);
$stmt->setFetchMode($this->defaultFetchMode);
diff --git a/lib/Doctrine/DBAL/Portability/Statement.php b/lib/Doctrine/DBAL/Portability/Statement.php
index 1499ff1bf48..24bc166d3b0 100644
--- a/lib/Doctrine/DBAL/Portability/Statement.php
+++ b/lib/Doctrine/DBAL/Portability/Statement.php
@@ -7,7 +7,6 @@
use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\ParameterType;
use IteratorAggregate;
-use PDO;
use function array_change_key_case;
use function is_string;
use function rtrim;
@@ -100,11 +99,11 @@ public function execute($params = null)
/**
* {@inheritdoc}
*/
- public function setFetchMode($fetchMode, $arg1 = null, $arg2 = null)
+ public function setFetchMode($fetchMode, ...$args)
{
$this->defaultFetchMode = $fetchMode;
- return $this->stmt->setFetchMode($fetchMode, $arg1, $arg2);
+ return $this->stmt->setFetchMode($fetchMode, ...$args);
}
/**
@@ -118,11 +117,11 @@ public function getIterator()
/**
* {@inheritdoc}
*/
- public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEXT, $cursorOffset = 0)
+ public function fetch($fetchMode = null, ...$args)
{
$fetchMode = $fetchMode ?: $this->defaultFetchMode;
- $row = $this->stmt->fetch($fetchMode);
+ $row = $this->stmt->fetch($fetchMode, ...$args);
$iterateRow = $this->portability & (Connection::PORTABILITY_EMPTY_TO_NULL|Connection::PORTABILITY_RTRIM);
$fixCase = $this->case !== null
@@ -137,15 +136,11 @@ public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEX
/**
* {@inheritdoc}
*/
- public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = null)
+ public function fetchAll($fetchMode = null, ...$args)
{
$fetchMode = $fetchMode ?: $this->defaultFetchMode;
- if ($fetchArgument) {
- $rows = $this->stmt->fetchAll($fetchMode, $fetchArgument);
- } else {
- $rows = $this->stmt->fetchAll($fetchMode);
- }
+ $rows = $this->stmt->fetchAll($fetchMode, ...$args);
$iterateRow = $this->portability & (Connection::PORTABILITY_EMPTY_TO_NULL|Connection::PORTABILITY_RTRIM);
$fixCase = $this->case !== null
@@ -226,7 +221,7 @@ public function fetchColumn($columnIndex = 0)
/**
* {@inheritdoc}
*/
- public function rowCount()
+ public function rowCount() : int
{
return $this->stmt->rowCount();
}
diff --git a/lib/Doctrine/DBAL/Query/QueryBuilder.php b/lib/Doctrine/DBAL/Query/QueryBuilder.php
index 12584d960ab..57f6cd98959 100644
--- a/lib/Doctrine/DBAL/Query/QueryBuilder.php
+++ b/lib/Doctrine/DBAL/Query/QueryBuilder.php
@@ -1128,7 +1128,7 @@ private function getFromClauses()
// Loop through all FROM clauses
foreach ($this->sqlParts['from'] as $from) {
- if ($from['alias'] === null) {
+ if ($from['alias'] === null || $from['alias'] === $from['table']) {
$tableSql = $from['table'];
$tableReference = $from['table'];
} else {
@@ -1187,7 +1187,14 @@ private function getSQLForInsert()
*/
private function getSQLForUpdate()
{
- $table = $this->sqlParts['from']['table'] . ($this->sqlParts['from']['alias'] ? ' ' . $this->sqlParts['from']['alias'] : '');
+ $from = $this->sqlParts['from'];
+
+ if ($from['alias'] === null || $from['alias'] === $from['table']) {
+ $table = $from['table'];
+ } else {
+ $table = $from['table'] . ' ' . $from['alias'];
+ }
+
return 'UPDATE ' . $table
. ' SET ' . implode(', ', $this->sqlParts['set'])
. ($this->sqlParts['where'] !== null ? ' WHERE ' . ((string) $this->sqlParts['where']) : '');
@@ -1200,7 +1207,14 @@ private function getSQLForUpdate()
*/
private function getSQLForDelete()
{
- $table = $this->sqlParts['from']['table'] . ($this->sqlParts['from']['alias'] ? ' ' . $this->sqlParts['from']['alias'] : '');
+ $from = $this->sqlParts['from'];
+
+ if ($from['alias'] === null || $from['alias'] === $from['table']) {
+ $table = $from['table'];
+ } else {
+ $table = $from['table'] . ' ' . $from['alias'];
+ }
+
return 'DELETE FROM ' . $table . ($this->sqlParts['where'] !== null ? ' WHERE ' . ((string) $this->sqlParts['where']) : '');
}
diff --git a/lib/Doctrine/DBAL/Schema/AbstractSchemaManager.php b/lib/Doctrine/DBAL/Schema/AbstractSchemaManager.php
index 9b917427fd8..0d73b14f64f 100644
--- a/lib/Doctrine/DBAL/Schema/AbstractSchemaManager.php
+++ b/lib/Doctrine/DBAL/Schema/AbstractSchemaManager.php
@@ -263,12 +263,14 @@ public function listTableDetails($tableName)
{
$columns = $this->listTableColumns($tableName);
$foreignKeys = [];
+
if ($this->_platform->supportsForeignKeyConstraints()) {
$foreignKeys = $this->listTableForeignKeys($tableName);
}
+
$indexes = $this->listTableIndexes($tableName);
- return new Table($tableName, $columns, $indexes, $foreignKeys, false, []);
+ return new Table($tableName, $columns, $indexes, [], $foreignKeys, []);
}
/**
@@ -587,6 +589,7 @@ public function dropAndCreateView(View $view)
public function alterTable(TableDiff $tableDiff)
{
$queries = $this->_platform->getAlterTableSQL($tableDiff);
+
if (! is_array($queries) || ! count($queries)) {
return;
}
diff --git a/lib/Doctrine/DBAL/Schema/DrizzleSchemaManager.php b/lib/Doctrine/DBAL/Schema/DrizzleSchemaManager.php
deleted file mode 100644
index c334db2797b..00000000000
--- a/lib/Doctrine/DBAL/Schema/DrizzleSchemaManager.php
+++ /dev/null
@@ -1,103 +0,0 @@
-_platform->getDoctrineTypeMapping($dbType);
- $type = $this->extractDoctrineTypeFromComment($tableColumn['COLUMN_COMMENT'], $type);
- $tableColumn['COLUMN_COMMENT'] = $this->removeDoctrineTypeFromComment($tableColumn['COLUMN_COMMENT'], $type);
-
- $options = [
- 'notnull' => ! (bool) $tableColumn['IS_NULLABLE'],
- 'length' => (int) $tableColumn['CHARACTER_MAXIMUM_LENGTH'],
- 'default' => $tableColumn['COLUMN_DEFAULT'] ?? null,
- 'autoincrement' => (bool) $tableColumn['IS_AUTO_INCREMENT'],
- 'scale' => (int) $tableColumn['NUMERIC_SCALE'],
- 'precision' => (int) $tableColumn['NUMERIC_PRECISION'],
- 'comment' => isset($tableColumn['COLUMN_COMMENT']) && $tableColumn['COLUMN_COMMENT'] !== ''
- ? $tableColumn['COLUMN_COMMENT']
- : null,
- ];
-
- $column = new Column($tableColumn['COLUMN_NAME'], Type::getType($type), $options);
-
- if (! empty($tableColumn['COLLATION_NAME'])) {
- $column->setPlatformOption('collation', $tableColumn['COLLATION_NAME']);
- }
-
- return $column;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function _getPortableDatabaseDefinition($database)
- {
- return $database['SCHEMA_NAME'];
- }
-
- /**
- * {@inheritdoc}
- */
- protected function _getPortableTableDefinition($table)
- {
- return $table['TABLE_NAME'];
- }
-
- /**
- * {@inheritdoc}
- */
- public function _getPortableTableForeignKeyDefinition($tableForeignKey)
- {
- $columns = [];
- foreach (explode(',', $tableForeignKey['CONSTRAINT_COLUMNS']) as $value) {
- $columns[] = trim($value, ' `');
- }
-
- $refColumns = [];
- foreach (explode(',', $tableForeignKey['REFERENCED_TABLE_COLUMNS']) as $value) {
- $refColumns[] = trim($value, ' `');
- }
-
- return new ForeignKeyConstraint(
- $columns,
- $tableForeignKey['REFERENCED_TABLE_NAME'],
- $refColumns,
- $tableForeignKey['CONSTRAINT_NAME'],
- [
- 'onUpdate' => $tableForeignKey['UPDATE_RULE'],
- 'onDelete' => $tableForeignKey['DELETE_RULE'],
- ]
- );
- }
-
- /**
- * {@inheritdoc}
- */
- protected function _getPortableTableIndexesList($tableIndexes, $tableName = null)
- {
- $indexes = [];
- foreach ($tableIndexes as $k) {
- $k['primary'] = (bool) $k['primary'];
- $indexes[] = $k;
- }
-
- return parent::_getPortableTableIndexesList($indexes, $tableName);
- }
-}
diff --git a/lib/Doctrine/DBAL/Schema/Index.php b/lib/Doctrine/DBAL/Schema/Index.php
index bae6d218cb6..ae658b69af2 100644
--- a/lib/Doctrine/DBAL/Schema/Index.php
+++ b/lib/Doctrine/DBAL/Schema/Index.php
@@ -57,6 +57,7 @@ public function __construct($indexName, array $columns, $isUnique = false, $isPr
$isUnique = $isUnique || $isPrimary;
$this->_setName($indexName);
+
$this->_isUnique = $isUnique;
$this->_isPrimary = $isPrimary;
$this->options = $options;
@@ -64,6 +65,7 @@ public function __construct($indexName, array $columns, $isUnique = false, $isPr
foreach ($columns as $column) {
$this->_addColumn($column);
}
+
foreach ($flags as $flag) {
$this->addFlag($flag);
}
diff --git a/lib/Doctrine/DBAL/Schema/SchemaException.php b/lib/Doctrine/DBAL/Schema/SchemaException.php
index 213d218475b..658663ac16a 100644
--- a/lib/Doctrine/DBAL/Schema/SchemaException.php
+++ b/lib/Doctrine/DBAL/Schema/SchemaException.php
@@ -18,7 +18,8 @@ class SchemaException extends DBALException
public const SEQUENCE_ALREADY_EXISTS = 80;
public const INDEX_INVALID_NAME = 90;
public const FOREIGNKEY_DOESNT_EXIST = 100;
- public const NAMESPACE_ALREADY_EXISTS = 110;
+ public const CONSTRAINT_DOESNT_EXIST = 110;
+ public const NAMESPACE_ALREADY_EXISTS = 120;
/**
* @param string $tableName
@@ -142,6 +143,21 @@ public static function sequenceDoesNotExist($sequenceName)
return new self("There exists no sequence with the name '" . $sequenceName . "'.", self::SEQUENCE_DOENST_EXIST);
}
+ /**
+ * @param string $constraintName
+ * @param string $table
+ *
+ * @return self
+ */
+ public static function uniqueConstraintDoesNotExist($constraintName, $table)
+ {
+ return new self(sprintf(
+ 'There exists no unique constraint with the name "%s" on table "%s".',
+ $constraintName,
+ $table
+ ), self::CONSTRAINT_DOESNT_EXIST);
+ }
+
/**
* @param string $fkName
* @param string $table
diff --git a/lib/Doctrine/DBAL/Schema/Table.php b/lib/Doctrine/DBAL/Schema/Table.php
index 4822cf6b17d..e43c086cb82 100644
--- a/lib/Doctrine/DBAL/Schema/Table.php
+++ b/lib/Doctrine/DBAL/Schema/Table.php
@@ -5,15 +5,17 @@
use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Schema\Visitor\Visitor;
use Doctrine\DBAL\Types\Type;
-use const ARRAY_FILTER_USE_KEY;
-use function array_filter;
+use function array_keys;
use function array_merge;
+use function array_search;
+use function array_unique;
use function in_array;
use function is_numeric;
use function is_string;
use function preg_match;
use function strlen;
use function strtolower;
+use function uksort;
/**
* Object Representation of a table.
@@ -35,6 +37,9 @@ class Table extends AbstractAsset
/** @var string */
protected $_primaryKeyName = false;
+ /** @var UniqueConstraint[] */
+ protected $_uniqueConstraints = [];
+
/** @var ForeignKeyConstraint[] */
protected $_fkConstraints = [];
@@ -48,14 +53,20 @@ class Table extends AbstractAsset
* @param string $tableName
* @param Column[] $columns
* @param Index[] $indexes
+ * @param UniqueConstraint[] $uniqueConstraints
* @param ForeignKeyConstraint[] $fkConstraints
- * @param int $idGeneratorType
* @param mixed[] $options
*
* @throws DBALException
*/
- public function __construct($tableName, array $columns = [], array $indexes = [], array $fkConstraints = [], $idGeneratorType = 0, array $options = [])
- {
+ public function __construct(
+ $tableName,
+ array $columns = [],
+ array $indexes = [],
+ array $uniqueConstraints = [],
+ array $fkConstraints = [],
+ array $options = []
+ ) {
if (strlen($tableName) === 0) {
throw DBALException::invalidTableName($tableName);
}
@@ -70,8 +81,12 @@ public function __construct($tableName, array $columns = [], array $indexes = []
$this->_addIndex($idx);
}
- foreach ($fkConstraints as $constraint) {
- $this->_addForeignKeyConstraint($constraint);
+ foreach ($uniqueConstraints as $uniqueConstraint) {
+ $this->_addUniqueConstraint($uniqueConstraint);
+ }
+
+ foreach ($fkConstraints as $fkConstraint) {
+ $this->_addForeignKeyConstraint($fkConstraint);
}
$this->_options = $options;
@@ -85,18 +100,6 @@ public function setSchemaConfig(SchemaConfig $schemaConfig)
$this->_schemaConfig = $schemaConfig;
}
- /**
- * @return int
- */
- protected function _getMaxIdentifierLength()
- {
- if ($this->_schemaConfig instanceof SchemaConfig) {
- return $this->_schemaConfig->getMaxIdentifierLength();
- }
-
- return 63;
- }
-
/**
* Sets the Primary Key.
*
@@ -117,6 +120,27 @@ public function setPrimaryKey(array $columns, $indexName = false)
return $this;
}
+ /**
+ * @param mixed[] $columnNames
+ * @param string|null $indexName
+ * @param string[] $flags
+ * @param mixed[] $options
+ *
+ * @return self
+ */
+ public function addUniqueConstraint(array $columnNames, $indexName = null, array $flags = [], array $options = [])
+ {
+ if ($indexName === null) {
+ $indexName = $this->_generateIdentifierName(
+ array_merge([$this->getName()], $columnNames),
+ 'uniq',
+ $this->_getMaxIdentifierLength()
+ );
+ }
+
+ return $this->_addUniqueConstraint($this->_createUniqueConstraint($columnNames, $indexName, $flags, $options));
+ }
+
/**
* @param mixed[][] $columnNames
* @param string|null $indexName
@@ -161,9 +185,11 @@ public function dropPrimaryKey()
public function dropIndex($indexName)
{
$indexName = $this->normalizeIdentifier($indexName);
+
if (! $this->hasIndex($indexName)) {
throw SchemaException::indexDoesNotExist($indexName, $this->_name);
}
+
unset($this->_indexes[$indexName]);
}
@@ -252,37 +278,6 @@ public function columnsAreIndexed(array $columnsNames)
return false;
}
- /**
- * @param mixed[][] $columnNames
- * @param string $indexName
- * @param bool $isUnique
- * @param bool $isPrimary
- * @param string[] $flags
- * @param mixed[] $options
- *
- * @return Index
- *
- * @throws SchemaException
- */
- private function _createIndex(array $columnNames, $indexName, $isUnique, $isPrimary, array $flags = [], array $options = [])
- {
- if (preg_match('(([^a-zA-Z0-9_]+))', $this->normalizeIdentifier($indexName))) {
- throw SchemaException::indexNameInvalid($indexName);
- }
-
- foreach ($columnNames as $columnName => $indexColOptions) {
- if (is_numeric($columnName) && is_string($indexColOptions)) {
- $columnName = $indexColOptions;
- }
-
- if (! $this->hasColumn($columnName)) {
- throw SchemaException::columnDoesNotExist($columnName, $this->_name);
- }
- }
-
- return new Index($indexName, $columnNames, $isUnique, $isPrimary, $flags, $options);
- }
-
/**
* @param string $columnName
* @param string $typeName
@@ -311,9 +306,11 @@ public function addColumn($columnName, $typeName, array $options = [])
*/
public function renameColumn($oldColumnName, $newColumnName)
{
- throw new DBALException('Table#renameColumn() was removed, because it drops and recreates ' .
- 'the column instead. There is no fix available, because a schema diff cannot reliably detect if a ' .
- 'column was renamed or one column was created and another one dropped.');
+ throw new DBALException(
+ 'Table#renameColumn() was removed, because it drops and recreates the column instead. ' .
+ 'There is no fix available, because a schema diff cannot reliably detect if a column ' .
+ 'was renamed or one column was created and another one dropped.'
+ );
}
/**
@@ -327,6 +324,7 @@ public function renameColumn($oldColumnName, $newColumnName)
public function changeColumn($columnName, array $options)
{
$column = $this->getColumn($columnName);
+
$column->setOptions($options);
return $this;
@@ -342,6 +340,7 @@ public function changeColumn($columnName, array $options)
public function dropColumn($columnName)
{
$columnName = $this->normalizeIdentifier($columnName);
+
unset($this->_columns[$columnName]);
return $this;
@@ -362,7 +361,13 @@ public function dropColumn($columnName)
*/
public function addForeignKeyConstraint($foreignTable, array $localColumnNames, array $foreignColumnNames, array $options = [], $constraintName = null)
{
- $constraintName = $constraintName ?: $this->_generateIdentifierName(array_merge((array) $this->getName(), $localColumnNames), 'fk', $this->_getMaxIdentifierLength());
+ if (! $constraintName) {
+ $constraintName = $this->_generateIdentifierName(
+ array_merge((array) $this->getName(), $localColumnNames),
+ 'fk',
+ $this->_getMaxIdentifierLength()
+ );
+ }
return $this->addNamedForeignKeyConstraint($constraintName, $foreignTable, $localColumnNames, $foreignColumnNames, $options);
}
@@ -424,9 +429,8 @@ public function addNamedForeignKeyConstraint($name, $foreignTable, array $localC
$name,
$options
);
- $this->_addForeignKeyConstraint($constraint);
- return $this;
+ return $this->_addForeignKeyConstraint($constraint);
}
/**
@@ -443,137 +447,95 @@ public function addOption($name, $value)
}
/**
- * @return void
+ * Returns whether this table has a foreign key constraint with the given name.
*
- * @throws SchemaException
+ * @param string $constraintName
+ *
+ * @return bool
*/
- protected function _addColumn(Column $column)
+ public function hasForeignKey($constraintName)
{
- $columnName = $column->getName();
- $columnName = $this->normalizeIdentifier($columnName);
-
- if (isset($this->_columns[$columnName])) {
- throw SchemaException::columnAlreadyExists($this->getName(), $columnName);
- }
+ $constraintName = $this->normalizeIdentifier($constraintName);
- $this->_columns[$columnName] = $column;
+ return isset($this->_fkConstraints[$constraintName]);
}
/**
- * Adds an index to the table.
+ * Returns the foreign key constraint with the given name.
*
- * @return self
+ * @param string $constraintName The constraint name.
*
- * @throws SchemaException
+ * @return ForeignKeyConstraint
+ *
+ * @throws SchemaException If the foreign key does not exist.
*/
- protected function _addIndex(Index $indexCandidate)
+ public function getForeignKey($constraintName)
{
- $indexName = $indexCandidate->getName();
- $indexName = $this->normalizeIdentifier($indexName);
- $replacedImplicitIndexes = [];
-
- foreach ($this->implicitIndexes as $name => $implicitIndex) {
- if (! $implicitIndex->isFullfilledBy($indexCandidate) || ! isset($this->_indexes[$name])) {
- continue;
- }
-
- $replacedImplicitIndexes[] = $name;
- }
-
- if ((isset($this->_indexes[$indexName]) && ! in_array($indexName, $replacedImplicitIndexes, true)) ||
- ($this->_primaryKeyName !== false && $indexCandidate->isPrimary())
- ) {
- throw SchemaException::indexAlreadyExists($indexName, $this->_name);
- }
-
- foreach ($replacedImplicitIndexes as $name) {
- unset($this->_indexes[$name], $this->implicitIndexes[$name]);
- }
+ $constraintName = $this->normalizeIdentifier($constraintName);
- if ($indexCandidate->isPrimary()) {
- $this->_primaryKeyName = $indexName;
+ if (! $this->hasForeignKey($constraintName)) {
+ throw SchemaException::foreignKeyDoesNotExist($constraintName, $this->_name);
}
- $this->_indexes[$indexName] = $indexCandidate;
-
- return $this;
+ return $this->_fkConstraints[$constraintName];
}
/**
+ * Removes the foreign key constraint with the given name.
+ *
+ * @param string $constraintName The constraint name.
+ *
* @return void
+ *
+ * @throws SchemaException
*/
- protected function _addForeignKeyConstraint(ForeignKeyConstraint $constraint)
+ public function removeForeignKey($constraintName)
{
- $constraint->setLocalTable($this);
-
- if (strlen($constraint->getName())) {
- $name = $constraint->getName();
- } else {
- $name = $this->_generateIdentifierName(
- array_merge((array) $this->getName(), $constraint->getLocalColumns()),
- 'fk',
- $this->_getMaxIdentifierLength()
- );
- }
- $name = $this->normalizeIdentifier($name);
-
- $this->_fkConstraints[$name] = $constraint;
-
- // add an explicit index on the foreign key columns. If there is already an index that fulfils this requirements drop the request.
- // In the case of __construct calling this method during hydration from schema-details all the explicitly added indexes
- // lead to duplicates. This creates computation overhead in this case, however no duplicate indexes are ever added (based on columns).
- $indexName = $this->_generateIdentifierName(
- array_merge([$this->getName()], $constraint->getColumns()),
- 'idx',
- $this->_getMaxIdentifierLength()
- );
- $indexCandidate = $this->_createIndex($constraint->getColumns(), $indexName, false, false);
+ $constraintName = $this->normalizeIdentifier($constraintName);
- foreach ($this->_indexes as $existingIndex) {
- if ($indexCandidate->isFullfilledBy($existingIndex)) {
- return;
- }
+ if (! $this->hasForeignKey($constraintName)) {
+ throw SchemaException::foreignKeyDoesNotExist($constraintName, $this->_name);
}
- $this->_addIndex($indexCandidate);
- $this->implicitIndexes[$this->normalizeIdentifier($indexName)] = $indexCandidate;
+ unset($this->_fkConstraints[$constraintName]);
}
/**
- * Returns whether this table has a foreign key constraint with the given name.
+ * Returns whether this table has a unique constraint with the given name.
*
* @param string $constraintName
*
* @return bool
*/
- public function hasForeignKey($constraintName)
+ public function hasUniqueConstraint($constraintName)
{
$constraintName = $this->normalizeIdentifier($constraintName);
- return isset($this->_fkConstraints[$constraintName]);
+ return isset($this->_uniqueConstraints[$constraintName]);
}
/**
- * Returns the foreign key constraint with the given name.
+ * Returns the unique constraint with the given name.
*
* @param string $constraintName The constraint name.
*
- * @return ForeignKeyConstraint
+ * @return UniqueConstraint
*
* @throws SchemaException If the foreign key does not exist.
*/
- public function getForeignKey($constraintName)
+ public function getUniqueConstraint($constraintName)
{
$constraintName = $this->normalizeIdentifier($constraintName);
- if (! $this->hasForeignKey($constraintName)) {
- throw SchemaException::foreignKeyDoesNotExist($constraintName, $this->_name);
+
+ if (! $this->hasUniqueConstraint($constraintName)) {
+ throw SchemaException::uniqueConstraintDoesNotExist($constraintName, $this->_name);
}
- return $this->_fkConstraints[$constraintName];
+ return $this->_uniqueConstraints[$constraintName];
}
/**
- * Removes the foreign key constraint with the given name.
+ * Removes the unique constraint with the given name.
*
* @param string $constraintName The constraint name.
*
@@ -581,14 +543,15 @@ public function getForeignKey($constraintName)
*
* @throws SchemaException
*/
- public function removeForeignKey($constraintName)
+ public function removeUniqueConstraint($constraintName)
{
$constraintName = $this->normalizeIdentifier($constraintName);
- if (! $this->hasForeignKey($constraintName)) {
- throw SchemaException::foreignKeyDoesNotExist($constraintName, $this->_name);
+
+ if (! $this->hasUniqueConstraint($constraintName)) {
+ throw SchemaException::uniqueConstraintDoesNotExist($constraintName, $this->_name);
}
- unset($this->_fkConstraints[$constraintName]);
+ unset($this->_uniqueConstraints[$constraintName]);
}
/**
@@ -598,41 +561,26 @@ public function removeForeignKey($constraintName)
*/
public function getColumns()
{
- $primaryKeyColumns = [];
+ $columns = $this->_columns;
+ $pkCols = [];
+ $fkCols = [];
+
if ($this->hasPrimaryKey()) {
- $primaryKeyColumns = $this->filterColumns($this->getPrimaryKey()->getColumns());
+ $pkCols = $this->getPrimaryKey()->getColumns();
}
- return array_merge($primaryKeyColumns, $this->getForeignKeyColumns(), $this->_columns);
- }
-
- /**
- * Returns foreign key columns
- *
- * @return Column[]
- */
- private function getForeignKeyColumns()
- {
- $foreignKeyColumns = [];
- foreach ($this->getForeignKeys() as $foreignKey) {
- /** @var ForeignKeyConstraint $foreignKey */
- $foreignKeyColumns = array_merge($foreignKeyColumns, $foreignKey->getColumns());
+ foreach ($this->getForeignKeys() as $fk) {
+ /** @var ForeignKeyConstraint $fk */
+ $fkCols = array_merge($fkCols, $fk->getColumns());
}
- return $this->filterColumns($foreignKeyColumns);
- }
- /**
- * Returns only columns that have specified names
- *
- * @param string[] $columnNames
- *
- * @return Column[]
- */
- private function filterColumns(array $columnNames)
- {
- return array_filter($this->_columns, static function ($columnName) use ($columnNames) {
- return in_array($columnName, $columnNames, true);
- }, ARRAY_FILTER_USE_KEY);
+ $colNames = array_unique(array_merge($pkCols, $fkCols, array_keys($columns)));
+
+ uksort($columns, static function ($a, $b) use ($colNames) {
+ return array_search($a, $colNames) >= array_search($b, $colNames);
+ });
+
+ return $columns;
}
/**
@@ -661,6 +609,7 @@ public function hasColumn($columnName)
public function getColumn($columnName)
{
$columnName = $this->normalizeIdentifier($columnName);
+
if (! $this->hasColumn($columnName)) {
throw SchemaException::columnDoesNotExist($columnName, $this->_name);
}
@@ -675,11 +624,9 @@ public function getColumn($columnName)
*/
public function getPrimaryKey()
{
- if (! $this->hasPrimaryKey()) {
- return null;
- }
-
- return $this->getIndex($this->_primaryKeyName);
+ return $this->hasPrimaryKey()
+ ? $this->getIndex($this->_primaryKeyName)
+ : null;
}
/**
@@ -733,6 +680,7 @@ public function hasIndex($indexName)
public function getIndex($indexName)
{
$indexName = $this->normalizeIdentifier($indexName);
+
if (! $this->hasIndex($indexName)) {
throw SchemaException::indexDoesNotExist($indexName, $this->_name);
}
@@ -748,6 +696,16 @@ public function getIndexes()
return $this->_indexes;
}
+ /**
+ * Returns the unique constraints.
+ *
+ * @return UniqueConstraint[]
+ */
+ public function getUniqueConstraints()
+ {
+ return $this->_uniqueConstraints;
+ }
+
/**
* Returns the foreign key constraints.
*
@@ -816,15 +774,166 @@ public function __clone()
foreach ($this->_columns as $k => $column) {
$this->_columns[$k] = clone $column;
}
+
foreach ($this->_indexes as $k => $index) {
$this->_indexes[$k] = clone $index;
}
+
foreach ($this->_fkConstraints as $k => $fk) {
$this->_fkConstraints[$k] = clone $fk;
$this->_fkConstraints[$k]->setLocalTable($this);
}
}
+ /**
+ * @return int
+ */
+ protected function _getMaxIdentifierLength()
+ {
+ return $this->_schemaConfig instanceof SchemaConfig
+ ? $this->_schemaConfig->getMaxIdentifierLength()
+ : 63;
+ }
+
+ /**
+ * @return void
+ *
+ * @throws SchemaException
+ */
+ protected function _addColumn(Column $column)
+ {
+ $columnName = $column->getName();
+ $columnName = $this->normalizeIdentifier($columnName);
+
+ if (isset($this->_columns[$columnName])) {
+ throw SchemaException::columnAlreadyExists($this->getName(), $columnName);
+ }
+
+ $this->_columns[$columnName] = $column;
+ }
+
+ /**
+ * Adds an index to the table.
+ *
+ * @return self
+ *
+ * @throws SchemaException
+ */
+ protected function _addIndex(Index $indexCandidate)
+ {
+ $indexName = $indexCandidate->getName();
+ $indexName = $this->normalizeIdentifier($indexName);
+ $replacedImplicitIndexes = [];
+
+ foreach ($this->implicitIndexes as $name => $implicitIndex) {
+ if (! $implicitIndex->isFullfilledBy($indexCandidate) || ! isset($this->_indexes[$name])) {
+ continue;
+ }
+
+ $replacedImplicitIndexes[] = $name;
+ }
+
+ if ((isset($this->_indexes[$indexName]) && ! in_array($indexName, $replacedImplicitIndexes, true)) ||
+ ($this->_primaryKeyName !== false && $indexCandidate->isPrimary())
+ ) {
+ throw SchemaException::indexAlreadyExists($indexName, $this->_name);
+ }
+
+ foreach ($replacedImplicitIndexes as $name) {
+ unset($this->_indexes[$name], $this->implicitIndexes[$name]);
+ }
+
+ if ($indexCandidate->isPrimary()) {
+ $this->_primaryKeyName = $indexName;
+ }
+
+ $this->_indexes[$indexName] = $indexCandidate;
+
+ return $this;
+ }
+
+ /**
+ * @return self
+ */
+ protected function _addUniqueConstraint(UniqueConstraint $constraint)
+ {
+ $name = strlen($constraint->getName())
+ ? $constraint->getName()
+ : $this->_generateIdentifierName(
+ array_merge((array) $this->getName(), $constraint->getLocalColumns()),
+ 'fk',
+ $this->_getMaxIdentifierLength()
+ );
+
+ $name = $this->normalizeIdentifier($name);
+
+ $this->_uniqueConstraints[$name] = $constraint;
+
+ // If there is already an index that fulfills this requirements drop the request. In the case of __construct
+ // calling this method during hydration from schema-details all the explicitly added indexes lead to duplicates.
+ // This creates computation overhead in this case, however no duplicate indexes are ever added (column based).
+ $indexName = $this->_generateIdentifierName(
+ array_merge([$this->getName()], $constraint->getColumns()),
+ 'idx',
+ $this->_getMaxIdentifierLength()
+ );
+
+ $indexCandidate = $this->_createIndex($constraint->getColumns(), $indexName, true, false);
+
+ foreach ($this->_indexes as $existingIndex) {
+ if ($indexCandidate->isFullfilledBy($existingIndex)) {
+ return $this;
+ }
+ }
+
+ $this->implicitIndexes[$this->normalizeIdentifier($indexName)] = $indexCandidate;
+
+ return $this;
+ }
+
+ /**
+ * @return self
+ */
+ protected function _addForeignKeyConstraint(ForeignKeyConstraint $constraint)
+ {
+ $constraint->setLocalTable($this);
+
+ $name = strlen($constraint->getName())
+ ? $constraint->getName()
+ : $this->_generateIdentifierName(
+ array_merge((array) $this->getName(), $constraint->getLocalColumns()),
+ 'fk',
+ $this->_getMaxIdentifierLength()
+ );
+
+ $name = $this->normalizeIdentifier($name);
+
+ $this->_fkConstraints[$name] = $constraint;
+
+ // add an explicit index on the foreign key columns.
+ // If there is already an index that fulfills this requirements drop the request. In the case of __construct
+ // calling this method during hydration from schema-details all the explicitly added indexes lead to duplicates.
+ // This creates computation overhead in this case, however no duplicate indexes are ever added (column based).
+ $indexName = $this->_generateIdentifierName(
+ array_merge([$this->getName()], $constraint->getColumns()),
+ 'idx',
+ $this->_getMaxIdentifierLength()
+ );
+
+ $indexCandidate = $this->_createIndex($constraint->getColumns(), $indexName, false, false);
+
+ foreach ($this->_indexes as $existingIndex) {
+ if ($indexCandidate->isFullfilledBy($existingIndex)) {
+ return $this;
+ }
+ }
+
+ $this->_addIndex($indexCandidate);
+ $this->implicitIndexes[$this->normalizeIdentifier($indexName)] = $indexCandidate;
+
+ return $this;
+ }
+
/**
* Normalizes a given identifier.
*
@@ -838,4 +947,64 @@ private function normalizeIdentifier($identifier)
{
return $this->trimQuotes(strtolower($identifier));
}
+
+ /**
+ * @param mixed[] $columnNames
+ * @param string $indexName
+ * @param mixed[] $flags
+ * @param mixed[] $options
+ *
+ * @return UniqueConstraint
+ *
+ * @throws SchemaException
+ */
+ private function _createUniqueConstraint(array $columnNames, $indexName, array $flags = [], array $options = [])
+ {
+ if (preg_match('(([^a-zA-Z0-9_]+))', $this->normalizeIdentifier($indexName))) {
+ throw SchemaException::indexNameInvalid($indexName);
+ }
+
+ foreach ($columnNames as $columnName => $indexColOptions) {
+ if (is_numeric($columnName) && is_string($indexColOptions)) {
+ $columnName = $indexColOptions;
+ }
+
+ if (! $this->hasColumn($columnName)) {
+ throw SchemaException::columnDoesNotExist($columnName, $this->_name);
+ }
+ }
+
+ return new UniqueConstraint($indexName, $columnNames, $flags, $options);
+ }
+
+ /**
+ * @param mixed[] $columnNames
+ * @param string $indexName
+ * @param bool $isUnique
+ * @param bool $isPrimary
+ * @param string[] $flags
+ * @param mixed[] $options
+ *
+ * @return Index
+ *
+ * @throws SchemaException
+ */
+ private function _createIndex(array $columnNames, $indexName, $isUnique, $isPrimary, array $flags = [], array $options = [])
+ {
+ if (preg_match('(([^a-zA-Z0-9_]+))', $this->normalizeIdentifier($indexName))) {
+ throw SchemaException::indexNameInvalid($indexName);
+ }
+
+ foreach ($columnNames as $columnName => $indexColOptions) {
+ if (is_numeric($columnName) && is_string($indexColOptions)) {
+ $columnName = $indexColOptions;
+ }
+
+ if (! $this->hasColumn($columnName)) {
+ throw SchemaException::columnDoesNotExist($columnName, $this->_name);
+ }
+ }
+
+ return new Index($indexName, $columnNames, $isUnique, $isPrimary, $flags, $options);
+ }
}
diff --git a/lib/Doctrine/DBAL/Schema/UniqueConstraint.php b/lib/Doctrine/DBAL/Schema/UniqueConstraint.php
new file mode 100644
index 00000000000..8d47424769c
--- /dev/null
+++ b/lib/Doctrine/DBAL/Schema/UniqueConstraint.php
@@ -0,0 +1,184 @@
+ Identifier)
+ *
+ * @var Identifier[]
+ */
+ protected $columns = [];
+
+ /**
+ * Platform specific flags
+ * array($flagName => true)
+ *
+ * @var true[]
+ */
+ protected $flags = [];
+
+ /**
+ * Platform specific options
+ *
+ * @var mixed[]
+ */
+ private $options = [];
+
+ /**
+ * @param string $indexName
+ * @param string[] $columns
+ * @param string[] $flags
+ * @param mixed[] $options
+ */
+ public function __construct($indexName, array $columns, array $flags = [], array $options = [])
+ {
+ $this->_setName($indexName);
+
+ $this->options = $options;
+
+ foreach ($columns as $column) {
+ $this->_addColumn($column);
+ }
+
+ foreach ($flags as $flag) {
+ $this->addFlag($flag);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getColumns()
+ {
+ return array_keys($this->columns);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getQuotedColumns(AbstractPlatform $platform)
+ {
+ $columns = [];
+
+ foreach ($this->columns as $column) {
+ $columns[] = $column->getQuotedName($platform);
+ }
+
+ return $columns;
+ }
+
+ /**
+ * @return string[]
+ */
+ public function getUnquotedColumns()
+ {
+ return array_map([$this, 'trimQuotes'], $this->getColumns());
+ }
+
+ /**
+ * Returns platform specific flags for unique constraint.
+ *
+ * @return string[]
+ */
+ public function getFlags()
+ {
+ return array_keys($this->flags);
+ }
+
+ /**
+ * Adds flag for a unique constraint that translates to platform specific handling.
+ *
+ * @param string $flag
+ *
+ * @return self
+ *
+ * @example $uniqueConstraint->addFlag('CLUSTERED')
+ */
+ public function addFlag($flag)
+ {
+ $this->flags[strtolower($flag)] = true;
+
+ return $this;
+ }
+
+ /**
+ * Does this unique constraint have a specific flag?
+ *
+ * @param string $flag
+ *
+ * @return bool
+ */
+ public function hasFlag($flag)
+ {
+ return isset($this->flags[strtolower($flag)]);
+ }
+
+ /**
+ * Removes a flag.
+ *
+ * @param string $flag
+ *
+ * @return void
+ */
+ public function removeFlag($flag)
+ {
+ unset($this->flags[strtolower($flag)]);
+ }
+
+ /**
+ * @param string $name
+ *
+ * @return bool
+ */
+ public function hasOption($name)
+ {
+ return isset($this->options[strtolower($name)]);
+ }
+
+ /**
+ * @param string $name
+ *
+ * @return mixed
+ */
+ public function getOption($name)
+ {
+ return $this->options[strtolower($name)];
+ }
+
+ /**
+ * @return mixed[]
+ */
+ public function getOptions()
+ {
+ return $this->options;
+ }
+
+ /**
+ * @param string $column
+ *
+ * @return void
+ *
+ * @throws InvalidArgumentException
+ */
+ protected function _addColumn($column)
+ {
+ if (! is_string($column)) {
+ throw new InvalidArgumentException('Expecting a string as Index Column');
+ }
+
+ $this->columns[$column] = new Identifier($column);
+ }
+}
diff --git a/lib/Doctrine/DBAL/Statement.php b/lib/Doctrine/DBAL/Statement.php
index b65fa95e33a..fd8db886b8b 100644
--- a/lib/Doctrine/DBAL/Statement.php
+++ b/lib/Doctrine/DBAL/Statement.php
@@ -6,7 +6,6 @@
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Types\Type;
use IteratorAggregate;
-use PDO;
use Throwable;
use function is_array;
use function is_string;
@@ -145,16 +144,12 @@ public function execute($params = null)
}
$logger = $this->conn->getConfiguration()->getSQLLogger();
- if ($logger) {
- $logger->startQuery($this->sql, $this->params, $this->types);
- }
+ $logger->startQuery($this->sql, $this->params, $this->types);
try {
$stmt = $this->stmt->execute($params);
} catch (Throwable $ex) {
- if ($logger) {
- $logger->stopQuery();
- }
+ $logger->stopQuery();
throw DBALException::driverExceptionDuringQuery(
$this->conn->getDriver(),
$ex,
@@ -163,9 +158,7 @@ public function execute($params = null)
);
}
- if ($logger) {
- $logger->stopQuery();
- }
+ $logger->stopQuery();
$this->params = [];
$this->types = [];
@@ -213,15 +206,9 @@ public function errorInfo()
/**
* {@inheritdoc}
*/
- public function setFetchMode($fetchMode, $arg2 = null, $arg3 = null)
+ public function setFetchMode($fetchMode, ...$args)
{
- if ($arg2 === null) {
- return $this->stmt->setFetchMode($fetchMode);
- } elseif ($arg3 === null) {
- return $this->stmt->setFetchMode($fetchMode, $arg2);
- }
-
- return $this->stmt->setFetchMode($fetchMode, $arg2, $arg3);
+ return $this->stmt->setFetchMode($fetchMode, ...$args);
}
/**
@@ -237,21 +224,17 @@ public function getIterator()
/**
* {@inheritdoc}
*/
- public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEXT, $cursorOffset = 0)
+ public function fetch($fetchMode = null, ...$args)
{
- return $this->stmt->fetch($fetchMode);
+ return $this->stmt->fetch($fetchMode, ...$args);
}
/**
* {@inheritdoc}
*/
- public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = null)
+ public function fetchAll($fetchMode = null, ...$args)
{
- if ($fetchArgument) {
- return $this->stmt->fetchAll($fetchMode, $fetchArgument);
- }
-
- return $this->stmt->fetchAll($fetchMode);
+ return $this->stmt->fetchAll($fetchMode, ...$args);
}
/**
@@ -267,7 +250,7 @@ public function fetchColumn($columnIndex = 0)
*
* @return int The number of affected rows.
*/
- public function rowCount()
+ public function rowCount() : int
{
return $this->stmt->rowCount();
}
diff --git a/lib/Doctrine/DBAL/Tools/Console/Command/ImportCommand.php b/lib/Doctrine/DBAL/Tools/Console/Command/ImportCommand.php
deleted file mode 100644
index 0e815663786..00000000000
--- a/lib/Doctrine/DBAL/Tools/Console/Command/ImportCommand.php
+++ /dev/null
@@ -1,129 +0,0 @@
-setName('dbal:import')
- ->setDescription('Import SQL file(s) directly to Database.')
- ->setDefinition([new InputArgument(
- 'file',
- InputArgument::REQUIRED | InputArgument::IS_ARRAY,
- 'File path(s) of SQL to be executed.'
- ),
- ])
- ->setHelp(<<getHelper('db')->getConnection();
-
- $fileNames = $input->getArgument('file');
-
- if ($fileNames === null) {
- return null;
- }
-
- foreach ((array) $fileNames as $fileName) {
- $filePath = realpath($fileName);
-
- // Phar compatibility.
- if ($filePath === false) {
- $filePath = $fileName;
- }
-
- if (! file_exists($filePath)) {
- throw new InvalidArgumentException(
- sprintf("SQL file '%s' does not exist.", $filePath)
- );
- } elseif (! is_readable($filePath)) {
- throw new InvalidArgumentException(
- sprintf("SQL file '%s' does not have read permissions.", $filePath)
- );
- }
-
- $output->write(sprintf("Processing file '%s'... ", $filePath));
- $sql = file_get_contents($filePath);
-
- if ($conn instanceof PDOConnection) {
- // PDO Drivers
- try {
- $lines = 0;
-
- $stmt = $conn->prepare($sql);
- assert($stmt instanceof PDOStatement);
-
- $stmt->execute();
-
- do {
- // Required due to "MySQL has gone away!" issue
- $stmt->fetch();
- $stmt->closeCursor();
-
- $lines++;
- } while ($stmt->nextRowset());
-
- $output->write(sprintf('%d statements executed!', $lines) . PHP_EOL);
- } catch (PDOException $e) {
- $output->write('error!' . PHP_EOL);
-
- throw new RuntimeException($e->getMessage(), $e->getCode(), $e);
- }
- } else {
- // Non-PDO Drivers (ie. OCI8 driver)
- $stmt = $conn->prepare($sql);
- $rs = $stmt->execute();
-
- if (! $rs) {
- $error = $stmt->errorInfo();
-
- $output->write('error!' . PHP_EOL);
-
- throw new RuntimeException($error[2], $error[0]);
- }
-
- $output->writeln('OK!' . PHP_EOL);
-
- $stmt->closeCursor();
- }
- }
-
- return null;
- }
-}
diff --git a/lib/Doctrine/DBAL/Tools/Console/Command/ReservedWordsCommand.php b/lib/Doctrine/DBAL/Tools/Console/Command/ReservedWordsCommand.php
index fb8b6b5c46f..238aa7d74f8 100644
--- a/lib/Doctrine/DBAL/Tools/Console/Command/ReservedWordsCommand.php
+++ b/lib/Doctrine/DBAL/Tools/Console/Command/ReservedWordsCommand.php
@@ -8,17 +8,12 @@
use Doctrine\DBAL\Platforms\Keywords\MySQL80Keywords;
use Doctrine\DBAL\Platforms\Keywords\MySQLKeywords;
use Doctrine\DBAL\Platforms\Keywords\OracleKeywords;
-use Doctrine\DBAL\Platforms\Keywords\PostgreSQL91Keywords;
-use Doctrine\DBAL\Platforms\Keywords\PostgreSQL92Keywords;
+use Doctrine\DBAL\Platforms\Keywords\PostgreSQL100Keywords;
+use Doctrine\DBAL\Platforms\Keywords\PostgreSQL94Keywords;
use Doctrine\DBAL\Platforms\Keywords\PostgreSQLKeywords;
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\SQLiteKeywords;
-use Doctrine\DBAL\Platforms\Keywords\SQLServer2005Keywords;
-use Doctrine\DBAL\Platforms\Keywords\SQLServer2008Keywords;
use Doctrine\DBAL\Platforms\Keywords\SQLServer2012Keywords;
use Doctrine\DBAL\Platforms\Keywords\SQLServerKeywords;
use Doctrine\DBAL\Schema\Schema;
@@ -35,23 +30,18 @@ class ReservedWordsCommand extends Command
{
/** @var string[] */
private $keywordListClasses = [
+ 'db2' => DB2Keywords::class,
'mysql' => MySQLKeywords::class,
'mysql57' => MySQL57Keywords::class,
'mysql80' => MySQL80Keywords::class,
- 'sqlserver' => SQLServerKeywords::class,
- 'sqlserver2005' => SQLServer2005Keywords::class,
- 'sqlserver2008' => SQLServer2008Keywords::class,
- 'sqlserver2012' => SQLServer2012Keywords::class,
- 'sqlite' => SQLiteKeywords::class,
- 'pgsql' => PostgreSQLKeywords::class,
- 'pgsql91' => PostgreSQL91Keywords::class,
- 'pgsql92' => PostgreSQL92Keywords::class,
'oracle' => OracleKeywords::class,
- 'db2' => DB2Keywords::class,
+ 'pgsql' => PostgreSQLKeywords::class,
+ 'pgsql94' => PostgreSQL94Keywords::class,
+ 'pgsql100' => PostgreSQL100Keywords::class,
'sqlanywhere' => SQLAnywhereKeywords::class,
- 'sqlanywhere11' => SQLAnywhere11Keywords::class,
- 'sqlanywhere12' => SQLAnywhere12Keywords::class,
- 'sqlanywhere16' => SQLAnywhere16Keywords::class,
+ 'sqlite' => SQLiteKeywords::class,
+ 'sqlserver' => SQLServerKeywords::class,
+ 'sqlserver2012' => SQLServer2012Keywords::class,
];
/**
@@ -102,17 +92,13 @@ protected function configure()
* mysql57
* mysql80
* pgsql
- * pgsql92
+ * pgsql94
+ * pgsql100
* sqlite
* oracle
* sqlserver
- * sqlserver2005
- * sqlserver2008
* sqlserver2012
* sqlanywhere
- * sqlanywhere11
- * sqlanywhere12
- * sqlanywhere16
* db2 (Not checked by default)
EOT
);
@@ -128,23 +114,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
$keywordLists = (array) $input->getOption('list');
if (! $keywordLists) {
- $keywordLists = [
- 'mysql',
- 'mysql57',
- 'mysql80',
- 'pgsql',
- 'pgsql92',
- 'sqlite',
- 'oracle',
- 'sqlserver',
- 'sqlserver2005',
- 'sqlserver2008',
- 'sqlserver2012',
- 'sqlanywhere',
- 'sqlanywhere11',
- 'sqlanywhere12',
- 'sqlanywhere16',
- ];
+ $keywordLists = array_keys($this->keywordListClasses);
}
$keywords = [];
diff --git a/lib/Doctrine/DBAL/Tools/Console/ConsoleRunner.php b/lib/Doctrine/DBAL/Tools/Console/ConsoleRunner.php
index 520a9af80aa..0df6f086f2c 100644
--- a/lib/Doctrine/DBAL/Tools/Console/ConsoleRunner.php
+++ b/lib/Doctrine/DBAL/Tools/Console/ConsoleRunner.php
@@ -3,11 +3,10 @@
namespace Doctrine\DBAL\Tools\Console;
use Doctrine\DBAL\Connection;
-use Doctrine\DBAL\Tools\Console\Command\ImportCommand;
use Doctrine\DBAL\Tools\Console\Command\ReservedWordsCommand;
use Doctrine\DBAL\Tools\Console\Command\RunSqlCommand;
use Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper;
-use Doctrine\DBAL\Version;
+use PackageVersions\Versions;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Helper\HelperSet;
@@ -38,7 +37,7 @@ public static function createHelperSet(Connection $connection)
*/
public static function run(HelperSet $helperSet, $commands = [])
{
- $cli = new Application('Doctrine Command Line Interface', Version::VERSION);
+ $cli = new Application('Doctrine Command Line Interface', Versions::getVersion('doctrine/dbal'));
$cli->setCatchExceptions(true);
$cli->setHelperSet($helperSet);
@@ -56,7 +55,6 @@ public static function addCommands(Application $cli)
{
$cli->addCommands([
new RunSqlCommand(),
- new ImportCommand(),
new ReservedWordsCommand(),
]);
}
diff --git a/lib/Doctrine/DBAL/Types/BinaryType.php b/lib/Doctrine/DBAL/Types/BinaryType.php
index 14362e840ae..e40f0010493 100644
--- a/lib/Doctrine/DBAL/Types/BinaryType.php
+++ b/lib/Doctrine/DBAL/Types/BinaryType.php
@@ -4,11 +4,9 @@
use Doctrine\DBAL\ParameterType;
use Doctrine\DBAL\Platforms\AbstractPlatform;
-use function fopen;
-use function fseek;
-use function fwrite;
use function is_resource;
use function is_string;
+use function stream_get_contents;
/**
* Type that maps ab SQL BINARY/VARBINARY to a PHP resource stream.
@@ -32,14 +30,11 @@ public function convertToPHPValue($value, AbstractPlatform $platform)
return null;
}
- if (is_string($value)) {
- $fp = fopen('php://temp', 'rb+');
- fwrite($fp, $value);
- fseek($fp, 0);
- $value = $fp;
+ if (is_resource($value)) {
+ $value = stream_get_contents($value);
}
- if (! is_resource($value)) {
+ if (! is_string($value)) {
throw ConversionException::conversionFailed($value, self::BINARY);
}
diff --git a/lib/Doctrine/DBAL/Types/StringType.php b/lib/Doctrine/DBAL/Types/StringType.php
index 879359a13d8..c6197df949a 100644
--- a/lib/Doctrine/DBAL/Types/StringType.php
+++ b/lib/Doctrine/DBAL/Types/StringType.php
@@ -17,14 +17,6 @@ public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $pla
return $platform->getVarcharTypeDeclarationSQL($fieldDeclaration);
}
- /**
- * {@inheritdoc}
- */
- public function getDefaultLength(AbstractPlatform $platform)
- {
- return $platform->getVarcharDefaultLength();
- }
-
/**
* {@inheritdoc}
*/
diff --git a/lib/Doctrine/DBAL/Types/Type.php b/lib/Doctrine/DBAL/Types/Type.php
index ec1ab681356..6cee27cedab 100644
--- a/lib/Doctrine/DBAL/Types/Type.php
+++ b/lib/Doctrine/DBAL/Types/Type.php
@@ -5,9 +5,6 @@
use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\ParameterType;
use Doctrine\DBAL\Platforms\AbstractPlatform;
-use function end;
-use function explode;
-use function str_replace;
/**
* The base class for so-called Doctrine mapping types.
@@ -117,18 +114,6 @@ public function convertToPHPValue($value, AbstractPlatform $platform)
return $value;
}
- /**
- * Gets the default length of this type.
- *
- * @deprecated Rely on information provided by the platform instead.
- *
- * @return int|null
- */
- public function getDefaultLength(AbstractPlatform $platform)
- {
- return null;
- }
-
/**
* Gets the SQL declaration snippet for a field of this type.
*
@@ -248,18 +233,6 @@ public static function getTypesMap()
return self::$_typesMap;
}
- /**
- * @deprecated Relying on string representation is discouraged and will be removed in DBAL 3.0.
- *
- * @return string
- */
- public function __toString()
- {
- $e = explode('\\', static::class);
-
- return str_replace('Type', '', end($e));
- }
-
/**
* Does working with this column require SQL conversion functions?
*
diff --git a/lib/Doctrine/DBAL/Version.php b/lib/Doctrine/DBAL/Version.php
deleted file mode 100644
index 60530e69a76..00000000000
--- a/lib/Doctrine/DBAL/Version.php
+++ /dev/null
@@ -1,33 +0,0 @@
-createMock(Driver::class);
- $inner = new class extends Exception implements InnerDriverException
- {
- /**
- * {@inheritDoc}
- */
- public function getErrorCode()
- {
- }
-
- /**
- * {@inheritDoc}
- */
- public function getSQLState()
- {
- }
- };
+ $inner = new InnerDriverException('');
$ex = new DriverException('', $inner);
$e = DBALException::driverExceptionDuringQuery($driver, $ex, '');
self::assertSame($ex, $e);
diff --git a/tests/Doctrine/Tests/DBAL/Driver/AbstractDriverTest.php b/tests/Doctrine/Tests/DBAL/Driver/AbstractDriverTest.php
index 0475ea11b89..09bd4806c53 100644
--- a/tests/Doctrine/Tests/DBAL/Driver/AbstractDriverTest.php
+++ b/tests/Doctrine/Tests/DBAL/Driver/AbstractDriverTest.php
@@ -4,7 +4,6 @@
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Driver;
-use Doctrine\DBAL\Driver\DriverException as DriverExceptionInterface;
use Doctrine\DBAL\Driver\ExceptionConverterDriver;
use Doctrine\DBAL\Exception\ConnectionException;
use Doctrine\DBAL\Exception\ConstraintViolationException;
@@ -27,7 +26,6 @@
use Doctrine\DBAL\Schema\AbstractSchemaManager;
use Doctrine\DBAL\VersionAwarePlatformDriver;
use Doctrine\Tests\DbalTestCase;
-use Exception;
use function get_class;
use function sprintf;
@@ -83,29 +81,7 @@ public function testConvertsException()
);
}
- $driverException = new class extends Exception implements DriverExceptionInterface
- {
- public function __construct()
- {
- parent::__construct('baz');
- }
-
- /**
- * {@inheritDoc}
- */
- public function getErrorCode()
- {
- return 'foo';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getSQLState()
- {
- return 'bar';
- }
- };
+ $driverException = new Driver\DriverException('baz', 'bar', 'foo');
$data[] = [$driverException, self::EXCEPTION_DRIVER];
@@ -253,40 +229,7 @@ private function getExceptionConversions()
foreach ($this->getExceptionConversionData() as $convertedExceptionClassName => $errors) {
foreach ($errors as $error) {
- $driverException = new class ($error[0], $error[1], $error[2])
- extends Exception
- implements DriverExceptionInterface
- {
- /** @var mixed */
- private $errorCode;
-
- /** @var mixed */
- private $sqlState;
-
- public function __construct($errorCode, $sqlState, $message)
- {
- parent::__construct($message);
-
- $this->errorCode = $errorCode;
- $this->sqlState = $sqlState;
- }
-
- /**
- * {@inheritDoc}
- */
- public function getErrorCode()
- {
- return $this->errorCode;
- }
-
- /**
- * {@inheritDoc}
- */
- public function getSQLState()
- {
- return $this->sqlState;
- }
- };
+ $driverException = new Driver\DriverException($error[2] ?? '', $error[1], $error[0]);
$data[] = [$driverException, $convertedExceptionClassName];
}
diff --git a/tests/Doctrine/Tests/DBAL/Driver/AbstractPostgreSQLDriverTest.php b/tests/Doctrine/Tests/DBAL/Driver/AbstractPostgreSQLDriverTest.php
index d1159c80308..c51617bafc4 100644
--- a/tests/Doctrine/Tests/DBAL/Driver/AbstractPostgreSQLDriverTest.php
+++ b/tests/Doctrine/Tests/DBAL/Driver/AbstractPostgreSQLDriverTest.php
@@ -5,8 +5,6 @@
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Driver\AbstractPostgreSQLDriver;
use Doctrine\DBAL\Platforms\PostgreSQL100Platform;
-use Doctrine\DBAL\Platforms\PostgreSQL91Platform;
-use Doctrine\DBAL\Platforms\PostgreSQL92Platform;
use Doctrine\DBAL\Platforms\PostgreSQL94Platform;
use Doctrine\DBAL\Platforms\PostgreSqlPlatform;
use Doctrine\DBAL\Schema\PostgreSqlSchemaManager;
@@ -61,15 +59,9 @@ protected function createSchemaManager(Connection $connection)
protected function getDatabasePlatformsForVersions()
{
return [
- ['9.0.9', PostgreSqlPlatform::class],
- ['9.1', PostgreSQL91Platform::class],
- ['9.1.0', PostgreSQL91Platform::class],
- ['9.1.1', PostgreSQL91Platform::class],
- ['9.1.9', PostgreSQL91Platform::class],
- ['9.2', PostgreSQL92Platform::class],
- ['9.2.0', PostgreSQL92Platform::class],
- ['9.2.1', PostgreSQL92Platform::class],
- ['9.3.6', PostgreSQL92Platform::class],
+ ['9.3', PostgreSqlPlatform::class],
+ ['9.3.0', PostgreSqlPlatform::class],
+ ['9.3.6', PostgreSqlPlatform::class],
['9.4', PostgreSQL94Platform::class],
['9.4.0', PostgreSQL94Platform::class],
['9.4.1', PostgreSQL94Platform::class],
diff --git a/tests/Doctrine/Tests/DBAL/Driver/AbstractSQLAnywhereDriverTest.php b/tests/Doctrine/Tests/DBAL/Driver/AbstractSQLAnywhereDriverTest.php
index cbd23505bae..a05fef71214 100644
--- a/tests/Doctrine/Tests/DBAL/Driver/AbstractSQLAnywhereDriverTest.php
+++ b/tests/Doctrine/Tests/DBAL/Driver/AbstractSQLAnywhereDriverTest.php
@@ -4,9 +4,6 @@
use Doctrine\DBAL\Connection;
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\Schema\SQLAnywhereSchemaManager;
@@ -19,7 +16,7 @@ protected function createDriver()
protected function createPlatform()
{
- return new SQLAnywhere12Platform();
+ return new SQLAnywherePlatform();
}
protected function createSchemaManager(Connection $connection)
@@ -30,35 +27,13 @@ protected function createSchemaManager(Connection $connection)
protected function getDatabasePlatformsForVersions()
{
return [
- ['10', SQLAnywherePlatform::class],
- ['10.0', SQLAnywherePlatform::class],
- ['10.0.0', SQLAnywherePlatform::class],
- ['10.0.0.0', SQLAnywherePlatform::class],
- ['10.1.2.3', SQLAnywherePlatform::class],
- ['10.9.9.9', SQLAnywherePlatform::class],
- ['11', SQLAnywhere11Platform::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],
+ ['16', SQLAnywherePlatform::class],
+ ['16.0', SQLAnywherePlatform::class],
+ ['16.0.0', SQLAnywherePlatform::class],
+ ['16.0.0.0', SQLAnywherePlatform::class],
+ ['16.1.2.3', SQLAnywherePlatform::class],
+ ['16.9.9.9', SQLAnywherePlatform::class],
+ ['17', SQLAnywherePlatform::class],
];
}
diff --git a/tests/Doctrine/Tests/DBAL/Driver/AbstractSQLServerDriverTest.php b/tests/Doctrine/Tests/DBAL/Driver/AbstractSQLServerDriverTest.php
index 48fb3b29f3e..69eea132855 100644
--- a/tests/Doctrine/Tests/DBAL/Driver/AbstractSQLServerDriverTest.php
+++ b/tests/Doctrine/Tests/DBAL/Driver/AbstractSQLServerDriverTest.php
@@ -4,8 +4,6 @@
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Driver\AbstractSQLServerDriver;
-use Doctrine\DBAL\Platforms\SQLServer2005Platform;
-use Doctrine\DBAL\Platforms\SQLServer2008Platform;
use Doctrine\DBAL\Platforms\SQLServer2012Platform;
use Doctrine\DBAL\Platforms\SQLServerPlatform;
use Doctrine\DBAL\Schema\SQLServerSchemaManager;
@@ -19,7 +17,7 @@ protected function createDriver()
protected function createPlatform()
{
- return new SQLServer2008Platform();
+ return new SQLServerPlatform();
}
protected function createSchemaManager(Connection $connection)
@@ -30,27 +28,19 @@ protected function createSchemaManager(Connection $connection)
protected function getDatabasePlatformsForVersions()
{
return [
- ['9', SQLServerPlatform::class],
- ['9.00', SQLServerPlatform::class],
- ['9.00.0', SQLServerPlatform::class],
- ['9.00.1398', SQLServerPlatform::class],
- ['9.00.1398.99', SQLServerPlatform::class],
- ['9.00.1399', SQLServer2005Platform::class],
- ['9.00.1399.0', SQLServer2005Platform::class],
- ['9.00.1399.99', SQLServer2005Platform::class],
- ['9.00.1400', SQLServer2005Platform::class],
- ['9.10', SQLServer2005Platform::class],
- ['9.10.9999', SQLServer2005Platform::class],
- ['10.00.1599', SQLServer2005Platform::class],
- ['10.00.1599.99', SQLServer2005Platform::class],
- ['10.00.1600', SQLServer2008Platform::class],
- ['10.00.1600.0', SQLServer2008Platform::class],
- ['10.00.1600.99', SQLServer2008Platform::class],
- ['10.00.1601', SQLServer2008Platform::class],
- ['10.10', SQLServer2008Platform::class],
- ['10.10.9999', SQLServer2008Platform::class],
- ['11.00.2099', SQLServer2008Platform::class],
- ['11.00.2099.99', SQLServer2008Platform::class],
+ ['10', SQLServerPlatform::class],
+ ['10.00', SQLServerPlatform::class],
+ ['10.00.0', SQLServerPlatform::class],
+ ['10.00.1599', SQLServerPlatform::class],
+ ['10.00.1599.99', SQLServerPlatform::class],
+ ['10.00.1600', SQLServerPlatform::class],
+ ['10.00.1600.0', SQLServerPlatform::class],
+ ['10.00.1600.99', SQLServerPlatform::class],
+ ['10.00.1601', SQLServerPlatform::class],
+ ['10.10', SQLServerPlatform::class],
+ ['10.10.9999', SQLServerPlatform::class],
+ ['11.00.2099', SQLServerPlatform::class],
+ ['11.00.2099.99', SQLServerPlatform::class],
['11.00.2100', SQLServer2012Platform::class],
['11.00.2100.0', SQLServer2012Platform::class],
['11.00.2100.99', SQLServer2012Platform::class],
diff --git a/tests/Doctrine/Tests/DBAL/Driver/DrizzlePDOMySql/DriverTest.php b/tests/Doctrine/Tests/DBAL/Driver/DrizzlePDOMySql/DriverTest.php
deleted file mode 100644
index 520a732a0c3..00000000000
--- a/tests/Doctrine/Tests/DBAL/Driver/DrizzlePDOMySql/DriverTest.php
+++ /dev/null
@@ -1,49 +0,0 @@
-driver->getName());
- }
-
- public function testThrowsExceptionOnCreatingDatabasePlatformsForInvalidVersion()
- {
- $this->markTestSkipped('This test does not work on Drizzle as it is not version aware.');
- }
-
- protected function createDriver()
- {
- return new Driver();
- }
-
- protected function createPlatform()
- {
- return new DrizzlePlatform();
- }
-
- protected function createSchemaManager(Connection $connection)
- {
- return new DrizzleSchemaManager($connection);
- }
-
- /**
- * @return mixed[][]
- */
- protected function getDatabasePlatformsForVersions() : array
- {
- return [
- ['foo', DrizzlePlatform::class],
- ['bar', DrizzlePlatform::class],
- ['baz', DrizzlePlatform::class],
- ];
- }
-}
diff --git a/tests/Doctrine/Tests/DBAL/Driver/Mysqli/MysqliConnectionTest.php b/tests/Doctrine/Tests/DBAL/Driver/Mysqli/MysqliConnectionTest.php
index 9bd3172dd1d..38b5abebbba 100644
--- a/tests/Doctrine/Tests/DBAL/Driver/Mysqli/MysqliConnectionTest.php
+++ b/tests/Doctrine/Tests/DBAL/Driver/Mysqli/MysqliConnectionTest.php
@@ -2,8 +2,8 @@
namespace Doctrine\Tests\DBAL\Driver\Mysqli;
+use Doctrine\DBAL\Driver\DriverException;
use Doctrine\DBAL\Driver\Mysqli\MysqliConnection;
-use Doctrine\DBAL\Driver\Mysqli\MysqliException;
use Doctrine\DBAL\Platforms\MySqlPlatform;
use Doctrine\Tests\DbalFunctionalTestCase;
use PHPUnit_Framework_MockObject_MockObject;
@@ -52,8 +52,8 @@ public function testRestoresErrorHandlerOnException()
try {
new MysqliConnection(['host' => '255.255.255.255'], 'user', 'pass');
self::fail('An exception was supposed to be raised');
- } catch (MysqliException $e) {
- self::assertSame('Network is unreachable', $e->getMessage());
+ } catch (DriverException $e) {
+ // Do nothing
}
self::assertSame($handler, set_error_handler($default_handler), 'Restoring error handler failed.');
diff --git a/tests/Doctrine/Tests/DBAL/Driver/OCI8/OCI8StatementTest.php b/tests/Doctrine/Tests/DBAL/Driver/OCI8/OCI8StatementTest.php
index b51f3bf2f5b..665de3a7d11 100644
--- a/tests/Doctrine/Tests/DBAL/Driver/OCI8/OCI8StatementTest.php
+++ b/tests/Doctrine/Tests/DBAL/Driver/OCI8/OCI8StatementTest.php
@@ -2,8 +2,8 @@
namespace Doctrine\Tests\DBAL\Driver\OCI8;
+use Doctrine\DBAL\Driver\DriverException;
use Doctrine\DBAL\Driver\OCI8\OCI8Connection;
-use Doctrine\DBAL\Driver\OCI8\OCI8Exception;
use Doctrine\DBAL\Driver\OCI8\OCI8Statement;
use Doctrine\Tests\DbalTestCase;
use ReflectionProperty;
@@ -32,7 +32,7 @@ protected function setUp()
* @param mixed[] $params
*
* @dataProvider executeDataProvider
- * @expectedException \Doctrine\DBAL\Driver\OCI8\OCI8Exception
+ * @expectedException \Doctrine\DBAL\Driver\DriverException
*/
public function testExecute(array $params)
{
@@ -41,24 +41,20 @@ public function testExecute(array $params)
->disableOriginalConstructor()
->getMock();
- $statement->expects($this->at(0))
- ->method('bindValue')
- ->with(
- $this->equalTo(1),
- $this->equalTo($params[0])
- );
- $statement->expects($this->at(1))
- ->method('bindValue')
- ->with(
- $this->equalTo(2),
- $this->equalTo($params[1])
- );
- $statement->expects($this->at(2))
- ->method('bindValue')
- ->with(
- $this->equalTo(3),
- $this->equalTo($params[2])
- );
+ $statement->method('errorInfo')->willReturn([
+ 'message' => '',
+ 'code' => 0,
+ ]);
+
+ foreach ($params as $index => $value) {
+ $statement->expects($this->at($index))
+ ->method('bindValue')
+ ->with(
+ $this->equalTo($index + 1),
+ $this->equalTo($value)
+ )
+ ->willReturn(true);
+ }
// can't pass to constructor since we don't have a real database handle,
// but execute must check the connection for the executeMode
@@ -95,7 +91,7 @@ public static function executeDataProvider()
*/
public function testConvertNonTerminatedLiteral($sql, $message)
{
- $this->expectException(OCI8Exception::class);
+ $this->expectException(DriverException::class);
$this->expectExceptionMessageRegExp($message);
OCI8Statement::convertPositionalToNamedPlaceholders($sql);
}
diff --git a/tests/Doctrine/Tests/DBAL/Driver/PDOExceptionTest.php b/tests/Doctrine/Tests/DBAL/Driver/PDOExceptionTest.php
deleted file mode 100644
index 593f04d203c..00000000000
--- a/tests/Doctrine/Tests/DBAL/Driver/PDOExceptionTest.php
+++ /dev/null
@@ -1,71 +0,0 @@
-markTestSkipped('PDO is not installed.');
- }
-
- parent::setUp();
-
- $this->wrappedException = new \PDOException(self::MESSAGE, self::SQLSTATE);
-
- $this->wrappedException->errorInfo = [self::SQLSTATE, self::ERROR_CODE];
-
- $this->exception = new PDOException($this->wrappedException);
- }
-
- public function testReturnsCode()
- {
- self::assertSame(self::SQLSTATE, $this->exception->getCode());
- }
-
- public function testReturnsErrorCode()
- {
- self::assertSame(self::ERROR_CODE, $this->exception->getErrorCode());
- }
-
- public function testReturnsMessage()
- {
- self::assertSame(self::MESSAGE, $this->exception->getMessage());
- }
-
- public function testReturnsSQLState()
- {
- self::assertSame(self::SQLSTATE, $this->exception->getSQLState());
- }
-
- public function testOriginalExceptionIsInChain()
- {
- self::assertSame($this->wrappedException, $this->exception->getPrevious());
- }
-}
diff --git a/tests/Doctrine/Tests/DBAL/Driver/PDOIbm/DriverTest.php b/tests/Doctrine/Tests/DBAL/Driver/PDOIbm/DriverTest.php
deleted file mode 100644
index 6361f05575c..00000000000
--- a/tests/Doctrine/Tests/DBAL/Driver/PDOIbm/DriverTest.php
+++ /dev/null
@@ -1,19 +0,0 @@
-driver->getName());
- }
-
- protected function createDriver()
- {
- return new Driver();
- }
-}
diff --git a/tests/Doctrine/Tests/DBAL/Driver/PDOPgSql/DriverTest.php b/tests/Doctrine/Tests/DBAL/Driver/PDOPgSql/DriverTest.php
index a6ac2456b64..1e3a2745b65 100644
--- a/tests/Doctrine/Tests/DBAL/Driver/PDOPgSql/DriverTest.php
+++ b/tests/Doctrine/Tests/DBAL/Driver/PDOPgSql/DriverTest.php
@@ -36,7 +36,7 @@ public function testConnectionDisablesPreparesOnPhp56()
self::assertInstanceOf(PDOConnection::class, $connection);
try {
- self::assertTrue($connection->getAttribute(PDO::PGSQL_ATTR_DISABLE_PREPARES));
+ self::assertTrue($connection->getWrappedConnection()->getAttribute(PDO::PGSQL_ATTR_DISABLE_PREPARES));
} catch (PDOException $ignored) {
/** @link https://bugs.php.net/bug.php?id=68371 */
$this->markTestIncomplete('See https://bugs.php.net/bug.php?id=68371');
@@ -63,7 +63,10 @@ public function testConnectionDoesNotDisablePreparesOnPhp56WhenAttributeDefined(
self::assertInstanceOf(PDOConnection::class, $connection);
try {
- self::assertNotSame(true, $connection->getAttribute(PDO::PGSQL_ATTR_DISABLE_PREPARES));
+ self::assertNotSame(
+ true,
+ $connection->getWrappedConnection()->getAttribute(PDO::PGSQL_ATTR_DISABLE_PREPARES)
+ );
} catch (PDOException $ignored) {
/** @link https://bugs.php.net/bug.php?id=68371 */
$this->markTestIncomplete('See https://bugs.php.net/bug.php?id=68371');
@@ -90,7 +93,7 @@ public function testConnectionDisablePreparesOnPhp56WhenDisablePreparesIsExplici
self::assertInstanceOf(PDOConnection::class, $connection);
try {
- self::assertTrue($connection->getAttribute(PDO::PGSQL_ATTR_DISABLE_PREPARES));
+ self::assertTrue($connection->getWrappedConnection()->getAttribute(PDO::PGSQL_ATTR_DISABLE_PREPARES));
} catch (PDOException $ignored) {
/** @link https://bugs.php.net/bug.php?id=68371 */
$this->markTestIncomplete('See https://bugs.php.net/bug.php?id=68371');
diff --git a/tests/Doctrine/Tests/DBAL/DriverManagerTest.php b/tests/Doctrine/Tests/DBAL/DriverManagerTest.php
index e5520afcf1e..3fc4d872388 100644
--- a/tests/Doctrine/Tests/DBAL/DriverManagerTest.php
+++ b/tests/Doctrine/Tests/DBAL/DriverManagerTest.php
@@ -4,7 +4,6 @@
use Doctrine\DBAL\Connections\MasterSlaveConnection;
use Doctrine\DBAL\DBALException;
-use Doctrine\DBAL\Driver\DrizzlePDOMySql\Driver as DrizzlePDOMySqlDriver;
use Doctrine\DBAL\Driver\PDOMySql\Driver as PDOMySQLDriver;
use Doctrine\DBAL\Driver\PDOSqlite\Driver as PDOSqliteDriver;
use Doctrine\DBAL\Driver\SQLSrv\Driver as SQLSrvDriver;
@@ -346,17 +345,17 @@ public function databaseUrls()
],
],
'simple URL with fallthrough scheme containing underscores fails' => [
- 'drizzle_pdo_mysql://foo:bar@localhost/baz',
+ 'pdo_mysql://foo:bar@localhost/baz',
false,
],
'simple URL with fallthrough scheme containing dashes works' => [
- 'drizzle-pdo-mysql://foo:bar@localhost/baz',
+ 'pdo-mysql://foo:bar@localhost/baz',
[
'user' => 'foo',
'password' => 'bar',
'host' => 'localhost',
'dbname' => 'baz',
- 'driver' => DrizzlePDOMySqlDriver::class,
+ 'driver' => PDOMySQLDriver::class,
],
],
'simple URL with percent encoding' => [
diff --git a/tests/Doctrine/Tests/DBAL/Functional/Driver/Mysqli/ConnectionTest.php b/tests/Doctrine/Tests/DBAL/Functional/Driver/Mysqli/ConnectionTest.php
index 8c274e1cbb2..336402c543e 100644
--- a/tests/Doctrine/Tests/DBAL/Functional/Driver/Mysqli/ConnectionTest.php
+++ b/tests/Doctrine/Tests/DBAL/Functional/Driver/Mysqli/ConnectionTest.php
@@ -39,7 +39,7 @@ public function testDriverOptions()
}
/**
- * @expectedException \Doctrine\DBAL\Driver\Mysqli\MysqliException
+ * @expectedException \Doctrine\DBAL\Driver\DriverException
*/
public function testUnsupportedDriverOption()
{
diff --git a/tests/Doctrine/Tests/DBAL/Functional/Driver/PDOConnectionTest.php b/tests/Doctrine/Tests/DBAL/Functional/Driver/PDOConnectionTest.php
index 214f90700c1..1655527dd74 100644
--- a/tests/Doctrine/Tests/DBAL/Functional/Driver/PDOConnectionTest.php
+++ b/tests/Doctrine/Tests/DBAL/Functional/Driver/PDOConnectionTest.php
@@ -47,7 +47,7 @@ public function testDoesNotRequireQueryForServerVersion()
}
/**
- * @expectedException \Doctrine\DBAL\Driver\PDOException
+ * @expectedException \Doctrine\DBAL\Driver\DriverException
*/
public function testThrowsWrappedExceptionOnConstruct()
{
@@ -56,7 +56,7 @@ public function testThrowsWrappedExceptionOnConstruct()
/**
* @group DBAL-1022
- * @expectedException \Doctrine\DBAL\Driver\PDOException
+ * @expectedException \Doctrine\DBAL\Driver\DriverException
*/
public function testThrowsWrappedExceptionOnExec()
{
@@ -64,7 +64,7 @@ public function testThrowsWrappedExceptionOnExec()
}
/**
- * @expectedException \Doctrine\DBAL\Driver\PDOException
+ * @expectedException \Doctrine\DBAL\Driver\DriverException
*/
public function testThrowsWrappedExceptionOnPrepare()
{
@@ -74,7 +74,9 @@ public function testThrowsWrappedExceptionOnPrepare()
// Emulated prepared statements have to be disabled for this test
// so that PDO actually communicates with the database server to check the query.
- $this->driverConnection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
+ $this->driverConnection
+ ->getWrappedConnection()
+ ->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$this->driverConnection->prepare('foo');
@@ -92,7 +94,7 @@ public function testThrowsWrappedExceptionOnPrepare()
}
/**
- * @expectedException \Doctrine\DBAL\Driver\PDOException
+ * @expectedException \Doctrine\DBAL\Driver\DriverException
*/
public function testThrowsWrappedExceptionOnQuery()
{
diff --git a/tests/Doctrine/Tests/DBAL/Functional/Driver/PDOSqlsrv/DriverTest.php b/tests/Doctrine/Tests/DBAL/Functional/Driver/PDOSqlsrv/DriverTest.php
index f125eab3515..023590483ad 100644
--- a/tests/Doctrine/Tests/DBAL/Functional/Driver/PDOSqlsrv/DriverTest.php
+++ b/tests/Doctrine/Tests/DBAL/Functional/Driver/PDOSqlsrv/DriverTest.php
@@ -3,9 +3,11 @@
namespace Doctrine\Tests\DBAL\Functional\Driver\PDOSqlsrv;
use Doctrine\DBAL\Driver\Connection;
+use Doctrine\DBAL\Driver\PDOConnection;
use Doctrine\DBAL\Driver\PDOSqlsrv\Driver;
use Doctrine\Tests\DBAL\Functional\Driver\AbstractDriverTest;
use PDO;
+use function assert;
use function extension_loaded;
class DriverTest extends AbstractDriverTest
@@ -69,6 +71,13 @@ public function testDriverOptions() : void
{
$connection = $this->getConnection([PDO::ATTR_CASE => PDO::CASE_UPPER]);
- self::assertSame(PDO::CASE_UPPER, $connection->getAttribute(PDO::ATTR_CASE));
+ assert($connection instanceof PDOConnection);
+
+ self::assertSame(
+ PDO::CASE_UPPER,
+ $connection
+ ->getWrappedConnection()
+ ->getAttribute(PDO::ATTR_CASE)
+ );
}
}
diff --git a/tests/Doctrine/Tests/DBAL/Functional/Driver/SQLSrv/StatementTest.php b/tests/Doctrine/Tests/DBAL/Functional/Driver/SQLSrv/StatementTest.php
index 38df9cb5181..6637d6ae207 100644
--- a/tests/Doctrine/Tests/DBAL/Functional/Driver/SQLSrv/StatementTest.php
+++ b/tests/Doctrine/Tests/DBAL/Functional/Driver/SQLSrv/StatementTest.php
@@ -2,8 +2,8 @@
namespace Doctrine\Tests\DBAL\Functional\Driver\SQLSrv;
+use Doctrine\DBAL\Driver\DriverException;
use Doctrine\DBAL\Driver\SQLSrv\Driver;
-use Doctrine\DBAL\Driver\SQLSrv\SQLSrvException;
use Doctrine\Tests\DbalFunctionalTestCase;
use function extension_loaded;
@@ -27,11 +27,11 @@ protected function setUp()
public function testFailureToPrepareResultsInException()
{
// use the driver connection directly to avoid having exception wrapped
- $stmt = $this->connection->getWrappedConnection()->prepare(null);
+ $stmt = $this->connection->getWrappedConnection()->prepare('');
// it's impossible to prepare the statement without bound variables for SQL Server,
// so the preparation happens before the first execution when variables are already in place
- $this->expectException(SQLSrvException::class);
+ $this->expectException(DriverException::class);
$stmt->execute();
}
}
diff --git a/tests/Doctrine/Tests/DBAL/Functional/ExceptionTest.php b/tests/Doctrine/Tests/DBAL/Functional/ExceptionTest.php
index e420000ba58..a7810af9485 100644
--- a/tests/Doctrine/Tests/DBAL/Functional/ExceptionTest.php
+++ b/tests/Doctrine/Tests/DBAL/Functional/ExceptionTest.php
@@ -314,6 +314,7 @@ public function testConnectionExceptionSqLite($mode, $exceptionClass)
$table->addColumn('id', 'integer');
$this->expectException($exceptionClass);
+
foreach ($schema->toSql($conn->getDatabasePlatform()) as $sql) {
$conn->exec($sql);
}
@@ -337,10 +338,6 @@ public function testConnectionException($params)
$this->markTestSkipped('Only skipped if platform is not sqlite');
}
- if ($this->connection->getDatabasePlatform()->getName() === 'drizzle') {
- $this->markTestSkipped('Drizzle does not always support authentication');
- }
-
if ($this->connection->getDatabasePlatform()->getName() === 'postgresql' && isset($params['password'])) {
$this->markTestSkipped('Does not work on Travis');
}
diff --git a/tests/Doctrine/Tests/DBAL/Functional/Schema/DrizzleSchemaManagerTest.php b/tests/Doctrine/Tests/DBAL/Functional/Schema/DrizzleSchemaManagerTest.php
deleted file mode 100644
index 070e2173d63..00000000000
--- a/tests/Doctrine/Tests/DBAL/Functional/Schema/DrizzleSchemaManagerTest.php
+++ /dev/null
@@ -1,48 +0,0 @@
-addColumn('id', 'integer');
- $table->addColumn('column_varbinary', 'binary', []);
- $table->addColumn('column_binary', 'binary', ['fixed' => true]);
- $table->setPrimaryKey(['id']);
-
- $this->schemaManager->createTable($table);
-
- $table = $this->schemaManager->listTableDetails($tableName);
-
- self::assertInstanceOf(BinaryType::class, $table->getColumn('column_varbinary')->getType());
- self::assertFalse($table->getColumn('column_varbinary')->getFixed());
-
- self::assertInstanceOf(BinaryType::class, $table->getColumn('column_binary')->getType());
- self::assertFalse($table->getColumn('column_binary')->getFixed());
- }
-
- public function testColumnCollation()
- {
- $table = new Table('test_collation');
- $table->addOption('collate', $collation = 'utf8_unicode_ci');
- $table->addColumn('id', 'integer');
- $table->addColumn('text', 'text');
- $table->addColumn('foo', 'text')->setPlatformOption('collation', 'utf8_swedish_ci');
- $table->addColumn('bar', 'text')->setPlatformOption('collation', 'utf8_general_ci');
- $this->schemaManager->dropAndCreateTable($table);
-
- $columns = $this->schemaManager->listTableColumns('test_collation');
-
- self::assertArrayNotHasKey('collation', $columns['id']->getPlatformOptions());
- self::assertEquals('utf8_unicode_ci', $columns['text']->getPlatformOption('collation'));
- self::assertEquals('utf8_swedish_ci', $columns['foo']->getPlatformOption('collation'));
- self::assertEquals('utf8_general_ci', $columns['bar']->getPlatformOption('collation'));
- }
-}
diff --git a/tests/Doctrine/Tests/DBAL/Functional/Schema/SchemaManagerFunctionalTestCase.php b/tests/Doctrine/Tests/DBAL/Functional/Schema/SchemaManagerFunctionalTestCase.php
index 1c0afc93e66..e7dfde2f4cc 100644
--- a/tests/Doctrine/Tests/DBAL/Functional/Schema/SchemaManagerFunctionalTestCase.php
+++ b/tests/Doctrine/Tests/DBAL/Functional/Schema/SchemaManagerFunctionalTestCase.php
@@ -976,7 +976,7 @@ protected function createTestTable($name = 'test_table', array $data = [])
protected function getTestTable($name, $options = [])
{
- $table = new Table($name, [], [], [], false, $options);
+ $table = new Table($name, [], [], [], [], $options);
$table->setSchemaConfig($this->schemaManager->createSchemaConfig());
$table->addColumn('id', 'integer', ['notnull' => true]);
$table->setPrimaryKey(['id']);
@@ -987,7 +987,7 @@ protected function getTestTable($name, $options = [])
protected function getTestCompositeTable($name)
{
- $table = new Table($name, [], [], [], false, []);
+ $table = new Table($name, [], [], [], [], []);
$table->setSchemaConfig($this->schemaManager->createSchemaConfig());
$table->addColumn('id', 'integer', ['notnull' => true]);
$table->addColumn('other_id', 'integer', ['notnull' => true]);
@@ -999,14 +999,17 @@ protected function getTestCompositeTable($name)
protected function assertHasTable($tables, $tableName)
{
$foundTable = false;
+
foreach ($tables as $table) {
self::assertInstanceOf(Table::class, $table, 'No Table instance was found in tables array.');
+
if (strtolower($table->getName()) !== 'list_tables_test_new_name') {
continue;
}
$foundTable = true;
}
+
self::assertTrue($foundTable, 'Could not find new table');
}
diff --git a/tests/Doctrine/Tests/DBAL/Functional/StatementTest.php b/tests/Doctrine/Tests/DBAL/Functional/StatementTest.php
index 7aa374b461b..f545ebba2e2 100644
--- a/tests/Doctrine/Tests/DBAL/Functional/StatementTest.php
+++ b/tests/Doctrine/Tests/DBAL/Functional/StatementTest.php
@@ -2,6 +2,7 @@
namespace Doctrine\Tests\DBAL\Functional;
+use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Driver\Statement;
use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\ParameterType;
@@ -9,6 +10,7 @@
use Doctrine\DBAL\Types\Type;
use Doctrine\Tests\DbalFunctionalTestCase;
use function base64_decode;
+use function sprintf;
use function stream_get_contents;
class StatementTest extends DbalFunctionalTestCase
@@ -292,4 +294,40 @@ public function testFetchInColumnMode() : void
self::assertEquals(1, $result);
}
+
+ public function testExecWithRedundantParameters() : void
+ {
+ $driver = $this->connection->getDriver()->getName();
+
+ switch ($driver) {
+ case 'pdo_mysql':
+ case 'pdo_oracle':
+ case 'pdo_sqlsrv':
+ self::markTestSkipped(sprintf(
+ 'PDOStatement::execute() implemented in the "%s" driver does not report redundant parameters',
+ $driver
+ ));
+
+ return;
+ case 'ibm_db2':
+ self::markTestSkipped('db2_execute() does not report redundant parameters');
+
+ return;
+ case 'sqlsrv':
+ self::markTestSkipped('sqlsrv_prepare() does not report redundant parameters');
+
+ return;
+ }
+
+ $platform = $this->connection->getDatabasePlatform();
+ $query = $platform->getDummySelectSQL();
+ $stmt = $this->connection->prepare($query);
+
+ // we want to make sure the exception is thrown by the DBAL code, not by PHPUnit due to a PHP-level error,
+ // but the wrapper connection wraps everything in a DBAL exception
+ $this->iniSet('error_reporting', 0);
+
+ self::expectException(DBALException::class);
+ $stmt->execute([null]);
+ }
}
diff --git a/tests/Doctrine/Tests/DBAL/Functional/Ticket/DBAL421Test.php b/tests/Doctrine/Tests/DBAL/Functional/Ticket/DBAL421Test.php
deleted file mode 100644
index af41670690a..00000000000
--- a/tests/Doctrine/Tests/DBAL/Functional/Ticket/DBAL421Test.php
+++ /dev/null
@@ -1,56 +0,0 @@
-connection->getDatabasePlatform()->getName();
- if (in_array($platform, ['mysql', 'sqlite'])) {
- return;
- }
-
- $this->markTestSkipped('Currently restricted to MySQL and SQLite.');
- }
-
- public function testGuidShouldMatchPattern()
- {
- $guid = $this->connection->query($this->getSelectGuidSql())->fetchColumn();
- $pattern = '/[0-9A-F]{8}\-[0-9A-F]{4}\-[0-9A-F]{4}\-[8-9A-B][0-9A-F]{3}\-[0-9A-F]{12}/i';
- self::assertEquals(1, preg_match($pattern, $guid), 'GUID does not match pattern');
- }
-
- /**
- * This test does (of course) not proof that all generated GUIDs are
- * random, it should however provide some basic confidence.
- */
- public function testGuidShouldBeRandom()
- {
- $statement = $this->connection->prepare($this->getSelectGuidSql());
- $guids = [];
-
- for ($i = 0; $i < 99; $i++) {
- $statement->execute();
- $guid = $statement->fetchColumn();
- self::assertNotContains($guid, $guids, 'Duplicate GUID detected');
- $guids[] = $guid;
- }
-
- $statement->closeCursor();
- }
-
- private function getSelectGuidSql()
- {
- return 'SELECT ' . $this->connection->getDatabasePlatform()->getGuidExpression();
- }
-}
diff --git a/tests/Doctrine/Tests/DBAL/Functional/Ticket/DBAL630Test.php b/tests/Doctrine/Tests/DBAL/Functional/Ticket/DBAL630Test.php
index 827a9124277..7ba250cd13e 100644
--- a/tests/Doctrine/Tests/DBAL/Functional/Ticket/DBAL630Test.php
+++ b/tests/Doctrine/Tests/DBAL/Functional/Ticket/DBAL630Test.php
@@ -37,7 +37,9 @@ protected function setUp()
protected function tearDown()
{
if ($this->running) {
- $this->connection->getWrappedConnection()->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
+ $this->connection->getWrappedConnection()
+ ->getWrappedConnection()
+ ->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
}
parent::tearDown();
@@ -71,7 +73,9 @@ public function testBooleanConversionBoolParamRealPrepares()
public function testBooleanConversionBoolParamEmulatedPrepares()
{
- $this->connection->getWrappedConnection()->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
+ $this->connection->getWrappedConnection()
+ ->getWrappedConnection()
+ ->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
$platform = $this->connection->getDatabasePlatform();
@@ -95,7 +99,9 @@ public function testBooleanConversionNullParamEmulatedPrepares(
$statementValue,
$databaseConvertedValue
) {
- $this->connection->getWrappedConnection()->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
+ $this->connection->getWrappedConnection()
+ ->getWrappedConnection()
+ ->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
$platform = $this->connection->getDatabasePlatform();
@@ -119,7 +125,9 @@ public function testBooleanConversionNullParamEmulatedPreparesWithBooleanTypeInB
$statementValue,
$databaseConvertedValue
) {
- $this->connection->getWrappedConnection()->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
+ $this->connection->getWrappedConnection()
+ ->getWrappedConnection()
+ ->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
$platform = $this->connection->getDatabasePlatform();
diff --git a/tests/Doctrine/Tests/DBAL/Functional/Types/BinaryTest.php b/tests/Doctrine/Tests/DBAL/Functional/Types/BinaryTest.php
index d17d5250072..f911ab6146a 100644
--- a/tests/Doctrine/Tests/DBAL/Functional/Types/BinaryTest.php
+++ b/tests/Doctrine/Tests/DBAL/Functional/Types/BinaryTest.php
@@ -7,11 +7,10 @@
use Doctrine\DBAL\Driver\IBMDB2\DB2Driver;
use Doctrine\DBAL\ParameterType;
use Doctrine\DBAL\Schema\Table;
+use Doctrine\DBAL\Types\Type;
use Doctrine\Tests\DbalFunctionalTestCase;
-use function is_resource;
use function random_bytes;
use function str_replace;
-use function stream_get_contents;
class BinaryTest extends DbalFunctionalTestCase
{
@@ -74,14 +73,6 @@ private function select(string $id)
[ParameterType::BINARY]
);
- // Currently, `BinaryType` mistakenly converts string values fetched from the DB to a stream.
- // It should be the opposite. Streams should be used to represent large objects, not binary
- // strings. The confusion comes from the PostgreSQL's type system where binary strings and
- // large objects are represented by the same BYTEA type
- if (is_resource($value)) {
- $value = stream_get_contents($value);
- }
-
- return $value;
+ return Type::getType('binary')->convertToPHPValue($value, $this->connection->getDatabasePlatform());
}
}
diff --git a/tests/Doctrine/Tests/DBAL/Functional/WriteTest.php b/tests/Doctrine/Tests/DBAL/Functional/WriteTest.php
index 039fed14f8e..543a30b1065 100644
--- a/tests/Doctrine/Tests/DBAL/Functional/WriteTest.php
+++ b/tests/Doctrine/Tests/DBAL/Functional/WriteTest.php
@@ -3,6 +3,7 @@
namespace Doctrine\Tests\DBAL\Functional;
use DateTime;
+use Doctrine\DBAL\Driver\DriverException;
use Doctrine\DBAL\ParameterType;
use Doctrine\DBAL\Schema\AbstractSchemaManager;
use Doctrine\DBAL\Schema\Sequence;
@@ -189,7 +190,8 @@ public function testLastInsertIdNoSequenceGiven()
$this->markTestSkipped("Test only works consistently on platforms that support sequences and don't support identity columns.");
}
- self::assertFalse($this->connection->lastInsertId(null));
+ $this->expectException(DriverException::class);
+ $this->connection->lastInsertId();
}
/**
diff --git a/tests/Doctrine/Tests/DBAL/Logging/DebugStackTest.php b/tests/Doctrine/Tests/DBAL/Logging/DebugStackTest.php
index 914351c75dc..cc12a3234d9 100644
--- a/tests/Doctrine/Tests/DBAL/Logging/DebugStackTest.php
+++ b/tests/Doctrine/Tests/DBAL/Logging/DebugStackTest.php
@@ -27,8 +27,8 @@ public function testLoggedQuery()
[
1 => [
'sql' => 'SELECT column FROM table',
- 'params' => null,
- 'types' => null,
+ 'params' => [],
+ 'types' => [],
'executionMS' => 0,
],
],
diff --git a/tests/Doctrine/Tests/DBAL/Platforms/AbstractMySQLPlatformTestCase.php b/tests/Doctrine/Tests/DBAL/Platforms/AbstractMySQLPlatformTestCase.php
index 63148215f22..160b2b98bfb 100644
--- a/tests/Doctrine/Tests/DBAL/Platforms/AbstractMySQLPlatformTestCase.php
+++ b/tests/Doctrine/Tests/DBAL/Platforms/AbstractMySQLPlatformTestCase.php
@@ -509,27 +509,21 @@ public function testReturnsBinaryTypeDeclarationSQL()
self::assertSame('VARBINARY(255)', $this->platform->getBinaryTypeDeclarationSQL([]));
self::assertSame('VARBINARY(255)', $this->platform->getBinaryTypeDeclarationSQL(['length' => 0]));
self::assertSame('VARBINARY(65535)', $this->platform->getBinaryTypeDeclarationSQL(['length' => 65535]));
+ self::assertSame('VARBINARY(65536)', $this->platform->getBinaryTypeDeclarationSQL(['length' => 65536]));
self::assertSame('BINARY(255)', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true]));
- self::assertSame('BINARY(255)', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true, 'length' => 0]));
- self::assertSame('BINARY(65535)', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true, 'length' => 65535]));
- }
-
- /**
- * @group legacy
- * @expectedDeprecation Binary field length 65536 is greater than supported by the platform (65535). Reduce the field length or use a BLOB field instead.
- * @expectedDeprecation Binary field length 16777215 is greater than supported by the platform (65535). Reduce the field length or use a BLOB field instead.
- * @expectedDeprecation Binary field length 16777216 is greater than supported by the platform (65535). Reduce the field length or use a BLOB field instead.
- */
- public function testReturnsBinaryTypeLongerThanMaxDeclarationSQL()
- {
- self::assertSame('MEDIUMBLOB', $this->platform->getBinaryTypeDeclarationSQL(['length' => 65536]));
- self::assertSame('MEDIUMBLOB', $this->platform->getBinaryTypeDeclarationSQL(['length' => 16777215]));
- self::assertSame('LONGBLOB', $this->platform->getBinaryTypeDeclarationSQL(['length' => 16777216]));
-
- self::assertSame('MEDIUMBLOB', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true, 'length' => 65536]));
- self::assertSame('MEDIUMBLOB', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true, 'length' => 16777215]));
- self::assertSame('LONGBLOB', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true, 'length' => 16777216]));
+ self::assertSame('BINARY(255)', $this->platform->getBinaryTypeDeclarationSQL([
+ 'fixed' => true,
+ 'length' => 0,
+ ]));
+ self::assertSame('BINARY(65535)', $this->platform->getBinaryTypeDeclarationSQL([
+ 'fixed' => true,
+ 'length' => 65535,
+ ]));
+ self::assertSame('BINARY(65536)', $this->platform->getBinaryTypeDeclarationSQL([
+ 'fixed' => true,
+ 'length' => 65536,
+ ]));
}
public function testDoesNotPropagateForeignKeyCreationForNonSupportingEngines()
diff --git a/tests/Doctrine/Tests/DBAL/Platforms/AbstractPlatformTestCase.php b/tests/Doctrine/Tests/DBAL/Platforms/AbstractPlatformTestCase.php
index 8fee20fede2..af23b3a3af3 100644
--- a/tests/Doctrine/Tests/DBAL/Platforms/AbstractPlatformTestCase.php
+++ b/tests/Doctrine/Tests/DBAL/Platforms/AbstractPlatformTestCase.php
@@ -14,6 +14,7 @@
use Doctrine\DBAL\Schema\Index;
use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Schema\TableDiff;
+use Doctrine\DBAL\Schema\UniqueConstraint;
use Doctrine\DBAL\Types\Type;
use Doctrine\Tests\DbalTestCase;
use Doctrine\Tests\Types\CommentedType;
@@ -212,9 +213,9 @@ abstract public function getGenerateUniqueIndexSql();
public function testGeneratesPartialIndexesSqlOnlyWhenSupportingPartialIndexes()
{
- $where = 'test IS NULL AND test2 IS NOT NULL';
- $indexDef = new Index('name', ['test', 'test2'], false, false, [], ['where' => $where]);
- $uniqueIndex = new Index('name', ['test', 'test2'], true, false, [], ['where' => $where]);
+ $where = 'test IS NULL AND test2 IS NOT NULL';
+ $indexDef = new Index('name', ['test', 'test2'], false, false, [], ['where' => $where]);
+ $uniqueConstraint = new UniqueConstraint('name', ['test', 'test2'], [], []);
$expected = ' WHERE ' . $where;
@@ -224,15 +225,14 @@ public function testGeneratesPartialIndexesSqlOnlyWhenSupportingPartialIndexes()
$actuals[] = $this->platform->getIndexDeclarationSQL('name', $indexDef);
}
- $actuals[] = $this->platform->getUniqueConstraintDeclarationSQL('name', $uniqueIndex);
- $actuals[] = $this->platform->getCreateIndexSQL($indexDef, 'table');
+ $uniqueConstraintSQL = $this->platform->getUniqueConstraintDeclarationSQL('name', $uniqueConstraint);
+ $indexSQL = $this->platform->getCreateIndexSQL($indexDef, 'table');
- foreach ($actuals as $actual) {
- if ($this->platform->supportsPartialIndexes()) {
- self::assertStringEndsWith($expected, $actual, 'WHERE clause should be present');
- } else {
- self::assertStringEndsNotWith($expected, $actual, 'WHERE clause should NOT be present');
- }
+ $this->assertStringEndsNotWith($expected, $uniqueConstraintSQL, 'WHERE clause should NOT be present');
+ if ($this->platform->supportsPartialIndexes()) {
+ self::assertStringEndsWith($expected, $indexSQL, 'WHERE clause should be present');
+ } else {
+ self::assertStringEndsNotWith($expected, $indexSQL, 'WHERE clause should NOT be present');
}
}
@@ -701,11 +701,11 @@ public function testQuotedColumnInForeignKeyPropagation()
*/
public function testQuotesReservedKeywordInUniqueConstraintDeclarationSQL()
{
- $index = new Index('select', ['foo'], true);
+ $constraint = new UniqueConstraint('select', ['foo'], [], []);
self::assertSame(
$this->getQuotesReservedKeywordInUniqueConstraintDeclarationSQL(),
- $this->platform->getUniqueConstraintDeclarationSQL('select', $index)
+ $this->platform->getUniqueConstraintDeclarationSQL('select', $constraint)
);
}
@@ -848,11 +848,6 @@ public function testReturnsBinaryTypeDeclarationSQL()
$this->platform->getBinaryTypeDeclarationSQL([]);
}
- public function testReturnsBinaryTypeLongerThanMaxDeclarationSQL()
- {
- $this->markTestSkipped('Not applicable to the platform');
- }
-
/**
* @group DBAL-553
*/
diff --git a/tests/Doctrine/Tests/DBAL/Platforms/AbstractSQLServerPlatformTestCase.php b/tests/Doctrine/Tests/DBAL/Platforms/AbstractSQLServerPlatformTestCase.php
index 1341c9e8819..db7b9556cb3 100644
--- a/tests/Doctrine/Tests/DBAL/Platforms/AbstractSQLServerPlatformTestCase.php
+++ b/tests/Doctrine/Tests/DBAL/Platforms/AbstractSQLServerPlatformTestCase.php
@@ -985,18 +985,14 @@ public function testReturnsBinaryTypeDeclarationSQL()
self::assertSame('VARBINARY(8000)', $this->platform->getBinaryTypeDeclarationSQL(['length' => 8000]));
self::assertSame('BINARY(255)', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true]));
- self::assertSame('BINARY(255)', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true, 'length' => 0]));
- self::assertSame('BINARY(8000)', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true, 'length' => 8000]));
- }
-
- /**
- * @group legacy
- * @expectedDeprecation Binary field length 8001 is greater than supported by the platform (8000). Reduce the field length or use a BLOB field instead.
- */
- public function testReturnsBinaryTypeLongerThanMaxDeclarationSQL()
- {
- self::assertSame('VARBINARY(MAX)', $this->platform->getBinaryTypeDeclarationSQL(['length' => 8001]));
- self::assertSame('VARBINARY(MAX)', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true, 'length' => 8001]));
+ self::assertSame('BINARY(255)', $this->platform->getBinaryTypeDeclarationSQL([
+ 'fixed' => true,
+ 'length' => 0,
+ ]));
+ self::assertSame('BINARY(8000)', $this->platform->getBinaryTypeDeclarationSQL([
+ 'fixed' => true,
+ 'length' => 8000,
+ ]));
}
/**
@@ -1370,7 +1366,7 @@ public function getReturnsForeignKeyReferentialActionSQL()
*/
protected function getQuotesReservedKeywordInUniqueConstraintDeclarationSQL()
{
- return 'CONSTRAINT [select] UNIQUE (foo) WHERE foo IS NOT NULL';
+ return 'CONSTRAINT [select] UNIQUE (foo)';
}
/**
diff --git a/tests/Doctrine/Tests/DBAL/Platforms/DB2PlatformTest.php b/tests/Doctrine/Tests/DBAL/Platforms/DB2PlatformTest.php
index ce2b7df42a8..5b52552e81a 100644
--- a/tests/Doctrine/Tests/DBAL/Platforms/DB2PlatformTest.php
+++ b/tests/Doctrine/Tests/DBAL/Platforms/DB2PlatformTest.php
@@ -342,7 +342,7 @@ public function testModifiesLimitQuery()
{
self::assertEquals(
'SELECT * FROM user',
- $this->platform->modifyLimitQuery('SELECT * FROM user', null, null)
+ $this->platform->modifyLimitQuery('SELECT * FROM user', null, 0)
);
self::assertEquals(
@@ -415,16 +415,6 @@ public function testReturnsBinaryTypeDeclarationSQL()
self::assertSame('CHAR(254) FOR BIT DATA', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true, 'length' => 0]));
}
- /**
- * @group legacy
- * @expectedDeprecation Binary field length 32705 is greater than supported by the platform (32704). Reduce the field length or use a BLOB field instead.
- */
- public function testReturnsBinaryTypeLongerThanMaxDeclarationSQL()
- {
- self::assertSame('BLOB(1M)', $this->platform->getBinaryTypeDeclarationSQL(['length' => 32705]));
- self::assertSame('BLOB(1M)', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true, 'length' => 32705]));
- }
-
/**
* @group DBAL-234
*/
diff --git a/tests/Doctrine/Tests/DBAL/Platforms/OraclePlatformTest.php b/tests/Doctrine/Tests/DBAL/Platforms/OraclePlatformTest.php
index e8f8f0cdd7f..3cfdb7bef09 100644
--- a/tests/Doctrine/Tests/DBAL/Platforms/OraclePlatformTest.php
+++ b/tests/Doctrine/Tests/DBAL/Platforms/OraclePlatformTest.php
@@ -481,18 +481,14 @@ public function testReturnsBinaryTypeDeclarationSQL()
self::assertSame('RAW(2000)', $this->platform->getBinaryTypeDeclarationSQL(['length' => 2000]));
self::assertSame('RAW(255)', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true]));
- self::assertSame('RAW(2000)', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true, 'length' => 0]));
- self::assertSame('RAW(2000)', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true, 'length' => 2000]));
- }
-
- /**
- * @group legacy
- * @expectedDeprecation Binary field length 2001 is greater than supported by the platform (2000). Reduce the field length or use a BLOB field instead.
- */
- public function testReturnsBinaryTypeLongerThanMaxDeclarationSQL()
- {
- self::assertSame('BLOB', $this->platform->getBinaryTypeDeclarationSQL(['length' => 2001]));
- self::assertSame('BLOB', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true, 'length' => 2001]));
+ self::assertSame('RAW(2000)', $this->platform->getBinaryTypeDeclarationSQL([
+ 'fixed' => true,
+ 'length' => 0,
+ ]));
+ self::assertSame('RAW(2000)', $this->platform->getBinaryTypeDeclarationSQL([
+ 'fixed' => true,
+ 'length' => 2000,
+ ]));
}
public function testDoesNotPropagateUnnecessaryTableAlterationOnBinaryType()
diff --git a/tests/Doctrine/Tests/DBAL/Platforms/PostgreSQL91PlatformTest.php b/tests/Doctrine/Tests/DBAL/Platforms/PostgreSQL91PlatformTest.php
deleted file mode 100644
index ec62ac8b026..00000000000
--- a/tests/Doctrine/Tests/DBAL/Platforms/PostgreSQL91PlatformTest.php
+++ /dev/null
@@ -1,40 +0,0 @@
-platform->supportsColumnCollation());
- }
-
- public function testColumnCollationDeclarationSQL() : void
- {
- self::assertSame(
- 'COLLATE "en_US.UTF-8"',
- $this->platform->getColumnCollationDeclarationSQL('en_US.UTF-8')
- );
- }
-
- public function testGetCreateTableSQLWithColumnCollation() : void
- {
- $table = new Table('foo');
- $table->addColumn('no_collation', 'string');
- $table->addColumn('column_collation', 'string')->setPlatformOption('collation', 'en_US.UTF-8');
-
- self::assertSame(
- ['CREATE TABLE foo (no_collation VARCHAR(255) NOT NULL, column_collation VARCHAR(255) NOT NULL COLLATE "en_US.UTF-8")'],
- $this->platform->getCreateTableSQL($table),
- 'Column "no_collation" will use the default collation from the table/database and "column_collation" overwrites the collation on this column'
- );
- }
-}
diff --git a/tests/Doctrine/Tests/DBAL/Platforms/PostgreSQL92PlatformTest.php b/tests/Doctrine/Tests/DBAL/Platforms/PostgreSQL92PlatformTest.php
deleted file mode 100644
index fb36beb334a..00000000000
--- a/tests/Doctrine/Tests/DBAL/Platforms/PostgreSQL92PlatformTest.php
+++ /dev/null
@@ -1,71 +0,0 @@
-platform->hasNativeJsonType());
- }
-
- /**
- * @group DBAL-553
- */
- public function testReturnsJsonTypeDeclarationSQL()
- {
- self::assertSame('JSON', $this->platform->getJsonTypeDeclarationSQL([]));
- }
-
- public function testReturnsSmallIntTypeDeclarationSQL()
- {
- self::assertSame(
- 'SMALLSERIAL',
- $this->platform->getSmallIntTypeDeclarationSQL(['autoincrement' => true])
- );
-
- self::assertSame(
- 'SMALLINT',
- $this->platform->getSmallIntTypeDeclarationSQL(['autoincrement' => false])
- );
-
- self::assertSame(
- 'SMALLINT',
- $this->platform->getSmallIntTypeDeclarationSQL([])
- );
- }
-
- /**
- * @group DBAL-553
- */
- public function testInitializesJsonTypeMapping()
- {
- self::assertTrue($this->platform->hasDoctrineTypeMappingFor('json'));
- self::assertEquals(Type::JSON, $this->platform->getDoctrineTypeMapping('json'));
- }
-
- /**
- * @group DBAL-1220
- */
- public function testReturnsCloseActiveDatabaseConnectionsSQL()
- {
- self::assertSame(
- "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = 'foo'",
- $this->platform->getCloseActiveDatabaseConnectionsSQL('foo')
- );
- }
-}
diff --git a/tests/Doctrine/Tests/DBAL/Platforms/PostgreSQL94PlatformTest.php b/tests/Doctrine/Tests/DBAL/Platforms/PostgreSQL94PlatformTest.php
index ed118aec406..0bcf51e7435 100644
--- a/tests/Doctrine/Tests/DBAL/Platforms/PostgreSQL94PlatformTest.php
+++ b/tests/Doctrine/Tests/DBAL/Platforms/PostgreSQL94PlatformTest.php
@@ -5,7 +5,7 @@
use Doctrine\DBAL\Platforms\PostgreSQL94Platform;
use Doctrine\DBAL\Types\Type;
-class PostgreSQL94PlatformTest extends PostgreSQL92PlatformTest
+class PostgreSQL94PlatformTest extends PostgreSqlPlatformTest
{
/**
* {@inheritdoc}
diff --git a/tests/Doctrine/Tests/DBAL/Platforms/PostgreSqlPlatformTest.php b/tests/Doctrine/Tests/DBAL/Platforms/PostgreSqlPlatformTest.php
index b45a152ab0a..9fdffcb951e 100644
--- a/tests/Doctrine/Tests/DBAL/Platforms/PostgreSqlPlatformTest.php
+++ b/tests/Doctrine/Tests/DBAL/Platforms/PostgreSqlPlatformTest.php
@@ -3,6 +3,7 @@
namespace Doctrine\Tests\DBAL\Platforms;
use Doctrine\DBAL\Platforms\PostgreSqlPlatform;
+use Doctrine\DBAL\Types\Type;
class PostgreSqlPlatformTest extends AbstractPostgreSqlPlatformTestCase
{
@@ -15,4 +16,66 @@ public function testSupportsPartialIndexes()
{
self::assertTrue($this->platform->supportsPartialIndexes());
}
+
+ public function testColumnCollationDeclarationSQL()
+ {
+ self::assertEquals(
+ 'COLLATE "en_US.UTF-8"',
+ $this->platform->getColumnCollationDeclarationSQL('en_US.UTF-8')
+ );
+ }
+
+ /**
+ * @group DBAL-553
+ */
+ public function testHasNativeJsonType()
+ {
+ self::assertTrue($this->platform->hasNativeJsonType());
+ }
+
+ /**
+ * @group DBAL-553
+ */
+ public function testReturnsJsonTypeDeclarationSQL()
+ {
+ self::assertSame('JSON', $this->platform->getJsonTypeDeclarationSQL([]));
+ }
+
+ public function testReturnsSmallIntTypeDeclarationSQL()
+ {
+ self::assertSame(
+ 'SMALLSERIAL',
+ $this->platform->getSmallIntTypeDeclarationSQL(['autoincrement' => true])
+ );
+
+ self::assertSame(
+ 'SMALLINT',
+ $this->platform->getSmallIntTypeDeclarationSQL(['autoincrement' => false])
+ );
+
+ self::assertSame(
+ 'SMALLINT',
+ $this->platform->getSmallIntTypeDeclarationSQL([])
+ );
+ }
+
+ /**
+ * @group DBAL-553
+ */
+ public function testInitializesJsonTypeMapping()
+ {
+ self::assertTrue($this->platform->hasDoctrineTypeMappingFor('json'));
+ self::assertEquals(Type::JSON, $this->platform->getDoctrineTypeMapping('json'));
+ }
+
+ /**
+ * @group DBAL-1220
+ */
+ public function testReturnsCloseActiveDatabaseConnectionsSQL()
+ {
+ self::assertSame(
+ "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = 'foo'",
+ $this->platform->getCloseActiveDatabaseConnectionsSQL('foo')
+ );
+ }
}
diff --git a/tests/Doctrine/Tests/DBAL/Platforms/SQLAnywhere11PlatformTest.php b/tests/Doctrine/Tests/DBAL/Platforms/SQLAnywhere11PlatformTest.php
deleted file mode 100644
index 7e91777d6ef..00000000000
--- a/tests/Doctrine/Tests/DBAL/Platforms/SQLAnywhere11PlatformTest.php
+++ /dev/null
@@ -1,26 +0,0 @@
-markTestSkipped('This version of the platform now supports regular expressions.');
- }
-
- public function testGeneratesRegularExpressionSQLSnippet()
- {
- self::assertEquals('REGEXP', $this->platform->getRegexpExpression());
- }
-}
diff --git a/tests/Doctrine/Tests/DBAL/Platforms/SQLAnywhere12PlatformTest.php b/tests/Doctrine/Tests/DBAL/Platforms/SQLAnywhere12PlatformTest.php
deleted file mode 100644
index 7cbb2c69bb8..00000000000
--- a/tests/Doctrine/Tests/DBAL/Platforms/SQLAnywhere12PlatformTest.php
+++ /dev/null
@@ -1,141 +0,0 @@
-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'
- )
- );
- }
-}
diff --git a/tests/Doctrine/Tests/DBAL/Platforms/SQLAnywhere16PlatformTest.php b/tests/Doctrine/Tests/DBAL/Platforms/SQLAnywhere16PlatformTest.php
deleted file mode 100644
index 9692ffb1f76..00000000000
--- a/tests/Doctrine/Tests/DBAL/Platforms/SQLAnywhere16PlatformTest.php
+++ /dev/null
@@ -1,79 +0,0 @@
-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'
- );
- }
-}
diff --git a/tests/Doctrine/Tests/DBAL/Platforms/SQLAnywherePlatformTest.php b/tests/Doctrine/Tests/DBAL/Platforms/SQLAnywherePlatformTest.php
index 294b9836e2e..890e9d6f1d3 100644
--- a/tests/Doctrine/Tests/DBAL/Platforms/SQLAnywherePlatformTest.php
+++ b/tests/Doctrine/Tests/DBAL/Platforms/SQLAnywherePlatformTest.php
@@ -13,8 +13,10 @@
use Doctrine\DBAL\Schema\Constraint;
use Doctrine\DBAL\Schema\ForeignKeyConstraint;
use Doctrine\DBAL\Schema\Index;
+use Doctrine\DBAL\Schema\Sequence;
use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Schema\TableDiff;
+use Doctrine\DBAL\Schema\UniqueConstraint;
use Doctrine\DBAL\TransactionIsolationLevel;
use Doctrine\DBAL\Types\Type;
use InvalidArgumentException;
@@ -359,12 +361,12 @@ public function testGeneratesUniqueConstraintDeclarationSQL()
'CONSTRAINT unique_constraint UNIQUE CLUSTERED (a, b)',
$this->platform->getUniqueConstraintDeclarationSQL(
'unique_constraint',
- new Index(null, ['a', 'b'], true, false, ['clustered'])
+ new UniqueConstraint(null, ['a', 'b'], ['clustered'])
)
);
self::assertEquals(
- 'UNIQUE (a, b)',
- $this->platform->getUniqueConstraintDeclarationSQL(null, new Index(null, ['a', 'b'], true, false))
+ 'CONSTRAINT UNIQUE (a, b)',
+ $this->platform->getUniqueConstraintDeclarationSQL(null, new UniqueConstraint(null, ['a', 'b']))
);
}
@@ -372,7 +374,7 @@ public function testCannotGenerateUniqueConstraintDeclarationSQLWithEmptyColumns
{
$this->expectException(InvalidArgumentException::class);
- $this->platform->getUniqueConstraintDeclarationSQL('constr', new Index('constr', [], true));
+ $this->platform->getUniqueConstraintDeclarationSQL('constr', new UniqueConstraint('constr', []));
}
public function testGeneratesForeignKeyConstraintsWithAdvancedPlatformOptionsSQL()
@@ -452,20 +454,123 @@ public function testCannotGenerateCustomConstraintWithCreateConstraintSQL()
public function testGeneratesCreateIndexWithAdvancedPlatformOptionsSQL()
{
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(
new Index(
'fooindex',
['a', 'b'],
true,
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'
)
);
}
+ 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()
{
$this->expectException(DBALException::class);
@@ -530,7 +635,6 @@ public function testGeneratesSQLSnippets()
self::assertEquals('Y-m-d H:i:s.u', $this->platform->getDateTimeFormatString());
self::assertEquals('H:i:s.u', $this->platform->getTimeFormatString());
self::assertEquals('', $this->platform->getForUpdateSQL());
- self::assertEquals('NEWID()', $this->platform->getGuidExpression());
self::assertEquals('LOCATE(string_column, substring_column)', $this->platform->getLocateExpression('string_column', 'substring_column'));
self::assertEquals('LOCATE(string_column, substring_column, 1)', $this->platform->getLocateExpression('string_column', 'substring_column', 1));
self::assertEquals("HASH(column, 'MD5')", $this->platform->getMd5Expression('column'));
@@ -573,19 +677,28 @@ public function testGeneratesSQLSnippets()
);
}
- 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.
- // For versions before we have to ensure that the date time with timezone format
- // 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());
+ self::assertTrue($this->platform->hasDoctrineTypeMappingFor('timestamp with time zone'));
+ self::assertEquals('datetime', $this->platform->getDoctrineTypeMapping('timestamp with time zone'));
}
public function testHasCorrectDefaultTransactionIsolationLevel()
@@ -647,7 +760,7 @@ public function testModifiesLimitQueryWithOffset()
);
self::assertEquals(
'SELECT TOP ALL START AT 6 * FROM user',
- $this->platform->modifyLimitQuery('SELECT * FROM user', 0, 5)
+ $this->platform->modifyLimitQuery('SELECT * FROM user', null, 5)
);
}
@@ -736,7 +849,41 @@ public function testSupportsGettingAffectedRows()
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()
@@ -778,18 +925,14 @@ public function testReturnsBinaryTypeDeclarationSQL()
self::assertSame('VARBINARY(32767)', $this->platform->getBinaryTypeDeclarationSQL(['length' => 32767]));
self::assertSame('BINARY(1)', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true]));
- self::assertSame('BINARY(1)', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true, 'length' => 0]));
- self::assertSame('BINARY(32767)', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true, 'length' => 32767]));
- }
-
- /**
- * @group legacy
- * @expectedDeprecation Binary field length 32768 is greater than supported by the platform (32767). Reduce the field length or use a BLOB field instead.
- */
- public function testReturnsBinaryTypeLongerThanMaxDeclarationSQL()
- {
- self::assertSame('LONG BINARY', $this->platform->getBinaryTypeDeclarationSQL(['length' => 32768]));
- self::assertSame('LONG BINARY', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true, 'length' => 32768]));
+ self::assertSame('BINARY(1)', $this->platform->getBinaryTypeDeclarationSQL([
+ 'fixed' => true,
+ 'length' => 0,
+ ]));
+ self::assertSame('BINARY(32767)', $this->platform->getBinaryTypeDeclarationSQL([
+ 'fixed' => true,
+ 'length' => 32767,
+ ]));
}
/**
diff --git a/tests/Doctrine/Tests/DBAL/Platforms/SQLServer2008PlatformTest.php b/tests/Doctrine/Tests/DBAL/Platforms/SQLServer2008PlatformTest.php
deleted file mode 100644
index 3083ab7b606..00000000000
--- a/tests/Doctrine/Tests/DBAL/Platforms/SQLServer2008PlatformTest.php
+++ /dev/null
@@ -1,18 +0,0 @@
-platform->getDateTimeTzTypeDeclarationSQL([]));
- }
-}
diff --git a/tests/Doctrine/Tests/DBAL/Platforms/SQLServerPlatformTest.php b/tests/Doctrine/Tests/DBAL/Platforms/SQLServerPlatformTest.php
index ed2842813aa..f2f72719eff 100644
--- a/tests/Doctrine/Tests/DBAL/Platforms/SQLServerPlatformTest.php
+++ b/tests/Doctrine/Tests/DBAL/Platforms/SQLServerPlatformTest.php
@@ -53,7 +53,7 @@ public function getModifyLimitQueries()
[
'SELECT id_0, MIN(sclr_2) AS dctrn_minrownum FROM (SELECT c0_.id AS id_0, c0_.title AS title_1, ROW_NUMBER() OVER(ORDER BY c0_.title ASC) AS sclr_2 FROM TestTable c0_ ORDER BY c0_.title ASC) dctrn_result GROUP BY id_0 ORDER BY dctrn_minrownum ASC',
30,
- null,
+ 0,
'WITH dctrn_cte AS (SELECT TOP 30 id_0, MIN(sclr_2) AS dctrn_minrownum FROM (SELECT c0_.id AS id_0, c0_.title AS title_1, ROW_NUMBER() OVER(ORDER BY c0_.title ASC) AS sclr_2 FROM TestTable c0_) dctrn_result GROUP BY id_0 ORDER BY dctrn_minrownum ASC) SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS doctrine_rownum FROM dctrn_cte) AS doctrine_tbl WHERE doctrine_rownum <= 30 ORDER BY doctrine_rownum ASC',
],
@@ -61,9 +61,14 @@ public function getModifyLimitQueries()
[
'SELECT id_0, MIN(sclr_2) AS dctrn_minrownum FROM (SELECT c0_.id AS id_0, c0_.title AS title_1, ROW_NUMBER() OVER(ORDER BY c0_.title ASC) AS sclr_2 FROM TestTable c0_) dctrn_result GROUP BY id_0 ORDER BY dctrn_minrownum ASC',
30,
- null,
+ 0,
'WITH dctrn_cte AS (SELECT TOP 30 id_0, MIN(sclr_2) AS dctrn_minrownum FROM (SELECT c0_.id AS id_0, c0_.title AS title_1, ROW_NUMBER() OVER(ORDER BY c0_.title ASC) AS sclr_2 FROM TestTable c0_) dctrn_result GROUP BY id_0 ORDER BY dctrn_minrownum ASC) SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS doctrine_rownum FROM dctrn_cte) AS doctrine_tbl WHERE doctrine_rownum <= 30 ORDER BY doctrine_rownum ASC',
],
];
}
+
+ public function testGeneratesTypeDeclarationForDateTimeTz()
+ {
+ self::assertEquals('DATETIMEOFFSET(6)', $this->platform->getDateTimeTzTypeDeclarationSQL([]));
+ }
}
diff --git a/tests/Doctrine/Tests/DBAL/Query/QueryBuilderTest.php b/tests/Doctrine/Tests/DBAL/Query/QueryBuilderTest.php
index fdd28d87847..a865cf39546 100644
--- a/tests/Doctrine/Tests/DBAL/Query/QueryBuilderTest.php
+++ b/tests/Doctrine/Tests/DBAL/Query/QueryBuilderTest.php
@@ -411,6 +411,16 @@ public function testUpdateWithoutAlias()
self::assertEquals('UPDATE users SET foo = ?, bar = ?', (string) $qb);
}
+ public function testUpdateWithMatchingAlias()
+ {
+ $qb = new QueryBuilder($this->conn);
+ $qb->update('users', 'users')
+ ->set('foo', '?')
+ ->set('bar', '?');
+
+ self::assertEquals('UPDATE users SET foo = ?, bar = ?', (string) $qb);
+ }
+
public function testUpdateWhere()
{
$qb = new QueryBuilder($this->conn);
@@ -448,6 +458,15 @@ public function testDeleteWithoutAlias()
self::assertEquals('DELETE FROM users', (string) $qb);
}
+ public function testDeleteWithMatchingAlias()
+ {
+ $qb = new QueryBuilder($this->conn);
+ $qb->delete('users', 'users');
+
+ self::assertEquals(QueryBuilder::DELETE, $qb->getType());
+ self::assertEquals('DELETE FROM users', (string) $qb);
+ }
+
public function testDeleteWhere()
{
$qb = new QueryBuilder($this->conn);
@@ -776,6 +795,16 @@ public function testSimpleSelectWithoutTableAlias()
self::assertEquals('SELECT id FROM users', (string) $qb);
}
+ public function testSimpleSelectWithMatchingTableAlias()
+ {
+ $qb = new QueryBuilder($this->conn);
+
+ $qb->select('id')
+ ->from('users', 'users');
+
+ self::assertEquals('SELECT id FROM users', (string) $qb);
+ }
+
public function testSelectWithSimpleWhereWithoutTableAlias()
{
$qb = new QueryBuilder($this->conn);
diff --git a/tests/Doctrine/Tests/DBAL/Schema/ComparatorTest.php b/tests/Doctrine/Tests/DBAL/Schema/ComparatorTest.php
index d8b0c375801..b5e13ef02d5 100644
--- a/tests/Doctrine/Tests/DBAL/Schema/ComparatorTest.php
+++ b/tests/Doctrine/Tests/DBAL/Schema/ComparatorTest.php
@@ -1272,6 +1272,7 @@ public function testForeignKeyRemovalWithRenamedLocalColumn()
'id_table1' => new Column('id_table1', Type::getType('integer')),
],
[],
+ [],
[
new ForeignKeyConstraint(['id_table1'], 'table1', ['id'], 'fk_table2_table1'),
]
@@ -1285,6 +1286,7 @@ public function testForeignKeyRemovalWithRenamedLocalColumn()
'id_table3' => new Column('id_table3', Type::getType('integer')),
],
[],
+ [],
[
new ForeignKeyConstraint(['id_table3'], 'table3', ['id'], 'fk_table2_table3'),
]
diff --git a/tests/Doctrine/Tests/DBAL/Schema/TableTest.php b/tests/Doctrine/Tests/DBAL/Schema/TableTest.php
index ac5fead5bcf..cea88792394 100644
--- a/tests/Doctrine/Tests/DBAL/Schema/TableTest.php
+++ b/tests/Doctrine/Tests/DBAL/Schema/TableTest.php
@@ -200,7 +200,7 @@ public function testConstraints()
{
$constraint = new ForeignKeyConstraint([], 'foo', []);
- $tableA = new Table('foo', [], [], [$constraint]);
+ $tableA = new Table('foo', [], [], [], [$constraint]);
$constraints = $tableA->getForeignKeys();
self::assertCount(1, $constraints);
@@ -209,7 +209,7 @@ public function testConstraints()
public function testOptions()
{
- $table = new Table('foo', [], [], [], false, ['foo' => 'bar']);
+ $table = new Table('foo', [], [], [], [], ['foo' => 'bar']);
self::assertTrue($table->hasOption('foo'));
self::assertEquals('bar', $table->getOption('foo'));
diff --git a/tests/Doctrine/Tests/DBAL/StatementTest.php b/tests/Doctrine/Tests/DBAL/StatementTest.php
index 7f18b20936a..a9e977035ac 100644
--- a/tests/Doctrine/Tests/DBAL/StatementTest.php
+++ b/tests/Doctrine/Tests/DBAL/StatementTest.php
@@ -6,6 +6,7 @@
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Driver;
use Doctrine\DBAL\Driver\Connection as DriverConnection;
+use Doctrine\DBAL\Driver\Statement as DriverStatement;
use Doctrine\DBAL\Logging\SQLLogger;
use Doctrine\DBAL\ParameterType;
use Doctrine\DBAL\Statement;
@@ -23,26 +24,23 @@ class StatementTest extends DbalTestCase
private $configuration;
/** @var PDOStatement */
- private $pdoStatement;
+ private $driverStatement;
protected function setUp()
{
- $this->pdoStatement = $this->getMockBuilder(PDOStatement::class)
- ->setMethods(['execute', 'bindParam', 'bindValue'])
- ->getMock();
- $platform = new MockPlatform();
- $driverConnection = $this->createMock(DriverConnection::class);
- $driverConnection->expects($this->any())
- ->method('prepare')
- ->will($this->returnValue($this->pdoStatement));
-
- $driver = $this->createMock(Driver::class);
- $constructorArgs = [
- ['platform' => $platform],
- $driver,
- ];
- $this->conn = $this->getMockBuilder(Connection::class)
- ->setConstructorArgs($constructorArgs)
+ $this->driverStatement = $this->createMock(DriverStatement::class);
+
+ $driverConnection = $this->createConfiguredMock(DriverConnection::class, [
+ 'prepare' => $this->driverStatement,
+ ]);
+
+ $driver = $this->createMock(Driver::class);
+
+ $this->conn = $this->getMockBuilder(Connection::class)
+ ->setConstructorArgs([
+ ['platform' => new MockPlatform()],
+ $driver,
+ ])
->getMock();
$this->conn->expects($this->atLeastOnce())
->method('getWrappedConnection')
@@ -146,7 +144,7 @@ public function testExecuteCallsLoggerStopQueryOnException()
$logger->expects($this->once())
->method('stopQuery');
- $this->pdoStatement->expects($this->once())
+ $this->driverStatement->expects($this->once())
->method('execute')
->will($this->throwException(new Exception('Mock test exception')));
diff --git a/tests/Doctrine/Tests/DBAL/Types/BinaryTest.php b/tests/Doctrine/Tests/DBAL/Types/BinaryTest.php
index fbcf5fb9357..27b4f6098f1 100644
--- a/tests/Doctrine/Tests/DBAL/Types/BinaryTest.php
+++ b/tests/Doctrine/Tests/DBAL/Types/BinaryTest.php
@@ -7,9 +7,11 @@
use Doctrine\DBAL\Types\Type;
use Doctrine\Tests\DBAL\Mocks\MockPlatform;
use Doctrine\Tests\DbalTestCase;
+use function array_map;
use function base64_encode;
use function fopen;
-use function stream_get_contents;
+use function implode;
+use function range;
class BinaryTest extends DbalTestCase
{
@@ -50,11 +52,10 @@ public function testBinaryNullConvertsToPHPValue()
public function testBinaryStringConvertsToPHPValue()
{
- $databaseValue = 'binary string';
+ $databaseValue = $this->getBinaryString();
$phpValue = $this->type->convertToPHPValue($databaseValue, $this->platform);
- self::assertInternalType('resource', $phpValue);
- self::assertEquals($databaseValue, stream_get_contents($phpValue));
+ self::assertSame($databaseValue, $phpValue);
}
public function testBinaryResourceConvertsToPHPValue()
@@ -62,7 +63,15 @@ public function testBinaryResourceConvertsToPHPValue()
$databaseValue = fopen('data://text/plain;base64,' . base64_encode('binary string'), 'r');
$phpValue = $this->type->convertToPHPValue($databaseValue, $this->platform);
- self::assertSame($databaseValue, $phpValue);
+ self::assertSame('binary string', $phpValue);
+ }
+
+ /**
+ * Creates a binary string containing all possible byte values.
+ */
+ private function getBinaryString() : string
+ {
+ return implode(array_map('chr', range(0, 255)));
}
/**
diff --git a/tests/Doctrine/Tests/DBAL/Types/BlobTest.php b/tests/Doctrine/Tests/DBAL/Types/BlobTest.php
index 5500836cfdb..045b5cb320d 100644
--- a/tests/Doctrine/Tests/DBAL/Types/BlobTest.php
+++ b/tests/Doctrine/Tests/DBAL/Types/BlobTest.php
@@ -6,10 +6,6 @@
use Doctrine\DBAL\Types\Type;
use Doctrine\Tests\DBAL\Mocks\MockPlatform;
use Doctrine\Tests\DbalTestCase;
-use function base64_encode;
-use function chr;
-use function fopen;
-use function stream_get_contents;
class BlobTest extends DbalTestCase
{
@@ -32,37 +28,4 @@ public function testBlobNullConvertsToPHPValue()
{
self::assertNull($this->type->convertToPHPValue(null, $this->platform));
}
-
- public function testBinaryStringConvertsToPHPValue()
- {
- $databaseValue = $this->getBinaryString();
- $phpValue = $this->type->convertToPHPValue($databaseValue, $this->platform);
-
- self::assertInternalType('resource', $phpValue);
- self::assertSame($databaseValue, stream_get_contents($phpValue));
- }
-
- public function testBinaryResourceConvertsToPHPValue()
- {
- $databaseValue = fopen('data://text/plain;base64,' . base64_encode($this->getBinaryString()), 'r');
- $phpValue = $this->type->convertToPHPValue($databaseValue, $this->platform);
-
- self::assertSame($databaseValue, $phpValue);
- }
-
- /**
- * Creates a binary string containing all possible byte values.
- *
- * @return string
- */
- private function getBinaryString()
- {
- $string = '';
-
- for ($i = 0; $i < 256; $i++) {
- $string .= chr($i);
- }
-
- return $string;
- }
}
diff --git a/tests/Doctrine/Tests/DBAL/Types/StringTest.php b/tests/Doctrine/Tests/DBAL/Types/StringTest.php
index 74716e4f23c..dea28c2b0f5 100644
--- a/tests/Doctrine/Tests/DBAL/Types/StringTest.php
+++ b/tests/Doctrine/Tests/DBAL/Types/StringTest.php
@@ -25,11 +25,6 @@ public function testReturnsSqlDeclarationFromPlatformVarchar()
self::assertEquals('DUMMYVARCHAR()', $this->type->getSqlDeclaration([], $this->platform));
}
- public function testReturnsDefaultLengthFromPlatformVarchar()
- {
- self::assertEquals(255, $this->type->getDefaultLength($this->platform));
- }
-
public function testConvertToPHPValue()
{
self::assertInternalType('string', $this->type->convertToPHPValue('foo', $this->platform));
diff --git a/tests/Doctrine/Tests/Mocks/DriverConnectionMock.php b/tests/Doctrine/Tests/Mocks/DriverConnectionMock.php
deleted file mode 100644
index 7b8872f2ea8..00000000000
--- a/tests/Doctrine/Tests/Mocks/DriverConnectionMock.php
+++ /dev/null
@@ -1,42 +0,0 @@
-