1
0
mirror of synced 2024-12-13 14:56:01 +03:00

Support for transaction isolation levels, fixes #186

This commit is contained in:
zYne 2006-10-22 20:50:27 +00:00
parent 6aad5f8e73
commit 02bddbcf52
10 changed files with 315 additions and 48 deletions

View File

@ -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

View File

@ -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);
}

View File

@ -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 { }

View File

@ -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 {
/**

View File

@ -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
*

View File

@ -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

View File

@ -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
*

View File

@ -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
*

View File

@ -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) {

View File

@ -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);