Skip to content

Commit

Permalink
Merge pull request #2996 from morozov/issues/2953-2.x
Browse files Browse the repository at this point in the history
Forward compatibility with 3.x
  • Loading branch information
Ocramius authored Feb 1, 2018
2 parents d9aaf54 + be4253f commit e5fe8c8
Show file tree
Hide file tree
Showing 74 changed files with 1,414 additions and 802 deletions.
9 changes: 9 additions & 0 deletions UPGRADE.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,15 @@

``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`
Expand Down
18 changes: 14 additions & 4 deletions docs/en/reference/data-retrieval-and-manipulation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -180,13 +180,13 @@ Binding Types
-------------

Doctrine DBAL extends PDOs handling of binding types in prepared statements
considerably. Besides the well known ``\PDO::PARAM_*`` constants you
considerably. Besides ``Doctrine\DBAL\ParameterType`` constants, you
can make use of two very powerful additional features.

Doctrine\DBAL\Types Conversion
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If you don't specify an integer (through a ``PDO::PARAM*`` constant) to
If you don't specify an integer (through one of ``Doctrine\DBAL\ParameterType`` constants) to
any of the parameter binding methods but a string, Doctrine DBAL will
ask the type abstraction layer to convert the passed value from
its PHP to a database representation. This way you can pass ``\DateTime``
Expand Down Expand Up @@ -271,7 +271,14 @@ be specified as well:
// Same SQL WITHOUT usage of Doctrine\DBAL\Connection::PARAM_INT_ARRAY
$stmt = $conn->executeQuery('SELECT * FROM articles WHERE id IN (?, ?, ?, ?, ?, ?)',
array(1, 2, 3, 4, 5, 6),
array(\PDO::PARAM_INT, \PDO::PARAM_INT, \PDO::PARAM_INT, \PDO::PARAM_INT, \PDO::PARAM_INT, \PDO::PARAM_INT)
array(
ParameterType::INTEGER,
ParameterType::INTEGER,
ParameterType::INTEGER,
ParameterType::INTEGER,
ParameterType::INTEGER,
ParameterType::INTEGER,
)
);
This is much more complicated and is ugly to write generically.
Expand Down Expand Up @@ -469,8 +476,11 @@ Quote a value:
.. code-block:: php
<?php
use Doctrine\DBAL\ParameterType;
$quoted = $conn->quote('value');
$quoted = $conn->quote('1234', \PDO::PARAM_INT);
$quoted = $conn->quote('1234', ParameterType::INTEGER);
quoteIdentifier()
~~~~~~~~~~~~~~~~~
Expand Down
2 changes: 1 addition & 1 deletion docs/en/reference/known-vendor-issues.rst
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,6 @@ The ``PDO_SQLSRV`` driver currently has a bug when binding values to
VARBINARY/BLOB columns with ``bindValue`` in prepared statements.
This raises an implicit conversion from data type error as it tries
to convert a character type value to a binary type value even if
you explicitly define the value as ``\PDO::PARAM_LOB`` type.
you explicitly define the value as ``ParameterType::LARGE_OBJECT`` type.
Therefore it is highly encouraged to use the native ``sqlsrv``
driver instead which does not have this limitation.
12 changes: 8 additions & 4 deletions docs/en/reference/portability.rst
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,16 @@ Using the following code block in your initialization will:
.. code-block:: php
<?php
use Doctrine\DBAL\ColumnCase;
use Doctrine\DBAL\Portability\Connection as PortableConnection;
$params = array(
// vendor specific configuration
//...
'wrapperClass' => 'Doctrine\DBAL\Portability\Connection',
'portability' => \Doctrine\DBAL\Portability\Connection::PORTABILITY_ALL,
'fetch_case' => \PDO::CASE_LOWER,
'wrapperClass' => PortableConnection::class,
'portability' => PortableConnection::PORTABILITY_ALL,
'fetch_case' => ColumnCase::LOWER,
);
This sort of portability handling is pretty expensive because all the result
Expand All @@ -80,4 +84,4 @@ This functionality is only implemented with Doctrine 2.1 upwards.
Doctrine ships with lists of keywords for every supported vendor. You
can access a keyword list through the schema manager of the vendor you
are currently using or just instantiating it from the ``Doctrine\DBAL\Platforms\Keywords``
namespace.
namespace.
4 changes: 2 additions & 2 deletions docs/en/reference/security.rst
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ the ``Connection#quote`` method:
<?php
// Parameter quoting
$sql = "SELECT * FROM users WHERE name = " . $connection->quote($_GET['username'], \PDO::PARAM_STR);
$sql = "SELECT * FROM users WHERE name = " . $connection->quote($_GET['username']);
This method is only available for SQL, not for DQL. For DQL you are always encouraged to use prepared
statements not only for security, but also for caching reasons.
statements not only for security, but also for caching reasons.
43 changes: 25 additions & 18 deletions lib/Doctrine/DBAL/Cache/ArrayStatement.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
namespace Doctrine\DBAL\Cache;

use Doctrine\DBAL\Driver\ResultStatement;
use PDO;
use Doctrine\DBAL\FetchMode;

class ArrayStatement implements \IteratorAggregate, ResultStatement
{
Expand All @@ -42,7 +42,7 @@ class ArrayStatement implements \IteratorAggregate, ResultStatement
/**
* @var int
*/
private $defaultFetchMode = PDO::FETCH_BOTH;
private $defaultFetchMode = FetchMode::MIXED;

/**
* @param array $data
Expand Down Expand Up @@ -100,23 +100,30 @@ public function getIterator()
*/
public function fetch($fetchMode = null, $cursorOrientation = \PDO::FETCH_ORI_NEXT, $cursorOffset = 0)
{
if (isset($this->data[$this->num])) {
$row = $this->data[$this->num++];
$fetchMode = $fetchMode ?: $this->defaultFetchMode;
if ($fetchMode === PDO::FETCH_ASSOC) {
return $row;
} elseif ($fetchMode === PDO::FETCH_NUM) {
return array_values($row);
} elseif ($fetchMode === PDO::FETCH_BOTH) {
return array_merge($row, array_values($row));
} elseif ($fetchMode === PDO::FETCH_COLUMN) {
return reset($row);
} else {
throw new \InvalidArgumentException("Invalid fetch-style given for fetching result.");
}
if (! isset($this->data[$this->num])) {
return false;
}

return false;
$row = $this->data[$this->num++];
$fetchMode = $fetchMode ?: $this->defaultFetchMode;

if ($fetchMode === FetchMode::ASSOCIATIVE) {
return $row;
}

if ($fetchMode === FetchMode::NUMERIC) {
return array_values($row);
}

if ($fetchMode === FetchMode::MIXED) {
return array_merge($row, array_values($row));
}

if ($fetchMode === FetchMode::COLUMN) {
return reset($row);
}

throw new \InvalidArgumentException('Invalid fetch-style given for fetching result.');
}

/**
Expand All @@ -137,7 +144,7 @@ public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = n
*/
public function fetchColumn($columnIndex = 0)
{
$row = $this->fetch(PDO::FETCH_NUM);
$row = $this->fetch(FetchMode::NUMERIC);

// TODO: verify that return false is the correct behavior
return $row[$columnIndex] ?? false;
Expand Down
28 changes: 18 additions & 10 deletions lib/Doctrine/DBAL/Cache/ResultCacheStatement.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
use Doctrine\DBAL\Driver\Statement;
use Doctrine\DBAL\Driver\ResultStatement;
use Doctrine\Common\Cache\Cache;
use PDO;
use Doctrine\DBAL\FetchMode;

/**
* Cache statement for SQL results.
Expand Down Expand Up @@ -80,7 +80,7 @@ class ResultCacheStatement implements \IteratorAggregate, ResultStatement
/**
* @var int
*/
private $defaultFetchMode = PDO::FETCH_BOTH;
private $defaultFetchMode = FetchMode::MIXED;

/**
* @param \Doctrine\DBAL\Driver\Statement $stmt
Expand Down Expand Up @@ -153,24 +153,32 @@ public function fetch($fetchMode = null, $cursorOrientation = \PDO::FETCH_ORI_NE
$this->data = [];
}

$row = $this->statement->fetch(PDO::FETCH_ASSOC);
$row = $this->statement->fetch(FetchMode::ASSOCIATIVE);

if ($row) {
$this->data[] = $row;

$fetchMode = $fetchMode ?: $this->defaultFetchMode;

if ($fetchMode == PDO::FETCH_ASSOC) {
if ($fetchMode === FetchMode::ASSOCIATIVE) {
return $row;
} elseif ($fetchMode == PDO::FETCH_NUM) {
}

if ($fetchMode === FetchMode::NUMERIC) {
return array_values($row);
} elseif ($fetchMode == PDO::FETCH_BOTH) {
}

if ($fetchMode === FetchMode::MIXED) {
return array_merge($row, array_values($row));
} elseif ($fetchMode == PDO::FETCH_COLUMN) {
}

if ($fetchMode === FetchMode::COLUMN) {
return reset($row);
} else {
throw new \InvalidArgumentException("Invalid fetch-style given for caching result.");
}

throw new \InvalidArgumentException('Invalid fetch-style given for caching result.');
}

$this->emptied = true;

return false;
Expand All @@ -194,7 +202,7 @@ public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = n
*/
public function fetchColumn($columnIndex = 0)
{
$row = $this->fetch(PDO::FETCH_NUM);
$row = $this->fetch(FetchMode::NUMERIC);

// TODO: verify that return false is the correct behavior
return $row[$columnIndex] ?? false;
Expand Down
30 changes: 30 additions & 0 deletions lib/Doctrine/DBAL/ColumnCase.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

namespace Doctrine\DBAL;

/**
* Contains portable column case conversions.
*/
final class ColumnCase
{
/**
* Convert column names to upper case.
*
* @see \PDO::CASE_UPPER
*/
public const UPPER = \PDO::CASE_UPPER;

/**
* Convert column names to lower case.
*
* @see \PDO::CASE_LOWER
*/
public const LOWER = \PDO::CASE_LOWER;

/**
* This class cannot be instantiated.
*/
private function __construct()
{
}
}
15 changes: 7 additions & 8 deletions lib/Doctrine/DBAL/Connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@

use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
use Doctrine\DBAL\Exception\InvalidArgumentException;
use PDO;
use Closure;
use Exception;
use Doctrine\DBAL\Types\Type;
Expand Down Expand Up @@ -83,14 +82,14 @@ class Connection implements DriverConnection
*
* @var int
*/
const PARAM_INT_ARRAY = 101;
public const PARAM_INT_ARRAY = ParameterType::INTEGER + self::ARRAY_PARAM_OFFSET;

/**
* Represents an array of strings to be expanded by Doctrine SQL parsing.
*
* @var int
*/
const PARAM_STR_ARRAY = 102;
public const PARAM_STR_ARRAY = ParameterType::STRING + self::ARRAY_PARAM_OFFSET;

/**
* Offset by which PARAM_* constants are detected as arrays of the param type.
Expand Down Expand Up @@ -195,7 +194,7 @@ class Connection implements DriverConnection
/**
* @var int
*/
protected $defaultFetchMode = PDO::FETCH_ASSOC;
protected $defaultFetchMode = FetchMode::ASSOCIATIVE;

/**
* Initializes a new instance of the Connection class.
Expand Down Expand Up @@ -563,7 +562,7 @@ public function setFetchMode($fetchMode)
*/
public function fetchAssoc($statement, array $params = [], array $types = [])
{
return $this->executeQuery($statement, $params, $types)->fetch(PDO::FETCH_ASSOC);
return $this->executeQuery($statement, $params, $types)->fetch(FetchMode::ASSOCIATIVE);
}

/**
Expand All @@ -578,7 +577,7 @@ public function fetchAssoc($statement, array $params = [], array $types = [])
*/
public function fetchArray($statement, array $params = [], array $types = [])
{
return $this->executeQuery($statement, $params, $types)->fetch(PDO::FETCH_NUM);
return $this->executeQuery($statement, $params, $types)->fetch(FetchMode::NUMERIC);
}

/**
Expand Down Expand Up @@ -808,7 +807,7 @@ private function extractTypeValues(array $columnList, array $types)
$typeValues = [];

foreach ($columnList as $columnIndex => $columnName) {
$typeValues[] = $types[$columnName] ?? \PDO::PARAM_STR;
$typeValues[] = $types[$columnName] ?? ParameterType::STRING;
}

return $typeValues;
Expand Down Expand Up @@ -1592,7 +1591,7 @@ private function getBindingInfo($value, $type)
$value = $type->convertToDatabaseValue($value, $this->getDatabasePlatform());
$bindingType = $type->getBindingType();
} else {
$bindingType = $type; // PDO::PARAM_* constants
$bindingType = $type;
}

return [$value, $bindingType];
Expand Down
Loading

0 comments on commit e5fe8c8

Please sign in to comment.