Skip to content

Commit 7fb41ab

Browse files
authored
Merge pull request #2958 from morozov/issues/2953
Remove hard dependency on PDO
2 parents 4adca54 + 83a6c1b commit 7fb41ab

File tree

75 files changed

+1101
-688
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

75 files changed

+1101
-688
lines changed

UPGRADE.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,48 @@
1+
# Upgrade to DEVELOP
2+
3+
## BC BREAK: the PDO symbols are no longer part of the DBAL API
4+
5+
1. The support of `PDO::PARAM_*`, `PDO::FETCH_*`, `PDO::CASE_*` and `PDO::PARAM_INPUT_OUTPUT` constants in the DBAL API is removed.
6+
2. `\Doctrine\DBAL\Driver\PDOStatement` does not extend `\PDOStatement` anymore.
7+
8+
Before:
9+
10+
use Doctrine\DBAL\Portability\Connection;
11+
12+
$params = array(
13+
'wrapperClass' => Connection::class,
14+
'fetch_case' => PDO::CASE_LOWER,
15+
);
16+
17+
$stmt->bindValue(1, 1, PDO::PARAM_INT);
18+
$stmt->fetchAll(PDO::FETCH_COLUMN);
19+
20+
After:
21+
22+
use Doctrine\DBAL\ColumnCase;
23+
use Doctrine\DBAL\FetchMode;
24+
use Doctrine\DBAL\ParameterType;
25+
use Doctrine\DBAL\Portability\Connection;
26+
27+
$params = array(
28+
'wrapperClass' => Connection::class,
29+
'fetch_case' => ColumnCase::LOWER,
30+
);
31+
32+
$stmt->bindValue(1, 1, ParameterType::INTEGER);
33+
$stmt->fetchAll(FetchMode::COLUMN);
34+
35+
# Upgrade to UNRELEASED
36+
37+
## DEPRECATION: direct usage of the PDO APIs in the DBAL API
38+
39+
1. When calling `Doctrine\DBAL\Driver\Statement` methods, instead of `PDO::PARAM_*` constants, `Doctrine\DBAL\ParameterType` constants should be used.
40+
2. When calling `Doctrine\DBAL\Driver\ResultStatement` methods, instead of `PDO::FETCH_*` constants, `Doctrine\DBAL\FetchMode` constants should be used.
41+
3. When configuring `Doctrine\DBAL\Portability\Connection`, instead of `PDO::CASE_*` constants, `Doctrine\DBAL\ColumnCase` constants should be used.
42+
4. Usage of `PDO::PARAM_INPUT_OUTPUT` in `Doctrine\DBAL\Driver\Statement::bindValue()` is deprecated.
43+
5. Usage of `PDO::FETCH_FUNC` in `Doctrine\DBAL\Driver\ResultStatement::fetch()` is deprecated.
44+
6. Calls to `\PDOStatement` methods on a `\Doctrine\DBAL\Driver\PDOStatement` instance (e.g. `fetchObject()`) are deprecated.
45+
146
# Upgrade to 2.6
247

348
## MINOR BC BREAK: `fetch()` and `fetchAll()` method signatures in `Doctrine\DBAL\Driver\ResultStatement`

composer.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
],
1414
"require": {
1515
"php": "^7.2",
16-
"ext-pdo": "*",
1716
"doctrine/common": "^2.7.1"
1817
},
1918
"require-dev": {

docs/en/reference/data-retrieval-and-manipulation.rst

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -180,13 +180,13 @@ Binding Types
180180
-------------
181181

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

186186
Doctrine\DBAL\Types Conversion
187187
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
188188

189-
If you don't specify an integer (through a ``PDO::PARAM*`` constant) to
189+
If you don't specify an integer (through one of ``Doctrine\DBAL\ParameterType`` constants) to
190190
any of the parameter binding methods but a string, Doctrine DBAL will
191191
ask the type abstraction layer to convert the passed value from
192192
its PHP to a database representation. This way you can pass ``\DateTime``
@@ -271,7 +271,14 @@ be specified as well:
271271
// Same SQL WITHOUT usage of Doctrine\DBAL\Connection::PARAM_INT_ARRAY
272272
$stmt = $conn->executeQuery('SELECT * FROM articles WHERE id IN (?, ?, ?, ?, ?, ?)',
273273
array(1, 2, 3, 4, 5, 6),
274-
array(\PDO::PARAM_INT, \PDO::PARAM_INT, \PDO::PARAM_INT, \PDO::PARAM_INT, \PDO::PARAM_INT, \PDO::PARAM_INT)
274+
array(
275+
ParameterType::INTEGER,
276+
ParameterType::INTEGER,
277+
ParameterType::INTEGER,
278+
ParameterType::INTEGER,
279+
ParameterType::INTEGER,
280+
ParameterType::INTEGER,
281+
)
275282
);
276283
277284
This is much more complicated and is ugly to write generically.
@@ -469,8 +476,11 @@ Quote a value:
469476
.. code-block:: php
470477
471478
<?php
479+
480+
use Doctrine\DBAL\ParameterType;
481+
472482
$quoted = $conn->quote('value');
473-
$quoted = $conn->quote('1234', \PDO::PARAM_INT);
483+
$quoted = $conn->quote('1234', ParameterType::INTEGER);
474484
475485
quoteIdentifier()
476486
~~~~~~~~~~~~~~~~~

docs/en/reference/known-vendor-issues.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,6 @@ The ``PDO_SQLSRV`` driver currently has a bug when binding values to
187187
VARBINARY/BLOB columns with ``bindValue`` in prepared statements.
188188
This raises an implicit conversion from data type error as it tries
189189
to convert a character type value to a binary type value even if
190-
you explicitly define the value as ``\PDO::PARAM_LOB`` type.
190+
you explicitly define the value as ``ParameterType::LARGE_OBJECT`` type.
191191
Therefore it is highly encouraged to use the native ``sqlsrv``
192192
driver instead which does not have this limitation.

docs/en/reference/portability.rst

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,16 @@ Using the following code block in your initialization will:
5151
.. code-block:: php
5252
5353
<?php
54+
55+
use Doctrine\DBAL\ColumnCase;
56+
use Doctrine\DBAL\Portability\Connection as PortableConnection;
57+
5458
$params = array(
5559
// vendor specific configuration
5660
//...
57-
'wrapperClass' => 'Doctrine\DBAL\Portability\Connection',
58-
'portability' => \Doctrine\DBAL\Portability\Connection::PORTABILITY_ALL,
59-
'fetch_case' => \PDO::CASE_LOWER,
61+
'wrapperClass' => PortableConnection::class,
62+
'portability' => PortableConnection::PORTABILITY_ALL,
63+
'fetch_case' => PortableConnection::LOWER,
6064
);
6165
6266
This sort of portability handling is pretty expensive because all the result
@@ -80,4 +84,4 @@ This functionality is only implemented with Doctrine 2.1 upwards.
8084
Doctrine ships with lists of keywords for every supported vendor. You
8185
can access a keyword list through the schema manager of the vendor you
8286
are currently using or just instantiating it from the ``Doctrine\DBAL\Platforms\Keywords``
83-
namespace.
87+
namespace.

docs/en/reference/security.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ the ``Connection#quote`` method:
151151
152152
<?php
153153
// Parameter quoting
154-
$sql = "SELECT * FROM users WHERE name = " . $connection->quote($_GET['username'], \PDO::PARAM_STR);
154+
$sql = "SELECT * FROM users WHERE name = " . $connection->quote($_GET['username']);
155155
156156
This method is only available for SQL, not for DQL. For DQL you are always encouraged to use prepared
157-
statements not only for security, but also for caching reasons.
157+
statements not only for security, but also for caching reasons.

lib/Doctrine/DBAL/Cache/ArrayStatement.php

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
namespace Doctrine\DBAL\Cache;
44

55
use Doctrine\DBAL\Driver\ResultStatement;
6-
use PDO;
6+
use Doctrine\DBAL\FetchMode;
77

88
class ArrayStatement implements \IteratorAggregate, ResultStatement
99
{
@@ -25,7 +25,7 @@ class ArrayStatement implements \IteratorAggregate, ResultStatement
2525
/**
2626
* @var integer
2727
*/
28-
private $defaultFetchMode = PDO::FETCH_BOTH;
28+
private $defaultFetchMode = FetchMode::MIXED;
2929

3030
/**
3131
* @param array $data
@@ -57,9 +57,9 @@ public function columnCount()
5757
/**
5858
* {@inheritdoc}
5959
*/
60-
public function setFetchMode($fetchMode, $arg2 = null, $arg3 = null)
60+
public function setFetchMode($fetchMode, ...$args)
6161
{
62-
if ($arg2 !== null || $arg3 !== null) {
62+
if (count($args) > 0) {
6363
throw new \InvalidArgumentException("Caching layer does not support 2nd/3rd argument to setFetchMode()");
6464
}
6565

@@ -81,34 +81,41 @@ public function getIterator()
8181
/**
8282
* {@inheritdoc}
8383
*/
84-
public function fetch($fetchMode = null, $cursorOrientation = \PDO::FETCH_ORI_NEXT, $cursorOffset = 0)
84+
public function fetch($fetchMode = null, ...$args)
8585
{
86-
if (isset($this->data[$this->num])) {
87-
$row = $this->data[$this->num++];
88-
$fetchMode = $fetchMode ?: $this->defaultFetchMode;
89-
if ($fetchMode === PDO::FETCH_ASSOC) {
90-
return $row;
91-
} elseif ($fetchMode === PDO::FETCH_NUM) {
92-
return array_values($row);
93-
} elseif ($fetchMode === PDO::FETCH_BOTH) {
94-
return array_merge($row, array_values($row));
95-
} elseif ($fetchMode === PDO::FETCH_COLUMN) {
96-
return reset($row);
97-
} else {
98-
throw new \InvalidArgumentException("Invalid fetch-style given for fetching result.");
99-
}
86+
if ( ! isset($this->data[$this->num])) {
87+
return false;
88+
}
89+
90+
$row = $this->data[$this->num++];
91+
$fetchMode = $fetchMode ?: $this->defaultFetchMode;
92+
93+
if ($fetchMode === FetchMode::ASSOCIATIVE) {
94+
return $row;
95+
}
96+
97+
if ($fetchMode === FetchMode::NUMERIC) {
98+
return array_values($row);
10099
}
101100

102-
return false;
101+
if ($fetchMode === FetchMode::MIXED) {
102+
return array_merge($row, array_values($row));
103+
}
104+
105+
if ($fetchMode === FetchMode::COLUMN) {
106+
return reset($row);
107+
}
108+
109+
throw new \InvalidArgumentException("Invalid fetch-style given for fetching result.");
103110
}
104111

105112
/**
106113
* {@inheritdoc}
107114
*/
108-
public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = null)
115+
public function fetchAll($fetchMode = null, ...$args)
109116
{
110117
$rows = [];
111-
while ($row = $this->fetch($fetchMode)) {
118+
while ($row = $this->fetch($fetchMode, ...$args)) {
112119
$rows[] = $row;
113120
}
114121

@@ -120,7 +127,8 @@ public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = n
120127
*/
121128
public function fetchColumn($columnIndex = 0)
122129
{
123-
$row = $this->fetch(PDO::FETCH_NUM);
130+
$row = $this->fetch(FetchMode::NUMERIC);
131+
124132
if (!isset($row[$columnIndex])) {
125133
// TODO: verify this is correct behavior
126134
return false;

lib/Doctrine/DBAL/Cache/ResultCacheStatement.php

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
use Doctrine\DBAL\Driver\Statement;
66
use Doctrine\DBAL\Driver\ResultStatement;
77
use Doctrine\Common\Cache\Cache;
8-
use PDO;
8+
use Doctrine\DBAL\FetchMode;
99

1010
/**
1111
* Cache statement for SQL results.
@@ -63,7 +63,7 @@ class ResultCacheStatement implements \IteratorAggregate, ResultStatement
6363
/**
6464
* @var integer
6565
*/
66-
private $defaultFetchMode = PDO::FETCH_BOTH;
66+
private $defaultFetchMode = FetchMode::MIXED;
6767

6868
/**
6969
* @param \Doctrine\DBAL\Driver\Statement $stmt
@@ -110,7 +110,7 @@ public function columnCount()
110110
/**
111111
* {@inheritdoc}
112112
*/
113-
public function setFetchMode($fetchMode, $arg2 = null, $arg3 = null)
113+
public function setFetchMode($fetchMode, ...$args)
114114
{
115115
$this->defaultFetchMode = $fetchMode;
116116

@@ -130,30 +130,38 @@ public function getIterator()
130130
/**
131131
* {@inheritdoc}
132132
*/
133-
public function fetch($fetchMode = null, $cursorOrientation = \PDO::FETCH_ORI_NEXT, $cursorOffset = 0)
133+
public function fetch($fetchMode = null, ...$args)
134134
{
135135
if ($this->data === null) {
136136
$this->data = [];
137137
}
138138

139-
$row = $this->statement->fetch(PDO::FETCH_ASSOC);
139+
$row = $this->statement->fetch(FetchMode::ASSOCIATIVE);
140+
140141
if ($row) {
141142
$this->data[] = $row;
142143

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

145-
if ($fetchMode == PDO::FETCH_ASSOC) {
146+
if ($fetchMode == FetchMode::ASSOCIATIVE) {
146147
return $row;
147-
} elseif ($fetchMode == PDO::FETCH_NUM) {
148+
}
149+
150+
if ($fetchMode == FetchMode::NUMERIC) {
148151
return array_values($row);
149-
} elseif ($fetchMode == PDO::FETCH_BOTH) {
152+
}
153+
154+
if ($fetchMode == FetchMode::MIXED) {
150155
return array_merge($row, array_values($row));
151-
} elseif ($fetchMode == PDO::FETCH_COLUMN) {
156+
}
157+
158+
if ($fetchMode == FetchMode::COLUMN) {
152159
return reset($row);
153-
} else {
154-
throw new \InvalidArgumentException("Invalid fetch-style given for caching result.");
155160
}
161+
162+
throw new \InvalidArgumentException('Invalid fetch-style given for caching result.');
156163
}
164+
157165
$this->emptied = true;
158166

159167
return false;
@@ -162,10 +170,10 @@ public function fetch($fetchMode = null, $cursorOrientation = \PDO::FETCH_ORI_NE
162170
/**
163171
* {@inheritdoc}
164172
*/
165-
public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = null)
173+
public function fetchAll($fetchMode = null, ...$args)
166174
{
167175
$rows = [];
168-
while ($row = $this->fetch($fetchMode)) {
176+
while ($row = $this->fetch($fetchMode, ...$args)) {
169177
$rows[] = $row;
170178
}
171179

@@ -177,7 +185,8 @@ public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = n
177185
*/
178186
public function fetchColumn($columnIndex = 0)
179187
{
180-
$row = $this->fetch(PDO::FETCH_NUM);
188+
$row = $this->fetch(FetchMode::NUMERIC);
189+
181190
if (!isset($row[$columnIndex])) {
182191
// TODO: verify this is correct behavior
183192
return false;

lib/Doctrine/DBAL/ColumnCase.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
namespace Doctrine\DBAL;
4+
5+
/**
6+
* Contains portable column case conversions.
7+
*/
8+
class ColumnCase
9+
{
10+
/**
11+
* Convert column names to upper case.
12+
*
13+
* @see \PDO::CASE_UPPER
14+
*/
15+
public const UPPER = 1;
16+
17+
/**
18+
* Convert column names to lower case.
19+
*
20+
* @see \PDO::CASE_LOWER
21+
*/
22+
public const LOWER = 2;
23+
24+
/**
25+
* This class cannot be instantiated.
26+
*/
27+
final private function __construct()
28+
{
29+
}
30+
}

0 commit comments

Comments
 (0)