2007-01-07 17:52:16 +03:00
< ? 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 >.
*/
2007-02-17 01:54:59 +03:00
Doctrine :: autoload ( 'Doctrine_Configurable' );
2007-01-07 17:52:16 +03:00
/**
* Doctrine_Connection
*
2007-05-27 22:56:04 +04:00
* A wrapper layer on top of PDO / Doctrine_Adapter
*
* Doctrine_Connection is the heart of any Doctrine based application .
*
* 1. Event listeners
* An easy to use , pluggable eventlistener architecture . Aspects such as
* logging , query profiling and caching can be easily implemented through
* the use of these listeners
*
* 2. Lazy - connecting
* Creating an instance of Doctrine_Connection does not connect
* to database . Connecting to database is only invoked when actually needed
* ( for example when query () is being called )
*
* 3. Convenience methods
2007-06-15 01:50:12 +04:00
* Doctrine_Connection provides many convenience methods such as fetchAll (), fetchOne () etc .
2007-05-27 22:56:04 +04:00
*
* 4. Modular structure
* Higher level functionality such as schema importing , exporting , sequence handling etc .
* is divided into modules . For a full list of connection modules see
* Doctrine_Connection :: $_modules
*
2007-01-07 17:52:16 +03:00
* @ package Doctrine
2007-10-04 01:43:22 +04:00
* @ subpackage Connection
2007-01-07 17:52:16 +03:00
* @ license http :// www . opensource . org / licenses / lgpl - license . php LGPL
* @ link www . phpdoctrine . com
* @ since 1.0
* @ version $Revision $
* @ author Konsta Vesterinen < kvesteri @ cc . hut . fi >
* @ author Lukas Smith < smith @ pooteeweet . org > ( MDB2 library )
*/
abstract class Doctrine_Connection extends Doctrine_Configurable implements Countable , IteratorAggregate
{
/**
* @ var $dbh the database handler
*/
protected $dbh ;
2007-10-21 10:23:59 +04:00
2008-01-12 22:49:11 +03:00
/**
*
*/
2008-01-05 22:55:56 +03:00
protected $_tableFactory ;
2007-01-07 17:52:16 +03:00
/**
* @ var array $tables an array containing all the initialized Doctrine_Table objects
2008-01-05 22:55:56 +03:00
* keys representing component names and values as Doctrine_Table objects
2007-01-07 17:52:16 +03:00
*/
2008-01-05 22:55:56 +03:00
protected $tables = array ();
/**
* @ var array An array of mapper objects currently maintained by this connection .
*/
protected $_mappers = array ();
2008-01-23 00:42:17 +03:00
/**
* $_name
*
* Name of the connection
*
* @ var string $_name
*/
protected $_name ;
2007-10-21 10:23:59 +04:00
2007-01-07 17:52:16 +03:00
/**
* @ var string $driverName the name of this connection driver
*/
protected $driverName ;
2007-10-21 10:23:59 +04:00
2007-06-12 23:39:03 +04:00
/**
* @ var boolean $isConnected whether or not a connection has been established
*/
protected $isConnected = false ;
2007-10-21 10:23:59 +04:00
2007-01-07 17:52:16 +03:00
/**
* @ var array $supported an array containing all features this driver supports ,
* keys representing feature names and values as
* one of the following ( true , false , 'emulated' )
*/
protected $supported = array ();
2007-10-21 10:23:59 +04:00
2007-06-12 23:39:03 +04:00
/**
* @ var array $pendingAttributes An array of pending attributes . When setting attributes
* no connection is needed . When connected all the pending
* attributes are passed to the underlying adapter ( usually PDO ) instance .
*/
protected $pendingAttributes = array ();
2007-10-21 10:23:59 +04:00
2007-01-07 17:52:16 +03:00
/**
* @ var array $modules an array containing all modules
* transaction Doctrine_Transaction driver , handles savepoint and transaction isolation abstraction
*
* expression Doctrine_Expression driver , handles expression abstraction
*
* dataDict Doctrine_DataDict driver , handles datatype abstraction
*
* export Doctrine_Export driver , handles db structure modification abstraction ( contains
* methods such as alterTable , createConstraint etc . )
2007-08-17 01:54:14 +04:00
* import Doctrine_Import driver , handles db schema reading
2007-01-08 03:13:41 +03:00
*
* sequence Doctrine_Sequence driver , handles sequential id generation and retrieval
2007-01-07 17:52:16 +03:00
*
2007-05-27 22:56:04 +04:00
* unitOfWork Doctrine_Connection_UnitOfWork handles many orm functionalities such as object
* deletion and saving
*
* formatter Doctrine_Formatter handles data formatting , quoting and escaping
*
2007-01-07 17:52:16 +03:00
* @ see Doctrine_Connection :: __get ()
* @ see Doctrine_DataDict
* @ see Doctrine_Expression
* @ see Doctrine_Export
* @ see Doctrine_Transaction
2007-01-08 03:13:41 +03:00
* @ see Doctrine_Sequence
2007-05-27 22:56:04 +04:00
* @ see Doctrine_Connection_UnitOfWork
* @ see Doctrine_Formatter
2007-01-07 17:52:16 +03:00
*/
private $modules = array ( 'transaction' => false ,
'expression' => false ,
'dataDict' => false ,
'export' => false ,
2007-08-17 01:54:14 +04:00
'import' => false ,
2007-01-08 03:13:41 +03:00
'sequence' => false ,
2007-01-07 17:52:16 +03:00
'unitOfWork' => false ,
2007-06-12 03:25:46 +04:00
'formatter' => false ,
'util' => false ,
2007-01-07 17:52:16 +03:00
);
2007-10-21 10:23:59 +04:00
2007-01-07 17:52:16 +03:00
/**
* @ var array $properties an array of connection properties
*/
protected $properties = array ( 'sql_comments' => array ( array ( 'start' => '--' , 'end' => " \n " , 'escape' => false ),
2007-05-27 22:56:04 +04:00
array ( 'start' => '/*' , 'end' => '*/' , 'escape' => false )),
'identifier_quoting' => array ( 'start' => '"' , 'end' => '"' , 'escape' => '"' ),
2007-01-07 17:52:16 +03:00
'string_quoting' => array ( 'start' => " ' " ,
'end' => " ' " ,
'escape' => false ,
2007-05-27 22:56:04 +04:00
'escape_pattern' => false ),
2007-02-17 21:18:44 +03:00
'wildcards' => array ( '%' , '_' ),
'varchar_max_length' => 255 ,
2007-01-07 17:52:16 +03:00
);
2007-10-21 10:23:59 +04:00
2007-01-29 23:10:51 +03:00
/**
* @ var array $serverInfo
*/
protected $serverInfo = array ();
2007-06-12 23:39:03 +04:00
protected $options = array ();
2007-10-21 10:23:59 +04:00
2007-01-07 17:52:16 +03:00
/**
2007-11-18 19:06:37 +03:00
* @ var array $availableDrivers an array containing all available drivers
2007-01-07 17:52:16 +03:00
*/
2007-02-07 16:11:05 +03:00
private static $availableDrivers = array (
2007-01-07 17:52:16 +03:00
'Mysql' ,
'Pgsql' ,
'Oracle' ,
'Informix' ,
'Mssql' ,
'Sqlite' ,
'Firebird'
);
2008-01-12 22:49:11 +03:00
/**
* The query count . Represents the number of executed database queries by the connection .
*
* @ var integer
*/
2007-10-08 02:21:01 +04:00
protected $_count = 0 ;
2007-01-07 17:52:16 +03:00
/**
* the constructor
*
* @ param Doctrine_Manager $manager the manager object
* @ param PDO | Doctrine_Adapter_Interface $adapter database driver
*/
2007-06-12 23:39:03 +04:00
public function __construct ( Doctrine_Manager $manager , $adapter , $user = null , $pass = null )
2007-01-07 17:52:16 +03:00
{
2007-09-03 18:57:18 +04:00
if ( is_object ( $adapter )) {
2007-06-20 03:33:04 +04:00
if ( ! ( $adapter instanceof PDO ) && ! in_array ( 'Doctrine_Adapter_Interface' , class_implements ( $adapter ))) {
throw new Doctrine_Connection_Exception ( 'First argument should be an instance of PDO or implement Doctrine_Adapter_Interface' );
2007-06-12 23:39:03 +04:00
}
2007-06-20 03:33:04 +04:00
$this -> dbh = $adapter ;
$this -> isConnected = true ;
2007-11-18 19:06:37 +03:00
} else if ( is_array ( $adapter )) {
2007-06-20 03:33:04 +04:00
$this -> pendingAttributes [ Doctrine :: ATTR_DRIVER_NAME ] = $adapter [ 'scheme' ];
2007-06-12 23:39:03 +04:00
2007-06-20 03:33:04 +04:00
$this -> options [ 'dsn' ] = $adapter [ 'dsn' ];
$this -> options [ 'username' ] = $adapter [ 'user' ];
$this -> options [ 'password' ] = $adapter [ 'pass' ];
2007-10-09 03:22:31 +04:00
$this -> options [ 'other' ] = array ();
if ( isset ( $adapter [ 'other' ])) {
$this -> options [ 'other' ] = array ( Doctrine :: ATTR_PERSISTENT => $adapter [ 'persistent' ]);
}
2007-06-12 23:39:03 +04:00
}
2007-01-07 17:52:16 +03:00
$this -> setParent ( $manager );
2008-01-05 22:55:56 +03:00
$this -> _tableFactory = new Doctrine_Table_Factory ( $this );
2007-01-07 17:52:16 +03:00
2007-06-20 03:33:04 +04:00
$this -> setAttribute ( Doctrine :: ATTR_CASE , Doctrine :: CASE_NATURAL );
$this -> setAttribute ( Doctrine :: ATTR_ERRMODE , Doctrine :: ERRMODE_EXCEPTION );
2007-01-07 17:52:16 +03:00
$this -> getAttribute ( Doctrine :: ATTR_LISTENER ) -> onOpen ( $this );
}
2007-10-21 10:23:59 +04:00
2007-10-20 23:14:30 +04:00
/**
* getOption
*
* Retrieves option
*
* @ param string $option
* @ return void
*/
public function getOption ( $option )
{
if ( isset ( $this -> options [ $option ])) {
return $this -> options [ $option ];
}
}
2007-10-21 10:23:59 +04:00
2007-06-12 23:39:03 +04:00
/**
* getAttribute
* retrieves a database connection attribute
*
* @ param integer $attribute
* @ return mixed
*/
public function getAttribute ( $attribute )
{
2007-09-03 18:57:18 +04:00
if ( $attribute >= 100 ) {
2007-06-12 23:39:03 +04:00
if ( ! isset ( $this -> attributes [ $attribute ])) {
2007-10-30 20:51:33 +03:00
return parent :: getAttribute ( $attribute );
2007-06-12 23:39:03 +04:00
}
return $this -> attributes [ $attribute ];
2007-09-03 18:57:18 +04:00
}
2007-06-12 23:39:03 +04:00
if ( $this -> isConnected ) {
try {
return $this -> dbh -> getAttribute ( $attribute );
2007-12-06 22:02:29 +03:00
} catch ( Exception $e ) {
2007-06-12 23:39:03 +04:00
throw new Doctrine_Connection_Exception ( 'Attribute ' . $attribute . ' not found.' );
}
} else {
if ( ! isset ( $this -> pendingAttributes [ $attribute ])) {
$this -> connect ();
$this -> getAttribute ( $attribute );
}
return $this -> pendingAttributes [ $attribute ];
}
}
2007-10-21 10:23:59 +04:00
2007-06-12 23:39:03 +04:00
/**
* returns an array of available PDO drivers
*/
public static function getAvailableDrivers ()
{
return PDO :: getAvailableDrivers ();
}
2007-10-21 10:23:59 +04:00
2007-06-12 23:39:03 +04:00
/**
* setAttribute
* sets an attribute
*
2007-11-18 23:37:44 +03:00
* @ todo why check for >= 100 ? has this any special meaning when creating
* attributes ?
*
2007-06-12 23:39:03 +04:00
* @ param integer $attribute
* @ param mixed $value
* @ return boolean
*/
public function setAttribute ( $attribute , $value )
{
2007-09-03 18:57:18 +04:00
if ( $attribute >= 100 ) {
2007-06-12 23:39:03 +04:00
parent :: setAttribute ( $attribute , $value );
2007-09-03 18:57:18 +04:00
} else {
2007-06-12 23:39:03 +04:00
if ( $this -> isConnected ) {
$this -> dbh -> setAttribute ( $attribute , $value );
} else {
$this -> pendingAttributes [ $attribute ] = $value ;
}
}
return $this ;
}
2007-10-21 10:23:59 +04:00
2007-01-07 17:52:16 +03:00
/**
* getName
* returns the name of this driver
*
* @ return string the name of this driver
*/
public function getName ()
2008-01-23 00:42:17 +03:00
{
return $this -> _name ;
}
public function setName ( $name )
{
$this -> _name = $name ;
}
public function getDriverName ()
2007-01-07 17:52:16 +03:00
{
return $this -> driverName ;
}
2007-10-21 10:23:59 +04:00
2007-01-07 17:52:16 +03:00
/**
* __get
* lazy loads given module and returns it
*
* @ see Doctrine_DataDict
* @ see Doctrine_Expression
* @ see Doctrine_Export
* @ see Doctrine_Transaction
* @ see Doctrine_Connection :: $modules all availible modules
* @ param string $name the name of the module to get
* @ throws Doctrine_Connection_Exception if trying to get an unknown module
* @ return Doctrine_Connection_Module connection module
*/
public function __get ( $name )
{
2007-06-15 15:56:55 +04:00
if ( isset ( $this -> properties [ $name ])) {
2007-01-07 17:52:16 +03:00
return $this -> properties [ $name ];
2007-06-20 03:33:04 +04:00
}
2007-01-07 17:52:16 +03:00
if ( ! isset ( $this -> modules [ $name ])) {
throw new Doctrine_Connection_Exception ( 'Unknown module / property ' . $name );
}
if ( $this -> modules [ $name ] === false ) {
switch ( $name ) {
case 'unitOfWork' :
$this -> modules [ $name ] = new Doctrine_Connection_UnitOfWork ( $this );
break ;
2007-05-27 22:56:04 +04:00
case 'formatter' :
$this -> modules [ $name ] = new Doctrine_Formatter ( $this );
break ;
2007-01-07 17:52:16 +03:00
default :
2008-01-23 00:42:17 +03:00
$class = 'Doctrine_' . ucwords ( $name ) . '_' . $this -> getDriverName ();
2007-01-07 17:52:16 +03:00
$this -> modules [ $name ] = new $class ( $this );
}
}
return $this -> modules [ $name ];
}
2007-10-21 10:23:59 +04:00
2007-01-07 17:52:16 +03:00
/**
* returns the manager that created this connection
*
* @ return Doctrine_Manager
*/
public function getManager ()
{
return $this -> getParent ();
}
2007-10-21 10:23:59 +04:00
2007-01-07 17:52:16 +03:00
/**
2008-01-12 22:49:11 +03:00
* returns the database handler which this connection uses
2007-01-07 17:52:16 +03:00
*
* @ return PDO the database handler
*/
public function getDbh ()
{
2007-09-03 18:57:18 +04:00
$this -> connect ();
2007-01-07 17:52:16 +03:00
return $this -> dbh ;
}
2007-10-21 10:23:59 +04:00
2007-06-12 03:25:46 +04:00
/**
* connect
* connects into database
*
* @ return boolean
*/
public function connect ()
{
if ( $this -> isConnected ) {
return false ;
}
2007-06-25 21:24:20 +04:00
$event = new Doctrine_Event ( $this , Doctrine_Event :: CONN_CONNECT );
2007-06-25 14:08:03 +04:00
$this -> getListener () -> preConnect ( $event );
2007-06-12 03:25:46 +04:00
$e = explode ( ':' , $this -> options [ 'dsn' ]);
$found = false ;
if ( extension_loaded ( 'pdo' )) {
if ( in_array ( $e [ 0 ], PDO :: getAvailableDrivers ())) {
2007-10-09 03:22:31 +04:00
$this -> dbh = new PDO ( $this -> options [ 'dsn' ], $this -> options [ 'username' ],
$this -> options [ 'password' ], $this -> options [ 'other' ]);
2007-06-12 03:25:46 +04:00
$this -> dbh -> setAttribute ( PDO :: ATTR_ERRMODE , PDO :: ERRMODE_EXCEPTION );
$found = true ;
}
}
if ( ! $found ) {
$class = 'Doctrine_Adapter_' . ucwords ( $e [ 0 ]);
if ( class_exists ( $class )) {
$this -> dbh = new $class ( $this -> options [ 'dsn' ], $this -> options [ 'username' ], $this -> options [ 'password' ]);
} else {
2007-09-03 18:57:18 +04:00
throw new Doctrine_Connection_Exception ( " Couldn't locate driver named " . $e [ 0 ]);
2007-06-12 03:25:46 +04:00
}
}
2007-06-12 23:39:03 +04:00
// attach the pending attributes to adapter
2007-06-12 03:25:46 +04:00
foreach ( $this -> pendingAttributes as $attr => $value ) {
// some drivers don't support setting this so we just skip it
2007-09-03 18:57:18 +04:00
if ( $attr == Doctrine :: ATTR_DRIVER_NAME ) {
2007-06-12 03:25:46 +04:00
continue ;
}
$this -> dbh -> setAttribute ( $attr , $value );
}
$this -> isConnected = true ;
2007-06-25 14:08:03 +04:00
$this -> getListener () -> postConnect ( $event );
2007-06-12 03:25:46 +04:00
return true ;
}
2007-06-20 03:33:04 +04:00
public function incrementQueryCount ()
{
$this -> _count ++ ;
}
2007-10-21 10:23:59 +04:00
2007-01-07 17:52:16 +03:00
/**
* converts given driver name
*
* @ param
*/
public function driverName ( $name )
{
}
2007-10-21 10:23:59 +04:00
2007-01-07 17:52:16 +03:00
/**
* supports
*
* @ param string $feature the name of the feature
* @ return boolean whether or not this drivers supports given feature
*/
public function supports ( $feature )
{
return ( isset ( $this -> supported [ $feature ])
2007-05-27 22:56:04 +04:00
&& ( $this -> supported [ $feature ] === 'emulated'
|| $this -> supported [ $feature ]));
2007-01-07 17:52:16 +03:00
}
2007-10-21 10:23:59 +04:00
2007-01-07 17:52:16 +03:00
/**
* Execute a SQL REPLACE query . A REPLACE query is identical to a INSERT
* query , except that if there is already a row in the table with the same
* key field values , the REPLACE query just updates its values instead of
* inserting a new row .
*
* The REPLACE type of query does not make part of the SQL standards . Since
* practically only MySQL and SQLIte implement it natively , this type of
* query isemulated through this method for other DBMS using standard types
* of queries inside a transaction to assure the atomicity of the operation .
*
* @ param string name of the table on which the REPLACE query will
* be executed .
*
* @ param array an associative array that describes the fields and the
* values that will be inserted or updated in the specified table . The
* indexes of the array are the names of all the fields of the table .
*
* The values of the array are values to be assigned to the specified field .
*
* @ param array $keys an array containing all key fields ( primary key fields
* or unique index fields ) for this table
*
* the uniqueness of a row will be determined according to
* the provided key fields
*
* this method will fail if no key fields are specified
*
* @ throws Doctrine_Connection_Exception if this driver doesn ' t support replace
* @ throws Doctrine_Connection_Exception if some of the key values was null
* @ throws Doctrine_Connection_Exception if there were no key fields
* @ throws PDOException if something fails at PDO level
2007-11-18 23:37:44 +03:00
* @ return integer number of rows affected
2007-01-07 17:52:16 +03:00
*/
2007-11-18 19:06:37 +03:00
public function replace ( Doctrine_Table $table , array $fields , array $keys )
2007-01-07 17:52:16 +03:00
{
if ( empty ( $keys )) {
throw new Doctrine_Connection_Exception ( 'Not specified which fields are keys' );
}
$condition = $values = array ();
2007-11-18 19:06:37 +03:00
foreach ( $fields as $fieldName => $value ) {
$values [ $fieldName ] = $value ;
2007-01-07 17:52:16 +03:00
2007-11-18 19:06:37 +03:00
if ( in_array ( $fieldName , $keys )) {
2007-01-07 17:52:16 +03:00
if ( $value === null )
2007-11-18 19:06:37 +03:00
throw new Doctrine_Connection_Exception ( 'key value ' . $fieldName . ' may not be null' );
2007-01-07 17:52:16 +03:00
2007-11-18 19:06:37 +03:00
$condition [] = $table -> getColumnName ( $fieldName ) . ' = ?' ;
2007-01-07 17:52:16 +03:00
$conditionValues [] = $value ;
}
}
2007-11-18 19:06:37 +03:00
$query = 'DELETE FROM ' . $this -> quoteIdentifier ( $table -> getTableName ())
. ' WHERE ' . implode ( ' AND ' , $condition );
$affectedRows = $this -> exec ( $query , $conditionValues );
2007-01-07 17:52:16 +03:00
$this -> insert ( $table , $values );
$affectedRows ++ ;
return $affectedRows ;
}
2007-10-21 10:23:59 +04:00
2007-11-10 13:37:10 +03:00
/**
* deletes table row ( s ) matching the specified identifier
*
* @ throws Doctrine_Connection_Exception if something went wrong at the database level
* @ param string $table The table to delete data from
2008-01-12 22:49:11 +03:00
* @ param array $identifier An associateve array containing identifier fieldname - value pairs .
2007-11-10 13:37:10 +03:00
* @ return integer The number of affected rows
*/
2007-11-18 19:06:37 +03:00
public function delete ( Doctrine_Table $table , array $identifier )
2007-11-10 13:37:10 +03:00
{
2008-01-12 22:49:11 +03:00
$criteria = array ();
2007-11-10 13:37:10 +03:00
foreach ( array_keys ( $identifier ) as $id ) {
2008-01-12 22:49:11 +03:00
$criteria [] = $table -> getColumnName ( $id ) . ' = ?' ;
2007-11-10 13:37:10 +03:00
}
$query = 'DELETE FROM '
2007-11-18 19:06:37 +03:00
. $this -> quoteIdentifier ( $table -> getTableName ())
2008-01-12 22:49:11 +03:00
. ' WHERE ' . implode ( ' AND ' , $criteria );
2007-11-10 13:37:10 +03:00
2007-11-10 16:21:40 +03:00
return $this -> exec ( $query , array_values ( $identifier ));
2007-11-10 13:37:10 +03:00
}
2007-11-10 03:57:13 +03:00
/**
* Updates table row ( s ) with specified data
*
* @ throws Doctrine_Connection_Exception if something went wrong at the database level
* @ param string $table The table to insert data into
* @ param array $values An associateve array containing column - value pairs .
* @ return mixed boolean false if empty value array was given ,
* otherwise returns the number of affected rows
*/
2007-11-18 19:06:37 +03:00
public function update ( Doctrine_Table $table , array $fields , array $identifier )
2007-11-10 03:57:13 +03:00
{
2007-11-18 19:06:37 +03:00
if ( empty ( $fields )) {
2007-11-10 03:57:13 +03:00
return false ;
}
$set = array ();
2007-11-18 19:06:37 +03:00
foreach ( $fields as $fieldName => $value ) {
2007-11-10 03:57:13 +03:00
if ( $value instanceof Doctrine_Expression ) {
2007-11-18 19:06:37 +03:00
$set [] = $table -> getColumnName ( $fieldName ) . ' = ' . $value -> getSql ();
2007-11-29 02:06:04 +03:00
unset ( $fields [ $fieldName ]);
2007-11-10 03:57:13 +03:00
} else {
2007-11-18 19:06:37 +03:00
$set [] = $table -> getColumnName ( $fieldName ) . ' = ?' ;
2007-11-10 03:57:13 +03:00
}
}
2007-11-18 19:06:37 +03:00
$params = array_merge ( array_values ( $fields ), array_values ( $identifier ));
2007-11-10 03:57:13 +03:00
2007-11-18 19:06:37 +03:00
$sql = 'UPDATE ' . $this -> quoteIdentifier ( $table -> getTableName ())
2007-11-10 03:57:13 +03:00
. ' SET ' . implode ( ', ' , $set )
2007-11-18 19:06:37 +03:00
. ' WHERE ' . implode ( ' = ? AND ' , $table -> getIdentifierColumnNames ())
2007-11-10 03:57:13 +03:00
. ' = ?' ;
return $this -> exec ( $sql , $params );
}
2007-01-07 17:52:16 +03:00
/**
* Inserts a table row with specified data .
*
* @ param string $table The table to insert data into .
2008-01-12 22:49:11 +03:00
* @ param array $fields An associateve array containing fieldname - value pairs .
2007-11-10 13:37:10 +03:00
* @ return mixed boolean false if empty value array was given ,
* otherwise returns the number of affected rows
2007-01-07 17:52:16 +03:00
*/
2008-01-05 22:55:56 +03:00
public function insert ( Doctrine_Table $table , array $fields )
{
2007-11-18 19:06:37 +03:00
if ( empty ( $fields )) {
2007-01-07 17:52:16 +03:00
return false ;
}
2007-11-18 19:06:37 +03:00
$tableName = $table -> getTableName ();
2007-08-25 04:34:25 +04:00
// column names are specified as array keys
$cols = array ();
// the query VALUES will contain either expresions (eg 'NOW()') or ?
2007-07-01 15:27:45 +04:00
$a = array ();
2007-11-18 19:06:37 +03:00
foreach ( $fields as $fieldName => $value ) {
$cols [] = $this -> quoteIdentifier ( $table -> getColumnName ( $fieldName ));
2007-07-01 15:27:45 +04:00
if ( $value instanceof Doctrine_Expression ) {
2007-08-25 04:34:25 +04:00
$a [] = $value -> getSql ();
2007-11-18 19:06:37 +03:00
unset ( $fields [ $fieldName ]);
2007-07-01 15:27:45 +04:00
} else {
2007-08-25 04:34:25 +04:00
$a [] = '?' ;
2007-07-01 15:27:45 +04:00
}
}
2008-01-05 22:55:56 +03:00
2007-08-25 04:34:25 +04:00
// build the statement
2007-11-18 19:06:37 +03:00
$query = 'INSERT INTO ' . $this -> quoteIdentifier ( $tableName )
2007-08-25 04:34:25 +04:00
. ' (' . implode ( ', ' , $cols ) . ') '
. 'VALUES (' ;
2007-07-01 15:27:45 +04:00
$query .= implode ( ', ' , $a ) . ')' ;
2007-01-07 17:52:16 +03:00
// prepare and execute the statement
2008-01-05 22:55:56 +03:00
2008-01-12 22:49:11 +03:00
return $this -> exec ( $query , array_values ( $fields ));
}
2007-10-21 10:23:59 +04:00
2007-01-07 17:52:16 +03:00
/**
* Set the charset on the current connection
*
* @ param string charset
*/
public function setCharset ( $charset )
{
2008-01-12 22:49:11 +03:00
return true ;
2007-05-27 22:56:04 +04:00
}
2007-10-21 10:23:59 +04:00
2007-05-27 22:56:04 +04:00
/**
2008-01-12 22:49:11 +03:00
* Quote a string so it can be safely used as a table or column name .
2007-05-27 22:56:04 +04:00
*
* Delimiting style depends on which database driver is being used .
*
* NOTE : just because you CAN use delimited identifiers doesn ' t mean
* you SHOULD use them . In general , they end up causing way more
* problems than they solve .
*
* Portability is broken by using the following characters inside
* delimited identifiers :
* + backtick ( < kbd > ` </ kbd > ) -- due to MySQL
* + double quote ( < kbd > " </kbd>) -- due to Oracle
* + brackets ( < kbd > [ </ kbd > or < kbd > ] </ kbd > ) -- due to Access
*
* Delimited identifiers are known to generally work correctly under
* the following drivers :
* + mssql
* + mysql
* + mysqli
* + oci8
* + pgsql
* + sqlite
*
* InterBase doesn ' t seem to be able to use delimited identifiers
* via PHP 4. They work fine under PHP 5.
*
* @ param string $str identifier name to be quoted
* @ param bool $checkOption check the 'quote_identifier' option
*
* @ return string quoted identifier string
*/
public function quoteIdentifier ( $str , $checkOption = true )
{
2007-09-03 18:57:18 +04:00
// quick fix for the identifiers that contain a dot
2007-07-13 02:31:16 +04:00
if ( strpos ( $str , '.' )) {
$e = explode ( '.' , $str );
return $this -> formatter -> quoteIdentifier ( $e [ 0 ], $checkOption ) . '.'
. $this -> formatter -> quoteIdentifier ( $e [ 1 ], $checkOption );
}
2007-05-27 22:56:04 +04:00
return $this -> formatter -> quoteIdentifier ( $str , $checkOption );
}
2007-10-21 10:23:59 +04:00
2007-05-27 22:56:04 +04:00
/**
* convertBooleans
* some drivers need the boolean values to be converted into integers
* when using DQL API
*
* This method takes care of that conversion
*
* @ param array $item
* @ return void
*/
public function convertBooleans ( $item )
{
return $this -> formatter -> convertBooleans ( $item );
}
2007-10-21 10:23:59 +04:00
2007-05-27 22:56:04 +04:00
/**
* quote
* quotes given input parameter
*
* @ param mixed $input parameter to be quoted
* @ param string $type
* @ return mixed
*/
public function quote ( $input , $type = null )
{
return $this -> formatter -> quote ( $input , $type );
2007-01-07 17:52:16 +03:00
}
2007-10-21 10:23:59 +04:00
2007-01-20 14:44:41 +03:00
/**
* Set the date / time format for the current connection
*
* @ param string time format
*
* @ return void
*/
public function setDateFormat ( $format = null )
{
}
2007-10-21 10:23:59 +04:00
2007-01-07 17:52:16 +03:00
/**
* fetchAll
*
* @ param string $statement sql query to be executed
* @ param array $params prepared statement params
* @ return array
*/
2007-01-25 01:50:49 +03:00
public function fetchAll ( $statement , array $params = array ())
{
2007-06-25 21:24:20 +04:00
return $this -> execute ( $statement , $params ) -> fetchAll ( Doctrine :: FETCH_ASSOC );
2007-01-07 17:52:16 +03:00
}
2007-10-21 10:23:59 +04:00
2007-01-07 17:52:16 +03:00
/**
* fetchOne
*
* @ param string $statement sql query to be executed
* @ param array $params prepared statement params
* @ param int $colnum 0 - indexed column number to retrieve
* @ return mixed
*/
2007-01-25 01:50:49 +03:00
public function fetchOne ( $statement , array $params = array (), $colnum = 0 )
{
2007-01-07 17:52:16 +03:00
return $this -> execute ( $statement , $params ) -> fetchColumn ( $colnum );
}
2007-10-21 10:23:59 +04:00
2007-01-07 17:52:16 +03:00
/**
* fetchRow
*
* @ param string $statement sql query to be executed
* @ param array $params prepared statement params
* @ return array
*/
2007-01-25 01:50:49 +03:00
public function fetchRow ( $statement , array $params = array ())
{
2007-06-25 21:24:20 +04:00
return $this -> execute ( $statement , $params ) -> fetch ( Doctrine :: FETCH_ASSOC );
2007-01-07 17:52:16 +03:00
}
2007-10-21 10:23:59 +04:00
2007-01-07 17:52:16 +03:00
/**
* fetchArray
*
* @ param string $statement sql query to be executed
* @ param array $params prepared statement params
* @ return array
*/
2007-01-25 01:50:49 +03:00
public function fetchArray ( $statement , array $params = array ())
{
2007-06-25 21:24:20 +04:00
return $this -> execute ( $statement , $params ) -> fetch ( Doctrine :: FETCH_NUM );
2007-01-07 17:52:16 +03:00
}
2007-10-21 10:23:59 +04:00
2007-01-07 17:52:16 +03:00
/**
* fetchColumn
*
* @ param string $statement sql query to be executed
* @ param array $params prepared statement params
* @ param int $colnum 0 - indexed column number to retrieve
* @ return array
*/
2007-01-25 01:50:49 +03:00
public function fetchColumn ( $statement , array $params = array (), $colnum = 0 )
{
2007-06-25 21:24:20 +04:00
return $this -> execute ( $statement , $params ) -> fetchAll ( Doctrine :: FETCH_COLUMN , $colnum );
2007-01-07 17:52:16 +03:00
}
2007-10-21 10:23:59 +04:00
2007-01-07 17:52:16 +03:00
/**
* fetchAssoc
*
* @ param string $statement sql query to be executed
* @ param array $params prepared statement params
* @ return array
*/
2007-01-25 01:50:49 +03:00
public function fetchAssoc ( $statement , array $params = array ())
{
2007-06-25 21:24:20 +04:00
return $this -> execute ( $statement , $params ) -> fetchAll ( Doctrine :: FETCH_ASSOC );
2007-01-07 17:52:16 +03:00
}
2007-10-21 10:23:59 +04:00
2007-01-07 17:52:16 +03:00
/**
* fetchBoth
*
* @ param string $statement sql query to be executed
* @ param array $params prepared statement params
* @ return array
*/
2007-01-25 01:50:49 +03:00
public function fetchBoth ( $statement , array $params = array ())
{
2007-06-25 21:24:20 +04:00
return $this -> execute ( $statement , $params ) -> fetchAll ( Doctrine :: FETCH_BOTH );
2007-01-07 17:52:16 +03:00
}
2007-10-21 10:23:59 +04:00
2007-01-07 17:52:16 +03:00
/**
* query
* queries the database using Doctrine Query Language
* returns a collection of Doctrine_Record objects
*
* < code >
* $users = $conn -> query ( 'SELECT u.* FROM User u' );
*
* $users = $conn -> query ( 'SELECT u.* FROM User u WHERE u.name LIKE ?' , array ( 'someone' ));
* </ code >
*
* @ param string $query DQL query
* @ param array $params query parameters
2007-09-01 23:44:38 +04:00
* @ param int $hydrationMode Doctrine :: FETCH_ARRAY or Doctrine :: FETCH_RECORD
2007-01-07 17:52:16 +03:00
* @ see Doctrine_Query
* @ return Doctrine_Collection Collection of Doctrine_Record objects
*/
2007-09-01 23:44:38 +04:00
public function query ( $query , array $params = array (), $hydrationMode = null )
2007-01-25 01:50:49 +03:00
{
2007-01-07 17:52:16 +03:00
$parser = new Doctrine_Query ( $this );
2007-09-01 23:44:38 +04:00
return $parser -> query ( $query , $params , $hydrationMode );
2007-01-07 17:52:16 +03:00
}
2007-10-21 10:23:59 +04:00
2007-06-20 03:33:04 +04:00
/**
* prepare
*
* @ param string $statement
*/
public function prepare ( $statement )
{
$this -> connect ();
2007-07-12 02:03:47 +04:00
try {
$event = new Doctrine_Event ( $this , Doctrine_Event :: CONN_PREPARE , $statement );
$this -> getAttribute ( Doctrine :: ATTR_LISTENER ) -> prePrepare ( $event );
2007-06-20 03:33:04 +04:00
2007-07-12 02:03:47 +04:00
$stmt = false ;
if ( ! $event -> skipOperation ) {
$stmt = $this -> dbh -> prepare ( $statement );
}
$this -> getAttribute ( Doctrine :: ATTR_LISTENER ) -> postPrepare ( $event );
return new Doctrine_Connection_Statement ( $this , $stmt );
} catch ( Doctrine_Adapter_Exception $e ) {
} catch ( PDOException $e ) { }
2007-06-20 03:33:04 +04:00
2007-07-12 02:03:47 +04:00
$this -> rethrowException ( $e , $this );
2007-06-20 03:33:04 +04:00
}
2007-10-21 10:23:59 +04:00
2007-01-07 17:52:16 +03:00
/**
* query
* queries the database using Doctrine Query Language and returns
* the first record found
*
* < code >
* $user = $conn -> queryOne ( 'SELECT u.* FROM User u WHERE u.id = ?' , array ( 1 ));
*
* $user = $conn -> queryOne ( 'SELECT u.* FROM User u WHERE u.name LIKE ? AND u.password = ?' ,
* array ( 'someone' , 'password' )
* );
* </ code >
*
* @ param string $query DQL query
* @ param array $params query parameters
* @ see Doctrine_Query
* @ return Doctrine_Record | false Doctrine_Record object on success ,
* boolean false on failure
*/
2007-01-25 01:50:49 +03:00
public function queryOne ( $query , array $params = array ())
{
2007-01-07 17:52:16 +03:00
$parser = new Doctrine_Query ( $this );
$coll = $parser -> query ( $query , $params );
if ( ! $coll -> contains ( 0 )) {
return false ;
}
return $coll [ 0 ];
}
2007-10-21 10:23:59 +04:00
2007-01-07 17:52:16 +03:00
/**
* queries the database with limit and offset
2007-10-13 21:06:26 +04:00
* added to the query and returns a Doctrine_Connection_Statement object
2007-01-07 17:52:16 +03:00
*
* @ param string $query
* @ param integer $limit
* @ param integer $offset
2007-10-13 21:06:26 +04:00
* @ return Doctrine_Connection_Statement
2007-01-07 17:52:16 +03:00
*/
2007-06-12 23:39:03 +04:00
public function select ( $query , $limit = 0 , $offset = 0 )
2007-01-07 17:52:16 +03:00
{
if ( $limit > 0 || $offset > 0 ) {
$query = $this -> modifyLimitQuery ( $query , $limit , $offset );
}
2007-10-13 21:06:26 +04:00
return $this -> execute ( $query );
2007-01-07 17:52:16 +03:00
}
2007-10-21 10:23:59 +04:00
2007-01-25 01:50:49 +03:00
/**
* standaloneQuery
*
* @ param string $query sql query
* @ param array $params query parameters
*
* @ return PDOStatement | Doctrine_Adapter_Statement
*/
public function standaloneQuery ( $query , $params = array ())
{
return $this -> execute ( $query , $params );
}
2007-10-21 10:23:59 +04:00
2007-01-07 17:52:16 +03:00
/**
* execute
* @ param string $query sql query
* @ param array $params query parameters
*
* @ return PDOStatement | Doctrine_Adapter_Statement
*/
2007-06-25 14:08:03 +04:00
public function execute ( $query , array $params = array ())
2007-01-25 01:50:49 +03:00
{
2007-09-03 18:57:18 +04:00
$this -> connect ();
2007-06-12 23:39:03 +04:00
2007-01-07 17:52:16 +03:00
try {
if ( ! empty ( $params )) {
2007-06-27 02:29:31 +04:00
$stmt = $this -> prepare ( $query );
2007-01-07 17:52:16 +03:00
$stmt -> execute ( $params );
2007-05-27 22:56:04 +04:00
return $stmt ;
2007-01-07 17:52:16 +03:00
} else {
2007-06-25 21:24:20 +04:00
$event = new Doctrine_Event ( $this , Doctrine_Event :: CONN_QUERY , $query , $params );
2007-06-20 03:33:04 +04:00
2007-06-25 14:08:03 +04:00
$this -> getAttribute ( Doctrine :: ATTR_LISTENER ) -> preQuery ( $event );
2007-06-20 03:33:04 +04:00
2007-06-25 14:08:03 +04:00
if ( ! $event -> skipOperation ) {
2008-01-05 22:55:56 +03:00
//try {
$stmt = $this -> dbh -> query ( $query );
/* } catch ( Exception $e ) {
if ( strstr ( $e -> getMessage (), 'no such column' )) {
echo $query . " <br /><br /> " ;
}
} */
2007-06-25 14:08:03 +04:00
$this -> _count ++ ;
}
$this -> getAttribute ( Doctrine :: ATTR_LISTENER ) -> postQuery ( $event );
2007-06-20 03:33:04 +04:00
return $stmt ;
2007-01-07 17:52:16 +03:00
}
2007-11-24 21:11:09 +03:00
} catch ( Doctrine_Adapter_Exception $e ) {
} catch ( PDOException $e ) { }
2007-02-17 15:38:02 +03:00
2007-07-12 02:03:47 +04:00
$this -> rethrowException ( $e , $this );
2007-01-07 17:52:16 +03:00
}
2007-10-21 10:23:59 +04:00
2007-01-07 17:52:16 +03:00
/**
* exec
* @ param string $query sql query
* @ param array $params query parameters
*
* @ return PDOStatement | Doctrine_Adapter_Statement
*/
public function exec ( $query , array $params = array ()) {
2007-09-03 18:57:18 +04:00
$this -> connect ();
2007-09-01 21:35:44 +04:00
2007-01-07 17:52:16 +03:00
try {
if ( ! empty ( $params )) {
2007-06-20 03:33:04 +04:00
$stmt = $this -> prepare ( $query );
2007-01-07 17:52:16 +03:00
$stmt -> execute ( $params );
2008-01-05 22:55:56 +03:00
//echo "<br /><br />" . $query . "<br /><br />";
2007-01-15 21:48:50 +03:00
return $stmt -> rowCount ();
2007-01-07 17:52:16 +03:00
} else {
2007-06-25 21:24:20 +04:00
$event = new Doctrine_Event ( $this , Doctrine_Event :: CONN_EXEC , $query , $params );
2007-06-20 03:33:04 +04:00
2007-06-25 14:08:03 +04:00
$this -> getAttribute ( Doctrine :: ATTR_LISTENER ) -> preExec ( $event );
2007-06-20 03:33:04 +04:00
2007-06-25 14:08:03 +04:00
if ( ! $event -> skipOperation ) {
$count = $this -> dbh -> exec ( $query );
2008-01-05 22:55:56 +03:00
//echo "<br /><br />" . $query . "<br /><br />";
2007-06-25 14:08:03 +04:00
$this -> _count ++ ;
}
$this -> getAttribute ( Doctrine :: ATTR_LISTENER ) -> postExec ( $event );
2007-06-20 03:33:04 +04:00
return $count ;
2007-01-07 17:52:16 +03:00
}
2007-11-24 21:11:09 +03:00
} catch ( Doctrine_Adapter_Exception $e ) {
} catch ( PDOException $e ) { }
2007-01-07 17:52:16 +03:00
2007-07-12 02:03:47 +04:00
$this -> rethrowException ( $e , $this );
2007-01-07 17:52:16 +03:00
}
2007-10-21 10:23:59 +04:00
2007-01-07 17:52:16 +03:00
/**
* rethrowException
*
* @ throws Doctrine_Connection_Exception
*/
2007-07-12 02:03:47 +04:00
public function rethrowException ( Exception $e , $invoker )
2007-01-07 17:52:16 +03:00
{
2007-09-03 18:57:18 +04:00
$event = new Doctrine_Event ( $this , Doctrine_Event :: CONN_ERROR );
$this -> getListener () -> preError ( $event );
2007-11-24 21:11:09 +03:00
2007-01-07 17:52:16 +03:00
$name = 'Doctrine_Connection_' . $this -> driverName . '_Exception' ;
2008-01-05 22:55:56 +03:00
$exc = new $name ( $e -> getMessage (), ( int ) $e -> getCode ());
2007-01-07 17:52:16 +03:00
if ( ! is_array ( $e -> errorInfo )) {
$e -> errorInfo = array ( null , null , null , null );
}
$exc -> processErrorInfo ( $e -> errorInfo );
2007-07-12 02:03:47 +04:00
if ( $this -> getAttribute ( Doctrine :: ATTR_THROW_EXCEPTIONS )) {
throw $exc ;
}
$this -> getListener () -> postError ( $event );
2007-01-07 17:52:16 +03:00
}
2007-10-21 10:23:59 +04:00
2007-01-07 17:52:16 +03:00
/**
* hasTable
* whether or not this connection has table $name initialized
*
* @ param mixed $name
* @ return boolean
*/
public function hasTable ( $name )
{
return isset ( $this -> tables [ $name ]);
}
2008-01-05 22:55:56 +03:00
2007-01-07 17:52:16 +03:00
/**
2008-01-05 22:55:56 +03:00
* Gets the table object that represents the database table that is used to
* persist the specified domain class .
2007-01-07 17:52:16 +03:00
*
* @ param string $name component name
2008-01-05 22:55:56 +03:00
* @ return Doctrine_Table
2007-01-07 17:52:16 +03:00
*/
2008-01-05 22:55:56 +03:00
public function getTable ( $className )
2007-01-07 17:52:16 +03:00
{
2008-01-05 22:55:56 +03:00
if ( isset ( $this -> tables [ $className ])) {
return $this -> tables [ $className ];
2007-01-07 17:52:16 +03:00
}
2008-01-05 22:55:56 +03:00
$this -> _tableFactory -> loadTables ( $className , $this -> tables );
return $this -> tables [ $className ];
}
/**
2008-01-12 22:49:11 +03:00
* Gets a mapper for the specified domain class that is used to map instances of
2008-01-05 22:55:56 +03:00
* the class between the relational database and their object representation .
*
* @ return Doctrine_Mapper_Abstract The mapper object .
*/
public function getMapper ( $className )
{
if ( isset ( $this -> _mappers [ $className ])) {
return $this -> _mappers [ $className ];
}
$customMapperClass = $className . 'Mapper' ;
if ( class_exists ( $customMapperClass , $this -> getAttribute ( Doctrine :: ATTR_AUTOLOAD_TABLE_CLASSES )) &&
2008-01-12 22:49:11 +03:00
in_array ( 'Doctrine_Mapper_Abstract' , class_parents ( $customMapperClass ))) {
2008-01-05 22:55:56 +03:00
$table = $this -> getTable ( $className );
2008-01-12 22:49:11 +03:00
$mapper = new $customMapperClass ( $className , $table );
2007-01-07 17:52:16 +03:00
} else {
2008-01-05 22:55:56 +03:00
// instantiate correct mapper type
$table = $this -> getTable ( $className );
$inheritanceType = $table -> getInheritanceType ();
if ( $inheritanceType == Doctrine :: INHERITANCETYPE_JOINED ) {
$mapper = new Doctrine_Mapper_Joined ( $className , $table );
} else if ( $inheritanceType == Doctrine :: INHERITANCETYPE_SINGLE_TABLE ) {
$mapper = new Doctrine_Mapper_SingleTable ( $className , $table );
} else if ( $inheritanceType == Doctrine :: INHERITANCETYPE_TABLE_PER_CLASS ) {
$mapper = new Doctrine_Mapper_TablePerClass ( $className , $table );
} else {
throw new Doctrine_Connection_Exception ( " Unknown inheritance type ' $inheritanceType '. Can't create mapper. " );
}
2007-01-07 17:52:16 +03:00
}
2007-04-03 21:36:46 +04:00
2008-01-05 22:55:56 +03:00
$this -> _mappers [ $className ] = $mapper ;
return $mapper ;
2007-01-07 17:52:16 +03:00
}
2007-10-21 10:23:59 +04:00
2007-01-07 17:52:16 +03:00
/**
* returns an array of all initialized tables
*
* @ return array
*/
public function getTables ()
{
return $this -> tables ;
}
2008-01-05 22:55:56 +03:00
public function getMappers ()
{
//var_dump($this->_mappers);
return $this -> _mappers ;
}
2007-10-21 10:23:59 +04:00
2007-01-07 17:52:16 +03:00
/**
* returns an iterator that iterators through all
* initialized table objects
*
* < code >
* foreach ( $conn as $index => $table ) {
* print $table ; // get a string representation of each table object
* }
* </ code >
*
* @ return ArrayIterator SPL ArrayIterator object
*/
public function getIterator ()
{
return new ArrayIterator ( $this -> tables );
}
2007-10-21 10:23:59 +04:00
2007-01-07 17:52:16 +03:00
/**
* returns the count of initialized table objects
*
* @ return integer
*/
public function count ()
{
2007-06-20 03:33:04 +04:00
return $this -> _count ;
2007-01-07 17:52:16 +03:00
}
2007-10-21 10:23:59 +04:00
2007-01-07 17:52:16 +03:00
/**
* addTable
* adds a Doctrine_Table object into connection registry
*
2007-06-12 03:25:46 +04:00
* @ param $table a Doctrine_Table object to be added into registry
2007-01-07 17:52:16 +03:00
* @ return boolean
*/
2007-06-12 03:25:46 +04:00
public function addTable ( Doctrine_Table $table )
2007-01-07 17:52:16 +03:00
{
2007-06-12 03:25:46 +04:00
$name = $table -> getComponentName ();
2007-01-07 17:52:16 +03:00
if ( isset ( $this -> tables [ $name ])) {
return false ;
}
2007-06-12 03:25:46 +04:00
$this -> tables [ $name ] = $table ;
2007-01-07 17:52:16 +03:00
return true ;
}
2007-10-21 10:23:59 +04:00
2007-01-07 17:52:16 +03:00
/**
* create
* creates a record
*
* create creates a record
* @ param string $name component name
* @ return Doctrine_Record Doctrine_Record object
*/
public function create ( $name )
{
2008-01-05 22:55:56 +03:00
return $this -> getMapper ( $name ) -> create ();
2007-01-07 17:52:16 +03:00
}
2007-11-19 20:55:23 +03:00
/**
* Creates a new Doctrine_Query object that operates on this connection .
*
* @ return Doctrine_Query
*/
public function createQuery ()
{
return new Doctrine_Query ( $this );
}
2007-10-21 10:23:59 +04:00
2007-01-07 17:52:16 +03:00
/**
* flush
* saves all the records from all tables
* this operation is isolated using a transaction
*
* @ throws PDOException if something went wrong at database level
* @ return void
*/
public function flush ()
{
2007-12-12 18:52:12 +03:00
$this -> beginInternalTransaction ();
2007-01-07 17:52:16 +03:00
$this -> unitOfWork -> saveAll ();
$this -> commit ();
}
2007-10-21 10:23:59 +04:00
2007-01-07 17:52:16 +03:00
/**
* clear
* clears all repositories
*
* @ return void
*/
public function clear ()
{
2008-01-05 22:55:56 +03:00
foreach ( $this -> _mappers as $mapper ) {
$mapper -> getRepository () -> evictAll ();
$mapper -> clear ();
2007-01-07 17:52:16 +03:00
}
}
2007-10-21 10:23:59 +04:00
2007-01-07 17:52:16 +03:00
/**
* evictTables
* evicts all tables
*
* @ return void
*/
public function evictTables ()
{
$this -> tables = array ();
2008-01-05 22:55:56 +03:00
$this -> _mappers = array ();
2007-04-03 21:36:46 +04:00
$this -> exported = array ();
2007-01-07 17:52:16 +03:00
}
2007-10-21 10:23:59 +04:00
2007-01-07 17:52:16 +03:00
/**
* close
* closes the connection
*
* @ return void
*/
public function close ()
{
2007-09-03 18:57:18 +04:00
$event = new Doctrine_Event ( $this , Doctrine_Event :: CONN_CLOSE );
2007-06-26 16:08:50 +04:00
$this -> getAttribute ( Doctrine :: ATTR_LISTENER ) -> preClose ( $event );
2007-01-07 17:52:16 +03:00
$this -> clear ();
2007-06-26 16:08:50 +04:00
2007-08-30 01:57:46 +04:00
unset ( $this -> dbh );
2007-08-10 02:26:57 +04:00
$this -> isConnected = false ;
2007-01-07 17:52:16 +03:00
2007-06-26 16:08:50 +04:00
$this -> getAttribute ( Doctrine :: ATTR_LISTENER ) -> postClose ( $event );
2007-01-07 17:52:16 +03:00
}
2007-10-21 10:23:59 +04:00
2007-01-07 17:52:16 +03:00
/**
* get the current transaction nesting level
*
* @ return integer
*/
public function getTransactionLevel ()
{
return $this -> transaction -> getTransactionLevel ();
}
2008-01-05 22:55:56 +03:00
/**
* get the current internal transaction nesting level
*
* @ return integer
*/
public function getInternalTransactionLevel ()
{
return $this -> transaction -> getInternalTransactionLevel ();
}
2007-10-21 10:23:59 +04:00
2007-06-12 23:39:03 +04:00
/**
* errorCode
* Fetch the SQLSTATE associated with the last operation on the database handle
*
* @ return integer
*/
public function errorCode ()
{
2007-09-03 18:57:18 +04:00
$this -> connect ();
2007-06-12 23:39:03 +04:00
return $this -> dbh -> errorCode ();
}
2007-10-21 10:23:59 +04:00
2007-06-12 23:39:03 +04:00
/**
* errorInfo
* Fetch extended error information associated with the last operation on the database handle
*
* @ return array
*/
public function errorInfo ()
{
2007-09-03 18:57:18 +04:00
$this -> connect ();
2007-06-12 23:39:03 +04:00
return $this -> dbh -> errorInfo ();
}
2007-11-24 21:11:09 +03:00
/**
* getCacheDriver
*
* @ return Doctrine_Cache_Interface
* @ deprecated Use getResultCacheDriver ()
*/
public function getCacheDriver ()
{
return $this -> getResultCacheDriver ();
}
/**
* getResultCacheDriver
*
* @ return Doctrine_Cache_Interface
*/
public function getResultCacheDriver ()
{
2007-11-25 22:07:30 +03:00
if ( ! $this -> getAttribute ( Doctrine :: ATTR_RESULT_CACHE )) {
2007-11-24 21:11:09 +03:00
throw new Doctrine_Exception ( 'Result Cache driver not initialized.' );
}
2007-11-25 22:07:30 +03:00
return $this -> getAttribute ( Doctrine :: ATTR_RESULT_CACHE );
}
/**
* getQueryCacheDriver
*
* @ return Doctrine_Cache_Interface
*/
public function getQueryCacheDriver ()
{
if ( ! $this -> getAttribute ( Doctrine :: ATTR_QUERY_CACHE )) {
throw new Doctrine_Exception ( 'Query Cache driver not initialized.' );
}
return $this -> getAttribute ( Doctrine :: ATTR_QUERY_CACHE );
2007-11-24 21:11:09 +03:00
}
2007-10-21 10:23:59 +04:00
2007-06-12 03:37:24 +04:00
/**
* lastInsertId
*
* Returns the ID of the last inserted row , or the last value from a sequence object ,
* depending on the underlying driver .
*
* Note : This method may not return a meaningful or consistent result across different drivers ,
* because the underlying database may not even support the notion of auto - increment fields or sequences .
*
* @ param string $table name of the table into which a new row was inserted
* @ param string $field name of the field into which a new row was inserted
*/
public function lastInsertId ( $table = null , $field = null )
{
return $this -> sequence -> lastInsertId ( $table , $field );
}
2007-10-21 10:23:59 +04:00
2007-01-07 17:52:16 +03:00
/**
* beginTransaction
2007-06-12 03:25:46 +04:00
* Start a transaction or set a savepoint .
2007-01-07 17:52:16 +03:00
*
2007-06-12 03:25:46 +04:00
* if trying to set a savepoint and there is no active transaction
* a new transaction is being started
2007-01-07 17:52:16 +03:00
*
2007-06-12 03:25:46 +04:00
* Listeners : onPreTransactionBegin , onTransactionBegin
*
* @ param string $savepoint name of a savepoint to set
* @ throws Doctrine_Transaction_Exception if the transaction fails at database level
* @ return integer current transaction nesting level
2007-01-07 17:52:16 +03:00
*/
2007-06-12 03:25:46 +04:00
public function beginTransaction ( $savepoint = null )
2007-01-07 17:52:16 +03:00
{
2007-12-20 01:45:14 +03:00
return $this -> transaction -> beginTransaction ( $savepoint );
2007-01-07 17:52:16 +03:00
}
2007-12-12 18:52:12 +03:00
2008-01-05 22:55:56 +03:00
/**
* Initiates a transaction .
*
* This method must only be used by Doctrine itself to initiate transactions .
* Userland - code must use { @ link beginTransaction ()} .
*/
2007-12-12 18:52:12 +03:00
public function beginInternalTransaction ( $savepoint = null )
{
2007-12-20 01:45:14 +03:00
return $this -> transaction -> beginInternalTransaction ( $savepoint );
2007-12-12 18:52:12 +03:00
}
2007-10-21 10:23:59 +04:00
2007-01-07 17:52:16 +03:00
/**
2007-06-12 03:25:46 +04:00
* 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 .
2007-01-07 17:52:16 +03:00
*
2007-06-12 03:25:46 +04:00
* Listeners : onPreTransactionCommit , onTransactionCommit
*
* @ param string $savepoint name of a savepoint to release
* @ throws Doctrine_Transaction_Exception if the transaction fails at PDO level
* @ throws Doctrine_Validator_Exception if the transaction fails due to record validations
* @ return boolean false if commit couldn ' t be performed , true otherwise
2007-01-07 17:52:16 +03:00
*/
2007-06-12 03:25:46 +04:00
public function commit ( $savepoint = null )
2007-01-07 17:52:16 +03:00
{
2007-12-20 01:45:14 +03:00
return $this -> transaction -> commit ( $savepoint );
2007-01-07 17:52:16 +03:00
}
2007-10-21 10:23:59 +04:00
2007-01-07 17:52:16 +03:00
/**
* rollback
2007-06-12 03:25:46 +04:00
* Cancel any database changes done during a transaction or since a specific
* savepoint that is in progress . This function may only be called when
* auto - committing is disabled , otherwise it will fail . Therefore , a new
* transaction is implicitly started after canceling the pending changes .
2007-01-07 17:52:16 +03:00
*
2007-06-12 03:25:46 +04:00
* this method can be listened with onPreTransactionRollback and onTransactionRollback
* eventlistener methods
2007-01-07 17:52:16 +03:00
*
2007-06-12 03:25:46 +04:00
* @ param string $savepoint name of a savepoint to rollback to
* @ throws Doctrine_Transaction_Exception if the rollback operation fails at database level
* @ return boolean false if rollback couldn ' t be performed , true otherwise
2007-01-07 17:52:16 +03:00
*/
2007-06-12 03:25:46 +04:00
public function rollback ( $savepoint = null )
2007-01-07 17:52:16 +03:00
{
2007-06-12 03:25:46 +04:00
$this -> transaction -> rollback ( $savepoint );
2007-01-07 17:52:16 +03:00
}
2007-08-30 01:57:46 +04:00
2008-01-23 00:42:17 +03:00
/**
* createDatabase
*
2008-01-23 00:58:03 +03:00
* Method for creating the database for the connection instance
*
* @ return mixed Will return an instance of the exception thrown if the create database fails , otherwise it returns a string detailing the success
2008-01-23 00:42:17 +03:00
*/
public function createDatabase ()
{
2008-01-23 00:58:03 +03:00
try {
if ( ! $dsn = $this -> getOption ( 'dsn' )) {
throw new Doctrine_Connection_Exception ( 'You must create your Doctrine_Connection by using a valid Doctrine style dsn in order to use the create/drop database functionality' );
}
2008-01-23 00:42:17 +03:00
2008-01-23 00:58:03 +03:00
$manager = $this -> getManager ();
2008-01-23 00:42:17 +03:00
2008-01-23 00:58:03 +03:00
$info = $manager -> parsePdoDsn ( $dsn );
$username = $this -> getOption ( 'username' );
$password = $this -> getOption ( 'password' );
2008-01-23 00:42:17 +03:00
2008-01-23 00:58:03 +03:00
// Make connection without database specified so we can create it
$connect = $manager -> openConnection ( new PDO ( $info [ 'scheme' ] . ':host=' . $info [ 'host' ], $username , $password ), 'tmp_connection' , false );
2008-01-23 00:42:17 +03:00
2008-01-23 00:58:03 +03:00
// Create database
$connect -> export -> createDatabase ( $info [ 'dbname' ]);
2008-01-23 00:42:17 +03:00
2008-01-23 00:58:03 +03:00
// Close the tmp connection with no database
$manager -> closeConnection ( $connect );
2008-01-23 00:42:17 +03:00
2008-01-23 00:58:03 +03:00
// Close original connection
$manager -> closeConnection ( $this );
// Reopen original connection with newly created database
$manager -> openConnection ( new PDO ( $info [ 'dsn' ], $username , $password ), $this -> getName (), true );
return 'Successfully created database for connection "' . $this -> getName () . '" named "' . $info [ 'dbname' ] . '"' ;
} catch ( Exception $e ) {
return $e ;
}
2008-01-23 00:42:17 +03:00
}
/**
* dropDatabase
*
2008-01-23 00:58:03 +03:00
* Method for dropping the database for the connection instance
*
* @ return mixed Will return an instance of the exception thrown if the drop database fails , otherwise it returns a string detailing the success
2008-01-23 00:42:17 +03:00
*/
public function dropDatabase ()
{
try {
2008-01-23 00:58:03 +03:00
if ( ! $dsn = $this -> getOption ( 'dsn' )) {
throw new Doctrine_Connection_Exception ( 'You must create your Doctrine_Connection by using a valid Doctrine style dsn in order to use the create/drop database functionality' );
}
$info = $this -> getManager () -> parsePdoDsn ( $dsn );
2008-01-23 00:42:17 +03:00
$this -> export -> dropDatabase ( $info [ 'dbname' ]);
return 'Successfully dropped database for connection "' . $this -> getName () . '" named "' . $info [ 'dbname' ] . '"' ;
} catch ( Exception $e ) {
return $e ;
}
}
2007-01-07 17:52:16 +03:00
/**
* returns a string representation of this object
* @ return string
*/
public function __toString ()
{
return Doctrine_Lib :: getConnectionAsString ( $this );
}
2008-01-23 00:58:03 +03:00
}