Support for transaction isolation levels, fixes #186
This commit is contained in:
parent
6aad5f8e73
commit
02bddbcf52
@ -136,6 +136,22 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
|
||||
}
|
||||
return $this->dataDict;
|
||||
}
|
||||
/**
|
||||
* Set the transacton isolation level.
|
||||
* (implemented by the connection drivers)
|
||||
*
|
||||
* @param string standard isolation level
|
||||
* READ UNCOMMITTED (allows dirty reads)
|
||||
* READ COMMITTED (prevents dirty reads)
|
||||
* REPEATABLE READ (prevents nonrepeatable reads)
|
||||
* SERIALIZABLE (prevents phantom reads)
|
||||
* @throws Doctrine_Connection_Mysql_Exception if using unknown isolation level
|
||||
* @throws PDOException if something fails at the PDO level
|
||||
* @return void
|
||||
*/
|
||||
public function setTransactionIsolation($isolation) {
|
||||
throw new Doctrine_Connection_Exception('Transaction isolation levels not supported by this database driver.');
|
||||
}
|
||||
/**
|
||||
* getRegexpOperator
|
||||
* returns the regular expression operator
|
||||
|
@ -1,9 +1,40 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* <http://www.phpdoctrine.com>.
|
||||
*/
|
||||
Doctrine::autoload('Doctrine_Connection');
|
||||
/**
|
||||
* firebird driver
|
||||
* Doctrine_Connection_Firebird
|
||||
*
|
||||
* @package Doctrine ORM
|
||||
* @url www.phpdoctrine.com
|
||||
* @license LGPL
|
||||
*/
|
||||
class Doctrine_Connection_Firebird extends Doctrine_Connection {
|
||||
public function modifyLimitQuery($query,$limit,$offset) {
|
||||
/**
|
||||
* Adds an driver-specific LIMIT clause to the query
|
||||
*
|
||||
* @param string $query
|
||||
* @param mixed $limit
|
||||
* @param mixed $offset
|
||||
*/
|
||||
public function modifyLimitQuery($query, $limit, $offset) {
|
||||
return preg_replace('/^([\s(])*SELECT(?!\s*FIRST\s*\d+)/i',
|
||||
"SELECT FIRST $limit SKIP $offset", $query);
|
||||
}
|
||||
|
@ -1,6 +1,29 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* <http://www.phpdoctrine.com>.
|
||||
*/
|
||||
Doctrine::autoload('Doctrine_Connection');
|
||||
/**
|
||||
* informix database driver
|
||||
* Doctrine_Connection_Mysql
|
||||
*
|
||||
* @package Doctrine ORM
|
||||
* @url www.phpdoctrine.com
|
||||
* @license LGPL
|
||||
*/
|
||||
class Doctrine_Connection_Informix extends Doctrine_Connection { }
|
||||
|
||||
|
@ -1,6 +1,30 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* <http://www.phpdoctrine.com>.
|
||||
*/
|
||||
Doctrine::autoload('Doctrine_Connection');
|
||||
/**
|
||||
* mssql driver
|
||||
* Doctrine_Connection_Mssql
|
||||
*
|
||||
* @package Doctrine ORM
|
||||
* @url www.phpdoctrine.com
|
||||
* @license LGPL
|
||||
*/
|
||||
class Doctrine_Connection_Mssql extends Doctrine_Connection {
|
||||
/**
|
||||
|
@ -1,7 +1,30 @@
|
||||
<?php
|
||||
require_once("Common.php");
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* <http://www.phpdoctrine.com>.
|
||||
*/
|
||||
Doctrine::autoload('Doctrine_Connection_Common');
|
||||
/**
|
||||
* mysql driver
|
||||
* Doctrine_Connection_Mysql
|
||||
*
|
||||
* @package Doctrine ORM
|
||||
* @url www.phpdoctrine.com
|
||||
* @license LGPL
|
||||
*/
|
||||
class Doctrine_Connection_Mysql extends Doctrine_Connection_Common {
|
||||
|
||||
@ -23,6 +46,33 @@ class Doctrine_Connection_Mysql extends Doctrine_Connection_Common {
|
||||
public function getRegexpOperator() {
|
||||
return 'RLIKE';
|
||||
}
|
||||
/**
|
||||
* Set the transacton isolation level.
|
||||
*
|
||||
* @param string standard isolation level
|
||||
* READ UNCOMMITTED (allows dirty reads)
|
||||
* READ COMMITTED (prevents dirty reads)
|
||||
* REPEATABLE READ (prevents nonrepeatable reads)
|
||||
* SERIALIZABLE (prevents phantom reads)
|
||||
* @throws Doctrine_Connection_Mysql_Exception if using unknown isolation level
|
||||
* @throws PDOException if something fails at the PDO level
|
||||
* @return void
|
||||
*/
|
||||
public function setTransactionIsolation($isolation) {
|
||||
switch ($isolation) {
|
||||
case 'READ UNCOMMITTED':
|
||||
case 'READ COMMITTED':
|
||||
case 'REPEATABLE READ':
|
||||
case 'SERIALIZABLE':
|
||||
|
||||
break;
|
||||
default:
|
||||
throw new Doctrine_Connection_Mysql_Exception('Isolation level ' . $isolation . ' is not supported.');
|
||||
}
|
||||
|
||||
$query = "SET SESSION TRANSACTION ISOLATION LEVEL $isolation";
|
||||
return $this->dbh->query($query);
|
||||
}
|
||||
/**
|
||||
* Returns string to concatenate two or more string parameters
|
||||
*
|
||||
|
@ -1,6 +1,30 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* <http://www.phpdoctrine.com>.
|
||||
*/
|
||||
Doctrine::autoload('Doctrine_Connection');
|
||||
/**
|
||||
* oracle driver
|
||||
* Doctrine_Connection_Oracle
|
||||
*
|
||||
* @package Doctrine ORM
|
||||
* @url www.phpdoctrine.com
|
||||
* @license LGPL
|
||||
*/
|
||||
class Doctrine_Connection_Oracle extends Doctrine_Connection {
|
||||
/**
|
||||
@ -18,6 +42,32 @@ class Doctrine_Connection_Oracle extends Doctrine_Connection {
|
||||
$query = "SELECT $fields FROM (SELECT rownum as linenum, $fields FROM ($query) WHERE rownum <= ($offset + $limit)) WHERE linenum >= ".++$offset;
|
||||
return $query;
|
||||
}
|
||||
/**
|
||||
* Set the transacton isolation level.
|
||||
*
|
||||
* @param string standard isolation level
|
||||
* READ UNCOMMITTED (allows dirty reads)
|
||||
* READ COMMITTED (prevents dirty reads)
|
||||
* REPEATABLE READ (prevents nonrepeatable reads)
|
||||
* SERIALIZABLE (prevents phantom reads)
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
*/
|
||||
function setTransactionIsolation($isolation) {
|
||||
switch ($isolation) {
|
||||
case 'READ UNCOMMITTED':
|
||||
$isolation = 'READ COMMITTED';
|
||||
case 'READ COMMITTED':
|
||||
case 'REPEATABLE READ':
|
||||
$isolation = 'SERIALIZABLE';
|
||||
case 'SERIALIZABLE':
|
||||
break;
|
||||
default:
|
||||
throw new Doctrine_Connection_Oracle_Exception('Isolation level ' . $isolation . 'is not supported.');
|
||||
}
|
||||
|
||||
$query = 'ALTER SESSION ISOLATION LEVEL ' . $isolation;
|
||||
return $this->dbh->query($query);
|
||||
}
|
||||
/**
|
||||
* returns the next value in the given sequence
|
||||
* @param string $sequence
|
||||
|
@ -1,7 +1,30 @@
|
||||
<?php
|
||||
require_once("Common.php");
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* <http://www.phpdoctrine.com>.
|
||||
*/
|
||||
Doctrine::autoload("Doctrine_Connection_Common");
|
||||
/**
|
||||
* pgsql driver
|
||||
* Doctrine_Connection_Pgsql
|
||||
*
|
||||
* @package Doctrine ORM
|
||||
* @url www.phpdoctrine.com
|
||||
* @license LGPL
|
||||
*/
|
||||
class Doctrine_Connection_Pgsql extends Doctrine_Connection_Common {
|
||||
/**
|
||||
@ -14,6 +37,29 @@ class Doctrine_Connection_Pgsql extends Doctrine_Connection_Common {
|
||||
$data = $stmt->fetch(PDO::FETCH_NUM);
|
||||
return $data[0];
|
||||
}
|
||||
/**
|
||||
* Set the transacton isolation level.
|
||||
*
|
||||
* @param string standard isolation level
|
||||
* READ UNCOMMITTED (allows dirty reads)
|
||||
* READ COMMITTED (prevents dirty reads)
|
||||
* REPEATABLE READ (prevents nonrepeatable reads)
|
||||
* SERIALIZABLE (prevents phantom reads)
|
||||
* @return void
|
||||
*/
|
||||
function setTransactionIsolation($isolation) {
|
||||
switch ($isolation) {
|
||||
case 'READ UNCOMMITTED':
|
||||
case 'READ COMMITTED':
|
||||
case 'REPEATABLE READ':
|
||||
case 'SERIALIZABLE':
|
||||
break;
|
||||
throw new Doctrine_Connection_Pgsql_Exception('Isolation level '.$isolation.' is not supported.');
|
||||
}
|
||||
|
||||
$query = 'SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL ' . $isolation;
|
||||
return $this->dbh->query($query);
|
||||
}
|
||||
/**
|
||||
* getRegexpOperator
|
||||
*
|
||||
|
@ -45,6 +45,33 @@ class Doctrine_Connection_Sqlite extends Doctrine_Connection_Common {
|
||||
return 'datetime(\'now\')';
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Set the transacton isolation level.
|
||||
*
|
||||
* @param string standard isolation level
|
||||
* READ UNCOMMITTED (allows dirty reads)
|
||||
* READ COMMITTED (prevents dirty reads)
|
||||
* REPEATABLE READ (prevents nonrepeatable reads)
|
||||
* SERIALIZABLE (prevents phantom reads)
|
||||
* @return void
|
||||
*/
|
||||
function setTransactionIsolation($isolation) {
|
||||
switch ($isolation) {
|
||||
case 'READ UNCOMMITTED':
|
||||
$isolation = 0;
|
||||
break;
|
||||
case 'READ COMMITTED':
|
||||
case 'REPEATABLE READ':
|
||||
case 'SERIALIZABLE':
|
||||
$isolation = 1;
|
||||
break;
|
||||
default:
|
||||
throw new Doctrine_Connection_Sqlite_Exception('Isolation level ' . $isolation . 'is not supported.');
|
||||
}
|
||||
|
||||
$query = "PRAGMA read_uncommitted=$isolation";
|
||||
return $this->_doQuery($query, true);
|
||||
}
|
||||
/**
|
||||
* return string to call a function to get a substring inside an SQL statement
|
||||
*
|
||||
|
@ -154,7 +154,7 @@ class Doctrine_Connection_Transaction implements Countable, IteratorAggregate {
|
||||
} catch(Exception $e) {
|
||||
$this->rollback();
|
||||
|
||||
throw new Doctrine_Exception($e->__toString());
|
||||
throw new Doctrine_Connection_Transaction_Exception($e->__toString());
|
||||
}
|
||||
|
||||
if(count($this->invalid) > 0) {
|
||||
|
@ -109,48 +109,48 @@ class Doctrine_DataDict_Mssql extends Doctrine_DataDict {
|
||||
// todo: unsigned handling seems to be missing
|
||||
$unsigned = $fixed = null;
|
||||
switch ($db_type) {
|
||||
case 'bit':
|
||||
$type[0] = 'boolean';
|
||||
case 'bit':
|
||||
$type[0] = 'boolean';
|
||||
break;
|
||||
case 'int':
|
||||
$type[0] = 'integer';
|
||||
case 'int':
|
||||
$type[0] = 'integer';
|
||||
break;
|
||||
case 'datetime':
|
||||
$type[0] = 'timestamp';
|
||||
case 'datetime':
|
||||
$type[0] = 'timestamp';
|
||||
break;
|
||||
case 'float':
|
||||
case 'real':
|
||||
case 'numeric':
|
||||
$type[0] = 'float';
|
||||
case 'float':
|
||||
case 'real':
|
||||
case 'numeric':
|
||||
$type[0] = 'float';
|
||||
break;
|
||||
case 'decimal':
|
||||
case 'money':
|
||||
$type[0] = 'decimal';
|
||||
case 'decimal':
|
||||
case 'money':
|
||||
$type[0] = 'decimal';
|
||||
break;
|
||||
case 'text':
|
||||
case 'varchar':
|
||||
$fixed = false;
|
||||
case 'char':
|
||||
$type[0] = 'text';
|
||||
if ($length == '1') {
|
||||
$type[] = 'boolean';
|
||||
if (preg_match('/^[is|has]/', $field['name'])) {
|
||||
$type = array_reverse($type);
|
||||
case 'text':
|
||||
case 'varchar':
|
||||
$fixed = false;
|
||||
case 'char':
|
||||
$type[0] = 'text';
|
||||
if ($length == '1') {
|
||||
$type[] = 'boolean';
|
||||
if (preg_match('/^[is|has]/', $field['name'])) {
|
||||
$type = array_reverse($type);
|
||||
}
|
||||
} elseif (strstr($db_type, 'text')) {
|
||||
$type[] = 'clob';
|
||||
}
|
||||
if ($fixed !== false) {
|
||||
$fixed = true;
|
||||
}
|
||||
} elseif (strstr($db_type, 'text')) {
|
||||
$type[] = 'clob';
|
||||
}
|
||||
if ($fixed !== false) {
|
||||
$fixed = true;
|
||||
}
|
||||
break;
|
||||
case 'image':
|
||||
case 'varbinary':
|
||||
$type[] = 'blob';
|
||||
$length = null;
|
||||
case 'image':
|
||||
case 'varbinary':
|
||||
$type[] = 'blob';
|
||||
$length = null;
|
||||
break;
|
||||
default:
|
||||
throw new Doctrine_DataDict_Mssql_Exception('mapNativeDatatype: unknown database attribute type: '.$db_type);
|
||||
default:
|
||||
throw new Doctrine_DataDict_Mssql_Exception('mapNativeDatatype: unknown database attribute type: '.$db_type);
|
||||
}
|
||||
|
||||
return array($type, $length, $unsigned, $fixed);
|
||||
|
Loading…
Reference in New Issue
Block a user