Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Forward compatibility with 3.x #2996

Merged
merged 14 commits into from
Feb 1, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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)
morozov marked this conversation as resolved.
Show resolved Hide resolved
{
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