Unverified Commit 5ceeed8c authored by Sergei Morozov's avatar Sergei Morozov

Merge branch '2.11.x' into 3.0.x

parents 12793ff3 38d4d434
......@@ -337,9 +337,19 @@ Please use other database client applications for import, e.g.:
# Upgrade to 2.11
## Deprecated usage of wrapper-level components as implementations of driver-level interfaces
The usage of the wrapper `Connection` and `Statement` classes as implementations of the `Driver\Connection` and `Driver\Statement` interfaces is deprecated.
## Deprecations in the wrapper `Connection` class
1. The `executeUpdate()` method has been deprecated in favor of `executeStatement()`.
2. The `query()` method has been deprecated in favor of `executeQuery()`.
3. The `exec()` method has been deprecated in favor of `executeStatement()`.
## PDO-related classes outside of the PDO namespace are deprecated
The following outside of the PDO namespace have been deprecated in favor of their counterparts in the PDO namespace:
The following PDO-related classes outside of the PDO namespace have been deprecated in favor of their counterparts in the PDO namespace:
- `PDOMySql\Driver``PDO\MySQL\Driver`
- `PDOOracle\Driver``PDO\OCI\Driver`
......
......@@ -142,7 +142,7 @@ use prepared statements:
SQL query, bind the given params with their binding types and execute the query.
This method returns the executed prepared statement for iteration and is useful
for SELECT statements.
- ``executeUpdate($sql, $params, $types)`` - Create a prepared statement for the passed
- ``executeStatement($sql, $params, $types)`` - Create a prepared statement for the passed
SQL query, bind the given params with their binding types and execute the query.
This method returns the number of affected rows by the executed query and is useful
for UPDATE, DELETE and INSERT statements.
......@@ -170,7 +170,7 @@ of this query using the fetch API of a statement:
The fetch API of a prepared statement obviously works only for ``SELECT`` queries.
If you find it tedious to write all the prepared statement code you can alternatively use
the ``Doctrine\DBAL\Connection#executeQuery()`` and ``Doctrine\DBAL\Connection#executeUpdate()``
the ``Doctrine\DBAL\Connection#executeQuery()`` and ``Doctrine\DBAL\Connection#executeStatement()``
methods. See the API section below on details how to use them.
Additionally there are lots of convenience methods for data-retrieval and manipulation
......@@ -208,7 +208,7 @@ which means this code works independent of the database you are using.
.. note::
Be aware this type conversion only works with ``Statement#bindValue()``,
``Connection#executeQuery()`` and ``Connection#executeUpdate()``. It
``Connection#executeQuery()`` and ``Connection#executeStatement()``. It
is not supported to pass a doctrine type name to ``Statement#bindParam()``,
because this would not work with binding by reference.
......@@ -286,7 +286,7 @@ This is much more complicated and is ugly to write generically.
.. note::
The parameter list support only works with ``Doctrine\DBAL\Connection::executeQuery()``
and ``Doctrine\DBAL\Connection::executeUpdate()``, NOT with the binding methods of
and ``Doctrine\DBAL\Connection::executeStatement()``, NOT with the binding methods of
a prepared statement.
API
......@@ -319,7 +319,7 @@ Prepare a given SQL statement and return the
)
*/
executeUpdate()
executeStatement()
~~~~~~~~~~~~~~~
Executes a prepared statement with the given SQL and parameters and
......@@ -328,7 +328,7 @@ returns the affected rows count:
.. code-block:: php
<?php
$count = $conn->executeUpdate('UPDATE user SET username = ? WHERE id = ?', array('jwage', 1));
$count = $conn->executeStatement('UPDATE user SET username = ? WHERE id = ?', array('jwage', 1));
echo $count; // 1
The ``$types`` variable contains the PDO or Doctrine Type constants
......
......@@ -135,7 +135,7 @@ are using just the DBAL there are also helper methods which simplify the usage q
$sql = "SELECT * FROM users WHERE username = ?";
$stmt = $connection->executeQuery($sql, array($_GET['username']));
There is also ``executeUpdate`` which does not return a statement but the number of affected rows.
There is also ``executeStatement`` which does not return a statement but the number of affected rows.
Besides binding parameters you can also pass the type of the variable. This allows Doctrine or the underlying
vendor to not only escape but also cast the value to the correct type. See the docs on querying and DQL in the
......
......@@ -605,7 +605,7 @@ class Connection
$this->addIdentifierCondition($identifier, $columns, $values, $conditions);
return $this->executeUpdate(
return $this->executeStatement(
'DELETE FROM ' . $tableExpression . ' WHERE ' . implode(' AND ', $conditions),
$values,
is_string(key($types)) ? $this->extractTypeValues($columns, $types) : $types
......@@ -635,7 +635,7 @@ class Connection
{
$this->transactionIsolationLevel = $level;
return $this->executeUpdate($this->getDatabasePlatform()->getSetTransactionIsolationSQL($level));
return $this->executeStatement($this->getDatabasePlatform()->getSetTransactionIsolationSQL($level));
}
/**
......@@ -687,7 +687,7 @@ class Connection
$sql = 'UPDATE ' . $tableExpression . ' SET ' . implode(', ', $set)
. ' WHERE ' . implode(' AND ', $conditions);
return $this->executeUpdate($sql, $values, $types);
return $this->executeStatement($sql, $values, $types);
}
/**
......@@ -706,7 +706,7 @@ class Connection
public function insert($tableExpression, array $data, array $types = [])
{
if (count($data) === 0) {
return $this->executeUpdate('INSERT INTO ' . $tableExpression . ' () VALUES ()');
return $this->executeStatement('INSERT INTO ' . $tableExpression . ' () VALUES ()');
}
$columns = [];
......@@ -719,7 +719,7 @@ class Connection
$set[] = '?';
}
return $this->executeUpdate(
return $this->executeStatement(
'INSERT INTO ' . $tableExpression . ' (' . implode(', ', $columns) . ')' .
' VALUES (' . implode(', ', $set) . ')',
$values,
......@@ -1029,6 +1029,8 @@ class Connection
}
/**
* @deprecated Use {@link executeQuery()} instead.
*
* @throws DBALException
*/
public function query(string $sql): DriverResult
......@@ -1055,6 +1057,8 @@ class Connection
* Executes an SQL INSERT/UPDATE/DELETE query with the given parameters
* and returns the number of affected rows.
*
* @deprecated Use {@link executeStatement()} instead.
*
* @param string $query The SQL query.
* @param array<mixed> $params The query parameters.
* @param array<int|string|null> $types The parameter types.
......@@ -1062,19 +1066,44 @@ class Connection
* @throws DBALException
*/
public function executeUpdate(string $query, array $params = [], array $types = []): int
{
return $this->executeStatement($query, $params, $types);
}
/**
* Executes an SQL statement with the given parameters and returns the number of affected rows.
*
* Could be used for:
* - DML statements: INSERT, UPDATE, DELETE, etc.
* - DDL statements: CREATE, DROP, ALTER, etc.
* - DCL statements: GRANT, REVOKE, etc.
* - Session control statements: ALTER SESSION, SET, DECLARE, etc.
* - Other statements that don't yield a row set.
*
* This method supports PDO binding types as well as DBAL mapping types.
*
* @param string $sql The statement SQL
* @param array<mixed> $params The query parameters
* @param array<int|string|null> $types The parameter types
*
* @return int The number of affected rows.
*
* @throws DBALException
*/
public function executeStatement($sql, array $params = [], array $types = [])
{
$connection = $this->getWrappedConnection();
$logger = $this->_config->getSQLLogger();
if ($logger !== null) {
$logger->startQuery($query, $params, $types);
$logger->startQuery($sql, $params, $types);
}
try {
if (count($params) > 0) {
[$query, $params, $types] = SQLParserUtils::expandListParameters($query, $params, $types);
[$sql, $params, $types] = SQLParserUtils::expandListParameters($sql, $params, $types);
$stmt = $connection->prepare($query);
$stmt = $connection->prepare($sql);
if (count($types) > 0) {
$this->_bindTypedValues($stmt, $params, $types);
......@@ -1087,9 +1116,9 @@ class Connection
return $result->rowCount();
}
return $connection->exec($query);
return $connection->exec($sql);
} catch (DriverException $e) {
throw $this->convertExceptionDuringQuery($e, $query, $params, $types);
throw $this->convertExceptionDuringQuery($e, $sql, $params, $types);
} finally {
if ($logger !== null) {
$logger->stopQuery();
......@@ -1098,6 +1127,8 @@ class Connection
}
/**
* @deprecated Use {@link executeStatement()} instead.
*
* @throws DBALException
*/
public function exec(string $statement): int
......
......@@ -30,7 +30,7 @@ use function func_get_args;
*
* 1. Replica if primary was never picked before and ONLY if 'getWrappedConnection'
* or 'executeQuery' is used.
* 2. Primary picked when 'exec', 'executeUpdate', 'insert', 'delete', 'update', 'createSavepoint',
* 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.
......@@ -45,7 +45,7 @@ use function func_get_args;
* Be aware that Connection#executeQuery is a method specifically for READ
* operations only.
*
* Use Connection#executeUpdate for any SQL statement that changes/updates
* 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
......@@ -262,6 +262,8 @@ class PrimaryReadReplicaConnection extends Connection
/**
* {@inheritDoc}
*
* @deprecated Use {@link executeStatement()} instead.
*/
public function executeUpdate(string $query, array $params = [], array $types = []): int
{
......@@ -270,6 +272,16 @@ class PrimaryReadReplicaConnection extends Connection
return parent::executeUpdate($query, $params, $types);
}
/**
* {@inheritDoc}
*/
public function executeStatement($query, array $params = [], array $types = [])
{
$this->ensureConnectedToPrimary();
return parent::executeStatement($query, $params, $types);
}
/**
* {@inheritDoc}
*/
......
......@@ -64,7 +64,7 @@ class OracleSessionInit implements EventSubscriber
}
$sql = 'ALTER SESSION SET ' . implode(' ', $vars);
$args->getConnection()->executeUpdate($sql);
$args->getConnection()->executeStatement($sql);
}
/**
......
......@@ -131,7 +131,7 @@ class TableGenerator
$sql = 'UPDATE ' . $this->generatorTableName . ' ' .
'SET sequence_value = sequence_value + sequence_increment_by ' .
'WHERE sequence_name = ? AND sequence_value = ?';
$rows = $this->conn->executeUpdate($sql, [$sequenceName, $row['sequence_value']]);
$rows = $this->conn->executeStatement($sql, [$sequenceName, $row['sequence_value']]);
if ($rows !== 1) {
throw new DBALException('Race-condition detected while updating sequence. Aborting generation');
......
......@@ -199,9 +199,6 @@ class QueryBuilder
/**
* Executes this query using the bound parameters and their types.
*
* Uses {@see Connection::executeQuery} for select statements and {@see Connection::executeUpdate}
* for insert, update and delete statements.
*
* @return Result|int
*
* @throws DBALException
......@@ -212,7 +209,7 @@ class QueryBuilder
return $this->connection->executeQuery($this->getSQL(), $this->params, $this->paramTypes);
}
return $this->connection->executeUpdate($this->getSQL(), $this->params, $this->paramTypes);
return $this->connection->executeStatement($this->getSQL(), $this->params, $this->paramTypes);
}
/**
......
......@@ -1036,7 +1036,7 @@ abstract class AbstractSchemaManager
protected function _execSql($sql)
{
foreach ((array) $sql as $query) {
$this->_conn->executeUpdate($query);
$this->_conn->executeStatement($query);
}
}
......
......@@ -287,10 +287,10 @@ class OracleSchemaManager extends AbstractSchemaManager
$password = $params['password'];
$query = 'CREATE USER ' . $username . ' IDENTIFIED BY ' . $password;
$this->_conn->executeUpdate($query);
$this->_conn->executeStatement($query);
$query = 'GRANT DBA TO ' . $username;
$this->_conn->executeUpdate($query);
$this->_conn->executeStatement($query);
}
/**
......@@ -306,7 +306,7 @@ class OracleSchemaManager extends AbstractSchemaManager
$sql = $this->_platform->getDropAutoincrementSql($table);
foreach ($sql as $query) {
$this->_conn->executeUpdate($query);
$this->_conn->executeStatement($query);
}
return true;
......
......@@ -85,7 +85,7 @@ EOT
if (stripos($sql, 'select') === 0 || $forceFetch) {
$resultSet = $conn->fetchAllAssociative($sql);
} else {
$resultSet = $conn->executeUpdate($sql);
$resultSet = $conn->executeStatement($sql);
}
$output->write(Dumper::dump($resultSet, (int) $depth));
......
......@@ -20,13 +20,13 @@ final class LoggingTest extends TestCase
->executeQuery('SELECT * FROM table');
}
public function testLogExecuteUpdate(): void
public function testLogExecuteStatement(): void
{
$this->createConnection(
$this->createStub(DriverConnection::class),
'UPDATE table SET foo = ?'
)
->executeUpdate('UPDATE table SET foo = ?');
->executeStatement('UPDATE table SET foo = ?');
}
public function testLogPrepareExecute(): void
......
......@@ -49,7 +49,7 @@ class ConnectionTest extends TestCase
/**
* @return Connection|MockObject
*/
private function getExecuteUpdateMockConnection()
private function getExecuteStatementMockConnection()
{
$driverMock = $this->createMock(Driver::class);
......@@ -62,7 +62,7 @@ class ConnectionTest extends TestCase
$platform = $this->getMockForAbstractClass(AbstractPlatform::class);
return $this->getMockBuilder(Connection::class)
->onlyMethods(['executeUpdate'])
->onlyMethods(['executeStatement'])
->setConstructorArgs([['platform' => $platform], $driverMock])
->getMock();
}
......@@ -192,9 +192,9 @@ class ConnectionTest extends TestCase
},
];
yield 'executeUpdate' => [
yield 'executeStatement' => [
static function (Connection $connection, string $statement): void {
$connection->executeUpdate($statement);
$connection->executeStatement($statement);
},
];
......@@ -357,10 +357,10 @@ class ConnectionTest extends TestCase
public function testEmptyInsert(): void
{
$conn = $this->getExecuteUpdateMockConnection();
$conn = $this->getExecuteStatementMockConnection();
$conn->expects(self::once())
->method('executeUpdate')
->method('executeStatement')
->with('INSERT INTO footable () VALUES ()');
$conn->insert('footable', []);
......@@ -371,10 +371,10 @@ class ConnectionTest extends TestCase
*/
public function testUpdateWithDifferentColumnsInDataAndIdentifiers(): void
{
$conn = $this->getExecuteUpdateMockConnection();
$conn = $this->getExecuteStatementMockConnection();
$conn->expects(self::once())
->method('executeUpdate')
->method('executeStatement')
->with(
'UPDATE TestTable SET text = ?, is_edited = ? WHERE id = ? AND name = ?',
[
......@@ -415,10 +415,10 @@ class ConnectionTest extends TestCase
*/
public function testUpdateWithSameColumnInDataAndIdentifiers(): void
{
$conn = $this->getExecuteUpdateMockConnection();
$conn = $this->getExecuteStatementMockConnection();
$conn->expects(self::once())
->method('executeUpdate')
->method('executeStatement')
->with(
'UPDATE TestTable SET text = ?, is_edited = ? WHERE id = ? AND is_edited = ?',
[
......@@ -458,10 +458,10 @@ class ConnectionTest extends TestCase
*/
public function testUpdateWithIsNull(): void
{
$conn = $this->getExecuteUpdateMockConnection();
$conn = $this->getExecuteStatementMockConnection();
$conn->expects(self::once())
->method('executeUpdate')
->method('executeStatement')
->with(
'UPDATE TestTable SET text = ?, is_edited = ? WHERE id IS NULL AND name = ?',
[
......@@ -500,10 +500,10 @@ class ConnectionTest extends TestCase
*/
public function testDeleteWithIsNull(): void
{
$conn = $this->getExecuteUpdateMockConnection();
$conn = $this->getExecuteStatementMockConnection();
$conn->expects(self::once())
->method('executeUpdate')
->method('executeStatement')
->with(
'DELETE FROM TestTable WHERE id IS NULL AND name = ?',
['foo'],
......
......@@ -16,7 +16,7 @@ class OracleSessionInitTest extends TestCase
{
$connectionMock = $this->createMock(Connection::class);
$connectionMock->expects(self::once())
->method('executeUpdate')
->method('executeStatement')
->with(self::isType('string'));
$eventArgs = new ConnectionEventArgs($connectionMock);
......@@ -35,7 +35,7 @@ class OracleSessionInitTest extends TestCase
->disableOriginalConstructor()
->getMock();
$connectionMock->expects(self::once())
->method('executeUpdate')
->method('executeStatement')
->with(self::stringContains(sprintf('%s = %s', $name, $value)));
$eventArgs = new ConnectionEventArgs($connectionMock);
......
......@@ -302,12 +302,12 @@ class DataAccessTest extends FunctionalTestCase
/**
* @group DDC-697
*/
public function testExecuteUpdateBindDateTimeType(): void
public function testExecuteStatementBindDateTimeType(): void
{
$datetime = new DateTime('2010-02-02 20:20:20');
$sql = 'INSERT INTO fetch_table (test_int, test_string, test_datetime) VALUES (?, ?, ?)';
$affectedRows = $this->connection->executeUpdate($sql, [
$affectedRows = $this->connection->executeStatement($sql, [
1 => 50,
2 => 'foo',
3 => $datetime,
......@@ -595,7 +595,7 @@ class DataAccessTest extends FunctionalTestCase
public function testFetchAllStyleColumn(): void
{
$sql = 'DELETE FROM fetch_table';
$this->connection->executeUpdate($sql);
$this->connection->executeStatement($sql);
$this->connection->insert('fetch_table', ['test_int' => 1, 'test_string' => 'foo']);
$this->connection->insert('fetch_table', ['test_int' => 10, 'test_string' => 'foo']);
......
......@@ -40,7 +40,7 @@ class ConnectionTest extends FunctionalTestCase
$schemaManager->dropAndCreateTable($table);
$this->connection->executeUpdate('INSERT INTO DBAL2595 (foo) VALUES (1)');
$this->connection->executeStatement('INSERT INTO DBAL2595 (foo) VALUES (1)');
$schema = $this->connection->getDatabase();
$sequence = $platform->getIdentitySequenceName($schema . '.DBAL2595', 'id');
......
......@@ -207,7 +207,7 @@ class ExceptionTest extends FunctionalTestCase
$this->expectException(Exception\ForeignKeyConstraintViolationException::class);
try {
$this->connection->executeUpdate($platform->getTruncateTableSQL('constraint_error_table'));
$this->connection->executeStatement($platform->getTruncateTableSQL('constraint_error_table'));
} catch (Exception\ForeignKeyConstraintViolationException $exception) {
$this->tearDownForeignKeyConstraintViolationExceptionTest();
......
......@@ -42,7 +42,7 @@ class PrimaryReadReplicaConnectionTest extends FunctionalTestCase
} catch (Throwable $e) {
}
$this->connection->executeUpdate('DELETE FROM primary_replica_table');
$this->connection->executeStatement('DELETE FROM primary_replica_table');
$this->connection->insert('primary_replica_table', ['test_int' => 1]);
}
......
......@@ -458,7 +458,7 @@ class MySqlSchemaManagerTest extends SchemaManagerFunctionalTestCase
$this->schemaManager->dropAndCreateTable($table);
$this->connection->executeUpdate(
$this->connection->executeStatement(
'INSERT INTO test_column_defaults_are_valid () VALUES()'
);
......
......@@ -219,7 +219,7 @@ abstract class SchemaManagerFunctionalTestCase extends FunctionalTestCase
$namespaces = array_map('strtolower', $namespaces);
if (! in_array('test_create_schema', $namespaces, true)) {
$this->connection->executeUpdate($this->schemaManager->getDatabasePlatform()->getCreateSchemaSQL('test_create_schema'));
$this->connection->executeStatement($this->schemaManager->getDatabasePlatform()->getCreateSchemaSQL('test_create_schema'));
$namespaces = $this->schemaManager->listNamespaceNames();
$namespaces = array_map('strtolower', $namespaces);
......
......@@ -46,7 +46,7 @@ class TemporaryTableTest extends FunctionalTestCase
$createTempTableSQL = $platform->getCreateTemporaryTableSnippetSQL() . ' ' . $tempTable . ' ('
. $platform->getColumnDeclarationListSQL($columnDefinitions) . ')';
$this->connection->executeUpdate($createTempTableSQL);
$this->connection->executeStatement($createTempTableSQL);
$table = new Table('nontemporary');
$table->addColumn('id', 'integer');
......
......@@ -47,7 +47,7 @@ class DBAL630Test extends FunctionalTestCase
public function testBooleanConversionSqlLiteral(): void
{
$this->connection->executeUpdate('INSERT INTO dbal630 (bool_col) VALUES(false)');
$this->connection->executeStatement('INSERT INTO dbal630 (bool_col) VALUES(false)');
$id = $this->connection->lastInsertId('dbal630_id_seq');
self::assertNotEmpty($id);
......@@ -58,7 +58,7 @@ class DBAL630Test extends FunctionalTestCase
public function testBooleanConversionBoolParamRealPrepares(): void
{
$this->connection->executeUpdate(
$this->connection->executeStatement(
'INSERT INTO dbal630 (bool_col) VALUES(?)',
['false'],
[ParameterType::BOOLEAN]
......
......@@ -32,39 +32,39 @@ class WriteTest extends FunctionalTestCase
} catch (Throwable $e) {
}
$this->connection->executeUpdate('DELETE FROM write_table');
$this->connection->executeStatement('DELETE FROM write_table');
}
/**
* @group DBAL-80
*/
public function testExecuteUpdateFirstTypeIsNull(): void
public function testExecuteStatementFirstTypeIsNull(): void
{
$sql = 'INSERT INTO write_table (test_string, test_int) VALUES (?, ?)';
$this->connection->executeUpdate($sql, ['text', 1111], [null, ParameterType::INTEGER]);
$this->connection->executeStatement($sql, ['text', 1111], [null, ParameterType::INTEGER]);
$sql = 'SELECT * FROM write_table WHERE test_string = ? AND test_int = ?';
self::assertTrue((bool) $this->connection->fetchFirstColumn($sql, ['text', 1111]));
}
public function testExecuteUpdate(): void
public function testExecuteStatement(): void
{
$sql = 'INSERT INTO write_table (test_int) VALUES ( ' . $this->connection->quote(1) . ')';
$affected = $this->connection->executeUpdate($sql);
$affected = $this->connection->executeStatement($sql);
self::assertEquals(1, $affected, 'executeUpdate() should return the number of affected rows!');
self::assertEquals(1, $affected, 'executeStatement() should return the number of affected rows!');
}
public function testExecuteUpdateWithTypes(): void
public function testExecuteStatementWithTypes(): void
{
$sql = 'INSERT INTO write_table (test_int, test_string) VALUES (?, ?)';
$affected = $this->connection->executeUpdate(
$affected = $this->connection->executeStatement(
$sql,
[1, 'foo'],
[ParameterType::INTEGER, ParameterType::STRING]
);
self::assertEquals(1, $affected, 'executeUpdate() should return the number of affected rows!');
self::assertEquals(1, $affected, 'executeStatement() should return the number of affected rows!');
}
public function testPrepareRowCountReturnsAffectedRows(): void
......
......@@ -76,7 +76,7 @@ class RunSqlCommandTest extends TestCase
public function testUpdateStatementsPrintsAffectedLines(): void
{
$this->expectConnectionExecuteUpdate();
$this->expectConnectionExecuteStatement();
$this->commandTester->execute([
'command' => $this->command->getName(),
......@@ -87,11 +87,11 @@ class RunSqlCommandTest extends TestCase
self::assertDoesNotMatchRegularExpression('@array.*1.*@', $this->commandTester->getDisplay());
}
private function expectConnectionExecuteUpdate(): void
private function expectConnectionExecuteStatement(): void
{
$this->connectionMock
->expects(self::once())
->method('executeUpdate')
->method('executeStatement')
->willReturn(42);
$this->connectionMock
......@@ -108,7 +108,7 @@ class RunSqlCommandTest extends TestCase
$this->connectionMock
->expects(self::never())
->method('executeUpdate');
->method('executeStatement');
}
public function testStatementsWithFetchResultPrintsResult(): void
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment