Dropped handling of one-based numeric arrays of parameters in Statement::execute()

parent bfc8bb9e
# Upgrade to 3.0 # Upgrade to 3.0
## BC BREAK: Dropped handling of one-based numeric arrays of parameters in `Statement::execute()`
The statement implementations no longer detect whether `$params` is a zero- or one-based array. A zero-based numeric array is expected.
## BC BREAK: `ServerInfoAwareConnection::requiresQueryForServerVersion()` is removed. ## BC BREAK: `ServerInfoAwareConnection::requiresQueryForServerVersion()` is removed.
The `ServerInfoAwareConnection::requiresQueryForServerVersion()` method has been removed as an implementation detail which is the same for almost all supported drivers. The `ServerInfoAwareConnection::requiresQueryForServerVersion()` method has been removed as an implementation detail which is the same for almost all supported drivers.
......
...@@ -351,10 +351,8 @@ class OCI8Statement implements IteratorAggregate, Statement ...@@ -351,10 +351,8 @@ class OCI8Statement implements IteratorAggregate, Statement
public function execute(?array $params = null) : void public function execute(?array $params = null) : void
{ {
if ($params) { if ($params) {
$hasZeroIndex = array_key_exists(0, $params);
foreach ($params as $key => $val) { foreach ($params as $key => $val) {
if ($hasZeroIndex && is_int($key)) { if (is_int($key)) {
$param = $key + 1; $param = $key + 1;
} else { } else {
$param = $key; $param = $key;
......
...@@ -204,10 +204,8 @@ final class SQLSrvStatement implements IteratorAggregate, Statement ...@@ -204,10 +204,8 @@ final class SQLSrvStatement implements IteratorAggregate, Statement
public function execute(?array $params = null) : void public function execute(?array $params = null) : void
{ {
if ($params) { if ($params) {
$hasZeroIndex = array_key_exists(0, $params);
foreach ($params as $key => $val) { foreach ($params as $key => $val) {
if ($hasZeroIndex && is_int($key)) { if (is_int($key)) {
$this->bindValue($key + 1, $val); $this->bindValue($key + 1, $val);
} else { } else {
$this->bindValue($key, $val); $this->bindValue($key, $val);
......
...@@ -68,7 +68,7 @@ interface Statement extends ResultStatement ...@@ -68,7 +68,7 @@ interface Statement extends ResultStatement
* if any, of their associated parameter markers or pass an array of input-only * if any, of their associated parameter markers or pass an array of input-only
* parameter values. * parameter values.
* *
* @param mixed[]|null $params An array of values with as many elements as there are * @param mixed[]|null $params A numeric array of values with as many elements as there are
* bound parameters in the SQL statement being executed. * bound parameters in the SQL statement being executed.
* *
* @throws DriverException * @throws DriverException
......
...@@ -4,15 +4,10 @@ declare(strict_types=1); ...@@ -4,15 +4,10 @@ declare(strict_types=1);
namespace Doctrine\Tests\DBAL\Driver\OCI8; namespace Doctrine\Tests\DBAL\Driver\OCI8;
use Doctrine\DBAL\Driver\OCI8\OCI8Connection;
use Doctrine\DBAL\Driver\OCI8\OCI8Exception; use Doctrine\DBAL\Driver\OCI8\OCI8Exception;
use Doctrine\DBAL\Driver\OCI8\OCI8Statement; use Doctrine\DBAL\Driver\OCI8\OCI8Statement;
use Doctrine\Tests\DbalTestCase; use Doctrine\Tests\DbalTestCase;
use PHPUnit\Framework\MockObject\MockObject;
use ReflectionProperty;
use const OCI_NO_AUTO_COMMIT;
use function extension_loaded; use function extension_loaded;
use function fopen;
class OCI8StatementTest extends DbalTestCase class OCI8StatementTest extends DbalTestCase
{ {
...@@ -25,72 +20,6 @@ class OCI8StatementTest extends DbalTestCase ...@@ -25,72 +20,6 @@ class OCI8StatementTest extends DbalTestCase
parent::setUp(); parent::setUp();
} }
/**
* This scenario shows that when the first parameter is not null
* it properly sets $hasZeroIndex to 1 and calls bindValue starting at 1.
*
* This also verifies that the statement will check with the connection to
* see what the current execution mode is.
*
* The expected exception is due to oci_execute failing due to no valid connection.
*
* @param mixed[] $params
*
* @dataProvider executeDataProvider
*/
public function testExecute(array $params) : void
{
/** @var OCI8Statement|MockObject $statement */
$statement = $this->getMockBuilder(OCI8Statement::class)
->onlyMethods(['bindValue'])
->disableOriginalConstructor()
->getMock();
foreach ($params as $index => $value) {
$statement->expects($this->at($index))
->method('bindValue')
->with(
$this->equalTo($index + 1),
$this->equalTo($value)
);
}
// can't pass to constructor since we don't have a real database handle,
// but execute must check the connection for the executeMode
$conn = $this->createMock(OCI8Connection::class);
$conn->expects($this->once())
->method('getExecuteMode')
->willReturn(OCI_NO_AUTO_COMMIT);
$connectionReflection = new ReflectionProperty($statement, '_conn');
$connectionReflection->setAccessible(true);
$connectionReflection->setValue($statement, $conn);
$handleReflection = new ReflectionProperty($statement, '_sth');
$handleReflection->setAccessible(true);
$handleReflection->setValue($statement, fopen('php://temp', 'r'));
$this->expectException(OCI8Exception::class);
$statement->execute($params);
}
/**
* @return array<int, array<int, mixed>>
*/
public static function executeDataProvider() : iterable
{
return [
// $hasZeroIndex = isset($params[0]); == true
[
[0 => 'test', 1 => null, 2 => 'value'],
],
// $hasZeroIndex = isset($params[0]); == false
[
[0 => null, 1 => 'test', 2 => 'value'],
],
];
}
/** /**
* @dataProvider nonTerminatedLiteralProvider * @dataProvider nonTerminatedLiteralProvider
*/ */
......
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