1
0
mirror of synced 2024-12-13 22:56:04 +03:00

Updated Pgsql datadict driver, moved transaction isolation functionality to Doctrine_Transaction

This commit is contained in:
zYne 2006-11-14 18:21:36 +00:00
parent 256fbd5331
commit 8b5cf30ef8
4 changed files with 262 additions and 75 deletions

View File

@ -21,14 +21,14 @@
/**
* Doctrine_Connection
*
* @package Doctrine
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @category Object Relational Mapping
* @link www.phpdoctrine.com
* @since 1.0
* @version $Revision$
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
*/
* @package Doctrine
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @category Object Relational Mapping
* @link www.phpdoctrine.com
* @since 1.0
* @version $Revision$
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
*/
abstract class Doctrine_Connection extends Doctrine_Configurable implements Countable, IteratorAggregate {
/**
* @var $dbh the database handler
@ -295,41 +295,82 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
throw new Doctrine_Connection_Exception('Altering charset not supported by this driver.');
}
/**
* setTransactionIsolation
* fetchAll
*
* Set the transacton isolation level.
* (implemented by the connection drivers)
*
* example:
*
* <code>
* $conn->setTransactionIsolation('READ UNCOMMITTED');
* </code>
*
* @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_Exception if the feature is not supported by the driver
* @throws PDOException if something fails at the PDO level
* @return void
* @param string $statement sql query to be executed
* @param array $params prepared statement params
* @return array
*/
public function setTransactionIsolation($isolation) {
throw new Doctrine_Connection_Exception('Transaction isolation levels not supported by this driver.');
public function fetchAll($statement, array $params = array()) {
return $this->query($statement, $params)->fetchAll(PDO::FETCH_ASSOC);
}
/**
* fetchOne
*
* @param string $statement sql query to be executed
* @param array $params prepared statement params
* @return mixed
*/
public function fetchOne($statement, array $params = array()) {
return current($this->query($statement, $params)->fetch(PDO::FETCH_NUM));
}
/**
* fetchRow
*
* @param string $statement sql query to be executed
* @param array $params prepared statement params
* @return array
*/
public function fetchRow($statement, array $params = array()) {
return $this->query($statement, $params)->fetch(PDO::FETCH_ASSOC);
}
/**
* fetchArray
*
* @param string $statement sql query to be executed
* @param array $params prepared statement params
* @return array
*/
public function fetchArray($statement, array $params = array()) {
return $this->query($statement, $params)->fetch(PDO::FETCH_NUM);
}
/**
* fetchColumn
*
* @param string $statement sql query to be executed
* @param array $params prepared statement params
* @return array
*/
public function fetchColumn($statement, array $params = array()) {
$result = $this->query($statement, $params)->fetchAll(PDO::FETCH_COLUMN);
if($this->options['portability'] & Doctrine::PORTABILITY_FIX_CASE)
$result = array_map(($db->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $result);
return $result;
}
/**
* fetchAssoc
*
* @param string $statement sql query to be executed
* @param array $params prepared statement params
* @return array
*/
public function fetchAssoc($statement, array $params = array()) {
return $this->query($statement, $params)->fetchAll(PDO::FETCH_ASSOC);
}
/**
* fetchBoth
*
* @param string $statement sql query to be executed
* @param array $params prepared statement params
* @return array
*/
public function fetchBoth($statement, array $params = array()) {
return $this->query($statement, $params)->fetchAll(PDO::FETCH_BOTH);
}
/**
* getTransactionIsolation
*
* @throws Doctrine_Connection_Exception if the feature is not supported by the driver
* @throws PDOException if something fails at the PDO level
* @return string returns the current session transaction isolation level
*/
public function getTransactionIsolation() {
throw new Doctrine_Connection_Exception('Fetching transaction isolation level not supported by this driver.');
}
/**
* query
* queries the database using Doctrine Query Language

View File

@ -19,15 +19,17 @@
* <http://www.phpdoctrine.com>.
*/
/**
* @package Doctrine
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
* @package Doctrine
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
* @author Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library)
* @version $Revision$
* @category Object Relational Mapping
* @link www.phpdoctrine.com
* @since 1.0
*/
* @author Frank M. Kromann <frank@kromann.info> (PEAR MDB2 Mssql driver)
* @author David Coallier <davidc@php.net> (PEAR MDB2 Mssql driver)
* @version $Revision$
* @category Object Relational Mapping
* @link www.phpdoctrine.com
* @since 1.0
*/
class Doctrine_DataDict_Mssql extends Doctrine_DataDict {
/**
* Obtain DBMS specific SQL code portion needed to declare an text type
@ -189,7 +191,22 @@ class Doctrine_DataDict_Mssql extends Doctrine_DataDict {
* @return array
*/
public function listSequences($database = null) {
$query = "SELECT name FROM sysobjects WHERE xtype = 'U'";
$table_names = $db->queryCol($query);
if (PEAR::isError($table_names)) {
return $table_names;
}
$result = array();
foreach ($table_names as $table_name) {
if ($sqn = $this->_fixSequenceName($table_name, true)) {
$result[] = $sqn;
}
}
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
$result = array_map(($db->options['field_case'] == CASE_LOWER ?
'strtolower' : 'strtoupper'), $result);
}
return $result;
}
/**
* lists table constraints
@ -207,7 +224,7 @@ class Doctrine_DataDict_Mssql extends Doctrine_DataDict {
* @return array
*/
public function listTableColumns($table) {
$sql = "exec sp_columns @table_name = " . $this->quoteIdentifier($table);
$sql = 'EXEC sp_columns @table_name = ' . $this->quoteIdentifier($table);
$result = $this->dbh->query($sql)->fetchAll(PDO::FETCH_ASSOC);
$columns = array();
@ -262,7 +279,24 @@ class Doctrine_DataDict_Mssql extends Doctrine_DataDict {
* @return array
*/
public function listTableTriggers($table) {
$table = $db->quote($table, 'text');
$query = "SELECT name FROM sysobjects WHERE xtype = 'TR'";
if (!is_null($table)) {
$query .= "AND object_name(parent_obj) = $table";
}
$result = $db->queryCol($query);
if (PEAR::isError($results)) {
return $result;
}
if ($db->options['portability'] & Doctrine::PORTABILITY_FIX_CASE &&
$db->options['field_case'] == CASE_LOWER)
{
$result = array_map(($db->options['field_case'] == CASE_LOWER ?
'strtolower' : 'strtoupper'), $result);
}
return $result;
}
/**
* lists table views
@ -271,7 +305,34 @@ class Doctrine_DataDict_Mssql extends Doctrine_DataDict {
* @return array
*/
public function listTableViews($table) {
$keyName = 'INDEX_NAME';
$pkName = 'PK_NAME';
if ($db->options['portability'] & Doctrine::PORTABILITY_FIX_CASE) {
if ($db->options['field_case'] == CASE_LOWER) {
$keyName = strtolower($keyName);
$pkName = strtolower($pkName);
} else {
$keyName = strtoupper($keyName);
$pkName = strtoupper($pkName);
}
}
$table = $db->quote($table, 'text');
$query = 'EXEC sp_statistics @table_name = ' . $table;
$indexes = $db->queryCol($query, 'text', $keyName);
$query = 'EXEC sp_pkeys @table_name = ' . $table;
$pkAll = $db->queryCol($query, 'text', $pkName);
$result = array();
foreach ($indexes as $index) {
if (!in_array($index, $pkAll) && $index != null) {
$result[$this->_fixIndexName($index)] = true;
}
}
if ($db->options['portability'] & Doctrine::PORTABILITY_FIX_CASE) {
$result = array_change_key_case($result, $db->options['field_case']);
}
return array_keys($result);
}
/**
* lists database users
@ -288,6 +349,16 @@ class Doctrine_DataDict_Mssql extends Doctrine_DataDict {
* @return array
*/
public function listViews($database = null) {
$query = "SELECT name FROM sysobjects WHERE xtype = 'V'";
$result = $db->queryCol($query);
if ($db->options['portability'] & Doctrine::PORTABILITY_FIX_CASE &&
$db->options['field_case'] == CASE_LOWER)
{
$result = array_map(($db->options['field_case'] == CASE_LOWER ?
'strtolower' : 'strtoupper'), $result);
}
return $result;
}
}

View File

@ -532,12 +532,15 @@ class Doctrine_DataDict_Pgsql extends Doctrine_DataDict {
return array($type, $length, $unsigned, $fixed);
}
/**
* listDatabases
* lists all databases
*
* @return array
*/
public function listDatabases() {
$query = 'SELECT datname FROM pg_database';
return $this->conn->fetchColumn($query);
}
/**
* lists all availible database functions
@ -545,7 +548,20 @@ class Doctrine_DataDict_Pgsql extends Doctrine_DataDict {
* @return array
*/
public function listFunctions() {
$query = "
SELECT
proname
FROM
pg_proc pr,
pg_type tp
WHERE
tp.oid = pr.prorettype
AND pr.proisagg = FALSE
AND tp.typname <> 'trigger'
AND pr.pronamespace IN
(SELECT oid FROM pg_namespace WHERE nspname NOT LIKE 'pg_%' AND nspname != 'information_schema')";
return $this->conn->fetchColumn($query);
}
/**
* lists all database triggers
@ -563,7 +579,10 @@ class Doctrine_DataDict_Pgsql extends Doctrine_DataDict {
* @return array
*/
public function listSequences($database = null) {
$query = "SELECT relname FROM pg_class WHERE relkind = 'S' AND relnamespace IN";
$query.= "(SELECT oid FROM pg_namespace WHERE nspname NOT LIKE 'pg_%' AND nspname != 'information_schema')";
return $this->conn->fetchColumn($query);
}
/**
* lists table constraints
@ -572,7 +591,12 @@ class Doctrine_DataDict_Pgsql extends Doctrine_DataDict {
* @return array
*/
public function listTableConstraints($table) {
$table = $db->quote($table, 'text');
$subquery = "SELECT indexrelid FROM pg_index, pg_class";
$subquery.= " WHERE pg_class.relname=$table AND pg_class.oid=pg_index.indrelid AND (indisunique = 't' OR indisprimary = 't')";
$query = "SELECT relname FROM pg_class WHERE oid IN ($subquery)";
return $this->conn->fetchColumn($query);
}
/**
* lists table constraints
@ -619,13 +643,18 @@ class Doctrine_DataDict_Pgsql extends Doctrine_DataDict {
return $columns;
}
/**
* lists table constraints
* list all indexes in a table
*
* @param string $table database table name
* @return array
*/
public function listTableIndexes($table) {
$table = $db->quote($table, 'text');
$subquery = "SELECT indexrelid FROM pg_index, pg_class";
$subquery.= " WHERE pg_class.relname=$table AND pg_class.oid=pg_index.indrelid AND indisunique != 't' AND indisprimary != 't'";
$query = "SELECT relname FROM pg_class WHERE oid IN ($subquery)";
return $this->conn->fetchColumn($query);
}
/**
* lists tables
@ -659,21 +688,25 @@ class Doctrine_DataDict_Pgsql extends Doctrine_DataDict {
}
/**
* lists table views
* list the views in the database that reference a given table
*
* @param string $table database table name
* @return array
*/
public function listTableViews($table) {
$query = 'SELECT viewname FROM pg_views';
return $this->conn->fetchColumn($query);
}
/**
* lists database users
*
* @return array
*/
public function listUsers() {
public function listUsers() {
$query = 'SELECT usename FROM pg_user';
return $this->conn->fetchColumn($query);
}
/**
* lists database views
@ -681,7 +714,9 @@ class Doctrine_DataDict_Pgsql extends Doctrine_DataDict {
* @param string|null $database
* @return array
*/
public function listViews($database = null) {
public function listViews($database = null) {
$query = 'SELECT viewname FROM pg_views';
return $this->conn->fetchColumn($query);
}
}

View File

@ -30,21 +30,17 @@
*/
class Doctrine_Transaction {
/**
* Doctrine_Transaction is in open state when it is opened and there are no active transactions
* Doctrine_Transaction is in sleep state when it has no active transactions
*/
const STATE_OPEN = 0;
/**
* Doctrine_Transaction is in closed state when it is closed
*/
const STATE_CLOSED = 1;
const STATE_SLEEP = 0;
/**
* Doctrine_Transaction is in active state when it has one active transaction
*/
const STATE_ACTIVE = 2;
const STATE_ACTIVE = 1;
/**
* Doctrine_Transaction is in busy state when it has multiple active transactions
*/
const STATE_BUSY = 3;
const STATE_BUSY = 2;
/**
* @var Doctrine_Connection $conn the connection object
*/
@ -93,6 +89,8 @@ class Doctrine_Transaction {
* beginTransaction
* Start a transaction or set a savepoint.
*
* Listeners: onPreTransactionBegin, onTransactionBegin
*
* @param string $savepoint name of a savepoint to set
* @throws Doctrine_Transaction_Exception if trying to create a savepoint and there
* are no active transactions
@ -122,8 +120,9 @@ class Doctrine_Transaction {
* commit
* Commit the database changes done during a transaction that is in
* progress or release a savepoint. This function may only be called when
* auto-committing is disabled, otherwise it will fail. Therefore, a new
* transaction is implicitly started after committing the pending changes.
* auto-committing is disabled, otherwise it will fail.
*
* Listeners: onPreTransactionCommit, onTransactionCommit
*
* @param string $savepoint name of a savepoint to release
* @throws Doctrine_Transaction_Exception if the transaction fails at PDO level
@ -145,7 +144,7 @@ class Doctrine_Transaction {
try {
$this->bulkDelete();
} catch(Exception $e) {
$this->rollback();
@ -227,4 +226,45 @@ class Doctrine_Transaction {
public function rollbackSavePoint($savepoint) {
throw new Doctrine_Transaction_Exception('Savepoints not supported by this driver.');
}
/**
* setIsolation
*
* Set the transacton isolation level.
* (implemented by the connection drivers)
*
* example:
*
* <code>
* $tx->setIsolation('READ UNCOMMITTED');
* </code>
*
* @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_Exception if the feature is not supported by the driver
* @throws PDOException if something fails at the PDO level
* @return void
*/
public function setIsolation($isolation) {
throw new Doctrine_Connection_Exception('Transaction isolation levels not supported by this driver.');
}
/**
* getTransactionIsolation
*
* fetches the current session transaction isolation level
*
* note: some drivers may support setting the transaction isolation level
* but not fetching it
*
* @throws Doctrine_Connection_Exception if the feature is not supported by the driver
* @throws PDOException if something fails at the PDO level
* @return string returns the current session transaction isolation level
*/
public function getIsolation() {
throw new Doctrine_Connection_Exception('Fetching transaction isolation level not supported by this driver.');
}
}