updated-packages
This commit is contained in:
49
vendor/doctrine/dbal/.doctrine-project.json
vendored
49
vendor/doctrine/dbal/.doctrine-project.json
vendored
@@ -1,49 +0,0 @@
|
||||
{
|
||||
"active": true,
|
||||
"name": "Database Abstraction Layer",
|
||||
"shortName": "DBAL",
|
||||
"slug": "dbal",
|
||||
"docsSlug": "doctrine-dbal",
|
||||
"versions": [
|
||||
{
|
||||
"name": "3.0",
|
||||
"branchName": "develop",
|
||||
"slug": "latest",
|
||||
"upcoming": true
|
||||
},
|
||||
{
|
||||
"name": "2.9",
|
||||
"branchName": "master",
|
||||
"slug": "2.9",
|
||||
"upcoming": true
|
||||
},
|
||||
{
|
||||
"name": "2.8",
|
||||
"branchName": "2.8",
|
||||
"slug": "2.8",
|
||||
"current": true,
|
||||
"aliases": [
|
||||
"current",
|
||||
"stable"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "2.7",
|
||||
"branchName": "2.7",
|
||||
"slug": "2.7",
|
||||
"maintained": false
|
||||
},
|
||||
{
|
||||
"name": "2.6",
|
||||
"branchName": "2.6",
|
||||
"slug": "2.6",
|
||||
"maintained": false
|
||||
},
|
||||
{
|
||||
"name": "2.5",
|
||||
"branchName": "2.5",
|
||||
"slug": "2.5",
|
||||
"maintained": false
|
||||
}
|
||||
]
|
||||
}
|
4
vendor/doctrine/dbal/CONTRIBUTING.md
vendored
Normal file
4
vendor/doctrine/dbal/CONTRIBUTING.md
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
Doctrine has [general contributing guidelines][contributor workflow], make
|
||||
sure you follow them.
|
||||
|
||||
[contributor workflow]: https://www.doctrine-project.org/contribute/index.html
|
63
vendor/doctrine/dbal/README.md
vendored
63
vendor/doctrine/dbal/README.md
vendored
@@ -1,12 +1,11 @@
|
||||
# Doctrine DBAL
|
||||
|
||||
| [Master][Master] | [2.8][2.8] | [Develop][develop] |
|
||||
|:----------------:|:----------:|:------------------:|
|
||||
| [![Build status][Master image]][Master] | [![Build status][2.8 image]][2.8] | [![Build status][develop image]][develop] |
|
||||
| [![Build Status][ContinuousPHP image]][ContinuousPHP] | [![Build Status][ContinuousPHP 2.8 image]][ContinuousPHP] | [![Build Status][ContinuousPHP develop image]][ContinuousPHP] |
|
||||
| [![Code Coverage][Coverage image]][Scrutinizer Master] | [![Code Coverage][Coverage 2.8 image]][Scrutinizer 2.8] | [![Code Coverage][Coverage develop image]][Scrutinizer develop] |
|
||||
| [![Code Quality][Quality image]][Scrutinizer Master] | [![Code Quality][Quality 2.8 image]][Scrutinizer 2.8] | [![Code Quality][Quality develop image]][Scrutinizer develop] |
|
||||
| [![AppVeyor][AppVeyor master image]][AppVeyor master] | [![AppVeyor][AppVeyor 2.8 image]][AppVeyor 2.8] | [![AppVeyor][AppVeyor develop image]][AppVeyor develop] |
|
||||
| [4.0-dev][4.0] | [3.3][3.3] | [2.13][2.13] |
|
||||
|:----------------:|:----------:|:----------:|
|
||||
| [![GitHub Actions][GA 4.0 image]][GA 4.0] | [![GitHub Actions][GA 3.3 image]][GA 3.3] | [![GitHub Actions][GA 2.13 image]][GA 2.13] |
|
||||
| [![AppVeyor][AppVeyor 4.0 image]][AppVeyor 4.0] | [![AppVeyor][AppVeyor 3.3 image]][AppVeyor 3.3] | [![AppVeyor][AppVeyor 2.13 image]][AppVeyor 2.13] |
|
||||
| [![Code Coverage][Coverage image]][CodeCov 4.0] | [![Code Coverage][Coverage 3.3 image]][CodeCov 3.3] | [![Code Coverage][Coverage 2.13 image]][CodeCov 2.13] |
|
||||
| N/A | [![Code Coverage][TypeCov 3.3 image]][TypeCov 3.3] | N/A |
|
||||
|
||||
Powerful database abstraction layer with many features for database schema introspection, schema management and PDO abstraction.
|
||||
|
||||
@@ -16,30 +15,28 @@ Powerful database abstraction layer with many features for database schema intro
|
||||
* [Documentation](http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/)
|
||||
* [Issue Tracker](https://github.com/doctrine/dbal/issues)
|
||||
|
||||
[Coverage image]: https://codecov.io/gh/doctrine/dbal/branch/4.0.x/graph/badge.svg
|
||||
[4.0]: https://github.com/doctrine/dbal/tree/4.0.x
|
||||
[CodeCov 4.0]: https://codecov.io/gh/doctrine/dbal/branch/4.0.x
|
||||
[AppVeyor 4.0]: https://ci.appveyor.com/project/doctrine/dbal/branch/4.0.x
|
||||
[AppVeyor 4.0 image]: https://ci.appveyor.com/api/projects/status/i88kitq8qpbm0vie/branch/4.0.x?svg=true
|
||||
[GA 4.0]: https://github.com/doctrine/dbal/actions?query=workflow%3A%22Continuous+Integration%22+branch%3A4.0.x
|
||||
[GA 4.0 image]: https://github.com/doctrine/dbal/workflows/Continuous%20Integration/badge.svg
|
||||
|
||||
[Master image]: https://img.shields.io/travis/doctrine/dbal/master.svg?style=flat-square
|
||||
[Coverage image]: https://img.shields.io/scrutinizer/coverage/g/doctrine/dbal/master.svg?style=flat-square
|
||||
[Quality image]: https://img.shields.io/scrutinizer/g/doctrine/dbal/master.svg?style=flat-square
|
||||
[ContinuousPHP image]: https://img.shields.io/continuousphp/git-hub/doctrine/dbal/master.svg?style=flat-square
|
||||
[Master]: https://travis-ci.org/doctrine/dbal
|
||||
[Scrutinizer Master]: https://scrutinizer-ci.com/g/doctrine/dbal/
|
||||
[AppVeyor master]: https://ci.appveyor.com/project/doctrine/dbal/branch/master
|
||||
[AppVeyor master image]: https://ci.appveyor.com/api/projects/status/i88kitq8qpbm0vie/branch/master?svg=true
|
||||
[ContinuousPHP]: https://continuousphp.com/git-hub/doctrine/dbal
|
||||
[2.8 image]: https://img.shields.io/travis/doctrine/dbal/2.8.svg?style=flat-square
|
||||
[Coverage 2.8 image]: https://img.shields.io/scrutinizer/coverage/g/doctrine/dbal/2.8.svg?style=flat-square
|
||||
[Quality 2.8 image]: https://img.shields.io/scrutinizer/g/doctrine/dbal/2.8.svg?style=flat-square
|
||||
[ContinuousPHP 2.8 image]: https://img.shields.io/continuousphp/git-hub/doctrine/dbal/2.8.svg?style=flat-square
|
||||
[2.8]: https://github.com/doctrine/dbal/tree/2.8
|
||||
[Scrutinizer 2.8]: https://scrutinizer-ci.com/g/doctrine/dbal/?branch=2.8
|
||||
[AppVeyor 2.8]: https://ci.appveyor.com/project/doctrine/dbal/branch/2.8
|
||||
[AppVeyor 2.8 image]: https://ci.appveyor.com/api/projects/status/i88kitq8qpbm0vie/branch/2.8?svg=true
|
||||
[develop]: https://github.com/doctrine/dbal/tree/develop
|
||||
[develop image]: https://img.shields.io/travis/doctrine/dbal/develop.svg?style=flat-square
|
||||
[Coverage develop image]: https://img.shields.io/scrutinizer/coverage/g/doctrine/dbal/develop.svg?style=flat-square
|
||||
[Quality develop image]: https://img.shields.io/scrutinizer/g/doctrine/dbal/develop.svg?style=flat-square
|
||||
[ContinuousPHP develop image]: https://img.shields.io/continuousphp/git-hub/doctrine/dbal/develop.svg?style=flat-square
|
||||
[develop]: https://github.com/doctrine/dbal/tree/develop
|
||||
[Scrutinizer develop]: https://scrutinizer-ci.com/g/doctrine/dbal/?branch=develop
|
||||
[AppVeyor develop]: https://ci.appveyor.com/project/doctrine/dbal/branch/develop
|
||||
[AppVeyor develop image]: https://ci.appveyor.com/api/projects/status/i88kitq8qpbm0vie/branch/develop?svg=true
|
||||
[Coverage 3.3 image]: https://codecov.io/gh/doctrine/dbal/branch/3.3.x/graph/badge.svg
|
||||
[3.3]: https://github.com/doctrine/dbal/tree/3.3.x
|
||||
[CodeCov 3.3]: https://codecov.io/gh/doctrine/dbal/branch/3.3.x
|
||||
[AppVeyor 3.3]: https://ci.appveyor.com/project/doctrine/dbal/branch/3.3.x
|
||||
[AppVeyor 3.3 image]: https://ci.appveyor.com/api/projects/status/i88kitq8qpbm0vie/branch/3.3.x?svg=true
|
||||
[GA 3.3]: https://github.com/doctrine/dbal/actions?query=workflow%3A%22Continuous+Integration%22+branch%3A3.3.x
|
||||
[GA 3.3 image]: https://github.com/doctrine/dbal/workflows/Continuous%20Integration/badge.svg?branch=3.3.x
|
||||
[TypeCov 3.3]: https://shepherd.dev/github/doctrine/dbal
|
||||
[TypeCov 3.3 image]: https://shepherd.dev/github/doctrine/dbal/coverage.svg
|
||||
|
||||
[Coverage 2.13 image]: https://codecov.io/gh/doctrine/dbal/branch/2.13.x/graph/badge.svg
|
||||
[2.13]: https://github.com/doctrine/dbal/tree/2.13.x
|
||||
[CodeCov 2.13]: https://codecov.io/gh/doctrine/dbal/branch/2.13.x
|
||||
[AppVeyor 2.13]: https://ci.appveyor.com/project/doctrine/dbal/branch/2.13.x
|
||||
[AppVeyor 2.13 image]: https://ci.appveyor.com/api/projects/status/i88kitq8qpbm0vie/branch/2.13.x?svg=true
|
||||
[GA 2.13]: https://github.com/doctrine/dbal/actions?query=workflow%3A%22Continuous+Integration%22+branch%3A2.13.x
|
||||
[GA 2.13 image]: https://github.com/doctrine/dbal/workflows/Continuous%20Integration/badge.svg?branch=2.13.x
|
||||
|
14
vendor/doctrine/dbal/SECURITY.md
vendored
14
vendor/doctrine/dbal/SECURITY.md
vendored
@@ -1,14 +0,0 @@
|
||||
Security
|
||||
========
|
||||
|
||||
The Doctrine library is operating very close to your database and as such needs
|
||||
to handle and make assumptions about SQL injection vulnerabilities.
|
||||
|
||||
It is vital that you understand how Doctrine approaches security, because
|
||||
we cannot protect you from SQL injection.
|
||||
|
||||
Please read the documentation chapter on Security in Doctrine DBAL to
|
||||
understand the assumptions we make.
|
||||
|
||||
- [Latest security.rst page on Github](https://github.com/doctrine/dbal/blob/master/docs/en/reference/security.rst)
|
||||
- [Security Page in rendered documentation](http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/security.html)
|
359
vendor/doctrine/dbal/UPGRADE.md
vendored
359
vendor/doctrine/dbal/UPGRADE.md
vendored
@@ -1,359 +0,0 @@
|
||||
# Upgrade to 2.9
|
||||
|
||||
## Deprecated `Statement::fetchColumn()` with an invalid index
|
||||
|
||||
Calls to `Statement::fetchColumn()` with an invalid column index currently return `NULL`. In the future, such calls will result in a exception.
|
||||
|
||||
## Deprecated `Configuration::getFilterSchemaAssetsExpression()`, `::setFilterSchemaAssetsExpression()` and `AbstractSchemaManager::getFilterSchemaAssetsExpression()`.
|
||||
|
||||
Regular expression-based filters are hard to extend by combining together. Instead, you may use callback-based filers via `::getSchemaAssetsFilter()` and `::getSchemaAssetsFilter()`. Callbacks can use regular expressions internally.
|
||||
|
||||
## Deprecated `Doctrine\DBAL\Types\Type::getDefaultLength()`
|
||||
|
||||
This method was never used by DBAL internally. It is now deprecated and will be removed in DBAL 3.0.
|
||||
|
||||
## Deprecated `Doctrine\DBAL\Types\Type::__toString()`
|
||||
|
||||
Relying on string representation is discouraged and will be removed in DBAL 3.0.
|
||||
|
||||
## Deprecated `NULL` value of `$offset` in LIMIT queries
|
||||
|
||||
The `NULL` value of the `$offset` argument in `AbstractPlatform::(do)?ModifyLimitQuery()` methods is deprecated. If explicitly used in the method call, the absence of the offset should be indicated with a `0`.
|
||||
|
||||
## Deprecated dbal:import CLI command
|
||||
|
||||
The `dbal:import` CLI command has been deprecated since it only works with PDO-based drivers by relying on a non-documented behavior of the extension, and it's 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`.
|
||||
|
||||
# Upgrade to 2.8
|
||||
|
||||
## Deprecated usage of DB-generated UUIDs
|
||||
|
||||
The format of DB-generated UUIDs is inconsistent across supported platforms and therefore is not portable. Some of the platforms produce UUIDv1, some produce UUIDv4, some produce the values which are not even UUID.
|
||||
|
||||
Unless UUIDs are used in stored procedures which DBAL doesn't support, there's no real benefit of DB-generated UUIDs comparing to the application-generated ones.
|
||||
|
||||
Use a PHP library (e.g. [ramsey/uuid](https://packagist.org/packages/ramsey/uuid)) to generate UUIDs on the application side.
|
||||
|
||||
## Deprecated usage of binary fields whose length exceeds the platform maximum
|
||||
|
||||
- The usage of binary fields whose length exceeds the maximum field size on a given platform is deprecated.
|
||||
Use binary fields of a size which fits all target platforms, or use blob explicitly instead.
|
||||
|
||||
## Removed dependency on doctrine/common
|
||||
|
||||
The dependency on doctrine/common package has been removed.
|
||||
DBAL now depends on doctrine/cache and doctrine/event-manager instead.
|
||||
If you are using any other component from doctrine/common package,
|
||||
you will have to add an explicit dependency to your composer.json.
|
||||
|
||||
## Corrected exception thrown by ``Doctrine\DBAL\Platforms\SQLAnywhere16Platform::getAdvancedIndexOptionsSQL()``
|
||||
|
||||
This method now throws SPL ``UnexpectedValueException`` instead of accidentally throwing ``Doctrine\Common\Proxy\Exception\UnexpectedValueException``.
|
||||
|
||||
# Upgrade to 2.7
|
||||
|
||||
## Doctrine\DBAL\Platforms\AbstractPlatform::DATE_INTERVAL_UNIT_* constants deprecated
|
||||
|
||||
``Doctrine\DBAL\Platforms\AbstractPlatform::DATE_INTERVAL_UNIT_*`` constants were moved into ``Doctrine\DBAL\Platforms\DateIntervalUnit`` class without the ``DATE_INTERVAL_UNIT_`` prefix.
|
||||
|
||||
## Doctrine\DBAL\Platforms\AbstractPlatform::TRIM_* constants deprecated
|
||||
|
||||
``Doctrine\DBAL\Platforms\AbstractPlatform::TRIM_*`` constants were moved into ``Doctrine\DBAL\Platforms\TrimMode`` class without the ``TRIM_`` prefix.
|
||||
|
||||
## Doctrine\DBAL\Connection::TRANSACTION_* constants deprecated
|
||||
|
||||
``Doctrine\DBAL\Connection::TRANSACTION_*`` were moved into ``Doctrine\DBAL\TransactionIsolationLevel`` class without the ``TRANSACTION_`` prefix.
|
||||
|
||||
## DEPRECATION: direct usage of the PDO APIs in the DBAL API
|
||||
|
||||
1. When calling `Doctrine\DBAL\Driver\Statement` methods, instead of `PDO::PARAM_*` constants, `Doctrine\DBAL\ParameterType` constants should be used.
|
||||
2. When calling `Doctrine\DBAL\Driver\ResultStatement` methods, instead of `PDO::FETCH_*` constants, `Doctrine\DBAL\FetchMode` constants should be used.
|
||||
3. When configuring `Doctrine\DBAL\Portability\Connection`, instead of `PDO::CASE_*` constants, `Doctrine\DBAL\ColumnCase` constants should be used.
|
||||
4. Usage of `PDO::PARAM_INPUT_OUTPUT` in `Doctrine\DBAL\Driver\Statement::bindValue()` is deprecated.
|
||||
5. Usage of `PDO::FETCH_FUNC` in `Doctrine\DBAL\Driver\ResultStatement::fetch()` is deprecated.
|
||||
6. Calls to `\PDOStatement` methods on a `\Doctrine\DBAL\Driver\PDOStatement` instance (e.g. `fetchObject()`) are deprecated.
|
||||
|
||||
# Upgrade to 2.6
|
||||
|
||||
## MINOR BC BREAK: `fetch()` and `fetchAll()` method signatures in `Doctrine\DBAL\Driver\ResultStatement`
|
||||
|
||||
1. ``Doctrine\DBAL\Driver\ResultStatement::fetch()`` now has 3 arguments instead of 1, respecting
|
||||
``PDO::fetch()`` signature.
|
||||
|
||||
Before:
|
||||
|
||||
Doctrine\DBAL\Driver\ResultStatement::fetch($fetchMode);
|
||||
|
||||
After:
|
||||
|
||||
Doctrine\DBAL\Driver\ResultStatement::fetch($fetchMode, $cursorOrientation, $cursorOffset);
|
||||
|
||||
2. ``Doctrine\DBAL\Driver\ResultStatement::fetchAll()`` now has 3 arguments instead of 1, respecting
|
||||
``PDO::fetchAll()`` signature.
|
||||
|
||||
Before:
|
||||
|
||||
Doctrine\DBAL\Driver\ResultStatement::fetchAll($fetchMode);
|
||||
|
||||
After:
|
||||
|
||||
Doctrine\DBAL\Driver\ResultStatement::fetch($fetchMode, $fetchArgument, $ctorArgs);
|
||||
|
||||
|
||||
## MINOR BC BREAK: URL-style DSN with percentage sign in password
|
||||
|
||||
URL-style DSNs (e.g. ``mysql://foo@bar:localhost/db``) are now assumed to be percent-encoded
|
||||
in order to allow certain special characters in usernames, paswords and database names. If
|
||||
you are using a URL-style DSN and have a username, password or database name containing a
|
||||
percentage sign, you need to update your DSN. If your password is, say, ``foo%foo``, it
|
||||
should be encoded as ``foo%25foo``.
|
||||
|
||||
# Upgrade to 2.5.1
|
||||
|
||||
## MINOR BC BREAK: Doctrine\DBAL\Schema\Table
|
||||
|
||||
When adding indexes to ``Doctrine\DBAL\Schema\Table`` via ``addIndex()`` or ``addUniqueIndex()``,
|
||||
duplicate indexes are not silently ignored/dropped anymore (based on semantics, not naming!).
|
||||
Duplicate indexes are considered indexes that pass ``isFullfilledBy()`` or ``overrules()``
|
||||
in ``Doctrine\DBAL\Schema\Index``.
|
||||
This is required to make the index renaming feature introduced in 2.5.0 work properly and avoid
|
||||
issues in the ORM schema tool / DBAL schema manager which pretends users from updating
|
||||
their schemas and migrate to DBAL 2.5.*.
|
||||
Additionally it offers more flexibility in declaring indexes for the user and potentially fixes
|
||||
related issues in the ORM.
|
||||
With this change, the responsibility to decide which index is a "duplicate" is completely deferred
|
||||
to the user.
|
||||
Please also note that adding foreign key constraints to a table via ``addForeignKeyConstraint()``,
|
||||
``addUnnamedForeignKeyConstraint()`` or ``addNamedForeignKeyConstraint()`` now first checks if an
|
||||
appropriate index is already present and avoids adding an additional auto-generated one eventually.
|
||||
|
||||
# Upgrade to 2.5
|
||||
|
||||
## BC BREAK: time type resets date fields to UNIX epoch
|
||||
|
||||
When mapping `time` type field to PHP's `DateTime` instance all unused date fields are
|
||||
reset to UNIX epoch (i.e. 1970-01-01). This might break any logic which relies on comparing
|
||||
`DateTime` instances with date fields set to the current date.
|
||||
|
||||
Use `!` format prefix (see http://php.net/manual/en/datetime.createfromformat.php) for parsing
|
||||
time strings to prevent having different date fields when comparing user input and `DateTime`
|
||||
instances as mapped by Doctrine.
|
||||
|
||||
## BC BREAK: Doctrine\DBAL\Schema\Table
|
||||
|
||||
The methods ``addIndex()`` and ``addUniqueIndex()`` in ``Doctrine\DBAL\Schema\Table``
|
||||
have an additional, optional parameter. If you override these methods, you should
|
||||
add this new parameter to the declaration of your overridden methods.
|
||||
|
||||
## BC BREAK: Doctrine\DBAL\Connection
|
||||
|
||||
The visibility of the property ``$_platform`` in ``Doctrine\DBAL\Connection``
|
||||
was changed from protected to private. If you have subclassed ``Doctrine\DBAL\Connection``
|
||||
in your application and accessed ``$_platform`` directly, you have to change the code
|
||||
portions to use ``getDatabasePlatform()`` instead to retrieve the underlying database
|
||||
platform.
|
||||
The reason for this change is the new automatic platform version detection feature,
|
||||
which lazily evaluates the appropriate platform class to use for the underlying database
|
||||
server version at runtime.
|
||||
Please also note, that calling ``getDatabasePlatform()`` now needs to establish a connection
|
||||
in order to evaluate the appropriate platform class if ``Doctrine\DBAL\Connection`` is not
|
||||
already connected. Under the following circumstances, it is not possible anymore to retrieve
|
||||
the platform instance from the connection object without having to do a real connect:
|
||||
|
||||
1. ``Doctrine\DBAL\Connection`` was instantiated without the ``platform`` connection parameter.
|
||||
2. ``Doctrine\DBAL\Connection`` was instantiated without the ``serverVersion`` connection parameter.
|
||||
3. The underlying driver is "version aware" and can provide different platform instances
|
||||
for different versions.
|
||||
4. The underlying driver connection is "version aware" and can provide the database server
|
||||
version without having to query for it.
|
||||
|
||||
If one of the above conditions is NOT met, there is no need for ``Doctrine\DBAL\Connection``
|
||||
to do a connect when calling ``getDatabasePlatform()``.
|
||||
|
||||
## datetime Type uses date_create() as fallback
|
||||
|
||||
Before 2.5 the DateTime type always required a specific format, defined in
|
||||
`$platform->getDateTimeFormatString()`, which could cause quite some troubles
|
||||
on platforms that had various microtime precision formats. Starting with 2.5
|
||||
whenever the parsing of a date fails with the predefined platform format,
|
||||
the `date_create()` function will be used to parse the date.
|
||||
|
||||
This could cause some troubles when your date format is weird and not parsed
|
||||
correctly by `date_create`, however since databases are rather strict on dates
|
||||
there should be no problem.
|
||||
|
||||
## Support for pdo_ibm driver removed
|
||||
|
||||
The ``pdo_ibm`` driver is buggy and does not work well with Doctrine. Therefore it will no
|
||||
longer be supported and has been removed from the ``Doctrine\DBAL\DriverManager`` drivers
|
||||
map. It is highly encouraged to to use `ibm_db2` driver instead if you want to connect
|
||||
to an IBM DB2 database as it is much more stable and secure.
|
||||
|
||||
If for some reason you have to utilize the ``pdo_ibm`` driver you can still use the `driverClass`
|
||||
connection parameter to explicitly specify the ``Doctrine\DBAL\Driver\PDOIbm\Driver`` class.
|
||||
However be aware that you are doing this at your own risk and it will not be guaranteed that
|
||||
Doctrine will work as expected.
|
||||
|
||||
# Upgrade to 2.4
|
||||
|
||||
## Doctrine\DBAL\Schema\Constraint
|
||||
|
||||
If you have custom classes that implement the constraint interface, you have to implement
|
||||
an additional method ``getQuotedColumns`` now. This method is used to build proper constraint
|
||||
SQL for columns that need to be quoted, like keywords reserved by the specific platform used.
|
||||
The method has to return the same values as ``getColumns`` only that those column names that
|
||||
need quotation have to be returned quoted for the given platform.
|
||||
|
||||
# Upgrade to 2.3
|
||||
|
||||
## Oracle Session Init now sets Numeric Character
|
||||
|
||||
Before 2.3 the Oracle Session Init did not care about the numeric character of the Session.
|
||||
This could lead to problems on non english locale systems that required a comma as a floating
|
||||
point seperator in Oracle. Since 2.3, using the Oracle Session Init on connection start the
|
||||
client session will be altered to set the numeric character to ".,":
|
||||
|
||||
ALTER SESSION SET NLS_NUMERIC_CHARACTERS = '.,'
|
||||
|
||||
See [DBAL-345](http://www.doctrine-project.org/jira/browse/DBAL-345) for more details.
|
||||
|
||||
## Doctrine\DBAL\Connection and Doctrine\DBAL\Statement
|
||||
|
||||
The query related methods including but not limited to executeQuery, exec, query, and executeUpdate
|
||||
now wrap the driver exceptions such as PDOException with DBALException to add more debugging
|
||||
information such as the executed SQL statement, and any bound parameters.
|
||||
|
||||
If you want to retrieve the driver specific exception, you can retrieve it by calling the
|
||||
``getPrevious()`` method on DBALException.
|
||||
|
||||
Before:
|
||||
|
||||
catch(\PDOException $ex) {
|
||||
// ...
|
||||
}
|
||||
|
||||
After:
|
||||
|
||||
catch(\Doctrine\DBAL\DBALException $ex) {
|
||||
$pdoException = $ex->getPrevious();
|
||||
// ...
|
||||
}
|
||||
|
||||
## Doctrine\DBAL\Connection#setCharsetSQL() removed
|
||||
|
||||
This method only worked on MySQL and it is considered unsafe on MySQL to use SET NAMES UTF-8 instead
|
||||
of setting the charset directly on connection already. Replace this behavior with the
|
||||
connection charset option:
|
||||
|
||||
Before:
|
||||
|
||||
$conn = DriverManager::getConnection(array(..));
|
||||
$conn->setCharset('UTF8');
|
||||
|
||||
After:
|
||||
|
||||
$conn = DriverManager::getConnection(array('charset' => 'UTF8', ..));
|
||||
|
||||
## Doctrine\DBAL\Schema\Table#renameColumn() removed
|
||||
|
||||
Doctrine\DBAL\Schema\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.
|
||||
|
||||
You should use explicit SQL ALTER TABLE statements to change columns names.
|
||||
|
||||
## Schema Filter paths
|
||||
|
||||
The Filter Schema assets expression is not wrapped in () anymore for the regexp automatically.
|
||||
|
||||
Before:
|
||||
|
||||
$config->setFilterSchemaAssetsExpression('foo');
|
||||
|
||||
After:
|
||||
|
||||
$config->setFilterSchemaAssetsExpression('(foo)');
|
||||
|
||||
## Creating MySQL Tables now defaults to UTF-8
|
||||
|
||||
If you are creating a new MySQL Table through the Doctrine API, charset/collate are
|
||||
now set to 'utf8'/'utf8_unicode_ci' by default. Previously the MySQL server defaults were used.
|
||||
|
||||
# Upgrade to 2.2
|
||||
|
||||
## Doctrine\DBAL\Connection#insert and Doctrine\DBAL\Connection#update
|
||||
|
||||
Both methods now accept an optional last parameter $types with binding types of the values passed.
|
||||
This can potentially break child classes that have overwritten one of these methods.
|
||||
|
||||
## Doctrine\DBAL\Connection#executeQuery
|
||||
|
||||
Doctrine\DBAL\Connection#executeQuery() got a new last parameter "QueryCacheProfile $qcp"
|
||||
|
||||
## Doctrine\DBAL\Driver\Statement split
|
||||
|
||||
The Driver statement was split into a ResultStatement and the normal statement extending from it.
|
||||
This separates the configuration and the retrieval API from a statement.
|
||||
|
||||
## MsSql Platform/SchemaManager renamed
|
||||
|
||||
The MsSqlPlatform was renamed to SQLServerPlatform, the MsSqlSchemaManager was renamed
|
||||
to SQLServerSchemaManager.
|
||||
|
||||
## Cleanup SQLServer Platform version mess
|
||||
|
||||
DBAL 2.1 and before were actually only compatible to SQL Server 2008, not earlier versions.
|
||||
Still other parts of the platform did use old features instead of newly introduced datatypes
|
||||
in SQL Server 2005. Starting with DBAL 2.2 you can pick the Doctrine abstraction exactly
|
||||
matching your SQL Server version.
|
||||
|
||||
The PDO SqlSrv driver now uses the new `SQLServer2008Platform` as default platform.
|
||||
This platform uses new features of SQL Server as of version 2008. This also includes a switch
|
||||
in the used fields for "text" and "blob" field types to:
|
||||
|
||||
"text" => "VARCHAR(MAX)"
|
||||
"blob" => "VARBINARY(MAX)"
|
||||
|
||||
Additionally `SQLServerPlatform` in DBAL 2.1 and before used "DATE", "TIME" and "DATETIME2" for dates.
|
||||
This types are only available since version 2008 and the introduction of an explicit
|
||||
SQLServer 2008 platform makes this dependency explicit.
|
||||
|
||||
An `SQLServer2005Platform` was also introduced to differentiate the features between
|
||||
versions 2003, earlier and 2005.
|
||||
|
||||
With this change the `SQLServerPlatform` now throws an exception for using limit queries
|
||||
with an offset, since SQLServer 2003 and lower do not support this feature.
|
||||
|
||||
To use the old SQL Server Platform, because you are using SQL Server 2003 and below use
|
||||
the following configuration code:
|
||||
|
||||
use Doctrine\DBAL\DriverManager;
|
||||
use Doctrine\DBAL\Platforms\SQLServerPlatform;
|
||||
use Doctrine\DBAL\Platforms\SQLServer2005Platform;
|
||||
|
||||
// You are using SQL Server 2003 or earlier
|
||||
$conn = DriverManager::getConnection(array(
|
||||
'driver' => 'pdo_sqlsrv',
|
||||
'platform' => new SQLServerPlatform()
|
||||
// .. additional parameters
|
||||
));
|
||||
|
||||
// You are using SQL Server 2005
|
||||
$conn = DriverManager::getConnection(array(
|
||||
'driver' => 'pdo_sqlsrv',
|
||||
'platform' => new SQLServer2005Platform()
|
||||
// .. additional parameters
|
||||
));
|
||||
|
||||
// You are using SQL Server 2008
|
||||
$conn = DriverManager::getConnection(array(
|
||||
'driver' => 'pdo_sqlsrv',
|
||||
// 2008 is default platform
|
||||
// .. additional parameters
|
||||
));
|
18
vendor/doctrine/dbal/bin/doctrine-dbal.php
vendored
18
vendor/doctrine/dbal/bin/doctrine-dbal.php
vendored
@@ -1,5 +1,6 @@
|
||||
<?php
|
||||
|
||||
use Doctrine\DBAL\Tools\Console\ConnectionProvider;
|
||||
use Doctrine\DBAL\Tools\Console\ConsoleRunner;
|
||||
use Symfony\Component\Console\Helper\HelperSet;
|
||||
|
||||
@@ -41,17 +42,20 @@ if (! is_readable($configFile)) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$commands = [];
|
||||
$helperSet = require $configFile;
|
||||
$commands = [];
|
||||
$helperSetOrConnectionProvider = require $configFile;
|
||||
|
||||
if (! $helperSet instanceof HelperSet) {
|
||||
foreach ($GLOBALS as $helperSetCandidate) {
|
||||
if ($helperSetCandidate instanceof HelperSet) {
|
||||
$helperSet = $helperSetCandidate;
|
||||
if (
|
||||
! $helperSetOrConnectionProvider instanceof HelperSet
|
||||
&& ! $helperSetOrConnectionProvider instanceof ConnectionProvider
|
||||
) {
|
||||
foreach ($GLOBALS as $candidate) {
|
||||
if ($candidate instanceof HelperSet) {
|
||||
$helperSetOrConnectionProvider = $candidate;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ConsoleRunner::run($helperSet, $commands);
|
||||
ConsoleRunner::run($helperSetOrConnectionProvider, $commands);
|
||||
|
55
vendor/doctrine/dbal/composer.json
vendored
55
vendor/doctrine/dbal/composer.json
vendored
@@ -3,14 +3,25 @@
|
||||
"type": "library",
|
||||
"description": "Powerful PHP database abstraction layer (DBAL) with many features for database schema introspection and management.",
|
||||
"keywords": [
|
||||
"php",
|
||||
"abstraction",
|
||||
"database",
|
||||
"dbal",
|
||||
"db2",
|
||||
"mariadb",
|
||||
"mssql",
|
||||
"mysql",
|
||||
"pgsql",
|
||||
"dbal",
|
||||
"database",
|
||||
"abstraction",
|
||||
"persistence",
|
||||
"queryobject"
|
||||
"postgresql",
|
||||
"oci8",
|
||||
"oracle",
|
||||
"pdo",
|
||||
"queryobject",
|
||||
"sasql",
|
||||
"sql",
|
||||
"sqlanywhere",
|
||||
"sqlite",
|
||||
"sqlserver",
|
||||
"sqlsrv"
|
||||
],
|
||||
"homepage": "https://www.doctrine-project.org/projects/dbal.html",
|
||||
"license": "MIT",
|
||||
@@ -21,36 +32,38 @@
|
||||
{"name": "Jonathan Wage", "email": "jonwage@gmail.com"}
|
||||
],
|
||||
"require": {
|
||||
"php": "^7.1",
|
||||
"php": "^7.1 || ^8",
|
||||
"ext-pdo": "*",
|
||||
"doctrine/cache": "^1.0",
|
||||
"doctrine/cache": "^1.0|^2.0",
|
||||
"doctrine/deprecations": "^0.5.3|^1",
|
||||
"doctrine/event-manager": "^1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/coding-standard": "^5.0",
|
||||
"jetbrains/phpstorm-stubs": "^2018.1.2",
|
||||
"phpstan/phpstan": "^0.10.1",
|
||||
"phpunit/phpunit": "^7.4",
|
||||
"symfony/console": "^2.0.5|^3.0|^4.0",
|
||||
"symfony/phpunit-bridge": "^3.4.5|^4.0.5"
|
||||
"doctrine/coding-standard": "9.0.0",
|
||||
"jetbrains/phpstorm-stubs": "2021.1",
|
||||
"phpstan/phpstan": "1.4.6",
|
||||
"phpunit/phpunit": "^7.5.20|^8.5|9.5.16",
|
||||
"psalm/plugin-phpunit": "0.16.1",
|
||||
"squizlabs/php_codesniffer": "3.6.2",
|
||||
"symfony/cache": "^4.4",
|
||||
"symfony/console": "^2.0.5|^3.0|^4.0|^5.0",
|
||||
"vimeo/psalm": "4.22.0"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/console": "For helpful console commands such as SQL execution and import of files."
|
||||
},
|
||||
"bin": ["bin/doctrine-dbal"],
|
||||
"config": {
|
||||
"sort-packages": true
|
||||
"sort-packages": true,
|
||||
"allow-plugins": {
|
||||
"dealerdirect/phpcodesniffer-composer-installer": true,
|
||||
"composer/package-versions-deprecated": true
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": { "Doctrine\\DBAL\\": "lib/Doctrine/DBAL" }
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": { "Doctrine\\Tests\\": "tests/Doctrine/Tests" }
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.9.x-dev",
|
||||
"dev-develop": "3.0.x-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
45
vendor/doctrine/dbal/lib/Doctrine/DBAL/Abstraction/Result.php
vendored
Normal file
45
vendor/doctrine/dbal/lib/Doctrine/DBAL/Abstraction/Result.php
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\DBAL\Abstraction;
|
||||
|
||||
use Doctrine\DBAL\Driver\Result as DriverResult;
|
||||
use Doctrine\DBAL\Exception;
|
||||
use Traversable;
|
||||
|
||||
/**
|
||||
* Abstraction-level result statement execution result. Provides additional methods on top
|
||||
* of the driver-level interface.
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
interface Result extends DriverResult
|
||||
{
|
||||
/**
|
||||
* Returns an iterator over the result set rows represented as numeric arrays.
|
||||
*
|
||||
* @return Traversable<int,array<int,mixed>>
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function iterateNumeric(): Traversable;
|
||||
|
||||
/**
|
||||
* Returns an iterator over the result set rows represented as associative arrays.
|
||||
*
|
||||
* @return Traversable<int,array<string,mixed>>
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function iterateAssociative(): Traversable;
|
||||
|
||||
/**
|
||||
* Returns an iterator over the values of the first column of the result set.
|
||||
*
|
||||
* @return Traversable<int,mixed>
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function iterateColumn(): Traversable;
|
||||
}
|
@@ -3,17 +3,24 @@
|
||||
namespace Doctrine\DBAL\Cache;
|
||||
|
||||
use ArrayIterator;
|
||||
use Doctrine\DBAL\Driver\FetchUtils;
|
||||
use Doctrine\DBAL\Driver\Result;
|
||||
use Doctrine\DBAL\Driver\ResultStatement;
|
||||
use Doctrine\DBAL\FetchMode;
|
||||
use InvalidArgumentException;
|
||||
use IteratorAggregate;
|
||||
use PDO;
|
||||
use ReturnTypeWillChange;
|
||||
|
||||
use function array_merge;
|
||||
use function array_values;
|
||||
use function count;
|
||||
use function reset;
|
||||
|
||||
class ArrayStatement implements IteratorAggregate, ResultStatement
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
class ArrayStatement implements IteratorAggregate, ResultStatement, Result
|
||||
{
|
||||
/** @var mixed[] */
|
||||
private $data;
|
||||
@@ -42,10 +49,22 @@ class ArrayStatement implements IteratorAggregate, ResultStatement
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated Use free() instead.
|
||||
*/
|
||||
public function closeCursor()
|
||||
{
|
||||
unset($this->data);
|
||||
$this->free();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function rowCount()
|
||||
{
|
||||
return count($this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -58,6 +77,8 @@ class ArrayStatement implements IteratorAggregate, ResultStatement
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated Use one of the fetch- or iterate-related methods.
|
||||
*/
|
||||
public function setFetchMode($fetchMode, $arg2 = null, $arg3 = null)
|
||||
{
|
||||
@@ -72,7 +93,10 @@ class ArrayStatement implements IteratorAggregate, ResultStatement
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated Use iterateNumeric(), iterateAssociative() or iterateColumn() instead.
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function getIterator()
|
||||
{
|
||||
$data = $this->fetchAll();
|
||||
@@ -82,6 +106,8 @@ class ArrayStatement implements IteratorAggregate, ResultStatement
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated Use fetchNumeric(), fetchAssociative() or fetchOne() instead.
|
||||
*/
|
||||
public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEXT, $cursorOffset = 0)
|
||||
{
|
||||
@@ -113,6 +139,8 @@ class ArrayStatement implements IteratorAggregate, ResultStatement
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated Use fetchAllNumeric(), fetchAllAssociative() or fetchFirstColumn() instead.
|
||||
*/
|
||||
public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = null)
|
||||
{
|
||||
@@ -126,6 +154,8 @@ class ArrayStatement implements IteratorAggregate, ResultStatement
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated Use fetchOne() instead.
|
||||
*/
|
||||
public function fetchColumn($columnIndex = 0)
|
||||
{
|
||||
@@ -134,4 +164,81 @@ class ArrayStatement implements IteratorAggregate, ResultStatement
|
||||
// TODO: verify that return false is the correct behavior
|
||||
return $row[$columnIndex] ?? false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchNumeric()
|
||||
{
|
||||
$row = $this->doFetch();
|
||||
|
||||
if ($row === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return array_values($row);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchAssociative()
|
||||
{
|
||||
return $this->doFetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchOne()
|
||||
{
|
||||
$row = $this->doFetch();
|
||||
|
||||
if ($row === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return reset($row);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchAllNumeric(): array
|
||||
{
|
||||
return FetchUtils::fetchAllNumeric($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchAllAssociative(): array
|
||||
{
|
||||
return FetchUtils::fetchAllAssociative($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchFirstColumn(): array
|
||||
{
|
||||
return FetchUtils::fetchFirstColumn($this);
|
||||
}
|
||||
|
||||
public function free(): void
|
||||
{
|
||||
$this->data = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed|false
|
||||
*/
|
||||
private function doFetch()
|
||||
{
|
||||
if (! isset($this->data[$this->num])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->data[$this->num++];
|
||||
}
|
||||
}
|
||||
|
@@ -2,12 +2,15 @@
|
||||
|
||||
namespace Doctrine\DBAL\Cache;
|
||||
|
||||
use Doctrine\DBAL\DBALException;
|
||||
use Doctrine\DBAL\Exception;
|
||||
|
||||
class CacheException extends DBALException
|
||||
/**
|
||||
* @psalm-immutable
|
||||
*/
|
||||
class CacheException extends Exception
|
||||
{
|
||||
/**
|
||||
* @return \Doctrine\DBAL\Cache\CacheException
|
||||
* @return CacheException
|
||||
*/
|
||||
public static function noCacheKey()
|
||||
{
|
||||
@@ -15,7 +18,7 @@ class CacheException extends DBALException
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Doctrine\DBAL\Cache\CacheException
|
||||
* @return CacheException
|
||||
*/
|
||||
public static function noResultDriverConfigured()
|
||||
{
|
||||
|
@@ -3,6 +3,8 @@
|
||||
namespace Doctrine\DBAL\Cache;
|
||||
|
||||
use Doctrine\Common\Cache\Cache;
|
||||
use Doctrine\DBAL\Types\Type;
|
||||
|
||||
use function hash;
|
||||
use function serialize;
|
||||
use function sha1;
|
||||
@@ -67,16 +69,16 @@ class QueryCacheProfile
|
||||
/**
|
||||
* Generates the real cache key from query, params, types and connection parameters.
|
||||
*
|
||||
* @param string $query
|
||||
* @param mixed[] $params
|
||||
* @param int[]|string[] $types
|
||||
* @param mixed[] $connectionParams
|
||||
* @param string $sql
|
||||
* @param array<int, mixed>|array<string, mixed> $params
|
||||
* @param array<int, Type|int|string|null>|array<string, Type|int|string|null> $types
|
||||
* @param array<string, mixed> $connectionParams
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function generateCacheKeys($query, $params, $types, array $connectionParams = [])
|
||||
public function generateCacheKeys($sql, $params, $types, array $connectionParams = [])
|
||||
{
|
||||
$realCacheKey = 'query=' . $query .
|
||||
$realCacheKey = 'query=' . $sql .
|
||||
'¶ms=' . serialize($params) .
|
||||
'&types=' . serialize($types) .
|
||||
'&connectionParams=' . hash('sha256', serialize($connectionParams));
|
||||
@@ -92,7 +94,7 @@ class QueryCacheProfile
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Doctrine\DBAL\Cache\QueryCacheProfile
|
||||
* @return QueryCacheProfile
|
||||
*/
|
||||
public function setResultCacheDriver(Cache $cache)
|
||||
{
|
||||
@@ -102,7 +104,7 @@ class QueryCacheProfile
|
||||
/**
|
||||
* @param string|null $cacheKey
|
||||
*
|
||||
* @return \Doctrine\DBAL\Cache\QueryCacheProfile
|
||||
* @return QueryCacheProfile
|
||||
*/
|
||||
public function setCacheKey($cacheKey)
|
||||
{
|
||||
@@ -112,7 +114,7 @@ class QueryCacheProfile
|
||||
/**
|
||||
* @param int $lifetime
|
||||
*
|
||||
* @return \Doctrine\DBAL\Cache\QueryCacheProfile
|
||||
* @return QueryCacheProfile
|
||||
*/
|
||||
public function setLifetime($lifetime)
|
||||
{
|
||||
|
@@ -4,14 +4,21 @@ namespace Doctrine\DBAL\Cache;
|
||||
|
||||
use ArrayIterator;
|
||||
use Doctrine\Common\Cache\Cache;
|
||||
use Doctrine\DBAL\Driver\Exception;
|
||||
use Doctrine\DBAL\Driver\FetchUtils;
|
||||
use Doctrine\DBAL\Driver\Result;
|
||||
use Doctrine\DBAL\Driver\ResultStatement;
|
||||
use Doctrine\DBAL\Driver\Statement;
|
||||
use Doctrine\DBAL\FetchMode;
|
||||
use InvalidArgumentException;
|
||||
use IteratorAggregate;
|
||||
use PDO;
|
||||
use ReturnTypeWillChange;
|
||||
|
||||
use function array_map;
|
||||
use function array_merge;
|
||||
use function array_values;
|
||||
use function assert;
|
||||
use function reset;
|
||||
|
||||
/**
|
||||
@@ -26,8 +33,10 @@ use function reset;
|
||||
*
|
||||
* Also you have to realize that the cache will load the whole result into memory at once to ensure 2.
|
||||
* This means that the memory usage for cached results might increase by using this feature.
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
class ResultCacheStatement implements IteratorAggregate, ResultStatement
|
||||
class ResultCacheStatement implements IteratorAggregate, ResultStatement, Result
|
||||
{
|
||||
/** @var Cache */
|
||||
private $resultCache;
|
||||
@@ -41,17 +50,10 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement
|
||||
/** @var int */
|
||||
private $lifetime;
|
||||
|
||||
/** @var Statement */
|
||||
/** @var ResultStatement */
|
||||
private $statement;
|
||||
|
||||
/**
|
||||
* Did we reach the end of the statement?
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $emptied = false;
|
||||
|
||||
/** @var mixed[] */
|
||||
/** @var array<int,array<string,mixed>>|null */
|
||||
private $data;
|
||||
|
||||
/** @var int */
|
||||
@@ -62,7 +64,7 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement
|
||||
* @param string $realKey
|
||||
* @param int $lifetime
|
||||
*/
|
||||
public function __construct(Statement $stmt, Cache $resultCache, $cacheKey, $realKey, $lifetime)
|
||||
public function __construct(ResultStatement $stmt, Cache $resultCache, $cacheKey, $realKey, $lifetime)
|
||||
{
|
||||
$this->statement = $stmt;
|
||||
$this->resultCache = $resultCache;
|
||||
@@ -73,22 +75,12 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated Use free() instead.
|
||||
*/
|
||||
public function closeCursor()
|
||||
{
|
||||
$this->statement->closeCursor();
|
||||
if (! $this->emptied || $this->data === null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$data = $this->resultCache->fetch($this->cacheKey);
|
||||
if (! $data) {
|
||||
$data = [];
|
||||
}
|
||||
$data[$this->realKey] = $this->data;
|
||||
|
||||
$this->resultCache->save($this->cacheKey, $data, $this->lifetime);
|
||||
unset($this->data);
|
||||
$this->free();
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -103,6 +95,8 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated Use one of the fetch- or iterate-related methods.
|
||||
*/
|
||||
public function setFetchMode($fetchMode, $arg2 = null, $arg3 = null)
|
||||
{
|
||||
@@ -113,7 +107,10 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated Use iterateNumeric(), iterateAssociative() or iterateColumn() instead.
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function getIterator()
|
||||
{
|
||||
$data = $this->fetchAll();
|
||||
@@ -122,7 +119,12 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement
|
||||
}
|
||||
|
||||
/**
|
||||
* Be warned that you will need to call this method until no rows are
|
||||
* available for caching to happen.
|
||||
*
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated Use fetchNumeric(), fetchAssociative() or fetchOne() instead.
|
||||
*/
|
||||
public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEXT, $cursorOffset = 0)
|
||||
{
|
||||
@@ -156,21 +158,48 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement
|
||||
throw new InvalidArgumentException('Invalid fetch-style given for caching result.');
|
||||
}
|
||||
|
||||
$this->emptied = true;
|
||||
$this->saveToCache();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated Use fetchAllNumeric(), fetchAllAssociative() or fetchFirstColumn() instead.
|
||||
*/
|
||||
public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = null)
|
||||
{
|
||||
return $this->statement->fetchAll($fetchMode, $fetchArgument, $ctorArgs);
|
||||
$data = $this->statement->fetchAll(FetchMode::ASSOCIATIVE, $fetchArgument, $ctorArgs);
|
||||
|
||||
$this->data = $data;
|
||||
|
||||
$this->saveToCache();
|
||||
|
||||
if ($fetchMode === FetchMode::NUMERIC) {
|
||||
foreach ($data as $i => $row) {
|
||||
$data[$i] = array_values($row);
|
||||
}
|
||||
} elseif ($fetchMode === FetchMode::MIXED) {
|
||||
foreach ($data as $i => $row) {
|
||||
$data[$i] = array_merge($row, array_values($row));
|
||||
}
|
||||
} elseif ($fetchMode === FetchMode::COLUMN) {
|
||||
foreach ($data as $i => $row) {
|
||||
$data[$i] = reset($row);
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Be warned that you will need to call this method until no rows are
|
||||
* available for caching to happen.
|
||||
*
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated Use fetchOne() instead.
|
||||
*/
|
||||
public function fetchColumn($columnIndex = 0)
|
||||
{
|
||||
@@ -180,6 +209,89 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement
|
||||
return $row[$columnIndex] ?? false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Be warned that you will need to call this method until no rows are
|
||||
* available for caching to happen.
|
||||
*
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchNumeric()
|
||||
{
|
||||
$row = $this->doFetch();
|
||||
|
||||
if ($row === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return array_values($row);
|
||||
}
|
||||
|
||||
/**
|
||||
* Be warned that you will need to call this method until no rows are
|
||||
* available for caching to happen.
|
||||
*
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchAssociative()
|
||||
{
|
||||
return $this->doFetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* Be warned that you will need to call this method until no rows are
|
||||
* available for caching to happen.
|
||||
*
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchOne()
|
||||
{
|
||||
return FetchUtils::fetchOne($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchAllNumeric(): array
|
||||
{
|
||||
if ($this->statement instanceof Result) {
|
||||
$data = $this->statement->fetchAllAssociative();
|
||||
} else {
|
||||
$data = $this->statement->fetchAll(FetchMode::ASSOCIATIVE);
|
||||
}
|
||||
|
||||
$this->data = $data;
|
||||
|
||||
$this->saveToCache();
|
||||
|
||||
return array_map('array_values', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchAllAssociative(): array
|
||||
{
|
||||
if ($this->statement instanceof Result) {
|
||||
$data = $this->statement->fetchAllAssociative();
|
||||
} else {
|
||||
$data = $this->statement->fetchAll(FetchMode::ASSOCIATIVE);
|
||||
}
|
||||
|
||||
$this->data = $data;
|
||||
|
||||
$this->saveToCache();
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchFirstColumn(): array
|
||||
{
|
||||
return FetchUtils::fetchFirstColumn($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of rows affected by the last DELETE, INSERT, or UPDATE statement
|
||||
* executed by the corresponding object.
|
||||
@@ -189,10 +301,61 @@ class ResultCacheStatement implements IteratorAggregate, ResultStatement
|
||||
* this behaviour is not guaranteed for all databases and should not be
|
||||
* relied on for portable applications.
|
||||
*
|
||||
* @return int The number of rows.
|
||||
* @return int|string The number of rows.
|
||||
*/
|
||||
public function rowCount()
|
||||
{
|
||||
assert($this->statement instanceof Statement);
|
||||
|
||||
return $this->statement->rowCount();
|
||||
}
|
||||
|
||||
public function free(): void
|
||||
{
|
||||
$this->data = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string,mixed>|false
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
private function doFetch()
|
||||
{
|
||||
if ($this->data === null) {
|
||||
$this->data = [];
|
||||
}
|
||||
|
||||
if ($this->statement instanceof Result) {
|
||||
$row = $this->statement->fetchAssociative();
|
||||
} else {
|
||||
$row = $this->statement->fetch(FetchMode::ASSOCIATIVE);
|
||||
}
|
||||
|
||||
if ($row !== false) {
|
||||
$this->data[] = $row;
|
||||
|
||||
return $row;
|
||||
}
|
||||
|
||||
$this->saveToCache();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function saveToCache(): void
|
||||
{
|
||||
if ($this->data === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$data = $this->resultCache->fetch($this->cacheKey);
|
||||
if (! $data) {
|
||||
$data = [];
|
||||
}
|
||||
|
||||
$data[$this->realKey] = $this->data;
|
||||
|
||||
$this->resultCache->save($this->cacheKey, $data, $this->lifetime);
|
||||
}
|
||||
}
|
||||
|
@@ -25,6 +25,8 @@ final class ColumnCase
|
||||
|
||||
/**
|
||||
* This class cannot be instantiated.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
|
@@ -5,13 +5,15 @@ namespace Doctrine\DBAL;
|
||||
use Doctrine\Common\Cache\Cache;
|
||||
use Doctrine\DBAL\Logging\SQLLogger;
|
||||
use Doctrine\DBAL\Schema\AbstractAsset;
|
||||
use Doctrine\Deprecations\Deprecation;
|
||||
|
||||
use function preg_match;
|
||||
|
||||
/**
|
||||
* Configuration container for the Doctrine DBAL.
|
||||
*
|
||||
* @internal When adding a new configuration option just write a getter/setter
|
||||
* pair and add the option to the _attributes array with a proper default value.
|
||||
* Internal note: When adding a new configuration option just write a getter/setter
|
||||
* pair and add the option to the _attributes array with a proper default value.
|
||||
*/
|
||||
class Configuration
|
||||
{
|
||||
@@ -72,15 +74,22 @@ class Configuration
|
||||
*
|
||||
* @deprecated Use Configuration::setSchemaAssetsFilter() instead
|
||||
*
|
||||
* @param string $filterExpression
|
||||
* @param string|null $filterExpression
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setFilterSchemaAssetsExpression($filterExpression)
|
||||
{
|
||||
Deprecation::trigger(
|
||||
'doctrine/dbal',
|
||||
'https://github.com/doctrine/dbal/pull/3316',
|
||||
'Configuration::setFilterSchemaAssetsExpression() is deprecated, use setSchemaAssetsFilter() instead.'
|
||||
);
|
||||
|
||||
$this->_attributes['filterSchemaAssetsExpression'] = $filterExpression;
|
||||
if ($filterExpression) {
|
||||
$this->_attributes['filterSchemaAssetsExpressionCallable'] = $this->buildSchemaAssetsFilterFromExpression($filterExpression);
|
||||
$this->_attributes['filterSchemaAssetsExpressionCallable']
|
||||
= $this->buildSchemaAssetsFilterFromExpression($filterExpression);
|
||||
} else {
|
||||
$this->_attributes['filterSchemaAssetsExpressionCallable'] = null;
|
||||
}
|
||||
@@ -95,18 +104,27 @@ class Configuration
|
||||
*/
|
||||
public function getFilterSchemaAssetsExpression()
|
||||
{
|
||||
Deprecation::trigger(
|
||||
'doctrine/dbal',
|
||||
'https://github.com/doctrine/dbal/pull/3316',
|
||||
'Configuration::getFilterSchemaAssetsExpression() is deprecated, use getSchemaAssetsFilter() instead.'
|
||||
);
|
||||
|
||||
return $this->_attributes['filterSchemaAssetsExpression'] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $filterExpression
|
||||
*
|
||||
* @return callable(string|AbstractAsset)
|
||||
*/
|
||||
private function buildSchemaAssetsFilterFromExpression($filterExpression) : callable
|
||||
private function buildSchemaAssetsFilterFromExpression($filterExpression): callable
|
||||
{
|
||||
return static function ($assetName) use ($filterExpression) {
|
||||
if ($assetName instanceof AbstractAsset) {
|
||||
$assetName = $assetName->getName();
|
||||
}
|
||||
|
||||
return preg_match($filterExpression, $assetName);
|
||||
};
|
||||
}
|
||||
@@ -114,16 +132,17 @@ class Configuration
|
||||
/**
|
||||
* Sets the callable to use to filter schema assets.
|
||||
*/
|
||||
public function setSchemaAssetsFilter(?callable $callable = null) : ?callable
|
||||
public function setSchemaAssetsFilter(?callable $callable = null): ?callable
|
||||
{
|
||||
$this->_attributes['filterSchemaAssetsExpression'] = null;
|
||||
$this->_attributes['filterSchemaAssetsExpression'] = null;
|
||||
|
||||
return $this->_attributes['filterSchemaAssetsExpressionCallable'] = $callable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the callable to use to filter schema assets.
|
||||
*/
|
||||
public function getSchemaAssetsFilter() : ?callable
|
||||
public function getSchemaAssetsFilter(): ?callable
|
||||
{
|
||||
return $this->_attributes['filterSchemaAssetsExpressionCallable'] ?? null;
|
||||
}
|
||||
@@ -138,6 +157,8 @@ class Configuration
|
||||
* @see getAutoCommit
|
||||
*
|
||||
* @param bool $autoCommit True to enable auto-commit mode; false to disable it.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setAutoCommit($autoCommit)
|
||||
{
|
||||
|
1112
vendor/doctrine/dbal/lib/Doctrine/DBAL/Connection.php
vendored
1112
vendor/doctrine/dbal/lib/Doctrine/DBAL/Connection.php
vendored
File diff suppressed because it is too large
Load Diff
@@ -2,10 +2,13 @@
|
||||
|
||||
namespace Doctrine\DBAL;
|
||||
|
||||
class ConnectionException extends DBALException
|
||||
/**
|
||||
* @psalm-immutable
|
||||
*/
|
||||
class ConnectionException extends Exception
|
||||
{
|
||||
/**
|
||||
* @return \Doctrine\DBAL\ConnectionException
|
||||
* @return ConnectionException
|
||||
*/
|
||||
public static function commitFailedRollbackOnly()
|
||||
{
|
||||
@@ -13,7 +16,7 @@ class ConnectionException extends DBALException
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Doctrine\DBAL\ConnectionException
|
||||
* @return ConnectionException
|
||||
*/
|
||||
public static function noActiveTransaction()
|
||||
{
|
||||
@@ -21,7 +24,7 @@ class ConnectionException extends DBALException
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Doctrine\DBAL\ConnectionException
|
||||
* @return ConnectionException
|
||||
*/
|
||||
public static function savepointsNotSupported()
|
||||
{
|
||||
@@ -29,7 +32,7 @@ class ConnectionException extends DBALException
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Doctrine\DBAL\ConnectionException
|
||||
* @return ConnectionException
|
||||
*/
|
||||
public static function mayNotAlterNestedTransactionWithSavepointsInTransaction()
|
||||
{
|
||||
|
@@ -4,370 +4,98 @@ namespace Doctrine\DBAL\Connections;
|
||||
|
||||
use Doctrine\Common\EventManager;
|
||||
use Doctrine\DBAL\Configuration;
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\Driver;
|
||||
use Doctrine\DBAL\Driver\Connection as DriverConnection;
|
||||
use Doctrine\DBAL\Event\ConnectionEventArgs;
|
||||
use Doctrine\DBAL\Events;
|
||||
use Doctrine\DBAL\DriverManager;
|
||||
use Doctrine\Deprecations\Deprecation;
|
||||
use InvalidArgumentException;
|
||||
use function array_rand;
|
||||
use function count;
|
||||
use function func_get_args;
|
||||
|
||||
/**
|
||||
* Master-Slave Connection
|
||||
* @deprecated Use PrimaryReadReplicaConnection instead
|
||||
*
|
||||
* Connection can be used with master-slave setups.
|
||||
*
|
||||
* Important for the understanding of this connection should be how and when
|
||||
* it picks the slave or master.
|
||||
*
|
||||
* 1. Slave if master was never picked before and ONLY if 'getWrappedConnection'
|
||||
* or 'executeQuery' is used.
|
||||
* 2. Master picked when 'exec', 'executeUpdate', 'insert', 'delete', 'update', 'createSavepoint',
|
||||
* 'releaseSavepoint', 'beginTransaction', 'rollback', 'commit', 'query' or
|
||||
* 'prepare' is called.
|
||||
* 3. If master was picked once during the lifetime of the connection it will always get picked afterwards.
|
||||
* 4. One slave connection is randomly picked ONCE during a request.
|
||||
*
|
||||
* ATTENTION: You can write to the slave with this connection if you execute a write query without
|
||||
* opening up a transaction. For example:
|
||||
*
|
||||
* $conn = DriverManager::getConnection(...);
|
||||
* $conn->executeQuery("DELETE FROM table");
|
||||
*
|
||||
* Be aware that Connection#executeQuery is a method specifically for READ
|
||||
* operations only.
|
||||
*
|
||||
* This connection is limited to slave operations using the
|
||||
* Connection#executeQuery operation only, because it wouldn't be compatible
|
||||
* with the ORM or SchemaManager code otherwise. Both use all the other
|
||||
* operations in a context where writes could happen to a slave, which makes
|
||||
* this restricted approach necessary.
|
||||
*
|
||||
* You can manually connect to the master at any time by calling:
|
||||
*
|
||||
* $conn->connect('master');
|
||||
*
|
||||
* Instantiation through the DriverManager looks like:
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* $conn = DriverManager::getConnection(array(
|
||||
* 'wrapperClass' => 'Doctrine\DBAL\Connections\MasterSlaveConnection',
|
||||
* 'driver' => 'pdo_mysql',
|
||||
* 'master' => array('user' => '', 'password' => '', 'host' => '', 'dbname' => ''),
|
||||
* 'slaves' => array(
|
||||
* array('user' => 'slave1', 'password', 'host' => '', 'dbname' => ''),
|
||||
* array('user' => 'slave2', 'password', 'host' => '', 'dbname' => ''),
|
||||
* )
|
||||
* ));
|
||||
*
|
||||
* You can also pass 'driverOptions' and any other documented option to each of this drivers to pass additional information.
|
||||
* @psalm-import-type Params from DriverManager
|
||||
*/
|
||||
class MasterSlaveConnection extends Connection
|
||||
class MasterSlaveConnection extends PrimaryReadReplicaConnection
|
||||
{
|
||||
/**
|
||||
* Master and slave connection (one of the randomly picked slaves).
|
||||
* Creates Primary Replica Connection.
|
||||
*
|
||||
* @var DriverConnection[]|null[]
|
||||
*/
|
||||
protected $connections = ['master' => null, 'slave' => null];
|
||||
|
||||
/**
|
||||
* You can keep the slave connection and then switch back to it
|
||||
* during the request if you know what you are doing.
|
||||
* @internal The connection can be only instantiated by the driver manager.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $keepSlave = false;
|
||||
|
||||
/**
|
||||
* Creates Master Slave Connection.
|
||||
*
|
||||
* @param mixed[] $params
|
||||
* @param array<string,mixed> $params
|
||||
* @psalm-param Params $params
|
||||
* @phpstan-param array<string,mixed> $params
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function __construct(array $params, Driver $driver, ?Configuration $config = null, ?EventManager $eventManager = null)
|
||||
{
|
||||
if (! isset($params['slaves'], $params['master'])) {
|
||||
throw new InvalidArgumentException('master or slaves configuration missing');
|
||||
}
|
||||
if (count($params['slaves']) === 0) {
|
||||
throw new InvalidArgumentException('You have to configure at least one slaves.');
|
||||
public function __construct(
|
||||
array $params,
|
||||
Driver $driver,
|
||||
?Configuration $config = null,
|
||||
?EventManager $eventManager = null
|
||||
) {
|
||||
$this->deprecated(self::class, PrimaryReadReplicaConnection::class);
|
||||
|
||||
if (isset($params['master'])) {
|
||||
$this->deprecated('Params key "master"', '"primary"');
|
||||
|
||||
$params['primary'] = $params['master'];
|
||||
}
|
||||
|
||||
$params['master']['driver'] = $params['driver'];
|
||||
foreach ($params['slaves'] as $slaveKey => $slave) {
|
||||
$params['slaves'][$slaveKey]['driver'] = $params['driver'];
|
||||
if (isset($params['slaves'])) {
|
||||
$this->deprecated('Params key "slaves"', '"replica"');
|
||||
|
||||
$params['replica'] = $params['slaves'];
|
||||
}
|
||||
|
||||
$this->keepSlave = (bool) ($params['keepSlave'] ?? false);
|
||||
if (isset($params['keepSlave'])) {
|
||||
$this->deprecated('Params key "keepSlave"', '"keepReplica"');
|
||||
|
||||
$params['keepReplica'] = $params['keepSlave'];
|
||||
}
|
||||
|
||||
parent::__construct($params, $driver, $config, $eventManager);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the connection is currently towards the master or not.
|
||||
* Checks if the connection is currently towards the primary or not.
|
||||
*/
|
||||
public function isConnectedToMaster(): bool
|
||||
{
|
||||
$this->deprecated('isConnectedtoMaster()', 'isConnectedToPrimary()');
|
||||
|
||||
return $this->isConnectedToPrimary();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $connectionName
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isConnectedToMaster()
|
||||
{
|
||||
return $this->_conn !== null && $this->_conn === $this->connections['master'];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function connect($connectionName = null)
|
||||
{
|
||||
$requestedConnectionChange = ($connectionName !== null);
|
||||
$connectionName = $connectionName ?: 'slave';
|
||||
|
||||
if ($connectionName !== 'slave' && $connectionName !== 'master') {
|
||||
throw new InvalidArgumentException('Invalid option to connect(), only master or slave allowed.');
|
||||
}
|
||||
|
||||
// If we have a connection open, and this is not an explicit connection
|
||||
// change request, then abort right here, because we are already done.
|
||||
// This prevents writes to the slave in case of "keepSlave" option enabled.
|
||||
if (isset($this->_conn) && $this->_conn && ! $requestedConnectionChange) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$forceMasterAsSlave = false;
|
||||
|
||||
if ($this->getTransactionNestingLevel() > 0) {
|
||||
$connectionName = 'master';
|
||||
$forceMasterAsSlave = true;
|
||||
}
|
||||
|
||||
if (isset($this->connections[$connectionName]) && $this->connections[$connectionName]) {
|
||||
$this->_conn = $this->connections[$connectionName];
|
||||
|
||||
if ($forceMasterAsSlave && ! $this->keepSlave) {
|
||||
$this->connections['slave'] = $this->_conn;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($connectionName === 'master') {
|
||||
$this->connections['master'] = $this->_conn = $this->connectTo($connectionName);
|
||||
$connectionName = 'primary';
|
||||
|
||||
// Set slave connection to master to avoid invalid reads
|
||||
if (! $this->keepSlave) {
|
||||
$this->connections['slave'] = $this->connections['master'];
|
||||
}
|
||||
} else {
|
||||
$this->connections['slave'] = $this->_conn = $this->connectTo($connectionName);
|
||||
$this->deprecated('connect("master")', 'ensureConnectedToPrimary()');
|
||||
}
|
||||
|
||||
if ($this->_eventManager->hasListeners(Events::postConnect)) {
|
||||
$eventArgs = new ConnectionEventArgs($this);
|
||||
$this->_eventManager->dispatchEvent(Events::postConnect, $eventArgs);
|
||||
if ($connectionName === 'slave') {
|
||||
$connectionName = 'replica';
|
||||
|
||||
$this->deprecated('connect("slave")', 'ensureConnectedToReplica()');
|
||||
}
|
||||
|
||||
return true;
|
||||
return $this->performConnect($connectionName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects to a specific connection.
|
||||
*
|
||||
* @param string $connectionName
|
||||
*
|
||||
* @return DriverConnection
|
||||
*/
|
||||
protected function connectTo($connectionName)
|
||||
private function deprecated(string $thing, string $instead): void
|
||||
{
|
||||
$params = $this->getParams();
|
||||
|
||||
$driverOptions = $params['driverOptions'] ?? [];
|
||||
|
||||
$connectionParams = $this->chooseConnectionConfiguration($connectionName, $params);
|
||||
|
||||
$user = $connectionParams['user'] ?? null;
|
||||
$password = $connectionParams['password'] ?? null;
|
||||
|
||||
return $this->_driver->connect($connectionParams, $user, $password, $driverOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $connectionName
|
||||
* @param mixed[] $params
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
protected function chooseConnectionConfiguration($connectionName, $params)
|
||||
{
|
||||
if ($connectionName === 'master') {
|
||||
return $params['master'];
|
||||
}
|
||||
|
||||
$config = $params['slaves'][array_rand($params['slaves'])];
|
||||
|
||||
if (! isset($config['charset']) && isset($params['master']['charset'])) {
|
||||
$config['charset'] = $params['master']['charset'];
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function executeUpdate($query, array $params = [], array $types = [])
|
||||
{
|
||||
$this->connect('master');
|
||||
|
||||
return parent::executeUpdate($query, $params, $types);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function beginTransaction()
|
||||
{
|
||||
$this->connect('master');
|
||||
|
||||
parent::beginTransaction();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function commit()
|
||||
{
|
||||
$this->connect('master');
|
||||
|
||||
parent::commit();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function rollBack()
|
||||
{
|
||||
$this->connect('master');
|
||||
|
||||
return parent::rollBack();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function delete($tableName, array $identifier, array $types = [])
|
||||
{
|
||||
$this->connect('master');
|
||||
|
||||
return parent::delete($tableName, $identifier, $types);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
unset($this->connections['master'], $this->connections['slave']);
|
||||
|
||||
parent::close();
|
||||
|
||||
$this->_conn = null;
|
||||
$this->connections = ['master' => null, 'slave' => null];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function update($tableName, array $data, array $identifier, array $types = [])
|
||||
{
|
||||
$this->connect('master');
|
||||
|
||||
return parent::update($tableName, $data, $identifier, $types);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function insert($tableName, array $data, array $types = [])
|
||||
{
|
||||
$this->connect('master');
|
||||
|
||||
return parent::insert($tableName, $data, $types);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function exec($statement)
|
||||
{
|
||||
$this->connect('master');
|
||||
|
||||
return parent::exec($statement);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function createSavepoint($savepoint)
|
||||
{
|
||||
$this->connect('master');
|
||||
|
||||
parent::createSavepoint($savepoint);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function releaseSavepoint($savepoint)
|
||||
{
|
||||
$this->connect('master');
|
||||
|
||||
parent::releaseSavepoint($savepoint);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function rollbackSavepoint($savepoint)
|
||||
{
|
||||
$this->connect('master');
|
||||
|
||||
parent::rollbackSavepoint($savepoint);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function query()
|
||||
{
|
||||
$this->connect('master');
|
||||
|
||||
$args = func_get_args();
|
||||
|
||||
$logger = $this->getConfiguration()->getSQLLogger();
|
||||
if ($logger) {
|
||||
$logger->startQuery($args[0]);
|
||||
}
|
||||
|
||||
$statement = $this->_conn->query(...$args);
|
||||
|
||||
if ($logger) {
|
||||
$logger->stopQuery();
|
||||
}
|
||||
|
||||
return $statement;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function prepare($statement)
|
||||
{
|
||||
$this->connect('master');
|
||||
|
||||
return parent::prepare($statement);
|
||||
Deprecation::trigger(
|
||||
'doctrine/dbal',
|
||||
'https://github.com/doctrine/dbal/pull/4054',
|
||||
'%s is deprecated since doctrine/dbal 2.11 and will be removed in 3.0, use %s instead.',
|
||||
$thing,
|
||||
$instead
|
||||
);
|
||||
}
|
||||
}
|
||||
|
442
vendor/doctrine/dbal/lib/Doctrine/DBAL/Connections/PrimaryReadReplicaConnection.php
vendored
Normal file
442
vendor/doctrine/dbal/lib/Doctrine/DBAL/Connections/PrimaryReadReplicaConnection.php
vendored
Normal file
@@ -0,0 +1,442 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\DBAL\Connections;
|
||||
|
||||
use Doctrine\Common\EventManager;
|
||||
use Doctrine\DBAL\Configuration;
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\Driver;
|
||||
use Doctrine\DBAL\Driver\Connection as DriverConnection;
|
||||
use Doctrine\DBAL\DriverManager;
|
||||
use Doctrine\DBAL\Event\ConnectionEventArgs;
|
||||
use Doctrine\DBAL\Events;
|
||||
use InvalidArgumentException;
|
||||
|
||||
use function array_rand;
|
||||
use function assert;
|
||||
use function count;
|
||||
use function func_get_args;
|
||||
|
||||
/**
|
||||
* Primary-Replica Connection
|
||||
*
|
||||
* Connection can be used with primary-replica setups.
|
||||
*
|
||||
* Important for the understanding of this connection should be how and when
|
||||
* it picks the replica or primary.
|
||||
*
|
||||
* 1. Replica if primary was never picked before and ONLY if 'getWrappedConnection'
|
||||
* or 'executeQuery' is used.
|
||||
* 2. Primary picked when 'exec', 'executeUpdate', 'executeStatement', 'insert', 'delete', 'update', 'createSavepoint',
|
||||
* 'releaseSavepoint', 'beginTransaction', 'rollback', 'commit', 'query' or
|
||||
* 'prepare' is called.
|
||||
* 3. If Primary was picked once during the lifetime of the connection it will always get picked afterwards.
|
||||
* 4. One replica connection is randomly picked ONCE during a request.
|
||||
*
|
||||
* ATTENTION: You can write to the replica with this connection if you execute a write query without
|
||||
* opening up a transaction. For example:
|
||||
*
|
||||
* $conn = DriverManager::getConnection(...);
|
||||
* $conn->executeQuery("DELETE FROM table");
|
||||
*
|
||||
* Be aware that Connection#executeQuery is a method specifically for READ
|
||||
* operations only.
|
||||
*
|
||||
* Use Connection#executeStatement for any SQL statement that changes/updates
|
||||
* state in the database (UPDATE, INSERT, DELETE or DDL statements).
|
||||
*
|
||||
* This connection is limited to replica operations using the
|
||||
* Connection#executeQuery operation only, because it wouldn't be compatible
|
||||
* with the ORM or SchemaManager code otherwise. Both use all the other
|
||||
* operations in a context where writes could happen to a replica, which makes
|
||||
* this restricted approach necessary.
|
||||
*
|
||||
* You can manually connect to the primary at any time by calling:
|
||||
*
|
||||
* $conn->ensureConnectedToPrimary();
|
||||
*
|
||||
* Instantiation through the DriverManager looks like:
|
||||
*
|
||||
* @psalm-import-type Params from DriverManager
|
||||
* @example
|
||||
*
|
||||
* $conn = DriverManager::getConnection(array(
|
||||
* 'wrapperClass' => 'Doctrine\DBAL\Connections\PrimaryReadReplicaConnection',
|
||||
* 'driver' => 'pdo_mysql',
|
||||
* 'primary' => array('user' => '', 'password' => '', 'host' => '', 'dbname' => ''),
|
||||
* 'replica' => array(
|
||||
* array('user' => 'replica1', 'password', 'host' => '', 'dbname' => ''),
|
||||
* array('user' => 'replica2', 'password', 'host' => '', 'dbname' => ''),
|
||||
* )
|
||||
* ));
|
||||
*
|
||||
* You can also pass 'driverOptions' and any other documented option to each of this drivers
|
||||
* to pass additional information.
|
||||
*/
|
||||
class PrimaryReadReplicaConnection extends Connection
|
||||
{
|
||||
/**
|
||||
* Primary and Replica connection (one of the randomly picked replicas).
|
||||
*
|
||||
* @var DriverConnection[]|null[]
|
||||
*/
|
||||
protected $connections = ['primary' => null, 'replica' => null];
|
||||
|
||||
/**
|
||||
* You can keep the replica connection and then switch back to it
|
||||
* during the request if you know what you are doing.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $keepReplica = false;
|
||||
|
||||
/**
|
||||
* Creates Primary Replica Connection.
|
||||
*
|
||||
* @internal The connection can be only instantiated by the driver manager.
|
||||
*
|
||||
* @param array<string,mixed> $params
|
||||
* @psalm-param Params $params
|
||||
* @phpstan-param array<string,mixed> $params
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function __construct(
|
||||
array $params,
|
||||
Driver $driver,
|
||||
?Configuration $config = null,
|
||||
?EventManager $eventManager = null
|
||||
) {
|
||||
if (! isset($params['replica'], $params['primary'])) {
|
||||
throw new InvalidArgumentException('primary or replica configuration missing');
|
||||
}
|
||||
|
||||
if (count($params['replica']) === 0) {
|
||||
throw new InvalidArgumentException('You have to configure at least one replica.');
|
||||
}
|
||||
|
||||
if (isset($params['driver'])) {
|
||||
$params['primary']['driver'] = $params['driver'];
|
||||
|
||||
foreach ($params['replica'] as $replicaKey => $replica) {
|
||||
$params['replica'][$replicaKey]['driver'] = $params['driver'];
|
||||
}
|
||||
}
|
||||
|
||||
$this->keepReplica = (bool) ($params['keepReplica'] ?? false);
|
||||
|
||||
parent::__construct($params, $driver, $config, $eventManager);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the connection is currently towards the primary or not.
|
||||
*/
|
||||
public function isConnectedToPrimary(): bool
|
||||
{
|
||||
return $this->_conn !== null && $this->_conn === $this->connections['primary'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $connectionName
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function connect($connectionName = null)
|
||||
{
|
||||
if ($connectionName !== null) {
|
||||
throw new InvalidArgumentException(
|
||||
'Passing a connection name as first argument is not supported anymore.'
|
||||
. ' Use ensureConnectedToPrimary()/ensureConnectedToReplica() instead.'
|
||||
);
|
||||
}
|
||||
|
||||
return $this->performConnect();
|
||||
}
|
||||
|
||||
protected function performConnect(?string $connectionName = null): bool
|
||||
{
|
||||
$requestedConnectionChange = ($connectionName !== null);
|
||||
$connectionName = $connectionName ?: 'replica';
|
||||
|
||||
if ($connectionName !== 'replica' && $connectionName !== 'primary') {
|
||||
throw new InvalidArgumentException('Invalid option to connect(), only primary or replica allowed.');
|
||||
}
|
||||
|
||||
// If we have a connection open, and this is not an explicit connection
|
||||
// change request, then abort right here, because we are already done.
|
||||
// This prevents writes to the replica in case of "keepReplica" option enabled.
|
||||
if ($this->_conn !== null && ! $requestedConnectionChange) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$forcePrimaryAsReplica = false;
|
||||
|
||||
if ($this->getTransactionNestingLevel() > 0) {
|
||||
$connectionName = 'primary';
|
||||
$forcePrimaryAsReplica = true;
|
||||
}
|
||||
|
||||
if (isset($this->connections[$connectionName])) {
|
||||
$this->_conn = $this->connections[$connectionName];
|
||||
|
||||
if ($forcePrimaryAsReplica && ! $this->keepReplica) {
|
||||
$this->connections['replica'] = $this->_conn;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($connectionName === 'primary') {
|
||||
$this->connections['primary'] = $this->_conn = $this->connectTo($connectionName);
|
||||
|
||||
// Set replica connection to primary to avoid invalid reads
|
||||
if (! $this->keepReplica) {
|
||||
$this->connections['replica'] = $this->connections['primary'];
|
||||
}
|
||||
} else {
|
||||
$this->connections['replica'] = $this->_conn = $this->connectTo($connectionName);
|
||||
}
|
||||
|
||||
if ($this->_eventManager->hasListeners(Events::postConnect)) {
|
||||
$eventArgs = new ConnectionEventArgs($this);
|
||||
$this->_eventManager->dispatchEvent(Events::postConnect, $eventArgs);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects to the primary node of the database cluster.
|
||||
*
|
||||
* All following statements after this will be executed against the primary node.
|
||||
*/
|
||||
public function ensureConnectedToPrimary(): bool
|
||||
{
|
||||
return $this->performConnect('primary');
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects to a replica node of the database cluster.
|
||||
*
|
||||
* All following statements after this will be executed against the replica node,
|
||||
* unless the keepReplica option is set to false and a primary connection
|
||||
* was already opened.
|
||||
*/
|
||||
public function ensureConnectedToReplica(): bool
|
||||
{
|
||||
return $this->performConnect('replica');
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects to a specific connection.
|
||||
*
|
||||
* @param string $connectionName
|
||||
*
|
||||
* @return DriverConnection
|
||||
*/
|
||||
protected function connectTo($connectionName)
|
||||
{
|
||||
$params = $this->getParams();
|
||||
|
||||
$driverOptions = $params['driverOptions'] ?? [];
|
||||
|
||||
$connectionParams = $this->chooseConnectionConfiguration($connectionName, $params);
|
||||
|
||||
$user = $connectionParams['user'] ?? null;
|
||||
$password = $connectionParams['password'] ?? null;
|
||||
|
||||
return $this->_driver->connect($connectionParams, $user, $password, $driverOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $connectionName
|
||||
* @param mixed[] $params
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
protected function chooseConnectionConfiguration($connectionName, $params)
|
||||
{
|
||||
if ($connectionName === 'primary') {
|
||||
return $params['primary'];
|
||||
}
|
||||
|
||||
$config = $params['replica'][array_rand($params['replica'])];
|
||||
|
||||
if (! isset($config['charset']) && isset($params['primary']['charset'])) {
|
||||
$config['charset'] = $params['primary']['charset'];
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @deprecated Use {@link executeStatement()} instead.
|
||||
*/
|
||||
public function executeUpdate($sql, array $params = [], array $types = [])
|
||||
{
|
||||
$this->ensureConnectedToPrimary();
|
||||
|
||||
return parent::executeUpdate($sql, $params, $types);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function executeStatement($sql, array $params = [], array $types = [])
|
||||
{
|
||||
$this->ensureConnectedToPrimary();
|
||||
|
||||
return parent::executeStatement($sql, $params, $types);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function beginTransaction()
|
||||
{
|
||||
$this->ensureConnectedToPrimary();
|
||||
|
||||
return parent::beginTransaction();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function commit()
|
||||
{
|
||||
$this->ensureConnectedToPrimary();
|
||||
|
||||
return parent::commit();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function rollBack()
|
||||
{
|
||||
$this->ensureConnectedToPrimary();
|
||||
|
||||
return parent::rollBack();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function delete($table, array $criteria, array $types = [])
|
||||
{
|
||||
$this->ensureConnectedToPrimary();
|
||||
|
||||
return parent::delete($table, $criteria, $types);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
unset($this->connections['primary'], $this->connections['replica']);
|
||||
|
||||
parent::close();
|
||||
|
||||
$this->_conn = null;
|
||||
$this->connections = ['primary' => null, 'replica' => null];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function update($table, array $data, array $criteria, array $types = [])
|
||||
{
|
||||
$this->ensureConnectedToPrimary();
|
||||
|
||||
return parent::update($table, $data, $criteria, $types);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function insert($table, array $data, array $types = [])
|
||||
{
|
||||
$this->ensureConnectedToPrimary();
|
||||
|
||||
return parent::insert($table, $data, $types);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function exec($sql)
|
||||
{
|
||||
$this->ensureConnectedToPrimary();
|
||||
|
||||
return parent::exec($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function createSavepoint($savepoint)
|
||||
{
|
||||
$this->ensureConnectedToPrimary();
|
||||
|
||||
parent::createSavepoint($savepoint);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function releaseSavepoint($savepoint)
|
||||
{
|
||||
$this->ensureConnectedToPrimary();
|
||||
|
||||
parent::releaseSavepoint($savepoint);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function rollbackSavepoint($savepoint)
|
||||
{
|
||||
$this->ensureConnectedToPrimary();
|
||||
|
||||
parent::rollbackSavepoint($savepoint);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function query()
|
||||
{
|
||||
$this->ensureConnectedToPrimary();
|
||||
assert($this->_conn instanceof DriverConnection);
|
||||
|
||||
$args = func_get_args();
|
||||
|
||||
$logger = $this->getConfiguration()->getSQLLogger();
|
||||
if ($logger) {
|
||||
$logger->startQuery($args[0]);
|
||||
}
|
||||
|
||||
$statement = $this->_conn->query(...$args);
|
||||
|
||||
$statement->setFetchMode($this->defaultFetchMode);
|
||||
|
||||
if ($logger) {
|
||||
$logger->stopQuery();
|
||||
}
|
||||
|
||||
return $statement;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function prepare($sql)
|
||||
{
|
||||
$this->ensureConnectedToPrimary();
|
||||
|
||||
return parent::prepare($sql);
|
||||
}
|
||||
}
|
@@ -2,12 +2,13 @@
|
||||
|
||||
namespace Doctrine\DBAL;
|
||||
|
||||
use Doctrine\DBAL\Driver\DriverException as DriverExceptionInterface;
|
||||
use Doctrine\DBAL\Driver\DriverException as DeprecatedDriverException;
|
||||
use Doctrine\DBAL\Driver\ExceptionConverterDriver;
|
||||
use Doctrine\DBAL\Exception\DriverException;
|
||||
use Doctrine\DBAL\Platforms\AbstractPlatform;
|
||||
use Exception;
|
||||
use Doctrine\DBAL\Types\Type;
|
||||
use Throwable;
|
||||
|
||||
use function array_map;
|
||||
use function bin2hex;
|
||||
use function get_class;
|
||||
@@ -17,24 +18,33 @@ use function is_object;
|
||||
use function is_resource;
|
||||
use function is_string;
|
||||
use function json_encode;
|
||||
use function preg_replace;
|
||||
use function spl_object_hash;
|
||||
use function sprintf;
|
||||
use function str_split;
|
||||
|
||||
class DBALException extends Exception
|
||||
/**
|
||||
* @deprecated Use {@link Exception} instead
|
||||
*
|
||||
* @psalm-immutable
|
||||
*/
|
||||
class DBALException extends \Exception
|
||||
{
|
||||
/**
|
||||
* @param string $method
|
||||
*
|
||||
* @return \Doctrine\DBAL\DBALException
|
||||
* @return Exception
|
||||
*/
|
||||
public static function notSupported($method)
|
||||
{
|
||||
return new self(sprintf("Operation '%s' is not supported by platform.", $method));
|
||||
return new Exception(sprintf("Operation '%s' is not supported by platform.", $method));
|
||||
}
|
||||
|
||||
public static function invalidPlatformSpecified() : self
|
||||
/**
|
||||
* @deprecated Use {@link invalidPlatformType()} instead.
|
||||
*/
|
||||
public static function invalidPlatformSpecified(): self
|
||||
{
|
||||
return new self(
|
||||
return new Exception(
|
||||
"Invalid 'platform' option specified, need to give an instance of " . AbstractPlatform::class . '.'
|
||||
);
|
||||
}
|
||||
@@ -42,10 +52,10 @@ class DBALException extends Exception
|
||||
/**
|
||||
* @param mixed $invalidPlatform
|
||||
*/
|
||||
public static function invalidPlatformType($invalidPlatform) : self
|
||||
public static function invalidPlatformType($invalidPlatform): self
|
||||
{
|
||||
if (is_object($invalidPlatform)) {
|
||||
return new self(
|
||||
return new Exception(
|
||||
sprintf(
|
||||
"Option 'platform' must be a subtype of '%s', instance of '%s' given",
|
||||
AbstractPlatform::class,
|
||||
@@ -54,7 +64,7 @@ class DBALException extends Exception
|
||||
);
|
||||
}
|
||||
|
||||
return new self(
|
||||
return new Exception(
|
||||
sprintf(
|
||||
"Option 'platform' must be an object and subtype of '%s'. Got '%s'",
|
||||
AbstractPlatform::class,
|
||||
@@ -69,11 +79,11 @@ class DBALException extends Exception
|
||||
* @param string $version The invalid platform version given.
|
||||
* @param string $expectedFormat The expected platform version format.
|
||||
*
|
||||
* @return DBALException
|
||||
* @return Exception
|
||||
*/
|
||||
public static function invalidPlatformVersionSpecified($version, $expectedFormat)
|
||||
{
|
||||
return new self(
|
||||
return new Exception(
|
||||
sprintf(
|
||||
'Invalid platform version "%s" specified. ' .
|
||||
'The platform version has to be specified in the format: "%s".',
|
||||
@@ -84,11 +94,13 @@ class DBALException extends Exception
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Doctrine\DBAL\DBALException
|
||||
* @deprecated Passing a PDO instance in connection parameters is deprecated.
|
||||
*
|
||||
* @return Exception
|
||||
*/
|
||||
public static function invalidPdoInstance()
|
||||
{
|
||||
return new self(
|
||||
return new Exception(
|
||||
"The 'pdo' option was used in DriverManager::getConnection() but no " .
|
||||
'instance of PDO was given.'
|
||||
);
|
||||
@@ -97,12 +109,12 @@ class DBALException extends Exception
|
||||
/**
|
||||
* @param string|null $url The URL that was provided in the connection parameters (if any).
|
||||
*
|
||||
* @return \Doctrine\DBAL\DBALException
|
||||
* @return Exception
|
||||
*/
|
||||
public static function driverRequired($url = null)
|
||||
{
|
||||
if ($url) {
|
||||
return new self(
|
||||
return new Exception(
|
||||
sprintf(
|
||||
"The options 'driver' or 'driverClass' are mandatory if a connection URL without scheme " .
|
||||
'is given to DriverManager::getConnection(). Given URL: %s',
|
||||
@@ -111,7 +123,7 @@ class DBALException extends Exception
|
||||
);
|
||||
}
|
||||
|
||||
return new self("The options 'driver' or 'driverClass' are mandatory if no PDO " .
|
||||
return new Exception("The options 'driver' or 'driverClass' are mandatory if no PDO " .
|
||||
'instance is given to DriverManager::getConnection().');
|
||||
}
|
||||
|
||||
@@ -119,20 +131,21 @@ class DBALException extends Exception
|
||||
* @param string $unknownDriverName
|
||||
* @param string[] $knownDrivers
|
||||
*
|
||||
* @return \Doctrine\DBAL\DBALException
|
||||
* @return Exception
|
||||
*/
|
||||
public static function unknownDriver($unknownDriverName, array $knownDrivers)
|
||||
{
|
||||
return new self("The given 'driver' " . $unknownDriverName . ' is unknown, ' .
|
||||
return new Exception("The given 'driver' " . $unknownDriverName . ' is unknown, ' .
|
||||
'Doctrine currently supports only the following drivers: ' . implode(', ', $knownDrivers));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Exception $driverEx
|
||||
* @param string $sql
|
||||
* @param mixed[] $params
|
||||
* @deprecated
|
||||
*
|
||||
* @return \Doctrine\DBAL\DBALException
|
||||
* @param string $sql
|
||||
* @param mixed[] $params
|
||||
*
|
||||
* @return Exception
|
||||
*/
|
||||
public static function driverExceptionDuringQuery(Driver $driver, Throwable $driverEx, $sql, array $params = [])
|
||||
{
|
||||
@@ -140,36 +153,36 @@ class DBALException extends Exception
|
||||
if ($params) {
|
||||
$msg .= ' with params ' . self::formatParameters($params);
|
||||
}
|
||||
|
||||
$msg .= ":\n\n" . $driverEx->getMessage();
|
||||
|
||||
return static::wrapException($driver, $driverEx, $msg);
|
||||
return self::wrapException($driver, $driverEx, $msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Exception $driverEx
|
||||
* @deprecated
|
||||
*
|
||||
* @return \Doctrine\DBAL\DBALException
|
||||
* @return Exception
|
||||
*/
|
||||
public static function driverException(Driver $driver, Throwable $driverEx)
|
||||
{
|
||||
return static::wrapException($driver, $driverEx, 'An exception occurred in driver: ' . $driverEx->getMessage());
|
||||
return self::wrapException($driver, $driverEx, 'An exception occurred in driver: ' . $driverEx->getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Exception $driverEx
|
||||
*
|
||||
* @return \Doctrine\DBAL\DBALException
|
||||
* @return Exception
|
||||
*/
|
||||
private static function wrapException(Driver $driver, Throwable $driverEx, $msg)
|
||||
private static function wrapException(Driver $driver, Throwable $driverEx, string $msg)
|
||||
{
|
||||
if ($driverEx instanceof DriverException) {
|
||||
return $driverEx;
|
||||
}
|
||||
if ($driver instanceof ExceptionConverterDriver && $driverEx instanceof DriverExceptionInterface) {
|
||||
|
||||
if ($driver instanceof ExceptionConverterDriver && $driverEx instanceof DeprecatedDriverException) {
|
||||
return $driver->convertException($msg, $driverEx);
|
||||
}
|
||||
|
||||
return new self($msg, 0, $driverEx);
|
||||
return new Exception($msg, 0, $driverEx);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -191,7 +204,7 @@ class DBALException extends Exception
|
||||
|
||||
if (! is_string($json) || $json === 'null' && is_string($param)) {
|
||||
// JSON encoding failed, this is not a UTF-8 string.
|
||||
return '"\x' . implode('\x', str_split(bin2hex($param), 2)) . '"';
|
||||
return sprintf('"%s"', preg_replace('/.{2}/', '\\x$0', bin2hex($param)));
|
||||
}
|
||||
|
||||
return $json;
|
||||
@@ -201,70 +214,72 @@ class DBALException extends Exception
|
||||
/**
|
||||
* @param string $wrapperClass
|
||||
*
|
||||
* @return \Doctrine\DBAL\DBALException
|
||||
* @return Exception
|
||||
*/
|
||||
public static function invalidWrapperClass($wrapperClass)
|
||||
{
|
||||
return new self("The given 'wrapperClass' " . $wrapperClass . ' has to be a ' .
|
||||
return new Exception("The given 'wrapperClass' " . $wrapperClass . ' has to be a ' .
|
||||
'subtype of \Doctrine\DBAL\Connection.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $driverClass
|
||||
*
|
||||
* @return \Doctrine\DBAL\DBALException
|
||||
* @return Exception
|
||||
*/
|
||||
public static function invalidDriverClass($driverClass)
|
||||
{
|
||||
return new self("The given 'driverClass' " . $driverClass . ' has to implement the ' . Driver::class . ' interface.');
|
||||
return new Exception(
|
||||
"The given 'driverClass' " . $driverClass . ' has to implement the ' . Driver::class . ' interface.'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $tableName
|
||||
*
|
||||
* @return \Doctrine\DBAL\DBALException
|
||||
* @return Exception
|
||||
*/
|
||||
public static function invalidTableName($tableName)
|
||||
{
|
||||
return new self('Invalid table name specified: ' . $tableName);
|
||||
return new Exception('Invalid table name specified: ' . $tableName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $tableName
|
||||
*
|
||||
* @return \Doctrine\DBAL\DBALException
|
||||
* @return Exception
|
||||
*/
|
||||
public static function noColumnsSpecifiedForTable($tableName)
|
||||
{
|
||||
return new self('No columns specified for table ' . $tableName);
|
||||
return new Exception('No columns specified for table ' . $tableName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Doctrine\DBAL\DBALException
|
||||
* @return Exception
|
||||
*/
|
||||
public static function limitOffsetInvalid()
|
||||
{
|
||||
return new self('Invalid Offset in Limit Query, it has to be larger than or equal to 0.');
|
||||
return new Exception('Invalid Offset in Limit Query, it has to be larger than or equal to 0.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return \Doctrine\DBAL\DBALException
|
||||
* @return Exception
|
||||
*/
|
||||
public static function typeExists($name)
|
||||
{
|
||||
return new self('Type ' . $name . ' already exists.');
|
||||
return new Exception('Type ' . $name . ' already exists.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return \Doctrine\DBAL\DBALException
|
||||
* @return Exception
|
||||
*/
|
||||
public static function unknownColumnType($name)
|
||||
{
|
||||
return new self('Unknown column type "' . $name . '" requested. Any Doctrine type that you use has ' .
|
||||
return new Exception('Unknown column type "' . $name . '" requested. Any Doctrine type that you use has ' .
|
||||
'to be registered with \Doctrine\DBAL\Types\Type::addType(). You can get a list of all the ' .
|
||||
'known types with \Doctrine\DBAL\Types\Type::getTypesMap(). If this error occurs during database ' .
|
||||
'introspection then you might have forgotten to register all database types for a Doctrine Type. Use ' .
|
||||
@@ -276,10 +291,24 @@ class DBALException extends Exception
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return \Doctrine\DBAL\DBALException
|
||||
* @return Exception
|
||||
*/
|
||||
public static function typeNotFound($name)
|
||||
{
|
||||
return new self('Type to be overwritten ' . $name . ' does not exist.');
|
||||
return new Exception('Type to be overwritten ' . $name . ' does not exist.');
|
||||
}
|
||||
|
||||
public static function typeNotRegistered(Type $type): self
|
||||
{
|
||||
return new Exception(
|
||||
sprintf('Type of the class %s@%s is not registered.', get_class($type), spl_object_hash($type))
|
||||
);
|
||||
}
|
||||
|
||||
public static function typeAlreadyRegistered(Type $type): self
|
||||
{
|
||||
return new Exception(
|
||||
sprintf('Type of the class %s@%s is already registered.', get_class($type), spl_object_hash($type))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -14,6 +14,8 @@ interface Driver
|
||||
/**
|
||||
* Attempts to create a connection with the database.
|
||||
*
|
||||
* The usage of NULL to indicate empty username or password is deprecated. Use an empty string instead.
|
||||
*
|
||||
* @param mixed[] $params All connection parameters passed by the user.
|
||||
* @param string|null $username The username to use when connecting.
|
||||
* @param string|null $password The password to use when connecting.
|
||||
@@ -42,6 +44,8 @@ interface Driver
|
||||
/**
|
||||
* Gets the name of the driver.
|
||||
*
|
||||
* @deprecated
|
||||
*
|
||||
* @return string The name of the driver.
|
||||
*/
|
||||
public function getName();
|
||||
@@ -49,6 +53,8 @@ interface Driver
|
||||
/**
|
||||
* Gets the name of the database connected to for this driver.
|
||||
*
|
||||
* @deprecated Use Connection::getDatabase() instead.
|
||||
*
|
||||
* @return string The name of the database.
|
||||
*/
|
||||
public function getDatabase(Connection $conn);
|
||||
|
@@ -4,16 +4,20 @@ namespace Doctrine\DBAL\Driver;
|
||||
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\Driver;
|
||||
use Doctrine\DBAL\Driver\DriverException as TheDriverException;
|
||||
use Doctrine\DBAL\Exception\DriverException;
|
||||
use Doctrine\DBAL\Platforms\DB2Platform;
|
||||
use Doctrine\DBAL\Schema\DB2SchemaManager;
|
||||
|
||||
/**
|
||||
* Abstract base implementation of the {@link Doctrine\DBAL\Driver} interface for IBM DB2 based drivers.
|
||||
* Abstract base implementation of the {@link Driver} interface for IBM DB2 based drivers.
|
||||
*/
|
||||
abstract class AbstractDB2Driver implements Driver
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated Use Connection::getDatabase() instead.
|
||||
*/
|
||||
public function getDatabase(Connection $conn)
|
||||
{
|
||||
@@ -37,4 +41,14 @@ abstract class AbstractDB2Driver implements Driver
|
||||
{
|
||||
return new DB2SchemaManager($conn);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
*
|
||||
* @return DriverException
|
||||
*/
|
||||
public function convertException($message, TheDriverException $exception)
|
||||
{
|
||||
return new DriverException($message, $exception);
|
||||
}
|
||||
}
|
||||
|
@@ -2,53 +2,11 @@
|
||||
|
||||
namespace Doctrine\DBAL\Driver;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Abstract base implementation of the {@link DriverException} interface.
|
||||
* @deprecated
|
||||
*
|
||||
* @psalm-immutable
|
||||
*/
|
||||
abstract class AbstractDriverException extends Exception implements DriverException
|
||||
class AbstractDriverException extends AbstractException
|
||||
{
|
||||
/**
|
||||
* The driver specific error code.
|
||||
*
|
||||
* @var int|string|null
|
||||
*/
|
||||
private $errorCode;
|
||||
|
||||
/**
|
||||
* The SQLSTATE of the driver.
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
public function __construct($message, $sqlState = null, $errorCode = null)
|
||||
{
|
||||
parent::__construct($message);
|
||||
|
||||
$this->errorCode = $errorCode;
|
||||
$this->sqlState = $sqlState;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getErrorCode()
|
||||
{
|
||||
return $this->errorCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getSQLState()
|
||||
{
|
||||
return $this->sqlState;
|
||||
}
|
||||
}
|
||||
|
69
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractException.php
vendored
Normal file
69
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractException.php
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\DBAL\Driver;
|
||||
|
||||
use Doctrine\Deprecations\Deprecation;
|
||||
use Exception as BaseException;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Base implementation of the {@link Exception} interface.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @psalm-immutable
|
||||
*/
|
||||
abstract class AbstractException extends BaseException implements DriverException
|
||||
{
|
||||
/**
|
||||
* The driver specific error code.
|
||||
*
|
||||
* @var int|string|null
|
||||
*/
|
||||
private $errorCode;
|
||||
|
||||
/**
|
||||
* The SQLSTATE of the driver.
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
public function __construct($message, $sqlState = null, $errorCode = null, ?Throwable $previous = null)
|
||||
{
|
||||
parent::__construct($message, 0, $previous);
|
||||
|
||||
$this->errorCode = $errorCode;
|
||||
$this->sqlState = $sqlState;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getErrorCode()
|
||||
{
|
||||
/** @psalm-suppress ImpureMethodCall */
|
||||
Deprecation::triggerIfCalledFromOutside(
|
||||
'doctrine/dbal',
|
||||
'https://github.com/doctrine/dbal/pull/4112',
|
||||
'Driver\AbstractException::getErrorCode() is deprecated, use getSQLState() or getCode() instead.'
|
||||
);
|
||||
|
||||
return $this->errorCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getSQLState()
|
||||
{
|
||||
return $this->sqlState;
|
||||
}
|
||||
}
|
@@ -3,66 +3,85 @@
|
||||
namespace Doctrine\DBAL\Driver;
|
||||
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\DBALException;
|
||||
use Doctrine\DBAL\Driver;
|
||||
use Doctrine\DBAL\Driver\DriverException as DeprecatedDriverException;
|
||||
use Doctrine\DBAL\Exception;
|
||||
use Doctrine\DBAL\Exception\ConnectionException;
|
||||
use Doctrine\DBAL\Exception\ConnectionLost;
|
||||
use Doctrine\DBAL\Exception\DeadlockException;
|
||||
use Doctrine\DBAL\Exception\DriverException;
|
||||
use Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException;
|
||||
use Doctrine\DBAL\Exception\InvalidFieldNameException;
|
||||
use Doctrine\DBAL\Exception\LockWaitTimeoutException;
|
||||
use Doctrine\DBAL\Exception\NonUniqueFieldNameException;
|
||||
use Doctrine\DBAL\Exception\NotNullConstraintViolationException;
|
||||
use Doctrine\DBAL\Exception\SyntaxErrorException;
|
||||
use Doctrine\DBAL\Exception\TableExistsException;
|
||||
use Doctrine\DBAL\Exception\TableNotFoundException;
|
||||
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
|
||||
use Doctrine\DBAL\Platforms\MariaDb1027Platform;
|
||||
use Doctrine\DBAL\Platforms\MySQL57Platform;
|
||||
use Doctrine\DBAL\Platforms\MySQL80Platform;
|
||||
use Doctrine\DBAL\Platforms\MySqlPlatform;
|
||||
use Doctrine\DBAL\Schema\MySqlSchemaManager;
|
||||
use Doctrine\DBAL\VersionAwarePlatformDriver;
|
||||
|
||||
use function assert;
|
||||
use function preg_match;
|
||||
use function stripos;
|
||||
use function version_compare;
|
||||
|
||||
/**
|
||||
* Abstract base implementation of the {@link Doctrine\DBAL\Driver} interface for MySQL based drivers.
|
||||
* Abstract base implementation of the {@link Driver} interface for MySQL based drivers.
|
||||
*/
|
||||
abstract class AbstractMySQLDriver implements Driver, ExceptionConverterDriver, VersionAwarePlatformDriver
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @link http://dev.mysql.com/doc/refman/5.7/en/error-messages-client.html
|
||||
* @link http://dev.mysql.com/doc/refman/5.7/en/error-messages-server.html
|
||||
* @deprecated
|
||||
*
|
||||
* @link https://dev.mysql.com/doc/mysql-errors/8.0/en/client-error-reference.html
|
||||
* @link https://dev.mysql.com/doc/mysql-errors/8.0/en/server-error-reference.html
|
||||
*/
|
||||
public function convertException($message, DriverException $exception)
|
||||
public function convertException($message, DeprecatedDriverException $exception)
|
||||
{
|
||||
switch ($exception->getErrorCode()) {
|
||||
case '1213':
|
||||
return new Exception\DeadlockException($message, $exception);
|
||||
return new DeadlockException($message, $exception);
|
||||
|
||||
case '1205':
|
||||
return new Exception\LockWaitTimeoutException($message, $exception);
|
||||
return new LockWaitTimeoutException($message, $exception);
|
||||
|
||||
case '1050':
|
||||
return new Exception\TableExistsException($message, $exception);
|
||||
return new TableExistsException($message, $exception);
|
||||
|
||||
case '1051':
|
||||
case '1146':
|
||||
return new Exception\TableNotFoundException($message, $exception);
|
||||
return new TableNotFoundException($message, $exception);
|
||||
|
||||
case '1216':
|
||||
case '1217':
|
||||
case '1451':
|
||||
case '1452':
|
||||
case '1701':
|
||||
return new Exception\ForeignKeyConstraintViolationException($message, $exception);
|
||||
return new ForeignKeyConstraintViolationException($message, $exception);
|
||||
|
||||
case '1062':
|
||||
case '1557':
|
||||
case '1569':
|
||||
case '1586':
|
||||
return new Exception\UniqueConstraintViolationException($message, $exception);
|
||||
return new UniqueConstraintViolationException($message, $exception);
|
||||
|
||||
case '1054':
|
||||
case '1166':
|
||||
case '1611':
|
||||
return new Exception\InvalidFieldNameException($message, $exception);
|
||||
return new InvalidFieldNameException($message, $exception);
|
||||
|
||||
case '1052':
|
||||
case '1060':
|
||||
case '1110':
|
||||
return new Exception\NonUniqueFieldNameException($message, $exception);
|
||||
return new NonUniqueFieldNameException($message, $exception);
|
||||
|
||||
case '1064':
|
||||
case '1149':
|
||||
@@ -76,7 +95,7 @@ abstract class AbstractMySQLDriver implements Driver, ExceptionConverterDriver,
|
||||
case '1541':
|
||||
case '1554':
|
||||
case '1626':
|
||||
return new Exception\SyntaxErrorException($message, $exception);
|
||||
return new SyntaxErrorException($message, $exception);
|
||||
|
||||
case '1044':
|
||||
case '1045':
|
||||
@@ -90,7 +109,10 @@ abstract class AbstractMySQLDriver implements Driver, ExceptionConverterDriver,
|
||||
case '1429':
|
||||
case '2002':
|
||||
case '2005':
|
||||
return new Exception\ConnectionException($message, $exception);
|
||||
return new ConnectionException($message, $exception);
|
||||
|
||||
case '2006':
|
||||
return new ConnectionLost($message, $exception);
|
||||
|
||||
case '1048':
|
||||
case '1121':
|
||||
@@ -100,16 +122,16 @@ abstract class AbstractMySQLDriver implements Driver, ExceptionConverterDriver,
|
||||
case '1263':
|
||||
case '1364':
|
||||
case '1566':
|
||||
return new Exception\NotNullConstraintViolationException($message, $exception);
|
||||
return new NotNullConstraintViolationException($message, $exception);
|
||||
}
|
||||
|
||||
return new Exception\DriverException($message, $exception);
|
||||
return new DriverException($message, $exception);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @throws DBALException
|
||||
* @throws Exception
|
||||
*/
|
||||
public function createDatabasePlatformForVersion($version)
|
||||
{
|
||||
@@ -123,6 +145,7 @@ abstract class AbstractMySQLDriver implements Driver, ExceptionConverterDriver,
|
||||
if (version_compare($oracleMysqlVersion, '8', '>=')) {
|
||||
return new MySQL80Platform();
|
||||
}
|
||||
|
||||
if (version_compare($oracleMysqlVersion, '5.7.9', '>=')) {
|
||||
return new MySQL57Platform();
|
||||
}
|
||||
@@ -137,20 +160,23 @@ abstract class AbstractMySQLDriver implements Driver, ExceptionConverterDriver,
|
||||
*
|
||||
* @param string $versionString Version string returned by the driver, i.e. '5.7.10'
|
||||
*
|
||||
* @throws DBALException
|
||||
* @throws Exception
|
||||
*/
|
||||
private function getOracleMysqlVersionNumber(string $versionString) : string
|
||||
private function getOracleMysqlVersionNumber(string $versionString): string
|
||||
{
|
||||
if (! preg_match(
|
||||
'/^(?P<major>\d+)(?:\.(?P<minor>\d+)(?:\.(?P<patch>\d+))?)?/',
|
||||
$versionString,
|
||||
$versionParts
|
||||
)) {
|
||||
throw DBALException::invalidPlatformVersionSpecified(
|
||||
if (
|
||||
! preg_match(
|
||||
'/^(?P<major>\d+)(?:\.(?P<minor>\d+)(?:\.(?P<patch>\d+))?)?/',
|
||||
$versionString,
|
||||
$versionParts
|
||||
)
|
||||
) {
|
||||
throw Exception::invalidPlatformVersionSpecified(
|
||||
$versionString,
|
||||
'<major_version>.<minor_version>.<patch_version>'
|
||||
);
|
||||
}
|
||||
|
||||
$majorVersion = $versionParts['major'];
|
||||
$minorVersion = $versionParts['minor'] ?? 0;
|
||||
$patchVersion = $versionParts['patch'] ?? null;
|
||||
@@ -168,16 +194,18 @@ abstract class AbstractMySQLDriver implements Driver, ExceptionConverterDriver,
|
||||
*
|
||||
* @param string $versionString Version string as returned by mariadb server, i.e. '5.5.5-Mariadb-10.0.8-xenial'
|
||||
*
|
||||
* @throws DBALException
|
||||
* @throws Exception
|
||||
*/
|
||||
private function getMariaDbMysqlVersionNumber(string $versionString) : string
|
||||
private function getMariaDbMysqlVersionNumber(string $versionString): string
|
||||
{
|
||||
if (! preg_match(
|
||||
'/^(?:5\.5\.5-)?(mariadb-)?(?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)/i',
|
||||
$versionString,
|
||||
$versionParts
|
||||
)) {
|
||||
throw DBALException::invalidPlatformVersionSpecified(
|
||||
if (
|
||||
! preg_match(
|
||||
'/^(?:5\.5\.5-)?(mariadb-)?(?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)/i',
|
||||
$versionString,
|
||||
$versionParts
|
||||
)
|
||||
) {
|
||||
throw Exception::invalidPlatformVersionSpecified(
|
||||
$versionString,
|
||||
'^(?:5\.5\.5-)?(mariadb-)?<major_version>.<minor_version>.<patch_version>'
|
||||
);
|
||||
@@ -188,12 +216,22 @@ abstract class AbstractMySQLDriver implements Driver, ExceptionConverterDriver,
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated Use Connection::getDatabase() instead.
|
||||
*/
|
||||
public function getDatabase(Connection $conn)
|
||||
{
|
||||
$params = $conn->getParams();
|
||||
|
||||
return $params['dbname'] ?? $conn->query('SELECT DATABASE()')->fetchColumn();
|
||||
if (isset($params['dbname'])) {
|
||||
return $params['dbname'];
|
||||
}
|
||||
|
||||
$database = $conn->query('SELECT DATABASE()')->fetchColumn();
|
||||
|
||||
assert($database !== false);
|
||||
|
||||
return $database;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -5,60 +5,74 @@ namespace Doctrine\DBAL\Driver;
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\Driver;
|
||||
use Doctrine\DBAL\Driver\AbstractOracleDriver\EasyConnectString;
|
||||
use Doctrine\DBAL\Exception;
|
||||
use Doctrine\DBAL\Driver\DriverException as DeprecatedDriverException;
|
||||
use Doctrine\DBAL\Exception\ConnectionException;
|
||||
use Doctrine\DBAL\Exception\DriverException;
|
||||
use Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException;
|
||||
use Doctrine\DBAL\Exception\InvalidFieldNameException;
|
||||
use Doctrine\DBAL\Exception\NonUniqueFieldNameException;
|
||||
use Doctrine\DBAL\Exception\NotNullConstraintViolationException;
|
||||
use Doctrine\DBAL\Exception\SyntaxErrorException;
|
||||
use Doctrine\DBAL\Exception\TableExistsException;
|
||||
use Doctrine\DBAL\Exception\TableNotFoundException;
|
||||
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
|
||||
use Doctrine\DBAL\Platforms\OraclePlatform;
|
||||
use Doctrine\DBAL\Schema\OracleSchemaManager;
|
||||
|
||||
/**
|
||||
* Abstract base implementation of the {@link Doctrine\DBAL\Driver} interface for Oracle based drivers.
|
||||
* Abstract base implementation of the {@link Driver} interface for Oracle based drivers.
|
||||
*/
|
||||
abstract class AbstractOracleDriver implements Driver, ExceptionConverterDriver
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
public function convertException($message, DriverException $exception)
|
||||
public function convertException($message, DeprecatedDriverException $exception)
|
||||
{
|
||||
switch ($exception->getErrorCode()) {
|
||||
case '1':
|
||||
case '2299':
|
||||
case '38911':
|
||||
return new Exception\UniqueConstraintViolationException($message, $exception);
|
||||
return new UniqueConstraintViolationException($message, $exception);
|
||||
|
||||
case '904':
|
||||
return new Exception\InvalidFieldNameException($message, $exception);
|
||||
return new InvalidFieldNameException($message, $exception);
|
||||
|
||||
case '918':
|
||||
case '960':
|
||||
return new Exception\NonUniqueFieldNameException($message, $exception);
|
||||
return new NonUniqueFieldNameException($message, $exception);
|
||||
|
||||
case '923':
|
||||
return new Exception\SyntaxErrorException($message, $exception);
|
||||
return new SyntaxErrorException($message, $exception);
|
||||
|
||||
case '942':
|
||||
return new Exception\TableNotFoundException($message, $exception);
|
||||
return new TableNotFoundException($message, $exception);
|
||||
|
||||
case '955':
|
||||
return new Exception\TableExistsException($message, $exception);
|
||||
return new TableExistsException($message, $exception);
|
||||
|
||||
case '1017':
|
||||
case '12545':
|
||||
return new Exception\ConnectionException($message, $exception);
|
||||
return new ConnectionException($message, $exception);
|
||||
|
||||
case '1400':
|
||||
return new Exception\NotNullConstraintViolationException($message, $exception);
|
||||
return new NotNullConstraintViolationException($message, $exception);
|
||||
|
||||
case '2266':
|
||||
case '2291':
|
||||
case '2292':
|
||||
return new Exception\ForeignKeyConstraintViolationException($message, $exception);
|
||||
return new ForeignKeyConstraintViolationException($message, $exception);
|
||||
}
|
||||
|
||||
return new Exception\DriverException($message, $exception);
|
||||
return new DriverException($message, $exception);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated Use Connection::getDatabase() instead.
|
||||
*/
|
||||
public function getDatabase(Connection $conn)
|
||||
{
|
||||
|
@@ -23,7 +23,7 @@ final class EasyConnectString
|
||||
$this->string = $string;
|
||||
}
|
||||
|
||||
public function __toString() : string
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->string;
|
||||
}
|
||||
@@ -33,7 +33,7 @@ final class EasyConnectString
|
||||
*
|
||||
* @param mixed[] $params
|
||||
*/
|
||||
public static function fromArray(array $params) : self
|
||||
public static function fromArray(array $params): self
|
||||
{
|
||||
return new self(self::renderParams($params));
|
||||
}
|
||||
@@ -43,7 +43,7 @@ final class EasyConnectString
|
||||
*
|
||||
* @param mixed[] $params
|
||||
*/
|
||||
public static function fromConnectionParameters(array $params) : self
|
||||
public static function fromConnectionParameters(array $params): self
|
||||
{
|
||||
if (! empty($params['connectstring'])) {
|
||||
return new self($params['connectstring']);
|
||||
@@ -90,7 +90,7 @@ final class EasyConnectString
|
||||
/**
|
||||
* @param mixed[] $params
|
||||
*/
|
||||
private static function renderParams(array $params) : string
|
||||
private static function renderParams(array $params): string
|
||||
{
|
||||
$chunks = [];
|
||||
|
||||
@@ -110,7 +110,7 @@ final class EasyConnectString
|
||||
/**
|
||||
* @param mixed $value
|
||||
*/
|
||||
private static function renderValue($value) : string
|
||||
private static function renderValue($value): string
|
||||
{
|
||||
if (is_array($value)) {
|
||||
return self::renderParams($value);
|
||||
|
@@ -3,9 +3,20 @@
|
||||
namespace Doctrine\DBAL\Driver;
|
||||
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\DBALException;
|
||||
use Doctrine\DBAL\Driver;
|
||||
use Doctrine\DBAL\Driver\DriverException as DeprecatedDriverException;
|
||||
use Doctrine\DBAL\Exception;
|
||||
use Doctrine\DBAL\Exception\ConnectionException;
|
||||
use Doctrine\DBAL\Exception\DeadlockException;
|
||||
use Doctrine\DBAL\Exception\DriverException;
|
||||
use Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException;
|
||||
use Doctrine\DBAL\Exception\InvalidFieldNameException;
|
||||
use Doctrine\DBAL\Exception\NonUniqueFieldNameException;
|
||||
use Doctrine\DBAL\Exception\NotNullConstraintViolationException;
|
||||
use Doctrine\DBAL\Exception\SyntaxErrorException;
|
||||
use Doctrine\DBAL\Exception\TableExistsException;
|
||||
use Doctrine\DBAL\Exception\TableNotFoundException;
|
||||
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
|
||||
use Doctrine\DBAL\Platforms\PostgreSQL100Platform;
|
||||
use Doctrine\DBAL\Platforms\PostgreSQL91Platform;
|
||||
use Doctrine\DBAL\Platforms\PostgreSQL92Platform;
|
||||
@@ -13,70 +24,82 @@ use Doctrine\DBAL\Platforms\PostgreSQL94Platform;
|
||||
use Doctrine\DBAL\Platforms\PostgreSqlPlatform;
|
||||
use Doctrine\DBAL\Schema\PostgreSqlSchemaManager;
|
||||
use Doctrine\DBAL\VersionAwarePlatformDriver;
|
||||
|
||||
use function assert;
|
||||
use function preg_match;
|
||||
use function strpos;
|
||||
use function version_compare;
|
||||
|
||||
/**
|
||||
* Abstract base implementation of the {@link Doctrine\DBAL\Driver} interface for PostgreSQL based drivers.
|
||||
* Abstract base implementation of the {@link Driver} interface for PostgreSQL based drivers.
|
||||
*/
|
||||
abstract class AbstractPostgreSQLDriver implements Driver, ExceptionConverterDriver, VersionAwarePlatformDriver
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated
|
||||
*
|
||||
* @link http://www.postgresql.org/docs/9.3/static/errcodes-appendix.html
|
||||
*/
|
||||
public function convertException($message, DriverException $exception)
|
||||
public function convertException($message, DeprecatedDriverException $exception)
|
||||
{
|
||||
switch ($exception->getSQLState()) {
|
||||
$sqlState = $exception->getSQLState();
|
||||
|
||||
switch ($sqlState) {
|
||||
case '40001':
|
||||
case '40P01':
|
||||
return new Exception\DeadlockException($message, $exception);
|
||||
return new DeadlockException($message, $exception);
|
||||
|
||||
case '0A000':
|
||||
// Foreign key constraint violations during a TRUNCATE operation
|
||||
// are considered "feature not supported" in PostgreSQL.
|
||||
if (strpos($exception->getMessage(), 'truncate') !== false) {
|
||||
return new Exception\ForeignKeyConstraintViolationException($message, $exception);
|
||||
return new ForeignKeyConstraintViolationException($message, $exception);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case '23502':
|
||||
return new Exception\NotNullConstraintViolationException($message, $exception);
|
||||
return new NotNullConstraintViolationException($message, $exception);
|
||||
|
||||
case '23503':
|
||||
return new Exception\ForeignKeyConstraintViolationException($message, $exception);
|
||||
return new ForeignKeyConstraintViolationException($message, $exception);
|
||||
|
||||
case '23505':
|
||||
return new Exception\UniqueConstraintViolationException($message, $exception);
|
||||
return new UniqueConstraintViolationException($message, $exception);
|
||||
|
||||
case '42601':
|
||||
return new Exception\SyntaxErrorException($message, $exception);
|
||||
return new SyntaxErrorException($message, $exception);
|
||||
|
||||
case '42702':
|
||||
return new Exception\NonUniqueFieldNameException($message, $exception);
|
||||
return new NonUniqueFieldNameException($message, $exception);
|
||||
|
||||
case '42703':
|
||||
return new Exception\InvalidFieldNameException($message, $exception);
|
||||
return new InvalidFieldNameException($message, $exception);
|
||||
|
||||
case '42P01':
|
||||
return new Exception\TableNotFoundException($message, $exception);
|
||||
return new TableNotFoundException($message, $exception);
|
||||
|
||||
case '42P07':
|
||||
return new Exception\TableExistsException($message, $exception);
|
||||
return new TableExistsException($message, $exception);
|
||||
|
||||
case '08006':
|
||||
return new Exception\ConnectionException($message, $exception);
|
||||
|
||||
case '7':
|
||||
// In some case (mainly connection errors) the PDO exception does not provide a SQLSTATE via its code.
|
||||
// The exception code is always set to 7 here.
|
||||
// Prior to fixing https://bugs.php.net/bug.php?id=64705 (PHP 7.3.22 and PHP 7.4.10),
|
||||
// in some cases (mainly connection errors) the PDO exception wouldn't provide a SQLSTATE via its code.
|
||||
// The exception code would be always set to 7 here.
|
||||
// We have to match against the SQLSTATE in the error message in these cases.
|
||||
if (strpos($exception->getMessage(), 'SQLSTATE[08006]') !== false) {
|
||||
return new Exception\ConnectionException($message, $exception);
|
||||
return new ConnectionException($message, $exception);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return new Exception\DriverException($message, $exception);
|
||||
return new DriverException($message, $exception);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -85,7 +108,7 @@ abstract class AbstractPostgreSQLDriver implements Driver, ExceptionConverterDri
|
||||
public function createDatabasePlatformForVersion($version)
|
||||
{
|
||||
if (! preg_match('/^(?P<major>\d+)(?:\.(?P<minor>\d+)(?:\.(?P<patch>\d+))?)?/', $version, $versionParts)) {
|
||||
throw DBALException::invalidPlatformVersionSpecified(
|
||||
throw Exception::invalidPlatformVersionSpecified(
|
||||
$version,
|
||||
'<major_version>.<minor_version>.<patch_version>'
|
||||
);
|
||||
@@ -112,12 +135,22 @@ abstract class AbstractPostgreSQLDriver implements Driver, ExceptionConverterDri
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated Use Connection::getDatabase() instead.
|
||||
*/
|
||||
public function getDatabase(Connection $conn)
|
||||
{
|
||||
$params = $conn->getParams();
|
||||
|
||||
return $params['dbname'] ?? $conn->query('SELECT CURRENT_DATABASE()')->fetchColumn();
|
||||
if (isset($params['dbname'])) {
|
||||
return $params['dbname'];
|
||||
}
|
||||
|
||||
$database = $conn->query('SELECT CURRENT_DATABASE()')->fetchColumn();
|
||||
|
||||
assert($database !== false);
|
||||
|
||||
return $database;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -3,66 +3,94 @@
|
||||
namespace Doctrine\DBAL\Driver;
|
||||
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\DBALException;
|
||||
use Doctrine\DBAL\Driver;
|
||||
use Doctrine\DBAL\Driver\DriverException as DeprecatedDriverException;
|
||||
use Doctrine\DBAL\Exception;
|
||||
use Doctrine\DBAL\Exception\ConnectionException;
|
||||
use Doctrine\DBAL\Exception\DeadlockException;
|
||||
use Doctrine\DBAL\Exception\DriverException;
|
||||
use Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException;
|
||||
use Doctrine\DBAL\Exception\InvalidFieldNameException;
|
||||
use Doctrine\DBAL\Exception\LockWaitTimeoutException;
|
||||
use Doctrine\DBAL\Exception\NonUniqueFieldNameException;
|
||||
use Doctrine\DBAL\Exception\NotNullConstraintViolationException;
|
||||
use Doctrine\DBAL\Exception\SyntaxErrorException;
|
||||
use Doctrine\DBAL\Exception\TableExistsException;
|
||||
use Doctrine\DBAL\Exception\TableNotFoundException;
|
||||
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
|
||||
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 assert;
|
||||
use function preg_match;
|
||||
use function version_compare;
|
||||
|
||||
/**
|
||||
* Abstract base implementation of the {@link Doctrine\DBAL\Driver} interface for SAP Sybase SQL Anywhere based drivers.
|
||||
* Abstract base implementation of the {@link Driver} interface for SAP Sybase SQL Anywhere based drivers.
|
||||
*
|
||||
* @deprecated Support for SQLAnywhere will be removed in 3.0.
|
||||
*/
|
||||
abstract class AbstractSQLAnywhereDriver implements Driver, ExceptionConverterDriver, VersionAwarePlatformDriver
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated
|
||||
*
|
||||
* @link http://dcx.sybase.com/index.html#sa160/en/saerrors/sqlerror.html
|
||||
*/
|
||||
public function convertException($message, DriverException $exception)
|
||||
public function convertException($message, DeprecatedDriverException $exception)
|
||||
{
|
||||
switch ($exception->getErrorCode()) {
|
||||
case '-306':
|
||||
case '-307':
|
||||
case '-684':
|
||||
return new Exception\DeadlockException($message, $exception);
|
||||
return new DeadlockException($message, $exception);
|
||||
|
||||
case '-210':
|
||||
case '-1175':
|
||||
case '-1281':
|
||||
return new Exception\LockWaitTimeoutException($message, $exception);
|
||||
return new LockWaitTimeoutException($message, $exception);
|
||||
|
||||
case '-100':
|
||||
case '-103':
|
||||
case '-832':
|
||||
return new Exception\ConnectionException($message, $exception);
|
||||
return new ConnectionException($message, $exception);
|
||||
|
||||
case '-143':
|
||||
return new Exception\InvalidFieldNameException($message, $exception);
|
||||
return new InvalidFieldNameException($message, $exception);
|
||||
|
||||
case '-193':
|
||||
case '-196':
|
||||
return new Exception\UniqueConstraintViolationException($message, $exception);
|
||||
return new UniqueConstraintViolationException($message, $exception);
|
||||
|
||||
case '-194':
|
||||
case '-198':
|
||||
return new Exception\ForeignKeyConstraintViolationException($message, $exception);
|
||||
return new ForeignKeyConstraintViolationException($message, $exception);
|
||||
|
||||
case '-144':
|
||||
return new Exception\NonUniqueFieldNameException($message, $exception);
|
||||
return new NonUniqueFieldNameException($message, $exception);
|
||||
|
||||
case '-184':
|
||||
case '-195':
|
||||
return new Exception\NotNullConstraintViolationException($message, $exception);
|
||||
return new NotNullConstraintViolationException($message, $exception);
|
||||
|
||||
case '-131':
|
||||
return new Exception\SyntaxErrorException($message, $exception);
|
||||
return new SyntaxErrorException($message, $exception);
|
||||
|
||||
case '-110':
|
||||
return new Exception\TableExistsException($message, $exception);
|
||||
return new TableExistsException($message, $exception);
|
||||
|
||||
case '-141':
|
||||
case '-1041':
|
||||
return new Exception\TableNotFoundException($message, $exception);
|
||||
return new TableNotFoundException($message, $exception);
|
||||
}
|
||||
|
||||
return new Exception\DriverException($message, $exception);
|
||||
return new DriverException($message, $exception);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -70,12 +98,14 @@ abstract class AbstractSQLAnywhereDriver implements Driver, ExceptionConverterDr
|
||||
*/
|
||||
public function createDatabasePlatformForVersion($version)
|
||||
{
|
||||
if (! preg_match(
|
||||
'/^(?P<major>\d+)(?:\.(?P<minor>\d+)(?:\.(?P<patch>\d+)(?:\.(?P<build>\d+))?)?)?/',
|
||||
$version,
|
||||
$versionParts
|
||||
)) {
|
||||
throw DBALException::invalidPlatformVersionSpecified(
|
||||
if (
|
||||
! preg_match(
|
||||
'/^(?P<major>\d+)(?:\.(?P<minor>\d+)(?:\.(?P<patch>\d+)(?:\.(?P<build>\d+))?)?)?/',
|
||||
$version,
|
||||
$versionParts
|
||||
)
|
||||
) {
|
||||
throw Exception::invalidPlatformVersionSpecified(
|
||||
$version,
|
||||
'<major_version>.<minor_version>.<patch_version>.<build_version>'
|
||||
);
|
||||
@@ -90,10 +120,13 @@ abstract class AbstractSQLAnywhereDriver implements Driver, ExceptionConverterDr
|
||||
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();
|
||||
}
|
||||
@@ -101,12 +134,22 @@ abstract class AbstractSQLAnywhereDriver implements Driver, ExceptionConverterDr
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated Use Connection::getDatabase() instead.
|
||||
*/
|
||||
public function getDatabase(Connection $conn)
|
||||
{
|
||||
$params = $conn->getParams();
|
||||
|
||||
return $params['dbname'] ?? $conn->query('SELECT DB_NAME()')->fetchColumn();
|
||||
if (isset($params['dbname'])) {
|
||||
return $params['dbname'];
|
||||
}
|
||||
|
||||
$database = $conn->query('SELECT DB_NAME()')->fetchColumn();
|
||||
|
||||
assert($database !== false);
|
||||
|
||||
return $database;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -3,19 +3,23 @@
|
||||
namespace Doctrine\DBAL\Driver;
|
||||
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\DBALException;
|
||||
use Doctrine\DBAL\Driver;
|
||||
use Doctrine\DBAL\Driver\DriverException as TheDriverException;
|
||||
use Doctrine\DBAL\Exception;
|
||||
use Doctrine\DBAL\Exception\DriverException;
|
||||
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;
|
||||
use Doctrine\DBAL\VersionAwarePlatformDriver;
|
||||
|
||||
use function assert;
|
||||
use function preg_match;
|
||||
use function version_compare;
|
||||
|
||||
/**
|
||||
* Abstract base implementation of the {@link Doctrine\DBAL\Driver} interface for Microsoft SQL Server based drivers.
|
||||
* Abstract base implementation of the {@link Driver} interface for Microsoft SQL Server based drivers.
|
||||
*/
|
||||
abstract class AbstractSQLServerDriver implements Driver, VersionAwarePlatformDriver
|
||||
{
|
||||
@@ -24,12 +28,14 @@ abstract class AbstractSQLServerDriver implements Driver, VersionAwarePlatformDr
|
||||
*/
|
||||
public function createDatabasePlatformForVersion($version)
|
||||
{
|
||||
if (! preg_match(
|
||||
'/^(?P<major>\d+)(?:\.(?P<minor>\d+)(?:\.(?P<patch>\d+)(?:\.(?P<build>\d+))?)?)?/',
|
||||
$version,
|
||||
$versionParts
|
||||
)) {
|
||||
throw DBALException::invalidPlatformVersionSpecified(
|
||||
if (
|
||||
! preg_match(
|
||||
'/^(?P<major>\d+)(?:\.(?P<minor>\d+)(?:\.(?P<patch>\d+)(?:\.(?P<build>\d+))?)?)?/',
|
||||
$version,
|
||||
$versionParts
|
||||
)
|
||||
) {
|
||||
throw Exception::invalidPlatformVersionSpecified(
|
||||
$version,
|
||||
'<major_version>.<minor_version>.<patch_version>.<build_version>'
|
||||
);
|
||||
@@ -55,12 +61,22 @@ abstract class AbstractSQLServerDriver implements Driver, VersionAwarePlatformDr
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated Use Connection::getDatabase() instead.
|
||||
*/
|
||||
public function getDatabase(Connection $conn)
|
||||
{
|
||||
$params = $conn->getParams();
|
||||
|
||||
return $params['dbname'] ?? $conn->query('SELECT DB_NAME()')->fetchColumn();
|
||||
if (isset($params['dbname'])) {
|
||||
return $params['dbname'];
|
||||
}
|
||||
|
||||
$database = $conn->query('SELECT DB_NAME()')->fetchColumn();
|
||||
|
||||
assert($database !== false);
|
||||
|
||||
return $database;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -78,4 +94,14 @@ abstract class AbstractSQLServerDriver implements Driver, VersionAwarePlatformDr
|
||||
{
|
||||
return new SQLServerSchemaManager($conn);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
*
|
||||
* @return DriverException
|
||||
*/
|
||||
public function convertException($message, TheDriverException $exception)
|
||||
{
|
||||
return new DriverException($message, $exception);
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\DBAL\Driver\AbstractSQLServerDriver\Exception;
|
||||
|
||||
use Doctrine\DBAL\Driver\AbstractDriverException;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @psalm-immutable
|
||||
*/
|
||||
final class PortWithoutHost extends AbstractDriverException
|
||||
{
|
||||
public static function new(): self
|
||||
{
|
||||
return new self('Connection port specified without the host');
|
||||
}
|
||||
}
|
@@ -4,74 +4,92 @@ namespace Doctrine\DBAL\Driver;
|
||||
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\Driver;
|
||||
use Doctrine\DBAL\Exception;
|
||||
use Doctrine\DBAL\Driver\DriverException as DeprecatedDriverException;
|
||||
use Doctrine\DBAL\Exception\ConnectionException;
|
||||
use Doctrine\DBAL\Exception\DriverException;
|
||||
use Doctrine\DBAL\Exception\InvalidFieldNameException;
|
||||
use Doctrine\DBAL\Exception\LockWaitTimeoutException;
|
||||
use Doctrine\DBAL\Exception\NonUniqueFieldNameException;
|
||||
use Doctrine\DBAL\Exception\NotNullConstraintViolationException;
|
||||
use Doctrine\DBAL\Exception\ReadOnlyException;
|
||||
use Doctrine\DBAL\Exception\SyntaxErrorException;
|
||||
use Doctrine\DBAL\Exception\TableExistsException;
|
||||
use Doctrine\DBAL\Exception\TableNotFoundException;
|
||||
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
|
||||
use Doctrine\DBAL\Platforms\SqlitePlatform;
|
||||
use Doctrine\DBAL\Schema\SqliteSchemaManager;
|
||||
|
||||
use function strpos;
|
||||
|
||||
/**
|
||||
* Abstract base implementation of the {@link Doctrine\DBAL\Driver} interface for SQLite based drivers.
|
||||
* Abstract base implementation of the {@link Driver} interface for SQLite based drivers.
|
||||
*/
|
||||
abstract class AbstractSQLiteDriver implements Driver, ExceptionConverterDriver
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated
|
||||
*
|
||||
* @link http://www.sqlite.org/c3ref/c_abort.html
|
||||
*/
|
||||
public function convertException($message, DriverException $exception)
|
||||
public function convertException($message, DeprecatedDriverException $exception)
|
||||
{
|
||||
if (strpos($exception->getMessage(), 'database is locked') !== false) {
|
||||
return new Exception\LockWaitTimeoutException($message, $exception);
|
||||
return new LockWaitTimeoutException($message, $exception);
|
||||
}
|
||||
|
||||
if (strpos($exception->getMessage(), 'must be unique') !== false ||
|
||||
if (
|
||||
strpos($exception->getMessage(), 'must be unique') !== false ||
|
||||
strpos($exception->getMessage(), 'is not unique') !== false ||
|
||||
strpos($exception->getMessage(), 'are not unique') !== false ||
|
||||
strpos($exception->getMessage(), 'UNIQUE constraint failed') !== false
|
||||
) {
|
||||
return new Exception\UniqueConstraintViolationException($message, $exception);
|
||||
return new UniqueConstraintViolationException($message, $exception);
|
||||
}
|
||||
|
||||
if (strpos($exception->getMessage(), 'may not be NULL') !== false ||
|
||||
if (
|
||||
strpos($exception->getMessage(), 'may not be NULL') !== false ||
|
||||
strpos($exception->getMessage(), 'NOT NULL constraint failed') !== false
|
||||
) {
|
||||
return new Exception\NotNullConstraintViolationException($message, $exception);
|
||||
return new NotNullConstraintViolationException($message, $exception);
|
||||
}
|
||||
|
||||
if (strpos($exception->getMessage(), 'no such table:') !== false) {
|
||||
return new Exception\TableNotFoundException($message, $exception);
|
||||
return new TableNotFoundException($message, $exception);
|
||||
}
|
||||
|
||||
if (strpos($exception->getMessage(), 'already exists') !== false) {
|
||||
return new Exception\TableExistsException($message, $exception);
|
||||
return new TableExistsException($message, $exception);
|
||||
}
|
||||
|
||||
if (strpos($exception->getMessage(), 'has no column named') !== false) {
|
||||
return new Exception\InvalidFieldNameException($message, $exception);
|
||||
return new InvalidFieldNameException($message, $exception);
|
||||
}
|
||||
|
||||
if (strpos($exception->getMessage(), 'ambiguous column name') !== false) {
|
||||
return new Exception\NonUniqueFieldNameException($message, $exception);
|
||||
return new NonUniqueFieldNameException($message, $exception);
|
||||
}
|
||||
|
||||
if (strpos($exception->getMessage(), 'syntax error') !== false) {
|
||||
return new Exception\SyntaxErrorException($message, $exception);
|
||||
return new SyntaxErrorException($message, $exception);
|
||||
}
|
||||
|
||||
if (strpos($exception->getMessage(), 'attempt to write a readonly database') !== false) {
|
||||
return new Exception\ReadOnlyException($message, $exception);
|
||||
return new ReadOnlyException($message, $exception);
|
||||
}
|
||||
|
||||
if (strpos($exception->getMessage(), 'unable to open database file') !== false) {
|
||||
return new Exception\ConnectionException($message, $exception);
|
||||
return new ConnectionException($message, $exception);
|
||||
}
|
||||
|
||||
return new Exception\DriverException($message, $exception);
|
||||
return new DriverException($message, $exception);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated Use Connection::getDatabase() instead.
|
||||
*/
|
||||
public function getDatabase(Connection $conn)
|
||||
{
|
||||
|
@@ -15,11 +15,11 @@ interface Connection
|
||||
/**
|
||||
* Prepares a statement for execution and returns a Statement object.
|
||||
*
|
||||
* @param string $prepareString
|
||||
* @param string $sql
|
||||
*
|
||||
* @return Statement
|
||||
*/
|
||||
public function prepare($prepareString);
|
||||
public function prepare($sql);
|
||||
|
||||
/**
|
||||
* Executes an SQL statement, returning a result set as a Statement object.
|
||||
@@ -31,28 +31,28 @@ interface Connection
|
||||
/**
|
||||
* Quotes a string for use in a query.
|
||||
*
|
||||
* @param mixed $input
|
||||
* @param mixed $value
|
||||
* @param int $type
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function quote($input, $type = ParameterType::STRING);
|
||||
public function quote($value, $type = ParameterType::STRING);
|
||||
|
||||
/**
|
||||
* Executes an SQL statement and return the number of affected rows.
|
||||
*
|
||||
* @param string $statement
|
||||
* @param string $sql
|
||||
*
|
||||
* @return int
|
||||
* @return int|string
|
||||
*/
|
||||
public function exec($statement);
|
||||
public function exec($sql);
|
||||
|
||||
/**
|
||||
* Returns the ID of the last inserted row or sequence value.
|
||||
*
|
||||
* @param string|null $name
|
||||
*
|
||||
* @return string
|
||||
* @return string|int|false
|
||||
*/
|
||||
public function lastInsertId($name = null);
|
||||
|
||||
@@ -80,6 +80,8 @@ interface Connection
|
||||
/**
|
||||
* Returns the error code associated with the last operation on the database handle.
|
||||
*
|
||||
* @deprecated The error information is available via exceptions.
|
||||
*
|
||||
* @return string|null The error code, or null if no operation has been run on the database handle.
|
||||
*/
|
||||
public function errorCode();
|
||||
@@ -87,6 +89,8 @@ interface Connection
|
||||
/**
|
||||
* Returns extended error information associated with the last operation on the database handle.
|
||||
*
|
||||
* @deprecated The error information is available via exceptions.
|
||||
*
|
||||
* @return mixed[]
|
||||
*/
|
||||
public function errorInfo();
|
||||
|
@@ -2,39 +2,11 @@
|
||||
|
||||
namespace Doctrine\DBAL\Driver;
|
||||
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Contract for a driver exception.
|
||||
* @deprecated Use {@link Exception} instead
|
||||
*
|
||||
* Driver exceptions provide the SQLSTATE of the driver
|
||||
* and the driver specific error code at the time the error occurred.
|
||||
* @psalm-immutable
|
||||
*/
|
||||
interface DriverException extends Throwable
|
||||
interface DriverException extends Exception
|
||||
{
|
||||
/**
|
||||
* 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 int|string|null
|
||||
*/
|
||||
public function getErrorCode();
|
||||
|
||||
/**
|
||||
* Returns the driver error message.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getMessage();
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
public function getSQLState();
|
||||
}
|
||||
|
@@ -5,6 +5,9 @@ namespace Doctrine\DBAL\Driver\DrizzlePDOMySql;
|
||||
use Doctrine\DBAL\Driver\PDOConnection;
|
||||
use Doctrine\DBAL\ParameterType;
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
class Connection extends PDOConnection
|
||||
{
|
||||
/**
|
||||
|
@@ -7,6 +7,8 @@ use Doctrine\DBAL\Schema\DrizzleSchemaManager;
|
||||
|
||||
/**
|
||||
* Drizzle driver using PDO MySql.
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
class Driver extends \Doctrine\DBAL\Driver\PDOMySql\Driver
|
||||
{
|
||||
@@ -33,6 +35,8 @@ class Driver extends \Doctrine\DBAL\Driver\PDOMySql\Driver
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return DrizzlePlatform
|
||||
*/
|
||||
public function getDatabasePlatform()
|
||||
{
|
||||
@@ -41,6 +45,8 @@ class Driver extends \Doctrine\DBAL\Driver\PDOMySql\Driver
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return DrizzleSchemaManager
|
||||
*/
|
||||
public function getSchemaManager(\Doctrine\DBAL\Connection $conn)
|
||||
{
|
||||
@@ -49,6 +55,8 @@ class Driver extends \Doctrine\DBAL\Driver\PDOMySql\Driver
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
|
34
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Exception.php
vendored
Normal file
34
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Exception.php
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\DBAL\Driver;
|
||||
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* @psalm-immutable
|
||||
*/
|
||||
interface Exception extends Throwable
|
||||
{
|
||||
/**
|
||||
* Returns the driver specific error code if available.
|
||||
*
|
||||
* @deprecated Use {@link getCode()} or {@link getSQLState()} instead
|
||||
*
|
||||
* Returns null if no driver specific error code is available
|
||||
* for the error raised by the driver.
|
||||
*
|
||||
* @return int|string|null
|
||||
*/
|
||||
public function getErrorCode();
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
public function getSQLState();
|
||||
}
|
@@ -2,8 +2,13 @@
|
||||
|
||||
namespace Doctrine\DBAL\Driver;
|
||||
|
||||
use Doctrine\DBAL\Driver\DriverException as TheDriverException;
|
||||
use Doctrine\DBAL\Exception\DriverException;
|
||||
|
||||
/**
|
||||
* Contract for a driver that is capable of converting DBAL driver exceptions into standardized DBAL driver exceptions.
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
interface ExceptionConverterDriver
|
||||
{
|
||||
@@ -11,12 +16,14 @@ interface ExceptionConverterDriver
|
||||
* Converts a given DBAL driver exception into a standardized DBAL driver exception.
|
||||
*
|
||||
* It evaluates the vendor specific error code and SQLSTATE and transforms
|
||||
* it into a unified {@link Doctrine\DBAL\Exception\DriverException} subclass.
|
||||
* it into a unified {@link DriverException} subclass.
|
||||
*
|
||||
* @param string $message The DBAL exception message to use.
|
||||
* @param DriverException $exception The DBAL driver exception to convert.
|
||||
* @deprecated
|
||||
*
|
||||
* @return \Doctrine\DBAL\Exception\DriverException An instance of one of the DriverException subclasses.
|
||||
* @param string $message The DBAL exception message to use.
|
||||
* @param TheDriverException $exception The DBAL driver exception to convert.
|
||||
*
|
||||
* @return DriverException An instance of one of the DriverException subclasses.
|
||||
*/
|
||||
public function convertException($message, DriverException $exception);
|
||||
public function convertException($message, TheDriverException $exception);
|
||||
}
|
||||
|
75
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/FetchUtils.php
vendored
Normal file
75
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/FetchUtils.php
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\DBAL\Driver;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
final class FetchUtils
|
||||
{
|
||||
/**
|
||||
* @return mixed|false
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function fetchOne(Result $result)
|
||||
{
|
||||
$row = $result->fetchNumeric();
|
||||
|
||||
if ($row === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $row[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int,array<int,mixed>>
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function fetchAllNumeric(Result $result): array
|
||||
{
|
||||
$rows = [];
|
||||
|
||||
while (($row = $result->fetchNumeric()) !== false) {
|
||||
$rows[] = $row;
|
||||
}
|
||||
|
||||
return $rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int,array<string,mixed>>
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function fetchAllAssociative(Result $result): array
|
||||
{
|
||||
$rows = [];
|
||||
|
||||
while (($row = $result->fetchAssociative()) !== false) {
|
||||
$rows[] = $row;
|
||||
}
|
||||
|
||||
return $rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int,mixed>
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function fetchFirstColumn(Result $result): array
|
||||
{
|
||||
$rows = [];
|
||||
|
||||
while (($row = $result->fetchOne()) !== false) {
|
||||
$rows[] = $row;
|
||||
}
|
||||
|
||||
return $rows;
|
||||
}
|
||||
}
|
7
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/Connection.php
vendored
Normal file
7
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/Connection.php
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\DBAL\Driver\IBMDB2;
|
||||
|
||||
final class Connection extends DB2Connection
|
||||
{
|
||||
}
|
@@ -2,12 +2,16 @@
|
||||
|
||||
namespace Doctrine\DBAL\Driver\IBMDB2;
|
||||
|
||||
use Doctrine\DBAL\Driver\Connection;
|
||||
use Doctrine\DBAL\Driver\Connection as ConnectionInterface;
|
||||
use Doctrine\DBAL\Driver\IBMDB2\Exception\ConnectionError;
|
||||
use Doctrine\DBAL\Driver\IBMDB2\Exception\ConnectionFailed;
|
||||
use Doctrine\DBAL\Driver\IBMDB2\Exception\PrepareFailed;
|
||||
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
|
||||
use Doctrine\DBAL\ParameterType;
|
||||
use Doctrine\Deprecations\Deprecation;
|
||||
use stdClass;
|
||||
use const DB2_AUTOCOMMIT_OFF;
|
||||
use const DB2_AUTOCOMMIT_ON;
|
||||
|
||||
use function assert;
|
||||
use function db2_autocommit;
|
||||
use function db2_commit;
|
||||
use function db2_conn_error;
|
||||
@@ -21,15 +25,24 @@ use function db2_pconnect;
|
||||
use function db2_prepare;
|
||||
use function db2_rollback;
|
||||
use function db2_server_info;
|
||||
use function db2_stmt_errormsg;
|
||||
use function error_get_last;
|
||||
use function func_get_args;
|
||||
use function is_bool;
|
||||
|
||||
class DB2Connection implements Connection, ServerInfoAwareConnection
|
||||
use const DB2_AUTOCOMMIT_OFF;
|
||||
use const DB2_AUTOCOMMIT_ON;
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link Connection} instead
|
||||
*/
|
||||
class DB2Connection implements ConnectionInterface, ServerInfoAwareConnection
|
||||
{
|
||||
/** @var resource */
|
||||
private $conn = null;
|
||||
private $conn;
|
||||
|
||||
/**
|
||||
* @internal The connection can be only instantiated by its driver.
|
||||
*
|
||||
* @param mixed[] $params
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
@@ -42,13 +55,16 @@ class DB2Connection implements Connection, ServerInfoAwareConnection
|
||||
$isPersistent = (isset($params['persistent']) && $params['persistent'] === true);
|
||||
|
||||
if ($isPersistent) {
|
||||
$this->conn = db2_pconnect($params['dbname'], $username, $password, $driverOptions);
|
||||
$conn = db2_pconnect($params['dbname'], $username, $password, $driverOptions);
|
||||
} else {
|
||||
$this->conn = db2_connect($params['dbname'], $username, $password, $driverOptions);
|
||||
$conn = db2_connect($params['dbname'], $username, $password, $driverOptions);
|
||||
}
|
||||
if (! $this->conn) {
|
||||
throw new DB2Exception(db2_conn_errormsg());
|
||||
|
||||
if ($conn === false) {
|
||||
throw ConnectionFailed::new();
|
||||
}
|
||||
|
||||
$this->conn = $conn;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -56,8 +72,8 @@ class DB2Connection implements Connection, ServerInfoAwareConnection
|
||||
*/
|
||||
public function getServerVersion()
|
||||
{
|
||||
/** @var stdClass $serverInfo */
|
||||
$serverInfo = db2_server_info($this->conn);
|
||||
assert($serverInfo instanceof stdClass);
|
||||
|
||||
return $serverInfo->DBMS_VER;
|
||||
}
|
||||
@@ -67,6 +83,12 @@ class DB2Connection implements Connection, ServerInfoAwareConnection
|
||||
*/
|
||||
public function requiresQueryForServerVersion()
|
||||
{
|
||||
Deprecation::triggerIfCalledFromOutside(
|
||||
'doctrine/dbal',
|
||||
'https://github.com/doctrine/dbal/pull/4114',
|
||||
'ServerInfoAwareConnection::requiresQueryForServerVersion() is deprecated and removed in DBAL 3.'
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -76,11 +98,12 @@ class DB2Connection implements Connection, ServerInfoAwareConnection
|
||||
public function prepare($sql)
|
||||
{
|
||||
$stmt = @db2_prepare($this->conn, $sql);
|
||||
if (! $stmt) {
|
||||
throw new DB2Exception(db2_stmt_errormsg());
|
||||
|
||||
if ($stmt === false) {
|
||||
throw PrepareFailed::new(error_get_last());
|
||||
}
|
||||
|
||||
return new DB2Statement($stmt);
|
||||
return new Statement($stmt);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -99,26 +122,26 @@ class DB2Connection implements Connection, ServerInfoAwareConnection
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function quote($input, $type = ParameterType::STRING)
|
||||
public function quote($value, $type = ParameterType::STRING)
|
||||
{
|
||||
$input = db2_escape_string($input);
|
||||
$value = db2_escape_string($value);
|
||||
|
||||
if ($type === ParameterType::INTEGER) {
|
||||
return $input;
|
||||
return $value;
|
||||
}
|
||||
|
||||
return "'" . $input . "'";
|
||||
return "'" . $value . "'";
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function exec($statement)
|
||||
public function exec($sql)
|
||||
{
|
||||
$stmt = @db2_exec($this->conn, $statement);
|
||||
$stmt = @db2_exec($this->conn, $sql);
|
||||
|
||||
if ($stmt === false) {
|
||||
throw new DB2Exception(db2_stmt_errormsg());
|
||||
throw ConnectionError::new($this->conn);
|
||||
}
|
||||
|
||||
return db2_num_rows($stmt);
|
||||
@@ -137,7 +160,10 @@ class DB2Connection implements Connection, ServerInfoAwareConnection
|
||||
*/
|
||||
public function beginTransaction()
|
||||
{
|
||||
db2_autocommit($this->conn, DB2_AUTOCOMMIT_OFF);
|
||||
$result = db2_autocommit($this->conn, DB2_AUTOCOMMIT_OFF);
|
||||
assert(is_bool($result));
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -146,9 +172,13 @@ class DB2Connection implements Connection, ServerInfoAwareConnection
|
||||
public function commit()
|
||||
{
|
||||
if (! db2_commit($this->conn)) {
|
||||
throw new DB2Exception(db2_conn_errormsg($this->conn));
|
||||
throw ConnectionError::new($this->conn);
|
||||
}
|
||||
db2_autocommit($this->conn, DB2_AUTOCOMMIT_ON);
|
||||
|
||||
$result = db2_autocommit($this->conn, DB2_AUTOCOMMIT_ON);
|
||||
assert(is_bool($result));
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -157,13 +187,19 @@ class DB2Connection implements Connection, ServerInfoAwareConnection
|
||||
public function rollBack()
|
||||
{
|
||||
if (! db2_rollback($this->conn)) {
|
||||
throw new DB2Exception(db2_conn_errormsg($this->conn));
|
||||
throw ConnectionError::new($this->conn);
|
||||
}
|
||||
db2_autocommit($this->conn, DB2_AUTOCOMMIT_ON);
|
||||
|
||||
$result = db2_autocommit($this->conn, DB2_AUTOCOMMIT_ON);
|
||||
assert(is_bool($result));
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated The error information is available via exceptions.
|
||||
*/
|
||||
public function errorCode()
|
||||
{
|
||||
@@ -172,6 +208,8 @@ class DB2Connection implements Connection, ServerInfoAwareConnection
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated The error information is available via exceptions.
|
||||
*/
|
||||
public function errorInfo()
|
||||
{
|
||||
|
@@ -3,9 +3,12 @@
|
||||
namespace Doctrine\DBAL\Driver\IBMDB2;
|
||||
|
||||
use Doctrine\DBAL\Driver\AbstractDB2Driver;
|
||||
use Doctrine\Deprecations\Deprecation;
|
||||
|
||||
/**
|
||||
* IBM DB2 Driver.
|
||||
*
|
||||
* @deprecated Use {@link Driver} instead
|
||||
*/
|
||||
class DB2Driver extends AbstractDB2Driver
|
||||
{
|
||||
@@ -14,34 +17,31 @@ class DB2Driver extends AbstractDB2Driver
|
||||
*/
|
||||
public function connect(array $params, $username = null, $password = null, array $driverOptions = [])
|
||||
{
|
||||
if (! isset($params['protocol'])) {
|
||||
$params['protocol'] = 'TCPIP';
|
||||
}
|
||||
$params['user'] = $username;
|
||||
$params['password'] = $password;
|
||||
$params['dbname'] = DataSourceName::fromConnectionParameters($params)->toString();
|
||||
|
||||
if ($params['host'] !== 'localhost' && $params['host'] !== '127.0.0.1') {
|
||||
// if the host isn't localhost, use extended connection params
|
||||
$params['dbname'] = 'DRIVER={IBM DB2 ODBC DRIVER}' .
|
||||
';DATABASE=' . $params['dbname'] .
|
||||
';HOSTNAME=' . $params['host'] .
|
||||
';PROTOCOL=' . $params['protocol'] .
|
||||
';UID=' . $username .
|
||||
';PWD=' . $password . ';';
|
||||
if (isset($params['port'])) {
|
||||
$params['dbname'] .= 'PORT=' . $params['port'];
|
||||
}
|
||||
|
||||
$username = null;
|
||||
$password = null;
|
||||
}
|
||||
|
||||
return new DB2Connection($params, $username, $password, $driverOptions);
|
||||
return new Connection(
|
||||
$params,
|
||||
(string) $username,
|
||||
(string) $password,
|
||||
$driverOptions
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
Deprecation::trigger(
|
||||
'doctrine/dbal',
|
||||
'https://github.com/doctrine/dbal/issues/3580',
|
||||
'Driver::getName() is deprecated'
|
||||
);
|
||||
|
||||
return 'ibm_db2';
|
||||
}
|
||||
}
|
||||
|
@@ -2,8 +2,13 @@
|
||||
|
||||
namespace Doctrine\DBAL\Driver\IBMDB2;
|
||||
|
||||
use Exception;
|
||||
use Doctrine\DBAL\Driver\AbstractDriverException;
|
||||
|
||||
class DB2Exception extends Exception
|
||||
/**
|
||||
* @deprecated Use {@link \Doctrine\DBAL\Driver\Exception} instead
|
||||
*
|
||||
* @psalm-immutable
|
||||
*/
|
||||
class DB2Exception extends AbstractDriverException
|
||||
{
|
||||
}
|
||||
|
@@ -2,7 +2,13 @@
|
||||
|
||||
namespace Doctrine\DBAL\Driver\IBMDB2;
|
||||
|
||||
use Doctrine\DBAL\Driver\Statement;
|
||||
use Doctrine\DBAL\Driver\FetchUtils;
|
||||
use Doctrine\DBAL\Driver\IBMDB2\Exception\CannotCopyStreamToStream;
|
||||
use Doctrine\DBAL\Driver\IBMDB2\Exception\CannotCreateTemporaryFile;
|
||||
use Doctrine\DBAL\Driver\IBMDB2\Exception\CannotWriteToTemporaryFile;
|
||||
use Doctrine\DBAL\Driver\IBMDB2\Exception\StatementError;
|
||||
use Doctrine\DBAL\Driver\Result;
|
||||
use Doctrine\DBAL\Driver\Statement as StatementInterface;
|
||||
use Doctrine\DBAL\Driver\StatementIterator;
|
||||
use Doctrine\DBAL\FetchMode;
|
||||
use Doctrine\DBAL\ParameterType;
|
||||
@@ -11,14 +17,11 @@ use PDO;
|
||||
use ReflectionClass;
|
||||
use ReflectionObject;
|
||||
use ReflectionProperty;
|
||||
use ReturnTypeWillChange;
|
||||
use stdClass;
|
||||
use const CASE_LOWER;
|
||||
use const DB2_BINARY;
|
||||
use const DB2_CHAR;
|
||||
use const DB2_LONG;
|
||||
use const DB2_PARAM_FILE;
|
||||
use const DB2_PARAM_IN;
|
||||
|
||||
use function array_change_key_case;
|
||||
use function assert;
|
||||
use function db2_bind_param;
|
||||
use function db2_execute;
|
||||
use function db2_fetch_array;
|
||||
@@ -36,6 +39,7 @@ use function func_get_args;
|
||||
use function func_num_args;
|
||||
use function fwrite;
|
||||
use function gettype;
|
||||
use function is_int;
|
||||
use function is_object;
|
||||
use function is_resource;
|
||||
use function is_string;
|
||||
@@ -46,7 +50,17 @@ use function stream_get_meta_data;
|
||||
use function strtolower;
|
||||
use function tmpfile;
|
||||
|
||||
class DB2Statement implements IteratorAggregate, Statement
|
||||
use const CASE_LOWER;
|
||||
use const DB2_BINARY;
|
||||
use const DB2_CHAR;
|
||||
use const DB2_LONG;
|
||||
use const DB2_PARAM_FILE;
|
||||
use const DB2_PARAM_IN;
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link Statement} instead
|
||||
*/
|
||||
class DB2Statement implements IteratorAggregate, StatementInterface, Result
|
||||
{
|
||||
/** @var resource */
|
||||
private $stmt;
|
||||
@@ -79,6 +93,8 @@ class DB2Statement implements IteratorAggregate, Statement
|
||||
private $result = false;
|
||||
|
||||
/**
|
||||
* @internal The statement can be only instantiated by its driver connection.
|
||||
*
|
||||
* @param resource $stmt
|
||||
*/
|
||||
public function __construct($stmt)
|
||||
@@ -91,35 +107,39 @@ class DB2Statement implements IteratorAggregate, Statement
|
||||
*/
|
||||
public function bindValue($param, $value, $type = ParameterType::STRING)
|
||||
{
|
||||
assert(is_int($param));
|
||||
|
||||
return $this->bindParam($param, $value, $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function bindParam($column, &$variable, $type = ParameterType::STRING, $length = null)
|
||||
public function bindParam($param, &$variable, $type = ParameterType::STRING, $length = null)
|
||||
{
|
||||
assert(is_int($param));
|
||||
|
||||
switch ($type) {
|
||||
case ParameterType::INTEGER:
|
||||
$this->bind($column, $variable, DB2_PARAM_IN, DB2_LONG);
|
||||
$this->bind($param, $variable, DB2_PARAM_IN, DB2_LONG);
|
||||
break;
|
||||
|
||||
case ParameterType::LARGE_OBJECT:
|
||||
if (isset($this->lobs[$column])) {
|
||||
[, $handle] = $this->lobs[$column];
|
||||
if (isset($this->lobs[$param])) {
|
||||
[, $handle] = $this->lobs[$param];
|
||||
fclose($handle);
|
||||
}
|
||||
|
||||
$handle = $this->createTemporaryFile();
|
||||
$path = stream_get_meta_data($handle)['uri'];
|
||||
|
||||
$this->bind($column, $path, DB2_PARAM_FILE, DB2_BINARY);
|
||||
$this->bind($param, $path, DB2_PARAM_FILE, DB2_BINARY);
|
||||
|
||||
$this->lobs[$column] = [&$variable, $handle];
|
||||
$this->lobs[$param] = [&$variable, $handle];
|
||||
break;
|
||||
|
||||
default:
|
||||
$this->bind($column, $variable, DB2_PARAM_IN, DB2_CHAR);
|
||||
$this->bind($param, $variable, DB2_PARAM_IN, DB2_CHAR);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -127,29 +147,27 @@ class DB2Statement implements IteratorAggregate, Statement
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int|string $parameter Parameter position or name
|
||||
* @param mixed $variable
|
||||
* @param int $position Parameter position
|
||||
* @param mixed $variable
|
||||
*
|
||||
* @throws DB2Exception
|
||||
*/
|
||||
private function bind($parameter, &$variable, int $parameterType, int $dataType) : void
|
||||
private function bind($position, &$variable, int $parameterType, int $dataType): void
|
||||
{
|
||||
$this->bindParam[$parameter] =& $variable;
|
||||
$this->bindParam[$position] =& $variable;
|
||||
|
||||
if (! db2_bind_param($this->stmt, $parameter, 'variable', $parameterType, $dataType)) {
|
||||
throw new DB2Exception(db2_stmt_errormsg());
|
||||
if (! db2_bind_param($this->stmt, $position, 'variable', $parameterType, $dataType)) {
|
||||
throw StatementError::new($this->stmt);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated Use free() instead.
|
||||
*/
|
||||
public function closeCursor()
|
||||
{
|
||||
if (! $this->stmt) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->bindParam = [];
|
||||
|
||||
if (! db2_free_result($this->stmt)) {
|
||||
@@ -166,15 +184,13 @@ class DB2Statement implements IteratorAggregate, Statement
|
||||
*/
|
||||
public function columnCount()
|
||||
{
|
||||
if (! $this->stmt) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return db2_num_fields($this->stmt);
|
||||
return db2_num_fields($this->stmt) ?: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated The error information is available via exceptions.
|
||||
*/
|
||||
public function errorCode()
|
||||
{
|
||||
@@ -183,6 +199,8 @@ class DB2Statement implements IteratorAggregate, Statement
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated The error information is available via exceptions.
|
||||
*/
|
||||
public function errorInfo()
|
||||
{
|
||||
@@ -197,10 +215,6 @@ class DB2Statement implements IteratorAggregate, Statement
|
||||
*/
|
||||
public function execute($params = null)
|
||||
{
|
||||
if (! $this->stmt) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($params === null) {
|
||||
ksort($this->bindParam);
|
||||
|
||||
@@ -230,7 +244,7 @@ class DB2Statement implements IteratorAggregate, Statement
|
||||
$this->lobs = [];
|
||||
|
||||
if ($retval === false) {
|
||||
throw new DB2Exception(db2_stmt_errormsg());
|
||||
throw StatementError::new($this->stmt);
|
||||
}
|
||||
|
||||
$this->result = true;
|
||||
@@ -240,6 +254,8 @@ class DB2Statement implements IteratorAggregate, Statement
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated Use one of the fetch- or iterate-related methods.
|
||||
*/
|
||||
public function setFetchMode($fetchMode, $arg2 = null, $arg3 = null)
|
||||
{
|
||||
@@ -252,7 +268,10 @@ class DB2Statement implements IteratorAggregate, Statement
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated Use iterateNumeric(), iterateAssociative() or iterateColumn() instead.
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function getIterator()
|
||||
{
|
||||
return new StatementIterator($this);
|
||||
@@ -260,6 +279,8 @@ class DB2Statement implements IteratorAggregate, Statement
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated Use fetchNumeric(), fetchAssociative() or fetchOne() instead.
|
||||
*/
|
||||
public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEXT, $cursorOffset = 0)
|
||||
{
|
||||
@@ -311,6 +332,8 @@ class DB2Statement implements IteratorAggregate, Statement
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated Use fetchAllNumeric(), fetchAllAssociative() or fetchFirstColumn() instead.
|
||||
*/
|
||||
public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = null)
|
||||
{
|
||||
@@ -321,12 +344,16 @@ class DB2Statement implements IteratorAggregate, Statement
|
||||
while (($row = $this->fetch(...func_get_args())) !== false) {
|
||||
$rows[] = $row;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case FetchMode::COLUMN:
|
||||
while (($row = $this->fetchColumn()) !== false) {
|
||||
$rows[] = $row;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
while (($row = $this->fetch($fetchMode)) !== false) {
|
||||
$rows[] = $row;
|
||||
@@ -338,6 +365,8 @@ class DB2Statement implements IteratorAggregate, Statement
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated Use fetchOne() instead.
|
||||
*/
|
||||
public function fetchColumn($columnIndex = 0)
|
||||
{
|
||||
@@ -350,6 +379,64 @@ class DB2Statement implements IteratorAggregate, Statement
|
||||
return $row[$columnIndex] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function fetchNumeric()
|
||||
{
|
||||
if (! $this->result) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return db2_fetch_array($this->stmt);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchAssociative()
|
||||
{
|
||||
// do not try fetching from the statement if it's not expected to contain the result
|
||||
// in order to prevent exceptional situation
|
||||
if (! $this->result) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return db2_fetch_assoc($this->stmt);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchOne()
|
||||
{
|
||||
return FetchUtils::fetchOne($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchAllNumeric(): array
|
||||
{
|
||||
return FetchUtils::fetchAllNumeric($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchAllAssociative(): array
|
||||
{
|
||||
return FetchUtils::fetchAllAssociative($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchFirstColumn(): array
|
||||
{
|
||||
return FetchUtils::fetchFirstColumn($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -358,12 +445,21 @@ class DB2Statement implements IteratorAggregate, Statement
|
||||
return @db2_num_rows($this->stmt) ? : 0;
|
||||
}
|
||||
|
||||
public function free(): void
|
||||
{
|
||||
$this->bindParam = [];
|
||||
|
||||
db2_free_result($this->stmt);
|
||||
|
||||
$this->result = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Casts a stdClass object to the given class name mapping its' properties.
|
||||
*
|
||||
* @param stdClass $sourceObject Object to cast from.
|
||||
* @param string|object $destinationClass Name of the class or class instance to cast to.
|
||||
* @param mixed[] $ctorArgs Arguments to use for constructing the destination class instance.
|
||||
* @param stdClass $sourceObject Object to cast from.
|
||||
* @param class-string|object $destinationClass Name of the class or class instance to cast to.
|
||||
* @param mixed[] $ctorArgs Arguments to use for constructing the destination class instance.
|
||||
*
|
||||
* @return object
|
||||
*
|
||||
@@ -433,7 +529,7 @@ class DB2Statement implements IteratorAggregate, Statement
|
||||
$handle = @tmpfile();
|
||||
|
||||
if ($handle === false) {
|
||||
throw new DB2Exception('Could not create temporary file: ' . error_get_last()['message']);
|
||||
throw CannotCreateTemporaryFile::new(error_get_last());
|
||||
}
|
||||
|
||||
return $handle;
|
||||
@@ -445,10 +541,10 @@ class DB2Statement implements IteratorAggregate, Statement
|
||||
*
|
||||
* @throws DB2Exception
|
||||
*/
|
||||
private function copyStreamToStream($source, $target) : void
|
||||
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 CannotCopyStreamToStream::new(error_get_last());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -457,10 +553,10 @@ class DB2Statement implements IteratorAggregate, Statement
|
||||
*
|
||||
* @throws DB2Exception
|
||||
*/
|
||||
private function writeStringToStream(string $string, $target) : void
|
||||
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 CannotWriteToTemporaryFile::new(error_get_last());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
77
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/DataSourceName.php
vendored
Normal file
77
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/DataSourceName.php
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\DBAL\Driver\IBMDB2;
|
||||
|
||||
use function implode;
|
||||
use function sprintf;
|
||||
use function strpos;
|
||||
|
||||
/**
|
||||
* IBM DB2 DSN
|
||||
*/
|
||||
final class DataSourceName
|
||||
{
|
||||
/** @var string */
|
||||
private $string;
|
||||
|
||||
private function __construct(string $string)
|
||||
{
|
||||
$this->string = $string;
|
||||
}
|
||||
|
||||
public function toString(): string
|
||||
{
|
||||
return $this->string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the object from an array representation
|
||||
*
|
||||
* @param array<string,mixed> $params
|
||||
*/
|
||||
public static function fromArray(array $params): self
|
||||
{
|
||||
$chunks = [];
|
||||
|
||||
foreach ($params as $key => $value) {
|
||||
$chunks[] = sprintf('%s=%s', $key, $value);
|
||||
}
|
||||
|
||||
return new self(implode(';', $chunks));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the object from the given DBAL connection parameters.
|
||||
*
|
||||
* @param array<string,mixed> $params
|
||||
*/
|
||||
public static function fromConnectionParameters(array $params): self
|
||||
{
|
||||
if (isset($params['dbname']) && strpos($params['dbname'], '=') !== false) {
|
||||
return new self($params['dbname']);
|
||||
}
|
||||
|
||||
$dsnParams = [];
|
||||
|
||||
foreach (
|
||||
[
|
||||
'host' => 'HOSTNAME',
|
||||
'port' => 'PORT',
|
||||
'protocol' => 'PROTOCOL',
|
||||
'dbname' => 'DATABASE',
|
||||
'user' => 'UID',
|
||||
'password' => 'PWD',
|
||||
] as $dbalParam => $dsnParam
|
||||
) {
|
||||
if (! isset($params[$dbalParam])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$dsnParams[$dsnParam] = $params[$dbalParam];
|
||||
}
|
||||
|
||||
return self::fromArray($dsnParams);
|
||||
}
|
||||
}
|
9
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/Driver.php
vendored
Normal file
9
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/Driver.php
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\DBAL\Driver\IBMDB2;
|
||||
|
||||
final class Driver extends DB2Driver
|
||||
{
|
||||
}
|
29
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/Exception/CannotCopyStreamToStream.php
vendored
Normal file
29
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/Exception/CannotCopyStreamToStream.php
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\DBAL\Driver\IBMDB2\Exception;
|
||||
|
||||
use Doctrine\DBAL\Driver\IBMDB2\DB2Exception;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @psalm-immutable
|
||||
*/
|
||||
final class CannotCopyStreamToStream extends DB2Exception
|
||||
{
|
||||
/**
|
||||
* @psalm-param array{message: string}|null $error
|
||||
*/
|
||||
public static function new(?array $error): self
|
||||
{
|
||||
$message = 'Could not copy source stream to temporary file';
|
||||
|
||||
if ($error !== null) {
|
||||
$message .= ': ' . $error['message'];
|
||||
}
|
||||
|
||||
return new self($message);
|
||||
}
|
||||
}
|
29
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/Exception/CannotCreateTemporaryFile.php
vendored
Normal file
29
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/Exception/CannotCreateTemporaryFile.php
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\DBAL\Driver\IBMDB2\Exception;
|
||||
|
||||
use Doctrine\DBAL\Driver\IBMDB2\DB2Exception;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @psalm-immutable
|
||||
*/
|
||||
final class CannotCreateTemporaryFile extends DB2Exception
|
||||
{
|
||||
/**
|
||||
* @psalm-param array{message: string}|null $error
|
||||
*/
|
||||
public static function new(?array $error): self
|
||||
{
|
||||
$message = 'Could not create temporary file';
|
||||
|
||||
if ($error !== null) {
|
||||
$message .= ': ' . $error['message'];
|
||||
}
|
||||
|
||||
return new self($message);
|
||||
}
|
||||
}
|
29
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/Exception/CannotWriteToTemporaryFile.php
vendored
Normal file
29
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/Exception/CannotWriteToTemporaryFile.php
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\DBAL\Driver\IBMDB2\Exception;
|
||||
|
||||
use Doctrine\DBAL\Driver\IBMDB2\DB2Exception;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @psalm-immutable
|
||||
*/
|
||||
final class CannotWriteToTemporaryFile extends DB2Exception
|
||||
{
|
||||
/**
|
||||
* @psalm-param array{message: string}|null $error
|
||||
*/
|
||||
public static function new(?array $error): self
|
||||
{
|
||||
$message = 'Could not write string to temporary file';
|
||||
|
||||
if ($error !== null) {
|
||||
$message .= ': ' . $error['message'];
|
||||
}
|
||||
|
||||
return new self($message);
|
||||
}
|
||||
}
|
26
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/Exception/ConnectionError.php
vendored
Normal file
26
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/Exception/ConnectionError.php
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\DBAL\Driver\IBMDB2\Exception;
|
||||
|
||||
use Doctrine\DBAL\Driver\AbstractException;
|
||||
|
||||
use function db2_conn_error;
|
||||
use function db2_conn_errormsg;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @psalm-immutable
|
||||
*/
|
||||
final class ConnectionError extends AbstractException
|
||||
{
|
||||
/**
|
||||
* @param resource $connection
|
||||
*/
|
||||
public static function new($connection): self
|
||||
{
|
||||
return new self(db2_conn_errormsg($connection), db2_conn_error($connection));
|
||||
}
|
||||
}
|
23
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/Exception/ConnectionFailed.php
vendored
Normal file
23
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/Exception/ConnectionFailed.php
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\DBAL\Driver\IBMDB2\Exception;
|
||||
|
||||
use Doctrine\DBAL\Driver\AbstractException;
|
||||
|
||||
use function db2_conn_error;
|
||||
use function db2_conn_errormsg;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @psalm-immutable
|
||||
*/
|
||||
final class ConnectionFailed extends AbstractException
|
||||
{
|
||||
public static function new(): self
|
||||
{
|
||||
return new self(db2_conn_errormsg(), db2_conn_error());
|
||||
}
|
||||
}
|
27
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/Exception/PrepareFailed.php
vendored
Normal file
27
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/Exception/PrepareFailed.php
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\DBAL\Driver\IBMDB2\Exception;
|
||||
|
||||
use Doctrine\DBAL\Driver\AbstractException;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @psalm-immutable
|
||||
*/
|
||||
final class PrepareFailed extends AbstractException
|
||||
{
|
||||
/**
|
||||
* @psalm-param array{message: string}|null $error
|
||||
*/
|
||||
public static function new(?array $error): self
|
||||
{
|
||||
if ($error === null) {
|
||||
return new self('Unknown error');
|
||||
}
|
||||
|
||||
return new self($error['message']);
|
||||
}
|
||||
}
|
26
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/Exception/StatementError.php
vendored
Normal file
26
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/Exception/StatementError.php
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\DBAL\Driver\IBMDB2\Exception;
|
||||
|
||||
use Doctrine\DBAL\Driver\AbstractException;
|
||||
|
||||
use function db2_stmt_error;
|
||||
use function db2_stmt_errormsg;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @psalm-immutable
|
||||
*/
|
||||
final class StatementError extends AbstractException
|
||||
{
|
||||
/**
|
||||
* @param resource $statement
|
||||
*/
|
||||
public static function new($statement): self
|
||||
{
|
||||
return new self(db2_stmt_errormsg($statement), db2_stmt_error($statement));
|
||||
}
|
||||
}
|
7
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/Statement.php
vendored
Normal file
7
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/Statement.php
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\DBAL\Driver\IBMDB2;
|
||||
|
||||
final class Statement extends DB2Statement
|
||||
{
|
||||
}
|
7
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/Connection.php
vendored
Normal file
7
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/Connection.php
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\DBAL\Driver\Mysqli;
|
||||
|
||||
final class Connection extends MysqliConnection
|
||||
{
|
||||
}
|
@@ -2,8 +2,9 @@
|
||||
|
||||
namespace Doctrine\DBAL\Driver\Mysqli;
|
||||
|
||||
use Doctrine\DBAL\DBALException;
|
||||
use Doctrine\DBAL\Driver\AbstractMySQLDriver;
|
||||
use Doctrine\DBAL\Exception;
|
||||
use Doctrine\Deprecations\Deprecation;
|
||||
|
||||
class Driver extends AbstractMySQLDriver
|
||||
{
|
||||
@@ -13,9 +14,9 @@ class Driver extends AbstractMySQLDriver
|
||||
public function connect(array $params, $username = null, $password = null, array $driverOptions = [])
|
||||
{
|
||||
try {
|
||||
return new MysqliConnection($params, $username, $password, $driverOptions);
|
||||
return new Connection($params, (string) $username, (string) $password, $driverOptions);
|
||||
} catch (MysqliException $e) {
|
||||
throw DBALException::driverException($this, $e);
|
||||
throw Exception::driverException($this, $e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +25,12 @@ class Driver extends AbstractMySQLDriver
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
Deprecation::trigger(
|
||||
'doctrine/dbal',
|
||||
'https://github.com/doctrine/dbal/issues/3580',
|
||||
'Driver::getName() is deprecated'
|
||||
);
|
||||
|
||||
return 'mysqli';
|
||||
}
|
||||
}
|
||||
|
31
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/Exception/ConnectionError.php
vendored
Normal file
31
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/Exception/ConnectionError.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\DBAL\Driver\Mysqli\Exception;
|
||||
|
||||
use Doctrine\DBAL\Driver\Mysqli\MysqliException;
|
||||
use mysqli;
|
||||
use mysqli_sql_exception;
|
||||
use ReflectionProperty;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @psalm-immutable
|
||||
*/
|
||||
final class ConnectionError extends MysqliException
|
||||
{
|
||||
public static function new(mysqli $connection): self
|
||||
{
|
||||
return new self($connection->error, $connection->sqlstate, $connection->errno);
|
||||
}
|
||||
|
||||
public static function upcast(mysqli_sql_exception $exception): self
|
||||
{
|
||||
$p = new ReflectionProperty(mysqli_sql_exception::class, 'sqlstate');
|
||||
$p->setAccessible(true);
|
||||
|
||||
return new self($exception->getMessage(), $p->getValue($exception), $exception->getCode(), $exception);
|
||||
}
|
||||
}
|
36
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/Exception/ConnectionFailed.php
vendored
Normal file
36
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/Exception/ConnectionFailed.php
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\DBAL\Driver\Mysqli\Exception;
|
||||
|
||||
use Doctrine\DBAL\Driver\Mysqli\MysqliException;
|
||||
use mysqli;
|
||||
use mysqli_sql_exception;
|
||||
use ReflectionProperty;
|
||||
|
||||
use function assert;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @psalm-immutable
|
||||
*/
|
||||
final class ConnectionFailed extends MysqliException
|
||||
{
|
||||
public static function new(mysqli $connection): self
|
||||
{
|
||||
$error = $connection->connect_error;
|
||||
assert($error !== null);
|
||||
|
||||
return new self($error, 'HY000', $connection->connect_errno);
|
||||
}
|
||||
|
||||
public static function upcast(mysqli_sql_exception $exception): self
|
||||
{
|
||||
$p = new ReflectionProperty(mysqli_sql_exception::class, 'sqlstate');
|
||||
$p->setAccessible(true);
|
||||
|
||||
return new self($exception->getMessage(), $p->getValue($exception), $exception->getCode(), $exception);
|
||||
}
|
||||
}
|
22
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/Exception/FailedReadingStreamOffset.php
vendored
Normal file
22
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/Exception/FailedReadingStreamOffset.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\DBAL\Driver\Mysqli\Exception;
|
||||
|
||||
use Doctrine\DBAL\Driver\Mysqli\MysqliException;
|
||||
|
||||
use function sprintf;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @psalm-immutable
|
||||
*/
|
||||
final class FailedReadingStreamOffset extends MysqliException
|
||||
{
|
||||
public static function new(int $offset): self
|
||||
{
|
||||
return new self(sprintf('Failed reading the stream resource for parameter offset %d.', $offset));
|
||||
}
|
||||
}
|
28
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/Exception/InvalidOption.php
vendored
Normal file
28
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/Exception/InvalidOption.php
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\DBAL\Driver\Mysqli\Exception;
|
||||
|
||||
use Doctrine\DBAL\Driver\Mysqli\MysqliException;
|
||||
|
||||
use function sprintf;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @psalm-immutable
|
||||
*/
|
||||
final class InvalidOption extends MysqliException
|
||||
{
|
||||
/**
|
||||
* @param mixed $option
|
||||
* @param mixed $value
|
||||
*/
|
||||
public static function fromOption($option, $value): self
|
||||
{
|
||||
return new self(
|
||||
sprintf('Failed to set option %d with value "%s"', $option, $value)
|
||||
);
|
||||
}
|
||||
}
|
31
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/Exception/StatementError.php
vendored
Normal file
31
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/Exception/StatementError.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\DBAL\Driver\Mysqli\Exception;
|
||||
|
||||
use Doctrine\DBAL\Driver\Mysqli\MysqliException;
|
||||
use mysqli_sql_exception;
|
||||
use mysqli_stmt;
|
||||
use ReflectionProperty;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @psalm-immutable
|
||||
*/
|
||||
final class StatementError extends MysqliException
|
||||
{
|
||||
public static function new(mysqli_stmt $statement): self
|
||||
{
|
||||
return new self($statement->error, $statement->sqlstate, $statement->errno);
|
||||
}
|
||||
|
||||
public static function upcast(mysqli_sql_exception $exception): self
|
||||
{
|
||||
$p = new ReflectionProperty(mysqli_sql_exception::class, 'sqlstate');
|
||||
$p->setAccessible(true);
|
||||
|
||||
return new self($exception->getMessage(), $p->getValue($exception), $exception->getCode(), $exception);
|
||||
}
|
||||
}
|
25
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/Exception/UnknownType.php
vendored
Normal file
25
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/Exception/UnknownType.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\DBAL\Driver\Mysqli\Exception;
|
||||
|
||||
use Doctrine\DBAL\Driver\Mysqli\MysqliException;
|
||||
|
||||
use function sprintf;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @psalm-immutable
|
||||
*/
|
||||
final class UnknownType extends MysqliException
|
||||
{
|
||||
/**
|
||||
* @param mixed $type
|
||||
*/
|
||||
public static function new($type): self
|
||||
{
|
||||
return new self(sprintf('Unknown type, %d given.', $type));
|
||||
}
|
||||
}
|
@@ -2,18 +2,18 @@
|
||||
|
||||
namespace Doctrine\DBAL\Driver\Mysqli;
|
||||
|
||||
use Doctrine\DBAL\Driver\Connection;
|
||||
use Doctrine\DBAL\Driver\Connection as ConnectionInterface;
|
||||
use Doctrine\DBAL\Driver\Mysqli\Exception\ConnectionError;
|
||||
use Doctrine\DBAL\Driver\Mysqli\Exception\ConnectionFailed;
|
||||
use Doctrine\DBAL\Driver\Mysqli\Exception\InvalidOption;
|
||||
use Doctrine\DBAL\Driver\PingableConnection;
|
||||
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
|
||||
use Doctrine\DBAL\ParameterType;
|
||||
use Doctrine\Deprecations\Deprecation;
|
||||
use mysqli;
|
||||
use const MYSQLI_INIT_COMMAND;
|
||||
use const MYSQLI_OPT_CONNECT_TIMEOUT;
|
||||
use const MYSQLI_OPT_LOCAL_INFILE;
|
||||
use const MYSQLI_READ_DEFAULT_FILE;
|
||||
use const MYSQLI_READ_DEFAULT_GROUP;
|
||||
use const MYSQLI_SERVER_PUBLIC_KEY;
|
||||
use function defined;
|
||||
use mysqli_sql_exception;
|
||||
|
||||
use function assert;
|
||||
use function floor;
|
||||
use function func_get_args;
|
||||
use function in_array;
|
||||
@@ -22,12 +22,21 @@ use function mysqli_errno;
|
||||
use function mysqli_error;
|
||||
use function mysqli_init;
|
||||
use function mysqli_options;
|
||||
use function restore_error_handler;
|
||||
use function set_error_handler;
|
||||
use function sprintf;
|
||||
use function stripos;
|
||||
|
||||
class MysqliConnection implements Connection, PingableConnection, ServerInfoAwareConnection
|
||||
use const MYSQLI_INIT_COMMAND;
|
||||
use const MYSQLI_OPT_CONNECT_TIMEOUT;
|
||||
use const MYSQLI_OPT_LOCAL_INFILE;
|
||||
use const MYSQLI_OPT_READ_TIMEOUT;
|
||||
use const MYSQLI_READ_DEFAULT_FILE;
|
||||
use const MYSQLI_READ_DEFAULT_GROUP;
|
||||
use const MYSQLI_SERVER_PUBLIC_KEY;
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link Connection} instead
|
||||
*/
|
||||
class MysqliConnection implements ConnectionInterface, PingableConnection, ServerInfoAwareConnection
|
||||
{
|
||||
/**
|
||||
* Name of the option to set connection flags
|
||||
@@ -38,6 +47,8 @@ class MysqliConnection implements Connection, PingableConnection, ServerInfoAwar
|
||||
private $conn;
|
||||
|
||||
/**
|
||||
* @internal The connection can be only instantiated by its driver.
|
||||
*
|
||||
* @param mixed[] $params
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
@@ -57,21 +68,25 @@ class MysqliConnection implements Connection, PingableConnection, ServerInfoAwar
|
||||
$socket = $params['unix_socket'] ?? ini_get('mysqli.default_socket');
|
||||
$dbname = $params['dbname'] ?? null;
|
||||
|
||||
$flags = $driverOptions[static::OPTION_FLAGS] ?? null;
|
||||
$flags = $driverOptions[static::OPTION_FLAGS] ?? 0;
|
||||
|
||||
$this->conn = mysqli_init();
|
||||
$conn = mysqli_init();
|
||||
assert($conn !== false);
|
||||
|
||||
$this->conn = $conn;
|
||||
|
||||
$this->setSecureConnection($params);
|
||||
$this->setDriverOptions($driverOptions);
|
||||
|
||||
set_error_handler(static function () {
|
||||
});
|
||||
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);
|
||||
}
|
||||
} finally {
|
||||
restore_error_handler();
|
||||
$success = @$this->conn
|
||||
->real_connect($params['host'], $username, $password, $dbname, $port, $socket, $flags);
|
||||
} catch (mysqli_sql_exception $e) {
|
||||
throw ConnectionFailed::upcast($e);
|
||||
}
|
||||
|
||||
if (! $success) {
|
||||
throw ConnectionFailed::new($this->conn);
|
||||
}
|
||||
|
||||
if (! isset($params['charset'])) {
|
||||
@@ -120,15 +135,21 @@ class MysqliConnection implements Connection, PingableConnection, ServerInfoAwar
|
||||
*/
|
||||
public function requiresQueryForServerVersion()
|
||||
{
|
||||
Deprecation::triggerIfCalledFromOutside(
|
||||
'doctrine/dbal',
|
||||
'https://github.com/doctrine/dbal/pull/4114',
|
||||
'ServerInfoAwareConnection::requiresQueryForServerVersion() is deprecated and removed in DBAL 3.'
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function prepare($prepareString)
|
||||
public function prepare($sql)
|
||||
{
|
||||
return new MysqliStatement($this->conn, $prepareString);
|
||||
return new Statement($this->conn, $sql);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -147,18 +168,24 @@ class MysqliConnection implements Connection, PingableConnection, ServerInfoAwar
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function quote($input, $type = ParameterType::STRING)
|
||||
public function quote($value, $type = ParameterType::STRING)
|
||||
{
|
||||
return "'" . $this->conn->escape_string($input) . "'";
|
||||
return "'" . $this->conn->escape_string($value) . "'";
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function exec($statement)
|
||||
public function exec($sql)
|
||||
{
|
||||
if ($this->conn->query($statement) === false) {
|
||||
throw new MysqliException($this->conn->error, $this->conn->sqlstate, $this->conn->errno);
|
||||
try {
|
||||
$result = $this->conn->query($sql);
|
||||
} catch (mysqli_sql_exception $e) {
|
||||
throw ConnectionError::upcast($e);
|
||||
}
|
||||
|
||||
if ($result === false) {
|
||||
throw ConnectionError::new($this->conn);
|
||||
}
|
||||
|
||||
return $this->conn->affected_rows;
|
||||
@@ -187,7 +214,11 @@ class MysqliConnection implements Connection, PingableConnection, ServerInfoAwar
|
||||
*/
|
||||
public function commit()
|
||||
{
|
||||
return $this->conn->commit();
|
||||
try {
|
||||
return $this->conn->commit();
|
||||
} catch (mysqli_sql_exception $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -195,11 +226,19 @@ class MysqliConnection implements Connection, PingableConnection, ServerInfoAwar
|
||||
*/
|
||||
public function rollBack()
|
||||
{
|
||||
return $this->conn->rollback();
|
||||
try {
|
||||
return $this->conn->rollback();
|
||||
} catch (mysqli_sql_exception $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated The error information is available via exceptions.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function errorCode()
|
||||
{
|
||||
@@ -208,6 +247,10 @@ class MysqliConnection implements Connection, PingableConnection, ServerInfoAwar
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated The error information is available via exceptions.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function errorInfo()
|
||||
{
|
||||
@@ -222,20 +265,18 @@ class MysqliConnection implements Connection, PingableConnection, ServerInfoAwar
|
||||
* @throws MysqliException When one of of the options is not supported.
|
||||
* @throws MysqliException When applying doesn't work - e.g. due to incorrect value.
|
||||
*/
|
||||
private function setDriverOptions(array $driverOptions = [])
|
||||
private function setDriverOptions(array $driverOptions = []): void
|
||||
{
|
||||
$supportedDriverOptions = [
|
||||
MYSQLI_OPT_CONNECT_TIMEOUT,
|
||||
MYSQLI_OPT_LOCAL_INFILE,
|
||||
MYSQLI_OPT_READ_TIMEOUT,
|
||||
MYSQLI_INIT_COMMAND,
|
||||
MYSQLI_READ_DEFAULT_FILE,
|
||||
MYSQLI_READ_DEFAULT_GROUP,
|
||||
MYSQLI_SERVER_PUBLIC_KEY,
|
||||
];
|
||||
|
||||
if (defined('MYSQLI_SERVER_PUBLIC_KEY')) {
|
||||
$supportedDriverOptions[] = MYSQLI_SERVER_PUBLIC_KEY;
|
||||
}
|
||||
|
||||
$exceptionMsg = "%s option '%s' with value '%s'";
|
||||
|
||||
foreach ($driverOptions as $option => $value) {
|
||||
@@ -244,9 +285,7 @@ class MysqliConnection implements Connection, PingableConnection, ServerInfoAwar
|
||||
}
|
||||
|
||||
if (! in_array($option, $supportedDriverOptions, true)) {
|
||||
throw new MysqliException(
|
||||
sprintf($exceptionMsg, 'Unsupported', $option, $value)
|
||||
);
|
||||
throw InvalidOption::fromOption($option, $value);
|
||||
}
|
||||
|
||||
if (@mysqli_options($this->conn, $option, $value)) {
|
||||
@@ -267,6 +306,8 @@ class MysqliConnection implements Connection, PingableConnection, ServerInfoAwar
|
||||
/**
|
||||
* Pings the server and re-connects when `mysqli.reconnect = 1`
|
||||
*
|
||||
* @deprecated
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function ping()
|
||||
@@ -277,13 +318,14 @@ class MysqliConnection implements Connection, PingableConnection, ServerInfoAwar
|
||||
/**
|
||||
* Establish a secure connection
|
||||
*
|
||||
* @param mixed[] $params
|
||||
* @param array<string,string> $params
|
||||
*
|
||||
* @throws MysqliException
|
||||
*/
|
||||
private function setSecureConnection(array $params)
|
||||
private function setSecureConnection(array $params): void
|
||||
{
|
||||
if (! isset($params['ssl_key']) &&
|
||||
if (
|
||||
! isset($params['ssl_key']) &&
|
||||
! isset($params['ssl_cert']) &&
|
||||
! isset($params['ssl_ca']) &&
|
||||
! isset($params['ssl_capath']) &&
|
||||
@@ -293,11 +335,11 @@ class MysqliConnection implements Connection, PingableConnection, ServerInfoAwar
|
||||
}
|
||||
|
||||
$this->conn->ssl_set(
|
||||
$params['ssl_key'] ?? null,
|
||||
$params['ssl_cert'] ?? null,
|
||||
$params['ssl_ca'] ?? null,
|
||||
$params['ssl_capath'] ?? null,
|
||||
$params['ssl_cipher'] ?? null
|
||||
$params['ssl_key'] ?? '',
|
||||
$params['ssl_cert'] ?? '',
|
||||
$params['ssl_ca'] ?? '',
|
||||
$params['ssl_capath'] ?? '',
|
||||
$params['ssl_cipher'] ?? ''
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -5,7 +5,9 @@ namespace Doctrine\DBAL\Driver\Mysqli;
|
||||
use Doctrine\DBAL\Driver\AbstractDriverException;
|
||||
|
||||
/**
|
||||
* Exception thrown in case the mysqli driver errors.
|
||||
* @deprecated Use {@link \Doctrine\DBAL\Driver\Exception} instead
|
||||
*
|
||||
* @psalm-immutable
|
||||
*/
|
||||
class MysqliException extends AbstractDriverException
|
||||
{
|
||||
|
@@ -2,30 +2,45 @@
|
||||
|
||||
namespace Doctrine\DBAL\Driver\Mysqli;
|
||||
|
||||
use Doctrine\DBAL\Driver\Statement;
|
||||
use Doctrine\DBAL\Driver\FetchUtils;
|
||||
use Doctrine\DBAL\Driver\Mysqli\Exception\ConnectionError;
|
||||
use Doctrine\DBAL\Driver\Mysqli\Exception\FailedReadingStreamOffset;
|
||||
use Doctrine\DBAL\Driver\Mysqli\Exception\StatementError;
|
||||
use Doctrine\DBAL\Driver\Mysqli\Exception\UnknownType;
|
||||
use Doctrine\DBAL\Driver\Result;
|
||||
use Doctrine\DBAL\Driver\Statement as StatementInterface;
|
||||
use Doctrine\DBAL\Driver\StatementIterator;
|
||||
use Doctrine\DBAL\Exception\InvalidArgumentException;
|
||||
use Doctrine\DBAL\FetchMode;
|
||||
use Doctrine\DBAL\ParameterType;
|
||||
use IteratorAggregate;
|
||||
use mysqli;
|
||||
use mysqli_sql_exception;
|
||||
use mysqli_stmt;
|
||||
use PDO;
|
||||
use stdClass;
|
||||
use ReturnTypeWillChange;
|
||||
|
||||
use function array_combine;
|
||||
use function array_fill;
|
||||
use function assert;
|
||||
use function count;
|
||||
use function feof;
|
||||
use function fread;
|
||||
use function get_resource_type;
|
||||
use function is_array;
|
||||
use function is_int;
|
||||
use function is_resource;
|
||||
use function sprintf;
|
||||
use function str_repeat;
|
||||
|
||||
class MysqliStatement implements IteratorAggregate, Statement
|
||||
/**
|
||||
* @deprecated Use {@link Statement} instead
|
||||
*/
|
||||
class MysqliStatement implements IteratorAggregate, StatementInterface, Result
|
||||
{
|
||||
/** @var string[] */
|
||||
protected static $_paramTypeMap = [
|
||||
ParameterType::ASCII => 's',
|
||||
ParameterType::STRING => 's',
|
||||
ParameterType::BINARY => 's',
|
||||
ParameterType::BOOLEAN => 'i',
|
||||
@@ -40,11 +55,11 @@ class MysqliStatement implements IteratorAggregate, Statement
|
||||
/** @var mysqli_stmt */
|
||||
protected $_stmt;
|
||||
|
||||
/** @var string[]|bool|null */
|
||||
/** @var string[]|false|null */
|
||||
protected $_columnNames;
|
||||
|
||||
/** @var mixed[]|null */
|
||||
protected $_rowBindedValues;
|
||||
/** @var mixed[] */
|
||||
protected $_rowBindedValues = [];
|
||||
|
||||
/** @var mixed[] */
|
||||
protected $_bindedValues;
|
||||
@@ -70,6 +85,8 @@ class MysqliStatement implements IteratorAggregate, Statement
|
||||
private $result = false;
|
||||
|
||||
/**
|
||||
* @internal The statement can be only instantiated by its driver connection.
|
||||
*
|
||||
* @param string $prepareString
|
||||
*
|
||||
* @throws MysqliException
|
||||
@@ -77,16 +94,20 @@ class MysqliStatement implements IteratorAggregate, Statement
|
||||
public function __construct(mysqli $conn, $prepareString)
|
||||
{
|
||||
$this->_conn = $conn;
|
||||
$this->_stmt = $conn->prepare($prepareString);
|
||||
if ($this->_stmt === false) {
|
||||
throw new MysqliException($this->_conn->error, $this->_conn->sqlstate, $this->_conn->errno);
|
||||
|
||||
try {
|
||||
$stmt = $conn->prepare($prepareString);
|
||||
} catch (mysqli_sql_exception $e) {
|
||||
throw ConnectionError::upcast($e);
|
||||
}
|
||||
|
||||
$paramCount = $this->_stmt->param_count;
|
||||
if (0 >= $paramCount) {
|
||||
return;
|
||||
if ($stmt === false) {
|
||||
throw ConnectionError::new($this->_conn);
|
||||
}
|
||||
|
||||
$this->_stmt = $stmt;
|
||||
|
||||
$paramCount = $this->_stmt->param_count;
|
||||
$this->types = str_repeat('s', $paramCount);
|
||||
$this->_bindedValues = array_fill(1, $paramCount, null);
|
||||
}
|
||||
@@ -94,20 +115,16 @@ class MysqliStatement implements IteratorAggregate, Statement
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function bindParam($column, &$variable, $type = ParameterType::STRING, $length = null)
|
||||
public function bindParam($param, &$variable, $type = ParameterType::STRING, $length = null)
|
||||
{
|
||||
if ($type === null) {
|
||||
$type = 's';
|
||||
} else {
|
||||
if (! isset(self::$_paramTypeMap[$type])) {
|
||||
throw new MysqliException(sprintf("Unknown type: '%s'", $type));
|
||||
}
|
||||
assert(is_int($param));
|
||||
|
||||
$type = self::$_paramTypeMap[$type];
|
||||
if (! isset(self::$_paramTypeMap[$type])) {
|
||||
throw UnknownType::new($type);
|
||||
}
|
||||
|
||||
$this->_bindedValues[$column] =& $variable;
|
||||
$this->types[$column - 1] = $type;
|
||||
$this->_bindedValues[$param] =& $variable;
|
||||
$this->types[$param - 1] = self::$_paramTypeMap[$type];
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -117,19 +134,15 @@ class MysqliStatement implements IteratorAggregate, Statement
|
||||
*/
|
||||
public function bindValue($param, $value, $type = ParameterType::STRING)
|
||||
{
|
||||
if ($type === null) {
|
||||
$type = 's';
|
||||
} else {
|
||||
if (! isset(self::$_paramTypeMap[$type])) {
|
||||
throw new MysqliException(sprintf("Unknown type: '%s'", $type));
|
||||
}
|
||||
assert(is_int($param));
|
||||
|
||||
$type = self::$_paramTypeMap[$type];
|
||||
if (! isset(self::$_paramTypeMap[$type])) {
|
||||
throw UnknownType::new($type);
|
||||
}
|
||||
|
||||
$this->_values[$param] = $value;
|
||||
$this->_bindedValues[$param] =& $this->_values[$param];
|
||||
$this->types[$param - 1] = $type;
|
||||
$this->types[$param - 1] = self::$_paramTypeMap[$type];
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -139,31 +152,35 @@ class MysqliStatement implements IteratorAggregate, Statement
|
||||
*/
|
||||
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->bindUntypedValues($params)) {
|
||||
throw StatementError::new($this->_stmt);
|
||||
}
|
||||
} elseif (count($this->_bindedValues) > 0) {
|
||||
$this->bindTypedParameters();
|
||||
}
|
||||
|
||||
if (! $this->_stmt->execute()) {
|
||||
throw new MysqliException($this->_stmt->error, $this->_stmt->sqlstate, $this->_stmt->errno);
|
||||
try {
|
||||
$result = $this->_stmt->execute();
|
||||
} catch (mysqli_sql_exception $e) {
|
||||
throw StatementError::upcast($e);
|
||||
}
|
||||
|
||||
if (! $result) {
|
||||
throw StatementError::new($this->_stmt);
|
||||
}
|
||||
|
||||
if ($this->_columnNames === null) {
|
||||
$meta = $this->_stmt->result_metadata();
|
||||
if ($meta !== false) {
|
||||
$fields = $meta->fetch_fields();
|
||||
assert(is_array($fields));
|
||||
|
||||
$columnNames = [];
|
||||
foreach ($meta->fetch_fields() as $col) {
|
||||
foreach ($fields as $col) {
|
||||
$columnNames[] = $col->name;
|
||||
}
|
||||
|
||||
$meta->free();
|
||||
|
||||
$this->_columnNames = $columnNames;
|
||||
@@ -180,7 +197,7 @@ class MysqliStatement implements IteratorAggregate, Statement
|
||||
|
||||
// Bind row values _after_ storing the result. Otherwise, if mysqli is compiled with libmysql,
|
||||
// it will have to allocate as much memory as it may be needed for the given column type
|
||||
// (e.g. for a LONGBLOB field it's 4 gigabytes)
|
||||
// (e.g. for a LONGBLOB column it's 4 gigabytes)
|
||||
// @link https://bugs.php.net/bug.php?id=51386#1270673122
|
||||
//
|
||||
// Make sure that the values are bound after each execution. Otherwise, if closeCursor() has been
|
||||
@@ -197,7 +214,7 @@ class MysqliStatement implements IteratorAggregate, Statement
|
||||
}
|
||||
|
||||
if (! $this->_stmt->bind_result(...$refs)) {
|
||||
throw new MysqliException($this->_stmt->error, $this->_stmt->sqlstate, $this->_stmt->errno);
|
||||
throw StatementError::new($this->_stmt);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -207,17 +224,16 @@ class MysqliStatement implements IteratorAggregate, Statement
|
||||
}
|
||||
|
||||
/**
|
||||
* Split $this->_bindedValues into those values that need to be sent using mysqli::send_long_data()
|
||||
* and those that can be bound the usual way.
|
||||
*
|
||||
* @return array<int, array<int|string, mixed>|string>
|
||||
* Binds parameters with known types previously bound to the statement
|
||||
*/
|
||||
private function separateBoundValues()
|
||||
private function bindTypedParameters(): void
|
||||
{
|
||||
$streams = $values = [];
|
||||
$types = $this->types;
|
||||
|
||||
foreach ($this->_bindedValues as $parameter => $value) {
|
||||
assert(is_int($parameter));
|
||||
|
||||
if (! isset($types[$parameter - 1])) {
|
||||
$types[$parameter - 1] = static::$_paramTypeMap[ParameterType::STRING];
|
||||
}
|
||||
@@ -225,39 +241,48 @@ class MysqliStatement implements IteratorAggregate, Statement
|
||||
if ($types[$parameter - 1] === static::$_paramTypeMap[ParameterType::LARGE_OBJECT]) {
|
||||
if (is_resource($value)) {
|
||||
if (get_resource_type($value) !== 'stream') {
|
||||
throw new InvalidArgumentException('Resources passed with the LARGE_OBJECT parameter type must be stream resources.');
|
||||
throw new InvalidArgumentException(
|
||||
'Resources passed with the LARGE_OBJECT parameter type must be stream resources.'
|
||||
);
|
||||
}
|
||||
|
||||
$streams[$parameter] = $value;
|
||||
$values[$parameter] = null;
|
||||
continue;
|
||||
} else {
|
||||
$types[$parameter - 1] = static::$_paramTypeMap[ParameterType::STRING];
|
||||
}
|
||||
|
||||
$types[$parameter - 1] = static::$_paramTypeMap[ParameterType::STRING];
|
||||
}
|
||||
|
||||
$values[$parameter] = $value;
|
||||
}
|
||||
|
||||
return [$types, $values, $streams];
|
||||
if (! $this->_stmt->bind_param($types, ...$values)) {
|
||||
throw StatementError::new($this->_stmt);
|
||||
}
|
||||
|
||||
$this->sendLongData($streams);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle $this->_longData after regular query parameters have been bound
|
||||
*
|
||||
* @param array<int, resource> $streams
|
||||
*
|
||||
* @throws MysqliException
|
||||
*/
|
||||
private function sendLongData($streams)
|
||||
private function sendLongData(array $streams): void
|
||||
{
|
||||
foreach ($streams as $paramNr => $stream) {
|
||||
while (! feof($stream)) {
|
||||
$chunk = fread($stream, 8192);
|
||||
|
||||
if ($chunk === false) {
|
||||
throw new MysqliException("Failed reading the stream resource for parameter offset ${paramNr}.");
|
||||
throw FailedReadingStreamOffset::new($paramNr);
|
||||
}
|
||||
|
||||
if (! $this->_stmt->send_long_data($paramNr - 1, $chunk)) {
|
||||
throw new MysqliException($this->_stmt->error, $this->_stmt->sqlstate, $this->_stmt->errno);
|
||||
throw StatementError::new($this->_stmt);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -270,7 +295,7 @@ class MysqliStatement implements IteratorAggregate, Statement
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function _bindValues($values)
|
||||
private function bindUntypedValues(array $values)
|
||||
{
|
||||
$params = [];
|
||||
$types = str_repeat('s', count($values));
|
||||
@@ -283,11 +308,17 @@ class MysqliStatement implements IteratorAggregate, Statement
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed[]|false
|
||||
* @return mixed[]|false|null
|
||||
*
|
||||
* @throws StatementError
|
||||
*/
|
||||
private function _fetch()
|
||||
{
|
||||
$ret = $this->_stmt->fetch();
|
||||
try {
|
||||
$ret = $this->_stmt->fetch();
|
||||
} catch (mysqli_sql_exception $e) {
|
||||
throw StatementError::upcast($e);
|
||||
}
|
||||
|
||||
if ($ret === true) {
|
||||
$values = [];
|
||||
@@ -303,6 +334,8 @@ class MysqliStatement implements IteratorAggregate, Statement
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated Use fetchNumeric(), fetchAssociative() or fetchOne() instead.
|
||||
*/
|
||||
public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEXT, $cursorOffset = 0)
|
||||
{
|
||||
@@ -319,36 +352,32 @@ class MysqliStatement implements IteratorAggregate, Statement
|
||||
}
|
||||
|
||||
$values = $this->_fetch();
|
||||
|
||||
if ($values === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($values === false) {
|
||||
throw new MysqliException($this->_stmt->error, $this->_stmt->sqlstate, $this->_stmt->errno);
|
||||
throw StatementError::new($this->_stmt);
|
||||
}
|
||||
|
||||
switch ($fetchMode) {
|
||||
case FetchMode::NUMERIC:
|
||||
return $values;
|
||||
if ($fetchMode === FetchMode::NUMERIC) {
|
||||
return $values;
|
||||
}
|
||||
|
||||
assert(is_array($this->_columnNames));
|
||||
$assoc = array_combine($this->_columnNames, $values);
|
||||
assert(is_array($assoc));
|
||||
|
||||
switch ($fetchMode) {
|
||||
case FetchMode::ASSOCIATIVE:
|
||||
return array_combine($this->_columnNames, $values);
|
||||
return $assoc;
|
||||
|
||||
case FetchMode::MIXED:
|
||||
$ret = array_combine($this->_columnNames, $values);
|
||||
$ret += $values;
|
||||
|
||||
return $ret;
|
||||
return $assoc + $values;
|
||||
|
||||
case FetchMode::STANDARD_OBJECT:
|
||||
$assoc = array_combine($this->_columnNames, $values);
|
||||
$ret = new stdClass();
|
||||
|
||||
foreach ($assoc as $column => $value) {
|
||||
$ret->$column = $value;
|
||||
}
|
||||
|
||||
return $ret;
|
||||
return (object) $assoc;
|
||||
|
||||
default:
|
||||
throw new MysqliException(sprintf("Unknown fetch type '%s'", $fetchMode));
|
||||
@@ -357,6 +386,8 @@ class MysqliStatement implements IteratorAggregate, Statement
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated Use fetchAllNumeric(), fetchAllAssociative() or fetchFirstColumn() instead.
|
||||
*/
|
||||
public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = null)
|
||||
{
|
||||
@@ -379,6 +410,8 @@ class MysqliStatement implements IteratorAggregate, Statement
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated Use fetchOne() instead.
|
||||
*/
|
||||
public function fetchColumn($columnIndex = 0)
|
||||
{
|
||||
@@ -391,6 +424,82 @@ class MysqliStatement implements IteratorAggregate, Statement
|
||||
return $row[$columnIndex] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated The error information is available via exceptions.
|
||||
*/
|
||||
public function fetchNumeric()
|
||||
{
|
||||
// do not try fetching from the statement if it's not expected to contain the result
|
||||
// in order to prevent exceptional situation
|
||||
if (! $this->result) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$values = $this->_fetch();
|
||||
|
||||
if ($values === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($values === false) {
|
||||
throw StatementError::new($this->_stmt);
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function fetchAssociative()
|
||||
{
|
||||
$values = $this->fetchNumeric();
|
||||
|
||||
if ($values === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
assert(is_array($this->_columnNames));
|
||||
$row = array_combine($this->_columnNames, $values);
|
||||
assert(is_array($row));
|
||||
|
||||
return $row;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchOne()
|
||||
{
|
||||
return FetchUtils::fetchOne($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchAllNumeric(): array
|
||||
{
|
||||
return FetchUtils::fetchAllNumeric($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchAllAssociative(): array
|
||||
{
|
||||
return FetchUtils::fetchAllAssociative($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchFirstColumn(): array
|
||||
{
|
||||
return FetchUtils::fetchFirstColumn($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -401,6 +510,10 @@ class MysqliStatement implements IteratorAggregate, Statement
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated The error information is available via exceptions.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function errorInfo()
|
||||
{
|
||||
@@ -409,11 +522,12 @@ class MysqliStatement implements IteratorAggregate, Statement
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated Use free() instead.
|
||||
*/
|
||||
public function closeCursor()
|
||||
{
|
||||
$this->_stmt->free_result();
|
||||
$this->result = false;
|
||||
$this->free();
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -438,8 +552,16 @@ class MysqliStatement implements IteratorAggregate, Statement
|
||||
return $this->_stmt->field_count;
|
||||
}
|
||||
|
||||
public function free(): void
|
||||
{
|
||||
$this->_stmt->free_result();
|
||||
$this->result = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated Use one of the fetch- or iterate-related methods.
|
||||
*/
|
||||
public function setFetchMode($fetchMode, $arg2 = null, $arg3 = null)
|
||||
{
|
||||
@@ -450,7 +572,10 @@ class MysqliStatement implements IteratorAggregate, Statement
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated Use iterateNumeric(), iterateAssociative() or iterateColumn() instead.
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function getIterator()
|
||||
{
|
||||
return new StatementIterator($this);
|
||||
|
7
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/Statement.php
vendored
Normal file
7
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/Statement.php
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\DBAL\Driver\Mysqli;
|
||||
|
||||
final class Statement extends MysqliStatement
|
||||
{
|
||||
}
|
7
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/Connection.php
vendored
Normal file
7
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/Connection.php
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\DBAL\Driver\OCI8;
|
||||
|
||||
final class Connection extends OCI8Connection
|
||||
{
|
||||
}
|
@@ -2,9 +2,11 @@
|
||||
|
||||
namespace Doctrine\DBAL\Driver\OCI8;
|
||||
|
||||
use Doctrine\DBAL\DBALException;
|
||||
use Doctrine\DBAL\Driver\AbstractOracleDriver;
|
||||
use const OCI_DEFAULT;
|
||||
use Doctrine\DBAL\Exception;
|
||||
use Doctrine\Deprecations\Deprecation;
|
||||
|
||||
use const OCI_NO_AUTO_COMMIT;
|
||||
|
||||
/**
|
||||
* A Doctrine DBAL driver for the Oracle OCI8 PHP extensions.
|
||||
@@ -17,16 +19,16 @@ class Driver extends AbstractOracleDriver
|
||||
public function connect(array $params, $username = null, $password = null, array $driverOptions = [])
|
||||
{
|
||||
try {
|
||||
return new OCI8Connection(
|
||||
$username,
|
||||
$password,
|
||||
return new Connection(
|
||||
(string) $username,
|
||||
(string) $password,
|
||||
$this->_constructDsn($params),
|
||||
$params['charset'] ?? null,
|
||||
$params['sessionMode'] ?? OCI_DEFAULT,
|
||||
$params['charset'] ?? '',
|
||||
$params['sessionMode'] ?? OCI_NO_AUTO_COMMIT,
|
||||
$params['persistent'] ?? false
|
||||
);
|
||||
} catch (OCI8Exception $e) {
|
||||
throw DBALException::driverException($this, $e);
|
||||
throw Exception::driverException($this, $e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,9 +46,17 @@ class Driver extends AbstractOracleDriver
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
Deprecation::trigger(
|
||||
'doctrine/dbal',
|
||||
'https://github.com/doctrine/dbal/issues/3580',
|
||||
'Driver::getName() is deprecated'
|
||||
);
|
||||
|
||||
return 'oci8';
|
||||
}
|
||||
}
|
||||
|
27
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/Exception/NonTerminatedStringLiteral.php
vendored
Normal file
27
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/Exception/NonTerminatedStringLiteral.php
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\DBAL\Driver\OCI8\Exception;
|
||||
|
||||
use Doctrine\DBAL\Driver\OCI8\OCI8Exception;
|
||||
|
||||
use function sprintf;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @psalm-immutable
|
||||
*/
|
||||
final class NonTerminatedStringLiteral extends OCI8Exception
|
||||
{
|
||||
public static function new(int $offset): self
|
||||
{
|
||||
return new self(
|
||||
sprintf(
|
||||
'The statement contains non-terminated string literal starting at offset %d.',
|
||||
$offset
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
20
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/Exception/SequenceDoesNotExist.php
vendored
Normal file
20
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/Exception/SequenceDoesNotExist.php
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\DBAL\Driver\OCI8\Exception;
|
||||
|
||||
use Doctrine\DBAL\Driver\OCI8\OCI8Exception;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @psalm-immutable
|
||||
*/
|
||||
final class SequenceDoesNotExist extends OCI8Exception
|
||||
{
|
||||
public static function new(): self
|
||||
{
|
||||
return new self('lastInsertId failed: Query was executed but no result was returned.');
|
||||
}
|
||||
}
|
24
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/Exception/UnknownParameterIndex.php
vendored
Normal file
24
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/Exception/UnknownParameterIndex.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\DBAL\Driver\OCI8\Exception;
|
||||
|
||||
use Doctrine\DBAL\Driver\OCI8\OCI8Exception;
|
||||
|
||||
use function sprintf;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @psalm-immutable
|
||||
*/
|
||||
final class UnknownParameterIndex extends OCI8Exception
|
||||
{
|
||||
public static function new(int $index): self
|
||||
{
|
||||
return new self(
|
||||
sprintf('Could not find variable mapping with index %d, in the SQL statement', $index)
|
||||
);
|
||||
}
|
||||
}
|
@@ -2,16 +2,14 @@
|
||||
|
||||
namespace Doctrine\DBAL\Driver\OCI8;
|
||||
|
||||
use Doctrine\DBAL\Driver\Connection;
|
||||
use Doctrine\DBAL\Driver\Connection as ConnectionInterface;
|
||||
use Doctrine\DBAL\Driver\OCI8\Exception\SequenceDoesNotExist;
|
||||
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
|
||||
use Doctrine\DBAL\ParameterType;
|
||||
use Doctrine\Deprecations\Deprecation;
|
||||
use UnexpectedValueException;
|
||||
use const OCI_COMMIT_ON_SUCCESS;
|
||||
use const OCI_DEFAULT;
|
||||
use const OCI_NO_AUTO_COMMIT;
|
||||
|
||||
use function addcslashes;
|
||||
use function define;
|
||||
use function defined;
|
||||
use function func_get_args;
|
||||
use function is_float;
|
||||
use function is_int;
|
||||
@@ -25,10 +23,15 @@ use function preg_match;
|
||||
use function sprintf;
|
||||
use function str_replace;
|
||||
|
||||
use const OCI_COMMIT_ON_SUCCESS;
|
||||
use const OCI_NO_AUTO_COMMIT;
|
||||
|
||||
/**
|
||||
* OCI8 implementation of the Connection interface.
|
||||
*
|
||||
* @deprecated Use {@link Connection} instead
|
||||
*/
|
||||
class OCI8Connection implements Connection, ServerInfoAwareConnection
|
||||
class OCI8Connection implements ConnectionInterface, ServerInfoAwareConnection
|
||||
{
|
||||
/** @var resource */
|
||||
protected $dbh;
|
||||
@@ -39,28 +42,34 @@ class OCI8Connection implements Connection, ServerInfoAwareConnection
|
||||
/**
|
||||
* Creates a Connection to an Oracle Database using oci8 extension.
|
||||
*
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
* @param string $db
|
||||
* @param string|null $charset
|
||||
* @param int $sessionMode
|
||||
* @param bool $persistent
|
||||
* @internal The connection can be only instantiated by its driver.
|
||||
*
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
* @param string $db
|
||||
* @param string $charset
|
||||
* @param int $sessionMode
|
||||
* @param bool $persistent
|
||||
*
|
||||
* @throws OCI8Exception
|
||||
*/
|
||||
public function __construct($username, $password, $db, $charset = null, $sessionMode = OCI_DEFAULT, $persistent = false)
|
||||
{
|
||||
if (! defined('OCI_NO_AUTO_COMMIT')) {
|
||||
define('OCI_NO_AUTO_COMMIT', 0);
|
||||
}
|
||||
|
||||
$this->dbh = $persistent
|
||||
public function __construct(
|
||||
$username,
|
||||
$password,
|
||||
$db,
|
||||
$charset = '',
|
||||
$sessionMode = OCI_NO_AUTO_COMMIT,
|
||||
$persistent = false
|
||||
) {
|
||||
$dbh = $persistent
|
||||
? @oci_pconnect($username, $password, $db, $charset, $sessionMode)
|
||||
: @oci_connect($username, $password, $db, $charset, $sessionMode);
|
||||
|
||||
if (! $this->dbh) {
|
||||
if ($dbh === false) {
|
||||
throw OCI8Exception::fromErrorInfo(oci_error());
|
||||
}
|
||||
|
||||
$this->dbh = $dbh;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -71,17 +80,23 @@ class OCI8Connection implements Connection, ServerInfoAwareConnection
|
||||
*/
|
||||
public function getServerVersion()
|
||||
{
|
||||
if (! preg_match('/\s+(\d+\.\d+\.\d+\.\d+\.\d+)\s+/', oci_server_version($this->dbh), $version)) {
|
||||
$version = oci_server_version($this->dbh);
|
||||
|
||||
if ($version === false) {
|
||||
throw OCI8Exception::fromErrorInfo(oci_error($this->dbh));
|
||||
}
|
||||
|
||||
if (! preg_match('/\s+(\d+\.\d+\.\d+\.\d+\.\d+)\s+/', $version, $matches)) {
|
||||
throw new UnexpectedValueException(
|
||||
sprintf(
|
||||
'Unexpected database version string "%s". Cannot parse an appropriate version number from it. ' .
|
||||
'Please report this database version string to the Doctrine team.',
|
||||
oci_server_version($this->dbh)
|
||||
$version
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return $version[1];
|
||||
return $matches[1];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -89,15 +104,21 @@ class OCI8Connection implements Connection, ServerInfoAwareConnection
|
||||
*/
|
||||
public function requiresQueryForServerVersion()
|
||||
{
|
||||
Deprecation::triggerIfCalledFromOutside(
|
||||
'doctrine/dbal',
|
||||
'https://github.com/doctrine/dbal/pull/4114',
|
||||
'ServerInfoAwareConnection::requiresQueryForServerVersion() is deprecated and removed in DBAL 3.'
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function prepare($prepareString)
|
||||
public function prepare($sql)
|
||||
{
|
||||
return new OCI8Statement($this->dbh, $prepareString, $this);
|
||||
return new Statement($this->dbh, $sql, $this);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -122,6 +143,7 @@ class OCI8Connection implements Connection, ServerInfoAwareConnection
|
||||
if (is_int($value) || is_float($value)) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
$value = str_replace("'", "''", $value);
|
||||
|
||||
return "'" . addcslashes($value, "\000\n\r\\\032") . "'";
|
||||
@@ -130,9 +152,9 @@ class OCI8Connection implements Connection, ServerInfoAwareConnection
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function exec($statement)
|
||||
public function exec($sql)
|
||||
{
|
||||
$stmt = $this->prepare($statement);
|
||||
$stmt = $this->prepare($sql);
|
||||
$stmt->execute();
|
||||
|
||||
return $stmt->rowCount();
|
||||
@@ -140,6 +162,10 @@ class OCI8Connection implements Connection, ServerInfoAwareConnection
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @param string|null $name
|
||||
*
|
||||
* @return int|false
|
||||
*/
|
||||
public function lastInsertId($name = null)
|
||||
{
|
||||
@@ -152,7 +178,7 @@ class OCI8Connection implements Connection, ServerInfoAwareConnection
|
||||
$result = $stmt->fetchColumn();
|
||||
|
||||
if ($result === false) {
|
||||
throw new OCI8Exception('lastInsertId failed: Query was executed but no result was returned.');
|
||||
throw SequenceDoesNotExist::new();
|
||||
}
|
||||
|
||||
return (int) $result;
|
||||
@@ -161,6 +187,8 @@ class OCI8Connection implements Connection, ServerInfoAwareConnection
|
||||
/**
|
||||
* Returns the current execution mode.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getExecuteMode()
|
||||
@@ -186,6 +214,7 @@ class OCI8Connection implements Connection, ServerInfoAwareConnection
|
||||
if (! oci_commit($this->dbh)) {
|
||||
throw OCI8Exception::fromErrorInfo($this->errorInfo());
|
||||
}
|
||||
|
||||
$this->executeMode = OCI_COMMIT_ON_SUCCESS;
|
||||
|
||||
return true;
|
||||
@@ -199,6 +228,7 @@ class OCI8Connection implements Connection, ServerInfoAwareConnection
|
||||
if (! oci_rollback($this->dbh)) {
|
||||
throw OCI8Exception::fromErrorInfo($this->errorInfo());
|
||||
}
|
||||
|
||||
$this->executeMode = OCI_COMMIT_ON_SUCCESS;
|
||||
|
||||
return true;
|
||||
@@ -206,22 +236,33 @@ class OCI8Connection implements Connection, ServerInfoAwareConnection
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated The error information is available via exceptions.
|
||||
*/
|
||||
public function errorCode()
|
||||
{
|
||||
$error = oci_error($this->dbh);
|
||||
|
||||
if ($error !== false) {
|
||||
$error = $error['code'];
|
||||
return $error['code'];
|
||||
}
|
||||
|
||||
return $error;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated The error information is available via exceptions.
|
||||
*/
|
||||
public function errorInfo()
|
||||
{
|
||||
return oci_error($this->dbh);
|
||||
$error = oci_error($this->dbh);
|
||||
|
||||
if ($error === false) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $error;
|
||||
}
|
||||
}
|
||||
|
@@ -4,15 +4,24 @@ namespace Doctrine\DBAL\Driver\OCI8;
|
||||
|
||||
use Doctrine\DBAL\Driver\AbstractDriverException;
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link \Doctrine\DBAL\Driver\Exception} instead
|
||||
*
|
||||
* @psalm-immutable
|
||||
*/
|
||||
class OCI8Exception extends AbstractDriverException
|
||||
{
|
||||
/**
|
||||
* @param mixed[] $error
|
||||
* @param mixed[]|false $error
|
||||
*
|
||||
* @return \Doctrine\DBAL\Driver\OCI8\OCI8Exception
|
||||
* @return OCI8Exception
|
||||
*/
|
||||
public static function fromErrorInfo($error)
|
||||
{
|
||||
if ($error === false) {
|
||||
return new self('Database error occurred but no error information was retrieved from the driver.');
|
||||
}
|
||||
|
||||
return new self($error['message'], null, $error['code']);
|
||||
}
|
||||
}
|
||||
|
@@ -2,30 +2,25 @@
|
||||
|
||||
namespace Doctrine\DBAL\Driver\OCI8;
|
||||
|
||||
use Doctrine\DBAL\Driver\Statement;
|
||||
use Doctrine\DBAL\Driver\FetchUtils;
|
||||
use Doctrine\DBAL\Driver\OCI8\Exception\NonTerminatedStringLiteral;
|
||||
use Doctrine\DBAL\Driver\OCI8\Exception\UnknownParameterIndex;
|
||||
use Doctrine\DBAL\Driver\Result;
|
||||
use Doctrine\DBAL\Driver\Statement as StatementInterface;
|
||||
use Doctrine\DBAL\Driver\StatementIterator;
|
||||
use Doctrine\DBAL\FetchMode;
|
||||
use Doctrine\DBAL\ParameterType;
|
||||
use InvalidArgumentException;
|
||||
use IteratorAggregate;
|
||||
use PDO;
|
||||
use const OCI_ASSOC;
|
||||
use const OCI_B_BIN;
|
||||
use const OCI_B_BLOB;
|
||||
use const OCI_BOTH;
|
||||
use const OCI_D_LOB;
|
||||
use const OCI_FETCHSTATEMENT_BY_COLUMN;
|
||||
use const OCI_FETCHSTATEMENT_BY_ROW;
|
||||
use const OCI_NUM;
|
||||
use const OCI_RETURN_LOBS;
|
||||
use const OCI_RETURN_NULLS;
|
||||
use const OCI_TEMP_BLOB;
|
||||
use const PREG_OFFSET_CAPTURE;
|
||||
use const SQLT_CHR;
|
||||
use ReturnTypeWillChange;
|
||||
|
||||
use function array_key_exists;
|
||||
use function assert;
|
||||
use function count;
|
||||
use function implode;
|
||||
use function is_numeric;
|
||||
use function is_int;
|
||||
use function is_resource;
|
||||
use function oci_bind_by_name;
|
||||
use function oci_cancel;
|
||||
use function oci_error;
|
||||
@@ -39,13 +34,28 @@ use function oci_num_rows;
|
||||
use function oci_parse;
|
||||
use function preg_match;
|
||||
use function preg_quote;
|
||||
use function sprintf;
|
||||
use function substr;
|
||||
|
||||
use const OCI_ASSOC;
|
||||
use const OCI_B_BIN;
|
||||
use const OCI_B_BLOB;
|
||||
use const OCI_BOTH;
|
||||
use const OCI_D_LOB;
|
||||
use const OCI_FETCHSTATEMENT_BY_COLUMN;
|
||||
use const OCI_FETCHSTATEMENT_BY_ROW;
|
||||
use const OCI_NUM;
|
||||
use const OCI_RETURN_LOBS;
|
||||
use const OCI_RETURN_NULLS;
|
||||
use const OCI_TEMP_BLOB;
|
||||
use const PREG_OFFSET_CAPTURE;
|
||||
use const SQLT_CHR;
|
||||
|
||||
/**
|
||||
* The OCI8 implementation of the Statement interface.
|
||||
*
|
||||
* @deprecated Use {@link Statement} instead
|
||||
*/
|
||||
class OCI8Statement implements IteratorAggregate, Statement
|
||||
class OCI8Statement implements IteratorAggregate, StatementInterface, Result
|
||||
{
|
||||
/** @var resource */
|
||||
protected $_dbh;
|
||||
@@ -56,7 +66,11 @@ class OCI8Statement implements IteratorAggregate, Statement
|
||||
/** @var OCI8Connection */
|
||||
protected $_conn;
|
||||
|
||||
/** @var string */
|
||||
/**
|
||||
* @deprecated
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected static $_PARAM = ':param';
|
||||
|
||||
/** @var int[] */
|
||||
@@ -92,16 +106,22 @@ class OCI8Statement implements IteratorAggregate, Statement
|
||||
/**
|
||||
* Creates a new OCI8Statement that uses the given connection handle and SQL statement.
|
||||
*
|
||||
* @param resource $dbh The connection handle.
|
||||
* @param string $statement The SQL statement.
|
||||
* @internal The statement can be only instantiated by its driver connection.
|
||||
*
|
||||
* @param resource $dbh The connection handle.
|
||||
* @param string $query The SQL query.
|
||||
*/
|
||||
public function __construct($dbh, $statement, OCI8Connection $conn)
|
||||
public function __construct($dbh, $query, OCI8Connection $conn)
|
||||
{
|
||||
[$statement, $paramMap] = self::convertPositionalToNamedPlaceholders($statement);
|
||||
$this->_sth = oci_parse($dbh, $statement);
|
||||
$this->_dbh = $dbh;
|
||||
$this->_paramMap = $paramMap;
|
||||
$this->_conn = $conn;
|
||||
[$query, $paramMap] = self::convertPositionalToNamedPlaceholders($query);
|
||||
|
||||
$stmt = oci_parse($dbh, $query);
|
||||
assert(is_resource($stmt));
|
||||
|
||||
$this->_sth = $stmt;
|
||||
$this->_dbh = $dbh;
|
||||
$this->_paramMap = $paramMap;
|
||||
$this->_conn = $conn;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -116,6 +136,8 @@ class OCI8Statement implements IteratorAggregate, Statement
|
||||
* Question marks inside literal strings are therefore handled correctly by this method.
|
||||
* This comes at a cost, the whole sql statement has to be looped over.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @param string $statement The SQL statement to convert.
|
||||
*
|
||||
* @return mixed[] [0] => the statement value (string), [1] => the paramMap value (array).
|
||||
@@ -146,11 +168,8 @@ class OCI8Statement implements IteratorAggregate, Statement
|
||||
}
|
||||
} while ($result);
|
||||
|
||||
if ($currentLiteralDelimiter) {
|
||||
throw new OCI8Exception(sprintf(
|
||||
'The statement contains non-terminated string literal starting at offset %d',
|
||||
$tokenOffset - 1
|
||||
));
|
||||
if ($currentLiteralDelimiter !== null) {
|
||||
throw NonTerminatedStringLiteral::new($tokenOffset - 1);
|
||||
}
|
||||
|
||||
$fragments[] = substr($statement, $fragmentOffset);
|
||||
@@ -163,12 +182,14 @@ class OCI8Statement implements IteratorAggregate, Statement
|
||||
* Finds next placeholder or opening quote.
|
||||
*
|
||||
* @param string $statement The SQL statement to parse
|
||||
* @param string $tokenOffset The offset to start searching from
|
||||
* @param int $tokenOffset The offset to start searching from
|
||||
* @param int $fragmentOffset The offset to build the next fragment from
|
||||
* @param string[] $fragments Fragments of the original statement not containing placeholders
|
||||
* @param string[] $fragments Fragments of the original statement
|
||||
* not containing placeholders
|
||||
* @param string|null $currentLiteralDelimiter The delimiter of the current string literal
|
||||
* or NULL if not currently in a literal
|
||||
* @param array<int, string> $paramMap Mapping of the original parameter positions to their named replacements
|
||||
* @param array<int, string> $paramMap Mapping of the original parameter positions
|
||||
* to their named replacements
|
||||
*
|
||||
* @return bool Whether the token was found
|
||||
*/
|
||||
@@ -207,12 +228,13 @@ class OCI8Statement implements IteratorAggregate, Statement
|
||||
/**
|
||||
* Finds closing quote
|
||||
*
|
||||
* @param string $statement The SQL statement to parse
|
||||
* @param string $tokenOffset The offset to start searching from
|
||||
* @param string|null $currentLiteralDelimiter The delimiter of the current string literal
|
||||
* or NULL if not currently in a literal
|
||||
* @param string $statement The SQL statement to parse
|
||||
* @param int $tokenOffset The offset to start searching from
|
||||
* @param string $currentLiteralDelimiter The delimiter of the current string literal
|
||||
*
|
||||
* @return bool Whether the token was found
|
||||
*
|
||||
* @param-out string|null $currentLiteralDelimiter
|
||||
*/
|
||||
private static function findClosingQuote(
|
||||
$statement,
|
||||
@@ -229,7 +251,7 @@ class OCI8Statement implements IteratorAggregate, Statement
|
||||
return false;
|
||||
}
|
||||
|
||||
$currentLiteralDelimiter = false;
|
||||
$currentLiteralDelimiter = null;
|
||||
++$tokenOffset;
|
||||
|
||||
return true;
|
||||
@@ -240,7 +262,7 @@ class OCI8Statement implements IteratorAggregate, Statement
|
||||
* where the token was found.
|
||||
*
|
||||
* @param string $statement The SQL statement to parse
|
||||
* @param string $offset The offset to start searching from
|
||||
* @param int $offset The offset to start searching from
|
||||
* @param string $regex The regex containing token pattern
|
||||
*
|
||||
* @return string|null Token or NULL if not found
|
||||
@@ -249,6 +271,7 @@ class OCI8Statement implements IteratorAggregate, Statement
|
||||
{
|
||||
if (preg_match($regex, $statement, $matches, PREG_OFFSET_CAPTURE, $offset)) {
|
||||
$offset = $matches[0][1];
|
||||
|
||||
return $matches[0][0];
|
||||
}
|
||||
|
||||
@@ -266,9 +289,15 @@ class OCI8Statement implements IteratorAggregate, Statement
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function bindParam($column, &$variable, $type = ParameterType::STRING, $length = null)
|
||||
public function bindParam($param, &$variable, $type = ParameterType::STRING, $length = null)
|
||||
{
|
||||
$column = $this->_paramMap[$column] ?? $column;
|
||||
if (is_int($param)) {
|
||||
if (! isset($this->_paramMap[$param])) {
|
||||
throw UnknownParameterIndex::new($param);
|
||||
}
|
||||
|
||||
$param = $this->_paramMap[$param];
|
||||
}
|
||||
|
||||
if ($type === ParameterType::LARGE_OBJECT) {
|
||||
$lob = oci_new_descriptor($this->_dbh, OCI_D_LOB);
|
||||
@@ -277,11 +306,11 @@ class OCI8Statement implements IteratorAggregate, Statement
|
||||
$variable =& $lob;
|
||||
}
|
||||
|
||||
$this->boundValues[$column] =& $variable;
|
||||
$this->boundValues[$param] =& $variable;
|
||||
|
||||
return oci_bind_by_name(
|
||||
$this->_sth,
|
||||
$column,
|
||||
$param,
|
||||
$variable,
|
||||
$length ?? -1,
|
||||
$this->convertParameterType($type)
|
||||
@@ -291,7 +320,7 @@ class OCI8Statement implements IteratorAggregate, Statement
|
||||
/**
|
||||
* Converts DBAL parameter type to oci8 parameter type
|
||||
*/
|
||||
private function convertParameterType(int $type) : int
|
||||
private function convertParameterType(int $type): int
|
||||
{
|
||||
switch ($type) {
|
||||
case ParameterType::BINARY:
|
||||
@@ -307,17 +336,12 @@ class OCI8Statement implements IteratorAggregate, Statement
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated Use free() instead.
|
||||
*/
|
||||
public function closeCursor()
|
||||
{
|
||||
// not having the result means there's nothing to close
|
||||
if (! $this->result) {
|
||||
return true;
|
||||
}
|
||||
|
||||
oci_cancel($this->_sth);
|
||||
|
||||
$this->result = false;
|
||||
$this->free();
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -327,11 +351,13 @@ class OCI8Statement implements IteratorAggregate, Statement
|
||||
*/
|
||||
public function columnCount()
|
||||
{
|
||||
return oci_num_fields($this->_sth);
|
||||
return oci_num_fields($this->_sth) ?: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated The error information is available via exceptions.
|
||||
*/
|
||||
public function errorCode()
|
||||
{
|
||||
@@ -345,10 +371,18 @@ class OCI8Statement implements IteratorAggregate, Statement
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated The error information is available via exceptions.
|
||||
*/
|
||||
public function errorInfo()
|
||||
{
|
||||
return oci_error($this->_sth);
|
||||
$error = oci_error($this->_sth);
|
||||
|
||||
if ($error === false) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $error;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -358,8 +392,9 @@ class OCI8Statement implements IteratorAggregate, Statement
|
||||
{
|
||||
if ($params) {
|
||||
$hasZeroIndex = array_key_exists(0, $params);
|
||||
|
||||
foreach ($params as $key => $val) {
|
||||
if ($hasZeroIndex && is_numeric($key)) {
|
||||
if ($hasZeroIndex && is_int($key)) {
|
||||
$this->bindValue($key + 1, $val);
|
||||
} else {
|
||||
$this->bindValue($key, $val);
|
||||
@@ -379,6 +414,8 @@ class OCI8Statement implements IteratorAggregate, Statement
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated Use one of the fetch- or iterate-related methods.
|
||||
*/
|
||||
public function setFetchMode($fetchMode, $arg2 = null, $arg3 = null)
|
||||
{
|
||||
@@ -389,7 +426,10 @@ class OCI8Statement implements IteratorAggregate, Statement
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated Use iterateNumeric(), iterateAssociative() or iterateColumn() instead.
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function getIterator()
|
||||
{
|
||||
return new StatementIterator($this);
|
||||
@@ -397,6 +437,8 @@ class OCI8Statement implements IteratorAggregate, Statement
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated Use fetchNumeric(), fetchAssociative() or fetchOne() instead.
|
||||
*/
|
||||
public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEXT, $cursorOffset = 0)
|
||||
{
|
||||
@@ -428,6 +470,8 @@ class OCI8Statement implements IteratorAggregate, Statement
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated Use fetchAllNumeric(), fetchAllAssociative() or fetchFirstColumn() instead.
|
||||
*/
|
||||
public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = null)
|
||||
{
|
||||
@@ -482,6 +526,8 @@ class OCI8Statement implements IteratorAggregate, Statement
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated Use fetchOne() instead.
|
||||
*/
|
||||
public function fetchColumn($columnIndex = 0)
|
||||
{
|
||||
@@ -505,6 +551,105 @@ class OCI8Statement implements IteratorAggregate, Statement
|
||||
*/
|
||||
public function rowCount()
|
||||
{
|
||||
return oci_num_rows($this->_sth);
|
||||
return oci_num_rows($this->_sth) ?: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchNumeric()
|
||||
{
|
||||
return $this->doFetch(OCI_NUM);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchAssociative()
|
||||
{
|
||||
return $this->doFetch(OCI_ASSOC);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchOne()
|
||||
{
|
||||
return FetchUtils::fetchOne($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchAllNumeric(): array
|
||||
{
|
||||
return $this->doFetchAll(OCI_NUM, OCI_FETCHSTATEMENT_BY_ROW);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchAllAssociative(): array
|
||||
{
|
||||
return $this->doFetchAll(OCI_ASSOC, OCI_FETCHSTATEMENT_BY_ROW);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchFirstColumn(): array
|
||||
{
|
||||
return $this->doFetchAll(OCI_NUM, OCI_FETCHSTATEMENT_BY_COLUMN)[0];
|
||||
}
|
||||
|
||||
public function free(): void
|
||||
{
|
||||
// not having the result means there's nothing to close
|
||||
if (! $this->result) {
|
||||
return;
|
||||
}
|
||||
|
||||
oci_cancel($this->_sth);
|
||||
|
||||
$this->result = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed|false
|
||||
*/
|
||||
private function doFetch(int $mode)
|
||||
{
|
||||
// do not try fetching from the statement if it's not expected to contain the result
|
||||
// in order to prevent exceptional situation
|
||||
if (! $this->result) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return oci_fetch_array(
|
||||
$this->_sth,
|
||||
$mode | OCI_RETURN_NULLS | OCI_RETURN_LOBS
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<mixed>
|
||||
*/
|
||||
private function doFetchAll(int $mode, int $fetchStructure): array
|
||||
{
|
||||
// do not try fetching from the statement if it's not expected to contain the result
|
||||
// in order to prevent exceptional situation
|
||||
if (! $this->result) {
|
||||
return [];
|
||||
}
|
||||
|
||||
oci_fetch_all(
|
||||
$this->_sth,
|
||||
$result,
|
||||
0,
|
||||
-1,
|
||||
$mode | OCI_RETURN_NULLS | $fetchStructure | OCI_RETURN_LOBS
|
||||
);
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
7
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/Statement.php
vendored
Normal file
7
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/Statement.php
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\DBAL\Driver\OCI8;
|
||||
|
||||
final class Statement extends OCI8Statement
|
||||
{
|
||||
}
|
9
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDO/Connection.php
vendored
Normal file
9
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDO/Connection.php
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\DBAL\Driver\PDO;
|
||||
|
||||
use Doctrine\DBAL\Driver\PDOConnection;
|
||||
|
||||
class Connection extends PDOConnection
|
||||
{
|
||||
}
|
20
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDO/Exception.php
vendored
Normal file
20
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDO/Exception.php
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\DBAL\Driver\PDO;
|
||||
|
||||
use Doctrine\DBAL\Driver\PDOException;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @psalm-immutable
|
||||
*/
|
||||
final class Exception extends PDOException
|
||||
{
|
||||
public static function new(\PDOException $exception): self
|
||||
{
|
||||
return new self($exception);
|
||||
}
|
||||
}
|
9
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDO/MySQL/Driver.php
vendored
Normal file
9
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDO/MySQL/Driver.php
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\DBAL\Driver\PDO\MySQL;
|
||||
|
||||
use Doctrine\DBAL\Driver\PDOMySql;
|
||||
|
||||
final class Driver extends PDOMySql\Driver
|
||||
{
|
||||
}
|
9
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDO/OCI/Driver.php
vendored
Normal file
9
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDO/OCI/Driver.php
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\DBAL\Driver\PDO\OCI;
|
||||
|
||||
use Doctrine\DBAL\Driver\PDOOracle;
|
||||
|
||||
final class Driver extends PDOOracle\Driver
|
||||
{
|
||||
}
|
9
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDO/PgSQL/Driver.php
vendored
Normal file
9
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDO/PgSQL/Driver.php
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\DBAL\Driver\PDO\PgSQL;
|
||||
|
||||
use Doctrine\DBAL\Driver\PDOPgSql;
|
||||
|
||||
final class Driver extends PDOPgSql\Driver
|
||||
{
|
||||
}
|
9
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDO/SQLSrv/Connection.php
vendored
Normal file
9
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDO/SQLSrv/Connection.php
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\DBAL\Driver\PDO\SQLSrv;
|
||||
|
||||
use Doctrine\DBAL\Driver\PDOSqlsrv;
|
||||
|
||||
final class Connection extends PDOSqlsrv\Connection
|
||||
{
|
||||
}
|
9
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDO/SQLSrv/Driver.php
vendored
Normal file
9
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDO/SQLSrv/Driver.php
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\DBAL\Driver\PDO\SQLSrv;
|
||||
|
||||
use Doctrine\DBAL\Driver\PDOSqlsrv;
|
||||
|
||||
final class Driver extends PDOSqlsrv\Driver
|
||||
{
|
||||
}
|
9
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDO/SQLSrv/Statement.php
vendored
Normal file
9
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDO/SQLSrv/Statement.php
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\DBAL\Driver\PDO\SQLSrv;
|
||||
|
||||
use Doctrine\DBAL\Driver\PDOSqlsrv;
|
||||
|
||||
final class Statement extends PDOSqlsrv\Statement
|
||||
{
|
||||
}
|
9
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDO/SQLite/Driver.php
vendored
Normal file
9
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDO/SQLite/Driver.php
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\DBAL\Driver\PDO\SQLite;
|
||||
|
||||
use Doctrine\DBAL\Driver\PDOSqlite;
|
||||
|
||||
final class Driver extends PDOSqlite\Driver
|
||||
{
|
||||
}
|
9
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDO/Statement.php
vendored
Normal file
9
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDO/Statement.php
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\DBAL\Driver\PDO;
|
||||
|
||||
use Doctrine\DBAL\Driver\PDOStatement;
|
||||
|
||||
class Statement extends PDOStatement
|
||||
{
|
||||
}
|
@@ -2,18 +2,31 @@
|
||||
|
||||
namespace Doctrine\DBAL\Driver;
|
||||
|
||||
use Doctrine\DBAL\Driver\Connection as ConnectionInterface;
|
||||
use Doctrine\DBAL\Driver\PDO\Exception;
|
||||
use Doctrine\DBAL\Driver\PDO\Statement;
|
||||
use Doctrine\DBAL\ParameterType;
|
||||
use Doctrine\Deprecations\Deprecation;
|
||||
use PDO;
|
||||
use function count;
|
||||
use function func_get_args;
|
||||
use PDOException;
|
||||
use PDOStatement;
|
||||
use ReturnTypeWillChange;
|
||||
|
||||
use function assert;
|
||||
|
||||
/**
|
||||
* PDO implementation of the Connection interface.
|
||||
* Used by all PDO-based drivers.
|
||||
*
|
||||
* @deprecated Use {@link Connection} instead
|
||||
*/
|
||||
class PDOConnection extends PDO implements Connection, ServerInfoAwareConnection
|
||||
class PDOConnection extends PDO implements ConnectionInterface, ServerInfoAwareConnection
|
||||
{
|
||||
use PDOQueryImplementation;
|
||||
|
||||
/**
|
||||
* @internal The connection can be only instantiated by its driver.
|
||||
*
|
||||
* @param string $dsn
|
||||
* @param string|null $user
|
||||
* @param string|null $password
|
||||
@@ -24,23 +37,27 @@ class PDOConnection extends PDO implements Connection, ServerInfoAwareConnection
|
||||
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, []]);
|
||||
parent::__construct($dsn, (string) $user, (string) $password, (array) $options);
|
||||
$this->setAttribute(PDO::ATTR_STATEMENT_CLASS, [Statement::class, []]);
|
||||
$this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
} catch (\PDOException $exception) {
|
||||
throw new PDOException($exception);
|
||||
} catch (PDOException $exception) {
|
||||
throw Exception::new($exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function exec($statement)
|
||||
#[ReturnTypeWillChange]
|
||||
public function exec($sql)
|
||||
{
|
||||
try {
|
||||
return parent::exec($statement);
|
||||
} catch (\PDOException $exception) {
|
||||
throw new PDOException($exception);
|
||||
$result = parent::exec($sql);
|
||||
assert($result !== false);
|
||||
|
||||
return $result;
|
||||
} catch (PDOException $exception) {
|
||||
throw Exception::new($exception);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,61 +70,51 @@ class PDOConnection extends PDO implements Connection, ServerInfoAwareConnection
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @param string $sql
|
||||
* @param array<int, int> $driverOptions
|
||||
*
|
||||
* @return PDOStatement
|
||||
*/
|
||||
public function prepare($prepareString, $driverOptions = [])
|
||||
#[ReturnTypeWillChange]
|
||||
public function prepare($sql, $driverOptions = [])
|
||||
{
|
||||
try {
|
||||
return parent::prepare($prepareString, $driverOptions);
|
||||
} catch (\PDOException $exception) {
|
||||
throw new PDOException($exception);
|
||||
$statement = parent::prepare($sql, $driverOptions);
|
||||
assert($statement instanceof PDOStatement);
|
||||
|
||||
return $statement;
|
||||
} catch (PDOException $exception) {
|
||||
throw Exception::new($exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function query()
|
||||
#[ReturnTypeWillChange]
|
||||
public function quote($value, $type = ParameterType::STRING)
|
||||
{
|
||||
$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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function quote($input, $type = ParameterType::STRING)
|
||||
{
|
||||
return parent::quote($input, $type);
|
||||
return parent::quote($value, $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @param string|null $name
|
||||
*
|
||||
* @return string|int|false
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function lastInsertId($name = null)
|
||||
{
|
||||
try {
|
||||
if ($name === null) {
|
||||
return parent::lastInsertId();
|
||||
}
|
||||
|
||||
return parent::lastInsertId($name);
|
||||
} catch (\PDOException $exception) {
|
||||
throw new PDOException($exception);
|
||||
} catch (PDOException $exception) {
|
||||
throw Exception::new($exception);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,6 +123,28 @@ class PDOConnection extends PDO implements Connection, ServerInfoAwareConnection
|
||||
*/
|
||||
public function requiresQueryForServerVersion()
|
||||
{
|
||||
Deprecation::triggerIfCalledFromOutside(
|
||||
'doctrine/dbal',
|
||||
'https://github.com/doctrine/dbal/pull/4114',
|
||||
'ServerInfoAwareConnection::requiresQueryForServerVersion() is deprecated and removed in DBAL 3.'
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed ...$args
|
||||
*/
|
||||
private function doQuery(...$args): PDOStatement
|
||||
{
|
||||
try {
|
||||
$stmt = parent::query(...$args);
|
||||
} catch (PDOException $exception) {
|
||||
throw Exception::new($exception);
|
||||
}
|
||||
|
||||
assert($stmt instanceof PDOStatement);
|
||||
|
||||
return $stmt;
|
||||
}
|
||||
}
|
||||
|
@@ -2,8 +2,13 @@
|
||||
|
||||
namespace Doctrine\DBAL\Driver;
|
||||
|
||||
use Doctrine\DBAL\Driver\PDO\Exception;
|
||||
use Doctrine\Deprecations\Deprecation;
|
||||
|
||||
/**
|
||||
* Tiny wrapper for PDOException instances to implement the {@link DriverException} interface.
|
||||
* @deprecated Use {@link Exception} instead
|
||||
*
|
||||
* @psalm-immutable
|
||||
*/
|
||||
class PDOException extends \PDOException implements DriverException
|
||||
{
|
||||
@@ -39,6 +44,13 @@ class PDOException extends \PDOException implements DriverException
|
||||
*/
|
||||
public function getErrorCode()
|
||||
{
|
||||
/** @psalm-suppress ImpureMethodCall */
|
||||
Deprecation::triggerIfCalledFromOutside(
|
||||
'doctrine/dbal',
|
||||
'https://github.com/doctrine/dbal/pull/4112',
|
||||
'Driver\AbstractException::getErrorCode() is deprecated, use getSQLState() or getCode() instead.'
|
||||
);
|
||||
|
||||
return $this->errorCode;
|
||||
}
|
||||
|
||||
|
@@ -3,10 +3,13 @@
|
||||
namespace Doctrine\DBAL\Driver\PDOIbm;
|
||||
|
||||
use Doctrine\DBAL\Driver\AbstractDB2Driver;
|
||||
use Doctrine\DBAL\Driver\PDOConnection;
|
||||
use Doctrine\DBAL\Driver\PDO\Connection;
|
||||
use Doctrine\Deprecations\Deprecation;
|
||||
|
||||
/**
|
||||
* Driver for the PDO IBM extension.
|
||||
*
|
||||
* @deprecated Use the driver based on the ibm_db2 extension instead.
|
||||
*/
|
||||
class Driver extends AbstractDB2Driver
|
||||
{
|
||||
@@ -15,7 +18,7 @@ class Driver extends AbstractDB2Driver
|
||||
*/
|
||||
public function connect(array $params, $username = null, $password = null, array $driverOptions = [])
|
||||
{
|
||||
return new PDOConnection(
|
||||
return new Connection(
|
||||
$this->_constructPdoDsn($params),
|
||||
$username,
|
||||
$password,
|
||||
@@ -36,9 +39,11 @@ class Driver extends AbstractDB2Driver
|
||||
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'] . ';';
|
||||
@@ -49,9 +54,17 @@ class Driver extends AbstractDB2Driver
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
Deprecation::trigger(
|
||||
'doctrine/dbal',
|
||||
'https://github.com/doctrine/dbal/issues/3580',
|
||||
'Driver::getName() is deprecated'
|
||||
);
|
||||
|
||||
return 'pdo_ibm';
|
||||
}
|
||||
}
|
||||
|
@@ -2,13 +2,16 @@
|
||||
|
||||
namespace Doctrine\DBAL\Driver\PDOMySql;
|
||||
|
||||
use Doctrine\DBAL\DBALException;
|
||||
use Doctrine\DBAL\Driver\AbstractMySQLDriver;
|
||||
use Doctrine\DBAL\Driver\PDOConnection;
|
||||
use Doctrine\DBAL\Driver\PDO;
|
||||
use Doctrine\DBAL\Exception;
|
||||
use Doctrine\Deprecations\Deprecation;
|
||||
use PDOException;
|
||||
|
||||
/**
|
||||
* PDO MySql driver.
|
||||
*
|
||||
* @deprecated Use {@link PDO\MySQL\Driver} instead.
|
||||
*/
|
||||
class Driver extends AbstractMySQLDriver
|
||||
{
|
||||
@@ -18,14 +21,14 @@ class Driver extends AbstractMySQLDriver
|
||||
public function connect(array $params, $username = null, $password = null, array $driverOptions = [])
|
||||
{
|
||||
try {
|
||||
$conn = new PDOConnection(
|
||||
$conn = new PDO\Connection(
|
||||
$this->constructPdoDsn($params),
|
||||
$username,
|
||||
$password,
|
||||
$driverOptions
|
||||
);
|
||||
} catch (PDOException $e) {
|
||||
throw DBALException::driverException($this, $e);
|
||||
throw Exception::driverException($this, $e);
|
||||
}
|
||||
|
||||
return $conn;
|
||||
@@ -44,15 +47,19 @@ class Driver extends AbstractMySQLDriver
|
||||
if (isset($params['host']) && $params['host'] !== '') {
|
||||
$dsn .= 'host=' . $params['host'] . ';';
|
||||
}
|
||||
|
||||
if (isset($params['port'])) {
|
||||
$dsn .= 'port=' . $params['port'] . ';';
|
||||
}
|
||||
|
||||
if (isset($params['dbname'])) {
|
||||
$dsn .= 'dbname=' . $params['dbname'] . ';';
|
||||
}
|
||||
|
||||
if (isset($params['unix_socket'])) {
|
||||
$dsn .= 'unix_socket=' . $params['unix_socket'] . ';';
|
||||
}
|
||||
|
||||
if (isset($params['charset'])) {
|
||||
$dsn .= 'charset=' . $params['charset'] . ';';
|
||||
}
|
||||
@@ -62,9 +69,17 @@ class Driver extends AbstractMySQLDriver
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
Deprecation::trigger(
|
||||
'doctrine/dbal',
|
||||
'https://github.com/doctrine/dbal/issues/3580',
|
||||
'Driver::getName() is deprecated'
|
||||
);
|
||||
|
||||
return 'pdo_mysql';
|
||||
}
|
||||
}
|
||||
|
@@ -2,18 +2,16 @@
|
||||
|
||||
namespace Doctrine\DBAL\Driver\PDOOracle;
|
||||
|
||||
use Doctrine\DBAL\DBALException;
|
||||
use Doctrine\DBAL\Driver\AbstractOracleDriver;
|
||||
use Doctrine\DBAL\Driver\PDOConnection;
|
||||
use Doctrine\DBAL\Driver\PDO;
|
||||
use Doctrine\DBAL\Exception;
|
||||
use Doctrine\Deprecations\Deprecation;
|
||||
use PDOException;
|
||||
|
||||
/**
|
||||
* PDO Oracle driver.
|
||||
*
|
||||
* WARNING: This driver gives us segfaults in our testsuites on CLOB and other
|
||||
* stuff. PDO Oracle is not maintained by Oracle or anyone in the PHP community,
|
||||
* which leads us to the recommendation to use the "oci8" driver to connect
|
||||
* to Oracle instead.
|
||||
* @deprecated Use {@link PDO\OCI\Driver} instead.
|
||||
*/
|
||||
class Driver extends AbstractOracleDriver
|
||||
{
|
||||
@@ -23,14 +21,14 @@ class Driver extends AbstractOracleDriver
|
||||
public function connect(array $params, $username = null, $password = null, array $driverOptions = [])
|
||||
{
|
||||
try {
|
||||
return new PDOConnection(
|
||||
return new PDO\Connection(
|
||||
$this->constructPdoDsn($params),
|
||||
$username,
|
||||
$password,
|
||||
$driverOptions
|
||||
);
|
||||
} catch (PDOException $e) {
|
||||
throw DBALException::driverException($this, $e);
|
||||
throw Exception::driverException($this, $e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,6 +55,12 @@ class Driver extends AbstractOracleDriver
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
Deprecation::trigger(
|
||||
'doctrine/dbal',
|
||||
'https://github.com/doctrine/dbal/issues/3580',
|
||||
'Driver::getName() is deprecated'
|
||||
);
|
||||
|
||||
return 'pdo_oracle';
|
||||
}
|
||||
}
|
||||
|
@@ -2,15 +2,18 @@
|
||||
|
||||
namespace Doctrine\DBAL\Driver\PDOPgSql;
|
||||
|
||||
use Doctrine\DBAL\DBALException;
|
||||
use Doctrine\DBAL\Driver\AbstractPostgreSQLDriver;
|
||||
use Doctrine\DBAL\Driver\PDOConnection;
|
||||
use PDO;
|
||||
use Doctrine\DBAL\Driver\PDO;
|
||||
use Doctrine\DBAL\Exception;
|
||||
use Doctrine\Deprecations\Deprecation;
|
||||
use PDOException;
|
||||
|
||||
use function defined;
|
||||
|
||||
/**
|
||||
* Driver that connects through pdo_pgsql.
|
||||
*
|
||||
* @deprecated Use {@link PDO\PgSQL\Driver} instead.
|
||||
*/
|
||||
class Driver extends AbstractPostgreSQLDriver
|
||||
{
|
||||
@@ -20,19 +23,20 @@ class Driver extends AbstractPostgreSQLDriver
|
||||
public function connect(array $params, $username = null, $password = null, array $driverOptions = [])
|
||||
{
|
||||
try {
|
||||
$pdo = new PDOConnection(
|
||||
$pdo = new PDO\Connection(
|
||||
$this->_constructPdoDsn($params),
|
||||
$username,
|
||||
$password,
|
||||
$driverOptions
|
||||
);
|
||||
|
||||
if (defined('PDO::PGSQL_ATTR_DISABLE_PREPARES')
|
||||
&& (! isset($driverOptions[PDO::PGSQL_ATTR_DISABLE_PREPARES])
|
||||
|| $driverOptions[PDO::PGSQL_ATTR_DISABLE_PREPARES] === true
|
||||
if (
|
||||
defined('PDO::PGSQL_ATTR_DISABLE_PREPARES')
|
||||
&& (! isset($driverOptions[\PDO::PGSQL_ATTR_DISABLE_PREPARES])
|
||||
|| $driverOptions[\PDO::PGSQL_ATTR_DISABLE_PREPARES] === true
|
||||
)
|
||||
) {
|
||||
$pdo->setAttribute(PDO::PGSQL_ATTR_DISABLE_PREPARES, true);
|
||||
$pdo->setAttribute(\PDO::PGSQL_ATTR_DISABLE_PREPARES, true);
|
||||
}
|
||||
|
||||
/* defining client_encoding via SET NAMES to avoid inconsistent DSN support
|
||||
@@ -45,7 +49,7 @@ class Driver extends AbstractPostgreSQLDriver
|
||||
|
||||
return $pdo;
|
||||
} catch (PDOException $e) {
|
||||
throw DBALException::driverException($this, $e);
|
||||
throw Exception::driverException($this, $e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,9 +112,17 @@ class Driver extends AbstractPostgreSQLDriver
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
Deprecation::trigger(
|
||||
'doctrine/dbal',
|
||||
'https://github.com/doctrine/dbal/issues/3580',
|
||||
'Driver::getName() is deprecated'
|
||||
);
|
||||
|
||||
return 'pdo_pgsql';
|
||||
}
|
||||
}
|
||||
|
41
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOQueryImplementation.php
vendored
Normal file
41
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOQueryImplementation.php
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\DBAL\Driver;
|
||||
|
||||
use PDOStatement;
|
||||
use ReturnTypeWillChange;
|
||||
|
||||
use function func_get_args;
|
||||
|
||||
use const PHP_VERSION_ID;
|
||||
|
||||
if (PHP_VERSION_ID >= 80000) {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
trait PDOQueryImplementation
|
||||
{
|
||||
/**
|
||||
* @return PDOStatement
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function query(?string $query = null, ?int $fetchMode = null, mixed ...$fetchModeArgs)
|
||||
{
|
||||
return $this->doQuery($query, $fetchMode, ...$fetchModeArgs);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
trait PDOQueryImplementation
|
||||
{
|
||||
/**
|
||||
* @return PDOStatement
|
||||
*/
|
||||
public function query()
|
||||
{
|
||||
return $this->doQuery(...func_get_args());
|
||||
}
|
||||
}
|
||||
}
|
@@ -2,15 +2,19 @@
|
||||
|
||||
namespace Doctrine\DBAL\Driver\PDOSqlite;
|
||||
|
||||
use Doctrine\DBAL\DBALException;
|
||||
use Doctrine\DBAL\Driver\AbstractSQLiteDriver;
|
||||
use Doctrine\DBAL\Driver\PDOConnection;
|
||||
use Doctrine\DBAL\Driver\PDO;
|
||||
use Doctrine\DBAL\Exception;
|
||||
use Doctrine\DBAL\Platforms\SqlitePlatform;
|
||||
use Doctrine\Deprecations\Deprecation;
|
||||
use PDOException;
|
||||
|
||||
use function array_merge;
|
||||
|
||||
/**
|
||||
* The PDO Sqlite driver.
|
||||
*
|
||||
* @deprecated Use {@link PDO\SQLite\Driver} instead.
|
||||
*/
|
||||
class Driver extends AbstractSQLiteDriver
|
||||
{
|
||||
@@ -35,14 +39,14 @@ class Driver extends AbstractSQLiteDriver
|
||||
}
|
||||
|
||||
try {
|
||||
$pdo = new PDOConnection(
|
||||
$pdo = new PDO\Connection(
|
||||
$this->_constructPdoDsn($params),
|
||||
$username,
|
||||
$password,
|
||||
$driverOptions
|
||||
);
|
||||
} catch (PDOException $ex) {
|
||||
throw DBALException::driverException($this, $ex);
|
||||
throw Exception::driverException($this, $ex);
|
||||
}
|
||||
|
||||
foreach ($this->_userDefinedFunctions as $fn => $data) {
|
||||
@@ -73,9 +77,17 @@ class Driver extends AbstractSQLiteDriver
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
Deprecation::trigger(
|
||||
'doctrine/dbal',
|
||||
'https://github.com/doctrine/dbal/issues/3580',
|
||||
'Driver::getName() is deprecated'
|
||||
);
|
||||
|
||||
return 'pdo_sqlite';
|
||||
}
|
||||
}
|
||||
|
@@ -2,24 +2,30 @@
|
||||
|
||||
namespace Doctrine\DBAL\Driver\PDOSqlsrv;
|
||||
|
||||
use Doctrine\DBAL\Driver\PDOConnection;
|
||||
use Doctrine\DBAL\ParameterType;
|
||||
use PDO;
|
||||
use function strpos;
|
||||
use function substr;
|
||||
use Doctrine\DBAL\Driver\PDO;
|
||||
use Doctrine\DBAL\Driver\Result;
|
||||
|
||||
/**
|
||||
* Sqlsrv Connection implementation.
|
||||
*
|
||||
* @deprecated Use {@link PDO\SQLSrv\Connection} instead.
|
||||
*/
|
||||
class Connection extends PDOConnection
|
||||
class Connection extends PDO\Connection
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @internal The connection can be only instantiated by its driver.
|
||||
*
|
||||
* @param string $dsn
|
||||
* @param string|null $user
|
||||
* @param string|null $password
|
||||
* @param mixed[]|null $options
|
||||
*/
|
||||
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, []]);
|
||||
$this->setAttribute(\PDO::ATTR_STATEMENT_CLASS, [PDO\SQLSrv\Statement::class, []]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -34,21 +40,10 @@ class Connection extends PDOConnection
|
||||
$stmt = $this->prepare('SELECT CONVERT(VARCHAR(MAX), current_value) FROM sys.sequences WHERE name = ?');
|
||||
$stmt->execute([$name]);
|
||||
|
||||
return $stmt->fetchColumn();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function quote($value, $type = ParameterType::STRING)
|
||||
{
|
||||
$val = parent::quote($value, $type);
|
||||
|
||||
// Fix for a driver version terminating all values with null byte
|
||||
if (strpos($val, "\0") !== false) {
|
||||
$val = substr($val, 0, -1);
|
||||
if ($stmt instanceof Result) {
|
||||
return $stmt->fetchOne();
|
||||
}
|
||||
|
||||
return $val;
|
||||
return $stmt->fetchColumn();
|
||||
}
|
||||
}
|
||||
|
@@ -3,11 +3,17 @@
|
||||
namespace Doctrine\DBAL\Driver\PDOSqlsrv;
|
||||
|
||||
use Doctrine\DBAL\Driver\AbstractSQLServerDriver;
|
||||
use Doctrine\DBAL\Driver\AbstractSQLServerDriver\Exception\PortWithoutHost;
|
||||
use Doctrine\DBAL\Driver\PDO;
|
||||
use Doctrine\Deprecations\Deprecation;
|
||||
|
||||
use function is_int;
|
||||
use function sprintf;
|
||||
|
||||
/**
|
||||
* The PDO-based Sqlsrv driver.
|
||||
*
|
||||
* @deprecated Use {@link PDO\SQLSrv\Driver} instead.
|
||||
*/
|
||||
class Driver extends AbstractSQLServerDriver
|
||||
{
|
||||
@@ -16,13 +22,21 @@ class Driver extends AbstractSQLServerDriver
|
||||
*/
|
||||
public function connect(array $params, $username = null, $password = null, array $driverOptions = [])
|
||||
{
|
||||
[$driverOptions, $connectionOptions] = $this->splitOptions($driverOptions);
|
||||
$pdoOptions = $dsnOptions = [];
|
||||
|
||||
return new Connection(
|
||||
$this->_constructPdoDsn($params, $connectionOptions),
|
||||
foreach ($driverOptions as $option => $value) {
|
||||
if (is_int($option)) {
|
||||
$pdoOptions[$option] = $value;
|
||||
} else {
|
||||
$dsnOptions[$option] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return new PDO\SQLSrv\Connection(
|
||||
$this->_constructPdoDsn($params, $dsnOptions),
|
||||
$username,
|
||||
$password,
|
||||
$driverOptions
|
||||
$pdoOptions
|
||||
);
|
||||
}
|
||||
|
||||
@@ -40,10 +54,12 @@ class Driver extends AbstractSQLServerDriver
|
||||
|
||||
if (isset($params['host'])) {
|
||||
$dsn .= $params['host'];
|
||||
}
|
||||
|
||||
if (isset($params['port']) && ! empty($params['port'])) {
|
||||
$dsn .= ',' . $params['port'];
|
||||
if (isset($params['port'])) {
|
||||
$dsn .= ',' . $params['port'];
|
||||
}
|
||||
} elseif (isset($params['port'])) {
|
||||
throw PortWithoutHost::new();
|
||||
}
|
||||
|
||||
if (isset($params['dbname'])) {
|
||||
@@ -57,35 +73,12 @@ class Driver extends AbstractSQLServerDriver
|
||||
return $dsn . $this->getConnectionOptionsDsn($connectionOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Separates a connection options from a driver options
|
||||
*
|
||||
* @param int[]|string[] $options
|
||||
*
|
||||
* @return int[][]|string[][]
|
||||
*/
|
||||
private function splitOptions(array $options) : array
|
||||
{
|
||||
$driverOptions = [];
|
||||
$connectionOptions = [];
|
||||
|
||||
foreach ($options as $optionKey => $optionValue) {
|
||||
if (is_int($optionKey)) {
|
||||
$driverOptions[$optionKey] = $optionValue;
|
||||
} else {
|
||||
$connectionOptions[$optionKey] = $optionValue;
|
||||
}
|
||||
}
|
||||
|
||||
return [$driverOptions, $connectionOptions];
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a connection options array to the DSN
|
||||
*
|
||||
* @param string[] $connectionOptions
|
||||
*/
|
||||
private function getConnectionOptionsDsn(array $connectionOptions) : string
|
||||
private function getConnectionOptionsDsn(array $connectionOptions): string
|
||||
{
|
||||
$connectionOptionsDsn = '';
|
||||
|
||||
@@ -98,9 +91,17 @@ class Driver extends AbstractSQLServerDriver
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
Deprecation::trigger(
|
||||
'doctrine/dbal',
|
||||
'https://github.com/doctrine/dbal/issues/3580',
|
||||
'Driver::getName() is deprecated'
|
||||
);
|
||||
|
||||
return 'pdo_sqlsrv';
|
||||
}
|
||||
}
|
||||
|
@@ -2,27 +2,38 @@
|
||||
|
||||
namespace Doctrine\DBAL\Driver\PDOSqlsrv;
|
||||
|
||||
use Doctrine\DBAL\Driver\PDOStatement;
|
||||
use Doctrine\DBAL\Driver\PDO;
|
||||
use Doctrine\DBAL\ParameterType;
|
||||
use PDO;
|
||||
|
||||
/**
|
||||
* PDO SQL Server Statement
|
||||
*
|
||||
* @deprecated Use {@link PDO\SQLSrv\Statement} instead.
|
||||
*/
|
||||
class Statement extends PDOStatement
|
||||
class Statement extends PDO\Statement
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function bindParam($column, &$variable, $type = ParameterType::STRING, $length = null, $driverOptions = null)
|
||||
public function bindParam($param, &$variable, $type = ParameterType::STRING, $length = null, $driverOptions = null)
|
||||
{
|
||||
if (($type === ParameterType::LARGE_OBJECT || $type === ParameterType::BINARY)
|
||||
&& $driverOptions === null
|
||||
) {
|
||||
$driverOptions = PDO::SQLSRV_ENCODING_BINARY;
|
||||
switch ($type) {
|
||||
case ParameterType::LARGE_OBJECT:
|
||||
case ParameterType::BINARY:
|
||||
if ($driverOptions === null) {
|
||||
$driverOptions = \PDO::SQLSRV_ENCODING_BINARY;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case ParameterType::ASCII:
|
||||
$type = ParameterType::STRING;
|
||||
$length = 0;
|
||||
$driverOptions = \PDO::SQLSRV_ENCODING_SYSTEM;
|
||||
break;
|
||||
}
|
||||
|
||||
return parent::bindParam($column, $variable, $type, $length, $driverOptions);
|
||||
return parent::bindParam($param, $variable, $type, $length ?? 0, $driverOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -2,23 +2,35 @@
|
||||
|
||||
namespace Doctrine\DBAL\Driver;
|
||||
|
||||
use Doctrine\DBAL\Driver\PDO\Exception;
|
||||
use Doctrine\DBAL\Driver\Statement as StatementInterface;
|
||||
use Doctrine\DBAL\FetchMode;
|
||||
use Doctrine\DBAL\ParameterType;
|
||||
use Doctrine\Deprecations\Deprecation;
|
||||
use PDO;
|
||||
use const E_USER_DEPRECATED;
|
||||
use function sprintf;
|
||||
use function trigger_error;
|
||||
use PDOException;
|
||||
use ReturnTypeWillChange;
|
||||
|
||||
use function array_slice;
|
||||
use function assert;
|
||||
use function func_get_args;
|
||||
use function is_array;
|
||||
|
||||
/**
|
||||
* The PDO implementation of the Statement interface.
|
||||
* Used by all PDO-based drivers.
|
||||
*
|
||||
* @deprecated Use {@link Statement} instead
|
||||
*/
|
||||
class PDOStatement extends \PDOStatement implements Statement
|
||||
class PDOStatement extends \PDOStatement implements StatementInterface, Result
|
||||
{
|
||||
use PDOStatementImplementations;
|
||||
|
||||
private const PARAM_TYPE_MAP = [
|
||||
ParameterType::NULL => PDO::PARAM_NULL,
|
||||
ParameterType::INTEGER => PDO::PARAM_INT,
|
||||
ParameterType::STRING => PDO::PARAM_STR,
|
||||
ParameterType::ASCII => PDO::PARAM_STR,
|
||||
ParameterType::BINARY => PDO::PARAM_LOB,
|
||||
ParameterType::LARGE_OBJECT => PDO::PARAM_LOB,
|
||||
ParameterType::BOOLEAN => PDO::PARAM_BOOL,
|
||||
@@ -35,6 +47,8 @@ class PDOStatement extends \PDOStatement implements Statement
|
||||
|
||||
/**
|
||||
* Protected constructor.
|
||||
*
|
||||
* @internal The statement can be only instantiated by its driver connection.
|
||||
*/
|
||||
protected function __construct()
|
||||
{
|
||||
@@ -43,65 +57,50 @@ class PDOStatement extends \PDOStatement implements Statement
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setFetchMode($fetchMode, $arg2 = null, $arg3 = null)
|
||||
{
|
||||
$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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
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);
|
||||
} catch (PDOException $exception) {
|
||||
throw Exception::new($exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @param mixed $param
|
||||
* @param mixed $variable
|
||||
* @param int $type
|
||||
* @param int|null $length
|
||||
* @param mixed $driverOptions
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function bindParam($column, &$variable, $type = ParameterType::STRING, $length = null, $driverOptions = null)
|
||||
#[ReturnTypeWillChange]
|
||||
public function bindParam($param, &$variable, $type = ParameterType::STRING, $length = null, $driverOptions = null)
|
||||
{
|
||||
$type = $this->convertParamType($type);
|
||||
|
||||
try {
|
||||
return parent::bindParam($column, $variable, $type, $length, $driverOptions);
|
||||
} catch (\PDOException $exception) {
|
||||
throw new PDOException($exception);
|
||||
return parent::bindParam($param, $variable, $type, ...array_slice(func_get_args(), 3));
|
||||
} catch (PDOException $exception) {
|
||||
throw Exception::new($exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated Use free() instead.
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function closeCursor()
|
||||
{
|
||||
try {
|
||||
return parent::closeCursor();
|
||||
} catch (\PDOException $exception) {
|
||||
} catch (PDOException $exception) {
|
||||
// Exceptions not allowed by the interface.
|
||||
// In case driver implementations do not adhere to the interface, silence exceptions here.
|
||||
return true;
|
||||
@@ -111,92 +110,181 @@ class PDOStatement extends \PDOStatement implements Statement
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function execute($params = null)
|
||||
{
|
||||
try {
|
||||
return parent::execute($params);
|
||||
} catch (\PDOException $exception) {
|
||||
throw new PDOException($exception);
|
||||
} catch (PDOException $exception) {
|
||||
throw Exception::new($exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated Use fetchNumeric(), fetchAssociative() or fetchOne() instead.
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEXT, $cursorOffset = 0)
|
||||
{
|
||||
$fetchMode = $this->convertFetchMode($fetchMode);
|
||||
$args = func_get_args();
|
||||
|
||||
if (isset($args[0])) {
|
||||
$args[0] = $this->convertFetchMode($args[0]);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
return parent::fetch($fetchMode, $cursorOrientation, $cursorOffset);
|
||||
} catch (\PDOException $exception) {
|
||||
throw new PDOException($exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = null)
|
||||
{
|
||||
$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 ($ctorArgs === null) {
|
||||
return parent::fetchAll($fetchMode, $fetchArgument);
|
||||
}
|
||||
|
||||
return parent::fetchAll($fetchMode, $fetchArgument, $ctorArgs);
|
||||
} catch (\PDOException $exception) {
|
||||
throw new PDOException($exception);
|
||||
return parent::fetch(...$args);
|
||||
} catch (PDOException $exception) {
|
||||
throw Exception::new($exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated Use fetchOne() instead.
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function fetchColumn($columnIndex = 0)
|
||||
{
|
||||
try {
|
||||
return parent::fetchColumn($columnIndex);
|
||||
} catch (\PDOException $exception) {
|
||||
throw new PDOException($exception);
|
||||
} catch (PDOException $exception) {
|
||||
throw Exception::new($exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchNumeric()
|
||||
{
|
||||
return $this->fetch(PDO::FETCH_NUM);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchAssociative()
|
||||
{
|
||||
return $this->fetch(PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchOne()
|
||||
{
|
||||
return $this->fetch(PDO::FETCH_COLUMN);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchAllNumeric(): array
|
||||
{
|
||||
return $this->fetchAll(PDO::FETCH_NUM);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchAllAssociative(): array
|
||||
{
|
||||
return $this->fetchAll(PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchFirstColumn(): array
|
||||
{
|
||||
return $this->fetchAll(PDO::FETCH_COLUMN);
|
||||
}
|
||||
|
||||
public function free(): void
|
||||
{
|
||||
parent::closeCursor();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed ...$args
|
||||
*/
|
||||
private function doSetFetchMode(int $fetchMode, ...$args): bool
|
||||
{
|
||||
$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.
|
||||
$slice = [];
|
||||
|
||||
foreach ($args as $arg) {
|
||||
if ($arg === null) {
|
||||
break;
|
||||
}
|
||||
|
||||
$slice[] = $arg;
|
||||
}
|
||||
|
||||
try {
|
||||
return parent::setFetchMode($fetchMode, ...$slice);
|
||||
} catch (PDOException $exception) {
|
||||
throw Exception::new($exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed ...$args
|
||||
*
|
||||
* @return mixed[]
|
||||
*/
|
||||
private function doFetchAll(...$args): array
|
||||
{
|
||||
if (isset($args[0])) {
|
||||
$args[0] = $this->convertFetchMode($args[0]);
|
||||
}
|
||||
|
||||
$slice = [];
|
||||
|
||||
foreach ($args as $arg) {
|
||||
if ($arg === null) {
|
||||
break;
|
||||
}
|
||||
|
||||
$slice[] = $arg;
|
||||
}
|
||||
|
||||
try {
|
||||
$data = parent::fetchAll(...$slice);
|
||||
} catch (PDOException $exception) {
|
||||
throw Exception::new($exception);
|
||||
}
|
||||
|
||||
assert(is_array($data));
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts DBAL parameter type to PDO parameter type
|
||||
*
|
||||
* @param int $type Parameter type
|
||||
*/
|
||||
private function convertParamType(int $type) : int
|
||||
private function convertParamType(int $type): int
|
||||
{
|
||||
if (! isset(self::PARAM_TYPE_MAP[$type])) {
|
||||
// TODO: next major: throw an exception
|
||||
@trigger_error(sprintf(
|
||||
'Using a PDO parameter type (%d given) is deprecated and will cause an error in Doctrine 3.0',
|
||||
Deprecation::trigger(
|
||||
'doctrine/dbal',
|
||||
'https://github.com/doctrine/dbal/pull/3088',
|
||||
'Using a PDO parameter type (%d given) is deprecated, ' .
|
||||
'use \Doctrine\DBAL\Types\Types constants instead.',
|
||||
$type
|
||||
), E_USER_DEPRECATED);
|
||||
);
|
||||
|
||||
return $type;
|
||||
}
|
||||
@@ -207,21 +295,18 @@ class PDOStatement extends \PDOStatement implements Statement
|
||||
/**
|
||||
* Converts DBAL fetch mode to PDO fetch mode
|
||||
*
|
||||
* @param int|null $fetchMode Fetch mode
|
||||
* @param int $fetchMode Fetch mode
|
||||
*/
|
||||
private function convertFetchMode(?int $fetchMode) : ?int
|
||||
private function convertFetchMode(int $fetchMode): int
|
||||
{
|
||||
if ($fetchMode === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! isset(self::FETCH_MODE_MAP[$fetchMode])) {
|
||||
// TODO: next major: throw an exception
|
||||
@trigger_error(sprintf(
|
||||
'Using a PDO fetch mode or their combination (%d given)' .
|
||||
' is deprecated and will cause an error in Doctrine 3.0',
|
||||
Deprecation::trigger(
|
||||
'doctrine/dbal',
|
||||
'https://github.com/doctrine/dbal/pull/3088',
|
||||
'Using an unsupported PDO fetch mode or a bitmask of fetch modes (%d given)' .
|
||||
' is deprecated and will cause an error in Doctrine DBAL 3.0',
|
||||
$fetchMode
|
||||
), E_USER_DEPRECATED);
|
||||
);
|
||||
|
||||
return $fetchMode;
|
||||
}
|
||||
|
77
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatementImplementations.php
vendored
Normal file
77
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatementImplementations.php
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\DBAL\Driver;
|
||||
|
||||
use ReturnTypeWillChange;
|
||||
|
||||
use function func_get_args;
|
||||
|
||||
use const PHP_VERSION_ID;
|
||||
|
||||
if (PHP_VERSION_ID >= 80000) {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
trait PDOStatementImplementations
|
||||
{
|
||||
/**
|
||||
* @deprecated Use one of the fetch- or iterate-related methods.
|
||||
*
|
||||
* @param int $mode
|
||||
* @param mixed ...$args
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function setFetchMode($mode, ...$args)
|
||||
{
|
||||
return $this->doSetFetchMode($mode, ...$args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use fetchAllNumeric(), fetchAllAssociative() or fetchFirstColumn() instead.
|
||||
*
|
||||
* @param int|null $mode
|
||||
* @param mixed ...$args
|
||||
*
|
||||
* @return mixed[]
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function fetchAll($mode = null, ...$args)
|
||||
{
|
||||
return $this->doFetchAll($mode, ...$args);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
trait PDOStatementImplementations
|
||||
{
|
||||
/**
|
||||
* @deprecated Use one of the fetch- or iterate-related methods.
|
||||
*
|
||||
* @param int $fetchMode
|
||||
* @param mixed $arg2
|
||||
* @param mixed $arg3
|
||||
*/
|
||||
public function setFetchMode($fetchMode, $arg2 = null, $arg3 = null): bool
|
||||
{
|
||||
return $this->doSetFetchMode(...func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use fetchAllNumeric(), fetchAllAssociative() or fetchFirstColumn() instead.
|
||||
*
|
||||
* @param int|null $fetchMode
|
||||
* @param mixed $fetchArgument
|
||||
* @param mixed $ctorArgs
|
||||
*
|
||||
* @return mixed[]
|
||||
*/
|
||||
public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = null)
|
||||
{
|
||||
return $this->doFetchAll(...func_get_args());
|
||||
}
|
||||
}
|
||||
}
|
@@ -4,6 +4,8 @@ namespace Doctrine\DBAL\Driver;
|
||||
|
||||
/**
|
||||
* An interface for connections which support a "native" ping method.
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
interface PingableConnection
|
||||
{
|
||||
|
89
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Result.php
vendored
Normal file
89
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Result.php
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\DBAL\Driver;
|
||||
|
||||
/**
|
||||
* Driver-level result statement execution result.
|
||||
*/
|
||||
interface Result
|
||||
{
|
||||
/**
|
||||
* Returns the next row of the result as a numeric array or FALSE if there are no more rows.
|
||||
*
|
||||
* @return array<int,mixed>|false
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function fetchNumeric();
|
||||
|
||||
/**
|
||||
* Returns the next row of the result as an associative array or FALSE if there are no more rows.
|
||||
*
|
||||
* @return array<string,mixed>|false
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function fetchAssociative();
|
||||
|
||||
/**
|
||||
* Returns the first value of the next row of the result or FALSE if there are no more rows.
|
||||
*
|
||||
* @return mixed|false
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function fetchOne();
|
||||
|
||||
/**
|
||||
* Returns an array containing all of the result rows represented as numeric arrays.
|
||||
*
|
||||
* @return array<int,array<int,mixed>>
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function fetchAllNumeric(): array;
|
||||
|
||||
/**
|
||||
* Returns an array containing all of the result rows represented as associative arrays.
|
||||
*
|
||||
* @return array<int,array<string,mixed>>
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function fetchAllAssociative(): array;
|
||||
|
||||
/**
|
||||
* Returns an array containing the values of the first column of the result.
|
||||
*
|
||||
* @return array<int,mixed>
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function fetchFirstColumn(): array;
|
||||
|
||||
/**
|
||||
* Returns the number of rows affected by the DELETE, INSERT, or UPDATE statement that produced the result.
|
||||
*
|
||||
* If the statement executed a SELECT query or a similar platform-specific SQL (e.g. DESCRIBE, SHOW, etc.),
|
||||
* some database drivers may return the number of rows returned by that query. However, this behaviour
|
||||
* is not guaranteed for all drivers and should not be relied on in portable applications.
|
||||
*
|
||||
* @return int|string The number of rows.
|
||||
*/
|
||||
public function rowCount();
|
||||
|
||||
/**
|
||||
* Returns the number of columns in the result
|
||||
*
|
||||
* @return int The number of columns in the result. If the columns cannot be counted,
|
||||
* this method must return 0.
|
||||
*/
|
||||
public function columnCount();
|
||||
|
||||
/**
|
||||
* Discards the non-fetched portion of the result, enabling the originating statement to be executed again.
|
||||
*/
|
||||
public function free(): void;
|
||||
}
|
@@ -13,6 +13,8 @@ interface ResultStatement extends Traversable
|
||||
/**
|
||||
* Closes the cursor, enabling the statement to be executed again.
|
||||
*
|
||||
* @deprecated Use Result::free() instead.
|
||||
*
|
||||
* @return bool TRUE on success or FALSE on failure.
|
||||
*/
|
||||
public function closeCursor();
|
||||
@@ -29,7 +31,9 @@ interface ResultStatement extends Traversable
|
||||
/**
|
||||
* 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.
|
||||
* @deprecated Use one of the fetch- or iterate-related methods.
|
||||
*
|
||||
* @param int $fetchMode The fetch mode must be one of the {@link FetchMode} constants.
|
||||
* @param mixed $arg2
|
||||
* @param mixed $arg3
|
||||
*
|
||||
@@ -40,9 +44,11 @@ interface ResultStatement extends Traversable
|
||||
/**
|
||||
* Returns the next row of a result set.
|
||||
*
|
||||
* @deprecated Use fetchNumeric(), fetchAssociative() or fetchOne() instead.
|
||||
*
|
||||
* @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}.
|
||||
* The value must be one of the {@link FetchMode} constants,
|
||||
* defaulting to {@link 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,
|
||||
@@ -67,20 +73,24 @@ interface ResultStatement extends Traversable
|
||||
/**
|
||||
* 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}.
|
||||
* @deprecated Use fetchAllNumeric(), fetchAllAssociative() or fetchFirstColumn() instead.
|
||||
*
|
||||
* @param int|null $fetchMode Controls how the next row will be returned to the caller.
|
||||
* The value must be one of the {@link FetchMode} constants,
|
||||
* defaulting to {@link FetchMode::MIXED}.
|
||||
* @param int|string|null $fetchArgument This argument has a different meaning depending on the value
|
||||
* of the $fetchMode parameter:
|
||||
* * {@link FetchMode::COLUMN}:
|
||||
* Returns the indicated 0-indexed column.
|
||||
* * {@link FetchMode::CUSTOM_OBJECT}:
|
||||
* Returns instances of the specified class, mapping the columns of each row
|
||||
* to named properties in the class.
|
||||
* * {@link 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 FetchMode} constants,
|
||||
* defaulting to {@link FetchMode::MIXED}.
|
||||
*
|
||||
* @return mixed[]
|
||||
*/
|
||||
@@ -89,6 +99,8 @@ interface ResultStatement extends Traversable
|
||||
/**
|
||||
* Returns a single column from the next row of a result set or FALSE if there are no more rows.
|
||||
*
|
||||
* @deprecated Use fetchOne() instead.
|
||||
*
|
||||
* @param int $columnIndex 0-indexed number of the column you wish to retrieve from the row.
|
||||
* If no value is supplied, fetches the first column.
|
||||
*
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user