Commit 30eb6b95 authored by Danny Berger's avatar Danny Berger Committed by Benjamin Eberlei

Support OCI8 statements crossing transactions [DBAL-202]

parent 15c23239
......@@ -57,7 +57,7 @@ class OCI8Connection implements \Doctrine\DBAL\Driver\Connection
*/
public function prepare($prepareString)
{
return new OCI8Statement($this->_dbh, $prepareString, $this->_executeMode);
return new OCI8Statement($this->_dbh, $prepareString, $this);
}
/**
......@@ -107,6 +107,14 @@ class OCI8Connection implements \Doctrine\DBAL\Driver\Connection
//TODO: throw exception or support sequences?
}
/**
* Return the current execution mode.
*/
public function getExecuteMode()
{
return $this->_executeMode;
}
/**
* Start a transactiom
*
......
......@@ -34,7 +34,7 @@ class OCI8Statement implements \IteratorAggregate, Statement
/** Statement handle. */
protected $_dbh;
protected $_sth;
protected $_executeMode;
protected $_conn;
protected static $_PARAM = ':param';
protected static $fetchStyleMap = array(
PDO::FETCH_BOTH => OCI_BOTH,
......@@ -51,13 +51,13 @@ class OCI8Statement implements \IteratorAggregate, Statement
* @param resource $dbh The connection handle.
* @param string $statement The SQL statement.
*/
public function __construct($dbh, $statement, $executeMode)
public function __construct($dbh, $statement, OCI8Connection $conn)
{
list($statement, $paramMap) = self::convertPositionalToNamedPlaceholders($statement);
$this->_sth = oci_parse($dbh, $statement);
$this->_dbh = $dbh;
$this->_paramMap = $paramMap;
$this->_executeMode = $executeMode;
$this->_conn = $conn;
}
/**
......@@ -179,7 +179,7 @@ class OCI8Statement implements \IteratorAggregate, Statement
}
}
$ret = @oci_execute($this->_sth, $this->_executeMode);
$ret = @oci_execute($this->_sth, $this->_conn->getExecuteMode());
if ( ! $ret) {
throw OCI8Exception::fromErrorInfo($this->errorInfo());
}
......
......@@ -15,21 +15,13 @@ class OCI8StatementTest extends \Doctrine\Tests\DbalTestCase
parent::setUp();
}
protected function getMockOCI8Statement()
{
$dbh = null;
$statement = "update table set field1 = ?, field2 = ? where field3 = ?";
$executeMode = OCI_COMMIT_ON_SUCCESS;
return $this->getMock('\Doctrine\DBAL\Driver\OCI8\OCI8Statement',
array('bindValue', 'errorInfo'),
array(null, $statement, $executeMode), '', false);
}
/**
* 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.
*
* @dataProvider executeDataProvider
......@@ -37,7 +29,9 @@ class OCI8StatementTest extends \Doctrine\Tests\DbalTestCase
*/
public function testExecute(array $params)
{
$statement = $this->getMockOCI8Statement();
$statement = $this->getMock('\Doctrine\DBAL\Driver\OCI8\OCI8Statement',
array('bindValue', 'errorInfo'),
array(), '', false);
$statement->expects($this->at(0))
->method('bindValue')
......@@ -58,6 +52,16 @@ class OCI8StatementTest extends \Doctrine\Tests\DbalTestCase
$this->equalTo($params[2])
);
// 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->getMock('\Doctrine\DBAL\Driver\OCI8\OCI8Connection', array('getExecuteMode'), array(), '', false);
$conn->expects($this->once())
->method('getExecuteMode');
$reflProperty = new \ReflectionProperty($statement, '_conn');
$reflProperty->setAccessible(true);
$reflProperty->setValue($statement, $conn);
$statement->execute($params);
}
......
<?php
namespace Doctrine\Tests\DBAL\Functional\Ticket;
/**
* @group DBAL-202
*/
class DBAL202Test extends \Doctrine\Tests\DbalFunctionalTestCase
{
protected function setUp()
{
parent::setUp();
if ($this->_conn->getDatabasePlatform()->getName() != 'oracle') {
$this->markTestSkipped('OCI8 only test');
}
if ($this->_conn->getSchemaManager()->tablesExist('DBAL202')) {
$this->_conn->executeQuery('DELETE FROM DBAL202');
} else {
$table = new \Doctrine\DBAL\Schema\Table('DBAL202');
$table->addColumn('id', 'integer');
$table->setPrimaryKey(array('id'));
$this->_conn->getSchemaManager()->createTable($table);
}
}
public function testStatementRollback()
{
$stmt = $this->_conn->prepare('INSERT INTO DBAL202 VALUES (8)');
$this->_conn->beginTransaction();
$stmt->execute();
$this->_conn->rollback();
$this->assertEquals(0, $this->_conn->query('SELECT COUNT(1) FROM DBAL202')->fetchColumn());
}
public function testStatementCommit()
{
$stmt = $this->_conn->prepare('INSERT INTO DBAL202 VALUES (8)');
$this->_conn->beginTransaction();
$stmt->execute();
$this->_conn->commit();
$this->assertEquals(1, $this->_conn->query('SELECT COUNT(1) FROM DBAL202')->fetchColumn());
}
}
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