From c3ad955912352dc7f3aeb3e8bc0107a601d0e10f Mon Sep 17 00:00:00 2001 From: romanb Date: Fri, 12 Sep 2008 17:25:38 +0000 Subject: [PATCH] further cleanups --- lib/Doctrine/Connection.php | 953 ----------------- lib/Doctrine/Connection/Common.php | 60 -- lib/Doctrine/Connection/Db2.php | 65 -- lib/Doctrine/Connection/Exception.php | 118 --- lib/Doctrine/Connection/Firebird.php | 67 -- lib/Doctrine/Connection/Informix.php | 53 - lib/Doctrine/Connection/Module.php | 84 -- lib/Doctrine/Connection/Mssql.php | 140 --- lib/Doctrine/Connection/Mysql.php | 195 ---- lib/Doctrine/Connection/Oracle.php | 52 - lib/Doctrine/Connection/Pgsql.php | 130 --- lib/Doctrine/Connection/Profiler.php | 185 ---- .../Connection/Profiler/Exception.php | 36 - lib/Doctrine/Connection/Sqlite.php | 141 --- lib/Doctrine/Connection/Statement.php | 438 -------- lib/Doctrine/DBAL/Connection.php | 987 +++++++++++++++++- lib/Doctrine/DBAL/Driver.php | 2 +- lib/Doctrine/DBAL/Driver/Connection.php | 25 + lib/Doctrine/DBAL/Driver/PDOConnection.php | 12 + .../DBAL/Driver/PDOMsSql/Connection.php | 48 +- lib/Doctrine/DBAL/Driver/PDOMsSql/Driver.php | 6 +- .../DBAL/Driver/PDOMySql/Connection.php | 57 - lib/Doctrine/DBAL/Driver/PDOMySql/Driver.php | 6 +- lib/Doctrine/DBAL/Driver/PDOOracle/Driver.php | 6 +- lib/Doctrine/DBAL/Driver/PDOPgSql/Driver.php | 6 +- lib/Doctrine/DBAL/Driver/PDOSqlite/Driver.php | 12 +- lib/Doctrine/DBAL/Driver/PDOStatement.php | 6 + lib/Doctrine/DBAL/{ => Driver}/Statement.php | 7 +- lib/Doctrine/DBAL/DriverManager.php | 116 ++ .../DBAL/Exceptions/DBALException.php | 30 + .../DBAL/Platforms/AbstractPlatform.php | 42 + .../DBAL/Platforms/FirebirdPlatform.php | 33 + lib/Doctrine/DBAL/Platforms/MsSqlPlatform.php | 11 + lib/Doctrine/DBAL/Platforms/MySqlPlatform.php | 11 + .../DBAL/Platforms/OraclePlatform.php | 31 + .../DBAL/Platforms/PostgreSqlPlatform.php | 12 + .../DBAL/Platforms/SqlitePlatform.php | 31 + lib/Doctrine/ORM/EntityManager.php | 4 +- .../{Connection => ORM}/UnitOfWork.php | 6 +- lib/Doctrine/Query/Parser.php | 2 +- lib/Doctrine/Query/SqlBuilder.php | 41 +- lib/Doctrine/Sequence/Db2.php | 124 --- lib/Doctrine/Sequence/Exception.php | 34 - lib/Doctrine/Sequence/Firebird.php | 107 -- lib/Doctrine/Sequence/Informix.php | 35 - lib/Doctrine/Sequence/Mssql.php | 158 --- lib/Doctrine/Sequence/Mysql.php | 105 -- lib/Doctrine/Sequence/Oracle.php | 97 -- lib/Doctrine/Sequence/Pgsql.php | 96 -- lib/Doctrine/Sequence/Sqlite.php | 107 -- lib/Doctrine/Transaction/Exception.php | 35 - lib/Doctrine/Transaction/Firebird.php | 142 --- lib/Doctrine/Transaction/Informix.php | 33 - lib/Doctrine/Transaction/Mock.php | 37 - lib/Doctrine/Transaction/Mssql.php | 100 -- lib/Doctrine/Transaction/Mysql.php | 117 --- lib/Doctrine/Transaction/Oracle.php | 108 -- lib/Doctrine/Transaction/Pgsql.php | 110 -- lib/Doctrine/Transaction/Sqlite.php | 68 -- tests/lib/Doctrine_OrmTestCase.php | 5 +- tests/lib/Doctrine_OrmTestSuite.php | 3 +- tests/lib/Doctrine_TestUtil.php | 2 +- tests/lib/mocks/Doctrine_ConnectionMock.php | 12 +- .../mocks/Doctrine_DriverConnectionMock.php | 17 + tests/lib/mocks/Doctrine_DriverMock.php | 33 + 65 files changed, 1435 insertions(+), 4517 deletions(-) delete mode 100644 lib/Doctrine/Connection.php delete mode 100644 lib/Doctrine/Connection/Common.php delete mode 100644 lib/Doctrine/Connection/Db2.php delete mode 100644 lib/Doctrine/Connection/Exception.php delete mode 100644 lib/Doctrine/Connection/Firebird.php delete mode 100644 lib/Doctrine/Connection/Informix.php delete mode 100644 lib/Doctrine/Connection/Module.php delete mode 100644 lib/Doctrine/Connection/Mssql.php delete mode 100644 lib/Doctrine/Connection/Mysql.php delete mode 100644 lib/Doctrine/Connection/Oracle.php delete mode 100644 lib/Doctrine/Connection/Pgsql.php delete mode 100644 lib/Doctrine/Connection/Profiler.php delete mode 100644 lib/Doctrine/Connection/Profiler/Exception.php delete mode 100644 lib/Doctrine/Connection/Sqlite.php delete mode 100644 lib/Doctrine/Connection/Statement.php create mode 100644 lib/Doctrine/DBAL/Driver/Connection.php create mode 100644 lib/Doctrine/DBAL/Driver/PDOConnection.php delete mode 100644 lib/Doctrine/DBAL/Driver/PDOMySql/Connection.php create mode 100644 lib/Doctrine/DBAL/Driver/PDOStatement.php rename lib/Doctrine/DBAL/{ => Driver}/Statement.php (97%) create mode 100644 lib/Doctrine/DBAL/DriverManager.php create mode 100644 lib/Doctrine/DBAL/Exceptions/DBALException.php rename lib/Doctrine/{Connection => ORM}/UnitOfWork.php (99%) delete mode 100644 lib/Doctrine/Sequence/Db2.php delete mode 100644 lib/Doctrine/Sequence/Exception.php delete mode 100644 lib/Doctrine/Sequence/Firebird.php delete mode 100644 lib/Doctrine/Sequence/Informix.php delete mode 100644 lib/Doctrine/Sequence/Mssql.php delete mode 100644 lib/Doctrine/Sequence/Mysql.php delete mode 100644 lib/Doctrine/Sequence/Oracle.php delete mode 100644 lib/Doctrine/Sequence/Pgsql.php delete mode 100644 lib/Doctrine/Sequence/Sqlite.php delete mode 100644 lib/Doctrine/Transaction/Exception.php delete mode 100644 lib/Doctrine/Transaction/Firebird.php delete mode 100644 lib/Doctrine/Transaction/Informix.php delete mode 100644 lib/Doctrine/Transaction/Mock.php delete mode 100644 lib/Doctrine/Transaction/Mssql.php delete mode 100644 lib/Doctrine/Transaction/Mysql.php delete mode 100644 lib/Doctrine/Transaction/Oracle.php delete mode 100644 lib/Doctrine/Transaction/Pgsql.php delete mode 100644 lib/Doctrine/Transaction/Sqlite.php create mode 100644 tests/lib/mocks/Doctrine_DriverConnectionMock.php create mode 100644 tests/lib/mocks/Doctrine_DriverMock.php diff --git a/lib/Doctrine/Connection.php b/lib/Doctrine/Connection.php deleted file mode 100644 index ee28076e2..000000000 --- a/lib/Doctrine/Connection.php +++ /dev/null @@ -1,953 +0,0 @@ -. - */ - -#namespace Doctrine::DBAL; - -#use Doctrine::Common::Configuration; -#use Doctrine::Common::EventManager; -#use Doctrine::DBAL::Exceptions::ConnectionException; - -/** - * A wrapper around a Doctrine::DBAL::Connection that adds features like - * events, configuration, emulated transaction nesting and more. - * - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @since 1.0 - * @version $Revision$ - * @author Konsta Vesterinen - * @author Lukas Smith (MDB2 library) - * @author Roman Borschel - * @todo - * 1) REPLICATION SUPPORT - * Replication support should be tackled at this layer (DBAL). - * There can be options that look like: - * 'slaves' => array( - * 'slave1' => array( - * user, pass etc. - * ), - * 'slave2' => array( - * user, pass etc. - * )), - * 'slaveConnectionResolver' => new MySlaveConnectionResolver(), - * 'masters' => array(...), - * 'masterConnectionResolver' => new MyMasterConnectionResolver() - * - * Doctrine::DBAL could ship with a simple standard broker that uses a primitive - * round-robin approach to distribution. User can provide its own brokers. - * @todo Rename to ConnectionWrapper - */ -class Doctrine_Connection -{ - /** - * The PDO database handle. - * - * @var PDO - */ - protected $_pdo; - - /** - * The Configuration. - * - * @var Doctrine::Common::Configuration - */ - protected $_config; - - /** - * The EventManager. - * - * @var Doctrine::Commom::EventManager - */ - protected $_eventManager; - - /** - * The name of this connection driver. - * - * @var string $driverName - */ - protected $_driverName; - - /** - * Whether or not a connection has been established. - * - * @var boolean - */ - protected $_isConnected = false; - - /** - * Boolean flag that indicates whether identifiers should get quoted. - * - * @var boolean - */ - protected $_quoteIdentifiers; - - /** - * @var array - */ - protected $_serverInfo = array(); - - /** - * The transaction nesting level. - * - * @var integer - */ - protected $_transactionNestingLevel = 0; - - /** - * The parameters used during creation of the Connection. - * - * @var array - */ - protected $_params = array(); - - /** - * List of all available drivers. - * - * @var array $availableDrivers - * @todo Move elsewhere. - */ - private static $_availableDrivers = array( - 'Mysql', 'Pgsql', 'Oracle', 'Informix', 'Mssql', 'Sqlite', 'Firebird' - ); - - /** - * The query count. Represents the number of executed database queries by the connection. - * - * @var integer - */ - protected $_queryCount = 0; - - /** - * The DatabasePlatform object that provides information about the - * database platform used by the connection. - * - * @var Doctrine::DBAL::Platforms::DatabasePlatform - */ - protected $_platform; - - /** - * The transaction object. - * - * @var Doctrine::DBAL::Transaction - */ - protected $_transaction; - - /** - * The schema manager. - * - * @var Doctrine::DBAL::Schema::SchemaManager - */ - protected $_schemaManager; - - /** - * Constructor. - * Creates a new Connection. - * - * @param array $params The connection parameters. - */ - public function __construct(array $params, $config = null, $eventManager = null) - { - if (isset($params['pdo'])) { - $this->_pdo = $params['pdo']; - $this->_isConnected = true; - } - $this->_params = $params; - - // Create default config and event manager if none given - if ( ! $config) { - $this->_config = new Doctrine_Common_Configuration(); - } - if ( ! $eventManager) { - $this->_eventManager = new Doctrine_Common_EventManager(); - } - - // create platform - $class = "Doctrine_DBAL_Platforms_" . $this->_driverName . "Platform"; - $this->_platform = new $class(); - $this->_platform->setQuoteIdentifiers($this->_config->getQuoteIdentifiers()); - } - - public function __construct2(array $params, Doctrine_DBAL_Driver $driver, - Doctrine_Configuration $config = null, Doctrine_EventManager $eventManager = null) - { - $this->_driver = $driver; - $this->_params = $params; - - if (isset($params['pdo'])) { - $this->_pdo = $params['pdo']; - $this->_isConnected = true; - } - - // Create default config and event manager if none given - if ( ! $config) { - $this->_config = new Doctrine_Configuration(); - } - if ( ! $eventManager) { - $this->_eventManager = new Doctrine_EventManager(); - } - - $this->_platform = $driver->getDatabasePlatform(); - } - - /** - * Gets the Configuration used by the Connection. - * - * @return Configuration - */ - public function getConfiguration() - { - if ( ! $this->_config) { - $this->_config = new Doctrine_Configuration(); - } - return $this->_config; - } - - /** - * Gets the EventManager used by the Connection. - * - * @return Doctrine::Common::EventManager - */ - public function getEventManager() - { - if ( ! $this->_eventManager) { - $this->_eventManager = new Doctrine_EventManager(); - } - return $this->_eventManager; - } - - /** - * Gets the DatabasePlatform for the connection. - * - * @return Doctrine::DBAL::Platforms::DatabasePlatform - */ - public function getDatabasePlatform() - { - return $this->_platform; - } - - /** - * Returns an array of available PDO drivers - * @todo Move elsewhere. - */ - public static function getAvailableDrivers() - { - return PDO::getAvailableDrivers(); - } - - /** - * Gets the name of the instance driver - * - * @return void - */ - public function getDriverName() - { - return $this->_driverName; - } - - /** - * Gets the PDO handle used by the connection. - * - * @return PDO - */ - public function getPdo() - { - $this->connect(); - return $this->_pdo; - } - - /** - * Establishes the connection with the database. - * - * @return boolean - */ - public function connect() - { - if ($this->_isConnected) { - return false; - } - - // TODO: the extension_loaded check can happen earlier, maybe in the factory - if ( ! extension_loaded('pdo')) { - throw new Doctrine_Connection_Exception("Couldn't locate driver named " . $e[0]); - } - - $driverOptions = isset($this->_params['driverOptions']) ? - $this->_params['driverOptions'] : array(); - $user = isset($this->_params['user']) ? - $this->_params['user'] : null; - $password = isset($this->_params['password']) ? - $this->_params['password'] : null; - $this->_pdo = new PDO( - $this->_constructPdoDsn(), - $user, - $password, - $driverOptions - ); - $this->_pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); - $this->_pdo->setAttribute(PDO::ATTR_CASE, PDO::CASE_LOWER); - - $this->_isConnected = true; - - return true; - } - - /** - * Establishes the connection with the database. - * - * @return boolean - */ - public function connect2() - { - if ($this->_isConnected) { - return false; - } - - $driverOptions = isset($this->_params['driverOptions']) ? - $this->_params['driverOptions'] : array(); - $user = isset($this->_params['user']) ? - $this->_params['user'] : null; - $password = isset($this->_params['password']) ? - $this->_params['password'] : null; - - $this->_pdo = $this->_driver->connect($this->_params, $user, $password, $driverOptions); - - $this->_pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); - $this->_pdo->setAttribute(PDO::ATTR_CASE, PDO::CASE_LOWER); - - $this->_isConnected = true; - - return true; - } - - /** - * Constructs the PDO DSN for use in the PDO constructor. - * Concrete connection implementations override this implementation to - * create the proper DSN. - * - * @return string - * @todo make abstract, implement in subclasses. - * @todo throw different exception? - */ - protected function _constructPdoDsn() - { - throw Doctrine_Exception::notImplemented('_constructPdoDsn', get_class($this)); - } - - /** - * 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 - * @param array $identifier An associateve array containing identifier fieldname-value pairs. - * @return integer The number of affected rows - */ - public function delete($tableName, array $identifier) - { - $criteria = array(); - foreach (array_keys($identifier) as $id) { - $criteria[] = $this->quoteIdentifier($id) . ' = ?'; - } - - $query = 'DELETE FROM ' - . $this->quoteIdentifier($tableName) - . ' WHERE ' . implode(' AND ', $criteria); - - return $this->exec($query, array_values($identifier)); - } - - /** - * 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 - */ - public function update($tableName, array $data, array $identifier) - { - if (empty($data)) { - return false; - } - - $set = array(); - foreach ($data as $columnName => $value) { - if ($value instanceof Doctrine_Expression) { - $set[] = $this->quoteIdentifier($columnName) . ' = ' . $value->getSql(); - unset($data[$columnName]); - } else { - $set[] = $this->quoteIdentifier($columnName) . ' = ?'; - } - } - - $params = array_merge(array_values($data), array_values($identifier)); - - $sql = 'UPDATE ' . $this->quoteIdentifier($tableName) - . ' SET ' . implode(', ', $set) - . ' WHERE ' . implode(' = ? AND ', array_keys($identifier)) - . ' = ?'; - - return $this->exec($sql, $params); - } - - /** - * Inserts a table row with specified data. - * - * @param string $table The table to insert data into. - * @param array $fields An associateve array containing fieldname-value pairs. - * @return mixed boolean false if empty value array was given, - * otherwise returns the number of affected rows - */ - public function insert($tableName, array $data) - { - if (empty($data)) { - return false; - } - - // column names are specified as array keys - $cols = array(); - // the query VALUES will contain either expressions (eg 'NOW()') or ? - $a = array(); - foreach ($data as $columnName => $value) { - $cols[] = $this->quoteIdentifier($columnName); - if ($value instanceof Doctrine_Expression) { - $a[] = $value->getSql(); - unset($data[$columnName]); - } else { - $a[] = '?'; - } - } - - $query = 'INSERT INTO ' . $this->quoteIdentifier($tableName) - . ' (' . implode(', ', $cols) . ') ' - . 'VALUES ('; - $query .= implode(', ', $a) . ')'; - - return $this->exec($query, array_values($data)); - } - - /** - * Set the charset on the current connection - * - * @param string charset - */ - public function setCharset($charset) - { - $this->exec($this->_platform->getSetCharsetSql($charset)); - } - - /** - * Quote a string so it can be safely used as a table or column name. - * - * 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 (`) -- due to MySQL - * + double quote (") -- due to Oracle - * + brackets ([ or ]) -- 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 - * @todo Moved to DatabasePlatform - * @deprecated - */ - public function quoteIdentifier($str) - { - return $this->_platform->quoteIdentifier($str); - } - - /** - * Quotes given input parameter. - * - * @param mixed $input Parameter to be quoted. - * @param string $type Type of the parameter. - * @return string The quoted parameter. - */ - public function quote($input, $type = null) - { - return $this->_pdo->quote($input, $type); - } - - /** - * fetchAll - * - * @param string $statement sql query to be executed - * @param array $params prepared statement params - * @return array - */ - public function fetchAll($statement, array $params = array()) - { - return $this->execute($statement, $params)->fetchAll(PDO::FETCH_ASSOC); - } - - /** - * 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 - */ - public function fetchOne($statement, array $params = array(), $colnum = 0) - { - return $this->execute($statement, $params)->fetchColumn($colnum); - } - - /** - * 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->execute($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->execute($statement, $params)->fetch(PDO::FETCH_NUM); - } - - /** - * 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 - */ - public function fetchColumn($statement, array $params = array(), $colnum = 0) - { - return $this->execute($statement, $params)->fetchAll(PDO::FETCH_COLUMN, $colnum); - } - - /** - * 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->execute($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->execute($statement, $params)->fetchAll(PDO::FETCH_BOTH); - } - - /** - * prepare - * - * @param string $statement - */ - public function prepare($statement) - { - $this->connect(); - try { - $stmt = $this->_pdo->prepare($statement); - return new Doctrine_Connection_Statement($this, $stmt); - } catch (PDOException $e) { - $this->rethrowException($e, $this); - } - } - - /** - * Queries the database with limit and offset - * added to the query and returns a Doctrine_Connection_Statement object - * - * @param string $query - * @param integer $limit - * @param integer $offset - * @return Doctrine_Connection_Statement - */ - public function select($query, $limit = 0, $offset = 0) - { - if ($limit > 0 || $offset > 0) { - $query = $this->modifyLimitQuery($query, $limit, $offset); - } - return $this->execute($query); - } - - /** - * Executes an SQL SELECT query with the given parameters. - * - * @param string $query sql query - * @param array $params query parameters - * - * @return PDOStatement|Doctrine_Adapter_Statement - */ - public function execute($query, array $params = array()) - { - $this->connect(); - try { - if ( ! empty($params)) { - $stmt = $this->prepare($query); - $stmt->execute($params); - return $stmt; - } else { - $stmt = $this->_pdo->query($query); - $this->_queryCount++; - return $stmt; - } - } catch (PDOException $e) { - $this->rethrowException($e, $this); - } - } - - /** - * Executes an SQL INSERT/UPDATE/DELETE query with the given parameters. - * - * @param string $query sql query - * @param array $params query parameters - * - * @return PDOStatement|Doctrine_Adapter_Statement - * @todo Rename to executeUpdate(). - */ - public function exec($query, array $params = array()) { - $this->connect(); - try { - if ( ! empty($params)) { - $stmt = $this->prepare($query); - $stmt->execute($params); - return $stmt->rowCount(); - } else { - $count = $this->_pdo->exec($query); - $this->_queryCount++; - return $count; - } - } catch (PDOException $e) { - $this->rethrowException($e, $this); - } - } - - /** - * Wraps the given exception into a driver-specific exception and rethrows it. - * - * @throws Doctrine_Connection_Exception - */ - public function rethrowException(Exception $e, $invoker) - { - throw $exc; - } - - /** - * Returns the number of queries executed by the connection. - * - * @return integer - * @todo Better name: getQueryCount() - */ - public function getQueryCount() - { - return $this->_queryCount; - } - - /** - * Closes the connection. - * - * @return void - */ - public function close() - { - $this->clear(); - unset($this->_pdo); - $this->_isConnected = false; - } - - /** - * Returns the current total transaction nesting level. - * - * @return integer The nesting level. A value of 0 means theres no active transaction. - */ - public function getTransactionLevel() - { - return $this->_transaction->getTransactionLevel(); - } - - /** - * Fetch the SQLSTATE associated with the last operation on the database handle - * - * @return integer - */ - public function errorCode() - { - $this->connect(); - return $this->_pdo->errorCode(); - } - - /** - * Fetch extended error information associated with the last operation on the database handle - * - * @return array - */ - public function errorInfo() - { - $this->connect(); - return $this->_pdo->errorInfo(); - } - - /** - * 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($seqName = null) - { - return $this->_pdo->lastInsertId($seqName); - } - - /** - * Start a transaction or set a savepoint. - * - * if trying to set a savepoint and there is no active transaction - * a new transaction is being started. - * - * @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 - */ - public function beginTransaction() - { - if ($this->_transactionNestingLevel == 0) { - return $this->_pdo->beginTransaction(); - } - ++$this->_transactionNestingLevel; - return true; - } - - /** - * Commits 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. - * - * @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 - */ - public function commit() - { - if ($this->_transactionNestingLevel == 0) { - throw new Doctrine_Exception("Commit failed. There is no active transaction."); - } - - $this->connect(); - - if ($this->_transactionNestingLevel == 1) { - return $this->_pdo->commit(); - } - --$this->_transactionNestingLevel; - - return true; - } - - /** - * 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. - * - * this method can be listened with onPreTransactionRollback and onTransactionRollback - * eventlistener methods - * - * @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. - */ - public function rollback() - { - if ($this->_transactionNestingLevel == 0) { - throw new Doctrine_Exception("Rollback failed. There is no active transaction."); - } - - $this->connect(); - - if ($this->_transactionNestingLevel == 1) { - $this->_transactionNestingLevel = 0; - return $this->_pdo->rollback(); - - } - --$this->_transactionNestingLevel; - - return true; - } - - /** - * Quotes pattern (% and _) characters in a string) - * - * EXPERIMENTAL - * - * WARNING: this function is experimental and may change signature at - * any time until labelled as non-experimental - * - * @param string the input string to quote - * - * @return string quoted string - */ - protected function _escapePattern($text) - { - return $text; - } - - /** - * Removes any formatting in an sequence name using the 'seqname_format' option - * - * @param string $sqn string that containts name of a potential sequence - * @return string name of the sequence with possible formatting removed - */ - protected function _fixSequenceName($sqn) - { - $seqPattern = '/^'.preg_replace('/%s/', '([a-z0-9_]+)', $this->conn->getAttribute(Doctrine::ATTR_SEQNAME_FORMAT)).'$/i'; - $seqName = preg_replace($seqPattern, '\\1', $sqn); - - if ($seqName && ! strcasecmp($sqn, $this->getSequenceName($seqName))) { - return $seqName; - } - return $sqn; - } - - /** - * Removes any formatting in an index name using the 'idxname_format' option - * - * @param string $idx string that containts name of anl index - * @return string name of the index with possible formatting removed - */ - protected function _fixIndexName($idx) - { - $indexPattern = '/^'.preg_replace('/%s/', '([a-z0-9_]+)', $this->conn->getAttribute(Doctrine::ATTR_IDXNAME_FORMAT)).'$/i'; - $indexName = preg_replace($indexPattern, '\\1', $idx); - if ($indexName && ! strcasecmp($idx, $this->getIndexName($indexName))) { - return $indexName; - } - return $idx; - } - - /** - * adds sequence name formatting to a sequence name - * - * @param string name of the sequence - * @return string formatted sequence name - */ - protected function _getSequenceName($sqn) - { - return sprintf($this->conn->getAttribute(Doctrine::ATTR_SEQNAME_FORMAT), - preg_replace('/[^a-z0-9_\$.]/i', '_', $sqn)); - } - - /** - * adds index name formatting to a index name - * - * @param string name of the index - * @return string formatted index name - */ - protected function _getIndexName($idx) - { - return sprintf($this->conn->getAttribute(Doctrine::ATTR_IDXNAME_FORMAT), - preg_replace('/[^a-z0-9_\$]/i', '_', $idx)); - } - - /** - * adds table name formatting to a table name - * - * @param string name of the table - * @return string formatted table name - */ - protected function _getTableName($table) - { - return $table; - /* - return sprintf($this->conn->getAttribute(Doctrine::ATTR_TBLNAME_FORMAT), - $table);*/ - } - - /** - * returns a string representation of this object - * @return string - */ - public function __toString() - { - return Doctrine_Lib::getConnectionAsString($this); - } - - /** - * Gets the SchemaManager that can be used to inspect or change the - * database schema through the connection. - * - * @return Doctrine::DBAL::Schema::SchemaManager - */ - public function getSchemaManager() - { - if ( ! $this->_schemaManager) { - $class = "Doctrine_Schema_" . $this->_driverName . "SchemaManager"; - $this->_schemaManager = new $class($this); - } - return $this->_schemaManager; - } - - public function getSchemaManager2() - { - if ( ! $this->_schemaManager) { - $this->_schemaManager = $this->_driver->getSchemaManager(); - } - return $this->_schemaManager; - } -} diff --git a/lib/Doctrine/Connection/Common.php b/lib/Doctrine/Connection/Common.php deleted file mode 100644 index 322166c5c..000000000 --- a/lib/Doctrine/Connection/Common.php +++ /dev/null @@ -1,60 +0,0 @@ -. - */ - -/** - * standard connection, the parent of pgsql, mysql and sqlite - * - * @package Doctrine - * @subpackage Connection - * @link www.phpdoctrine.org - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @since 1.0 - * @version $Revision$ - * @author Konsta Vesterinen - * @TODO Remove this class and move the modifyLimitQuery implementation to Connection. - * @deprecated - */ -class Doctrine_Connection_Common extends Doctrine_Connection -{ - /** - * Adds an driver-specific LIMIT clause to the query - * - * @param string $query - * @param mixed $limit - * @param mixed $offset - * @todo 4th parameter not used? Remove? - */ - public function modifyLimitQuery($query, $limit = false, $offset = false, $isManip = false) - { - $limit = (int) $limit; - $offset = (int) $offset; - - if ($limit && $offset) { - $query .= ' LIMIT ' . $limit . ' OFFSET ' . $offset; - } elseif ($limit && ! $offset) { - $query .= ' LIMIT ' . $limit; - } elseif ( ! $limit && $offset) { - $query .= ' LIMIT 999999999999 OFFSET ' . $offset; - } - - return $query; - } -} \ No newline at end of file diff --git a/lib/Doctrine/Connection/Db2.php b/lib/Doctrine/Connection/Db2.php deleted file mode 100644 index 08416c51c..000000000 --- a/lib/Doctrine/Connection/Db2.php +++ /dev/null @@ -1,65 +0,0 @@ -. - */ - -/** - * Doctrine_Connection_Db2 - * - * @package Doctrine - * @subpackage Connection - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @link www.phpdoctrine.org - * @since 1.0 - * @version $Revision$ - * @author Konsta Vesterinen - * @deprecated - */ -class Doctrine_Connection_Db2 extends Doctrine_Connection -{ - /** - * Adds an driver-specific LIMIT clause to the query - * - * @param string $query query to modify - * @param integer $limit limit the number of rows - * @param integer $offset start reading from given offset - * @return string the modified query - */ - public function modifyLimitQuery($query, $limit, $offset) - { - if ($limit <= 0) - return $query; - - if ($offset == 0) { - return $query . ' FETCH FIRST '. $limit .' ROWS ONLY'; - } else { - $sqlPieces = explode('from', $query); - $select = $sqlPieces[0]; - $table = $sqlPieces[1]; - - $col = explode('select', $select); - - $sql = 'WITH OFFSET AS(' . $select . ', ROW_NUMBER() ' . - 'OVER(ORDER BY ' . $col[1] . ') AS doctrine_rownum FROM ' . $table . ')' . - $select . 'FROM OFFSET WHERE doctrine_rownum BETWEEN ' . $offset . - 'AND ' . ($offset + $limit - 1); - return $sql; - } - } -} \ No newline at end of file diff --git a/lib/Doctrine/Connection/Exception.php b/lib/Doctrine/Connection/Exception.php deleted file mode 100644 index 41b3003dc..000000000 --- a/lib/Doctrine/Connection/Exception.php +++ /dev/null @@ -1,118 +0,0 @@ -. - */ - -/** - * Doctrine_Exception - * - * @package Doctrine - * @subpackage Connection - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @link www.phpdoctrine.org - * @since 1.0 - * @version $Revision$ - * @author Konsta Vesterinen - * @deprecated - */ -class Doctrine_Connection_Exception extends Doctrine_Exception -{ - /** - * @var array $errorMessages an array containing messages for portable error codes - */ - static protected $errorMessages = array( - Doctrine::ERR => 'unknown error', - Doctrine::ERR_ALREADY_EXISTS => 'already exists', - Doctrine::ERR_CANNOT_CREATE => 'can not create', - Doctrine::ERR_CANNOT_ALTER => 'can not alter', - Doctrine::ERR_CANNOT_REPLACE => 'can not replace', - Doctrine::ERR_CANNOT_DELETE => 'can not delete', - Doctrine::ERR_CANNOT_DROP => 'can not drop', - Doctrine::ERR_CONSTRAINT => 'constraint violation', - Doctrine::ERR_CONSTRAINT_NOT_NULL=> 'null value violates not-null constraint', - Doctrine::ERR_DIVZERO => 'division by zero', - Doctrine::ERR_INVALID => 'invalid', - Doctrine::ERR_INVALID_DATE => 'invalid date or time', - Doctrine::ERR_INVALID_NUMBER => 'invalid number', - Doctrine::ERR_MISMATCH => 'mismatch', - Doctrine::ERR_NODBSELECTED => 'no database selected', - Doctrine::ERR_NOSUCHFIELD => 'no such field', - Doctrine::ERR_NOSUCHTABLE => 'no such table', - Doctrine::ERR_NOT_CAPABLE => 'Doctrine backend not capable', - Doctrine::ERR_NOT_FOUND => 'not found', - Doctrine::ERR_NOT_LOCKED => 'not locked', - Doctrine::ERR_SYNTAX => 'syntax error', - Doctrine::ERR_UNSUPPORTED => 'not supported', - Doctrine::ERR_VALUE_COUNT_ON_ROW => 'value count on row', - Doctrine::ERR_INVALID_DSN => 'invalid DSN', - Doctrine::ERR_CONNECT_FAILED => 'connect failed', - Doctrine::ERR_NEED_MORE_DATA => 'insufficient data supplied', - Doctrine::ERR_EXTENSION_NOT_FOUND=> 'extension not found', - Doctrine::ERR_NOSUCHDB => 'no such database', - Doctrine::ERR_ACCESS_VIOLATION => 'insufficient permissions', - Doctrine::ERR_LOADMODULE => 'error while including on demand module', - Doctrine::ERR_TRUNCATED => 'truncated', - Doctrine::ERR_DEADLOCK => 'deadlock detected', - ); - - /** - * @see Doctrine::ERR_* constants - * @since 1.0 - * @var integer $portableCode portable error code - */ - protected $portableCode; - - /** - * getPortableCode - * returns portable error code - * - * @return integer portable error code - */ - public function getPortableCode() - { - return $this->portableCode; - } - - /** - * getPortableMessage - * returns portable error message - * - * @return string portable error message - */ - public function getPortableMessage() - { - return self::errorMessage($this->portableCode); - } - - /** - * Return a textual error message for a Doctrine error code - * - * @param int|array integer error code, - * null to get the current error code-message map, - * or an array with a new error code-message map - * - * @return string error message, or false if the error code was - * not recognized - */ - public function errorMessage($value = null) - { - return isset(self::$errorMessages[$value]) ? - self::$errorMessages[$value] : self::$errorMessages[Doctrine::ERR]; - } -} \ No newline at end of file diff --git a/lib/Doctrine/Connection/Firebird.php b/lib/Doctrine/Connection/Firebird.php deleted file mode 100644 index 914d90e5d..000000000 --- a/lib/Doctrine/Connection/Firebird.php +++ /dev/null @@ -1,67 +0,0 @@ -. - */ - -/** - * Doctrine_Connection_Firebird - * - * @package Doctrine - * @subpackage Connection - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @author Konsta Vesterinen - * @author Lukas Smith (PEAR MDB2 library) - * @author Lorenzo Alberton (PEAR MDB2 Interbase driver) - * @version $Revision$ - * @link www.phpdoctrine.org - * @since 1.0 - * @deprecated - */ -class Doctrine_Connection_Firebird extends Doctrine_Connection -{ - /** - * @var string $driverName the name of this connection driver - */ - protected $driverName = 'Firebird'; - - /** - * the constructor - * - * @param Doctrine_Manager $manager - * @param PDO $pdo database handle - */ - public function __construct(array $params) - { - parent::__construct($params); - } - - /** - * Set the charset on the current connection - * - * @param string charset - * - * @return void - */ - public function setCharset($charset) - { - $query = 'SET NAMES '.$this->dbh->quote($charset); - $this->exec($query); - } - -} \ No newline at end of file diff --git a/lib/Doctrine/Connection/Informix.php b/lib/Doctrine/Connection/Informix.php deleted file mode 100644 index 8e72eab5b..000000000 --- a/lib/Doctrine/Connection/Informix.php +++ /dev/null @@ -1,53 +0,0 @@ -. - */ - -/** - * Doctrine_Connection_Mysql - * - * @package Doctrine - * @subpackage Connection - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @link www.phpdoctrine.org - * @since 1.0 - * @version $Revision$ - * @author Konsta Vesterinen - * @deprecated - */ -class Doctrine_Connection_Informix extends Doctrine_Connection -{ - /** - * @var string $driverName the name of this connection driver - */ - protected $driverName = 'Informix'; - - /** - * the constructor - * - * @param Doctrine_Manager $manager - * @param PDO $pdo database handle - */ - public function __construct(Doctrine_Manager $manager, $adapter) - { - // initialize all driver options - - parent::__construct($manager, $adapter); - } -} \ No newline at end of file diff --git a/lib/Doctrine/Connection/Module.php b/lib/Doctrine/Connection/Module.php deleted file mode 100644 index 365f16b4f..000000000 --- a/lib/Doctrine/Connection/Module.php +++ /dev/null @@ -1,84 +0,0 @@ -. - */ - -/** - * Doctrine_Connection_Module - * - * @package Doctrine - * @subpackage Connection - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @link www.phpdoctrine.org - * @since 1.0 - * @version $Revision$ - * @author Konsta Vesterinen - * @deprecated - */ -class Doctrine_Connection_Module -{ - /** - * @var Doctrine_Connection $conn Doctrine_Connection object, every connection - * module holds an instance of Doctrine_Connection - */ - protected $conn; - - /** - * @var string $moduleName the name of this module - */ - protected $moduleName; - - /** - * @param Doctrine_Connection $conn Doctrine_Connection object, every connection - * module holds an instance of Doctrine_Connection - */ - public function __construct($conn = null) - { - if ( ! ($conn instanceof Doctrine_Connection)) { - $conn = Doctrine_Manager::getInstance()->getCurrentConnection(); - } - $this->conn = $conn; - - $e = explode('_', get_class($this)); - - $this->moduleName = $e[1]; - } - - /** - * getConnection - * returns the connection object this module uses - * - * @return Doctrine_Connection - */ - public function getConnection() - { - return $this->conn; - } - - /** - * getModuleName - * returns the name of this module - * - * @return string the name of this module - */ - public function getModuleName() - { - return $this->moduleName; - } -} \ No newline at end of file diff --git a/lib/Doctrine/Connection/Mssql.php b/lib/Doctrine/Connection/Mssql.php deleted file mode 100644 index 55d5d6b96..000000000 --- a/lib/Doctrine/Connection/Mssql.php +++ /dev/null @@ -1,140 +0,0 @@ -. - */ - -/** - * Doctrine_Connection_Mssql - * - * @package Doctrine - * @subpackage Connection - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @author Konsta Vesterinen - * @author Lukas Smith (PEAR MDB2 library) - * @version $Revision$ - * @link www.phpdoctrine.org - * @since 1.0 - * @deprecated - */ -class Doctrine_Connection_Mssql extends Doctrine_Connection -{ - /** - * @var string $driverName the name of this connection driver - */ - protected $driverName = 'Mssql'; - - /** - * the constructor - * - * @param Doctrine_Manager $manager - * @param PDO $pdo database handle - */ - public function __construct(array $params) - { - parent::__construct($params); - } - - /** - * Quote a string so it can be safely used as a table / column name - * - * Quoting style depends on which database driver is being used. - * - * @param string $identifier identifier name to be quoted - * @param bool $checkOption check the 'quote_identifier' option - * - * @return string quoted identifier string - */ - public function quoteIdentifier($identifier, $checkOption = false) - { - if ($checkOption && ! $this->getAttribute(Doctrine::ATTR_QUOTE_IDENTIFIER)) { - return $identifier; - } - - if (strpos($identifier, '.') !== false) { - $parts = explode('.', $identifier); - $quotedParts = array(); - foreach ($parts as $p) { - $quotedParts[] = $this->quoteIdentifier($p); - } - - return implode('.', $quotedParts); - } - - return '[' . str_replace(']', ']]', $identifier) . ']'; - } - - /** - * return version information about the server - * - * @param bool $native determines if the raw version string should be returned - * @return mixed array/string with version information or MDB2 error object - */ - public function getServerVersion($native = false) - { - if ($this->serverInfo) { - $serverInfo = $this->serverInfo; - } else { - $query = 'SELECT @@VERSION'; - $serverInfo = $this->fetchOne($query); - } - // cache server_info - $this->serverInfo = $serverInfo; - if ( ! $native) { - if (preg_match('/([0-9]+)\.([0-9]+)\.([0-9]+)/', $serverInfo, $tmp)) { - $serverInfo = array( - 'major' => $tmp[1], - 'minor' => $tmp[2], - 'patch' => $tmp[3], - 'extra' => null, - 'native' => $serverInfo, - ); - } else { - $serverInfo = array( - 'major' => null, - 'minor' => null, - 'patch' => null, - 'extra' => null, - 'native' => $serverInfo, - ); - } - } - return $serverInfo; - } - - /** - * Checks if there's a sequence that exists. - * - * @param string $seq_name The sequence name to verify. - * @return boolean The value if the table exists or not - */ - public function checkSequence($seqName) - { - $query = 'SELECT * FROM ' . $seqName; - try { - $this->exec($query); - } catch(Doctrine_Connection_Exception $e) { - if ($e->getPortableCode() == Doctrine::ERR_NOSUCHTABLE) { - return false; - } - - throw $e; - } - return true; - } -} \ No newline at end of file diff --git a/lib/Doctrine/Connection/Mysql.php b/lib/Doctrine/Connection/Mysql.php deleted file mode 100644 index bea2cb944..000000000 --- a/lib/Doctrine/Connection/Mysql.php +++ /dev/null @@ -1,195 +0,0 @@ -. - */ - -#namespace Doctrine::DBAL::Connections; - -/** - * Doctrine_Connection_Mysql - * - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @author Konsta Vesterinen - * @author Lukas Smith (PEAR MDB2 library) - * @version $Revision$ - * @link www.phpdoctrine.org - * @since 1.0 - * @deprecated - */ -class Doctrine_Connection_Mysql extends Doctrine_Connection_Common -{ - /** - * Driver name. - * - * @var string - */ - protected $_driverName = 'Mysql'; - - /** - * the constructor - * - * @param Doctrine_Manager $manager - * @param PDO|Doctrine_Adapter $adapter database handler - */ - public function __construct(array $params) - { - parent::__construct($params); - } - - /** - * Set the charset on the current connection - * - * @param string charset - */ - public function setCharset($charset) - { - $this->exec('SET NAMES ' . $this->quote($charset)); - } - - /** - * 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 implements it natively, this type of query is - * emulated through this method for other DBMS using standard types of - * queries inside a transaction to assure the atomicity of the operation. - * - * @access public - * - * @param string $table name of the table on which the REPLACE query will - * be executed. - * @param array $fields 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 also associative arrays that describe the - * values and other properties of the table fields. - * - * Here follows a list of field properties that need to be specified: - * - * value: - * Value to be assigned to the specified field. This value may be - * of specified in database independent type format as this - * function can perform the necessary datatype conversions. - * - * Default: - * this property is required unless the Null property - * is set to 1. - * - * type - * Name of the type of the field. Currently, all types Metabase - * are supported except for clob and blob. - * - * Default: no type conversion - * - * null - * Boolean property that indicates that the value for this field - * should be set to null. - * - * The default value for fields missing in INSERT queries may be - * specified the definition of a table. Often, the default value - * is already null, but since the REPLACE may be emulated using - * an UPDATE query, make sure that all fields of the table are - * listed in this function argument array. - * - * Default: 0 - * - * key - * Boolean property that indicates that this field should be - * handled as a primary key or at least as part of the compound - * unique index of the table that will determine the row that will - * updated if it exists or inserted a new row otherwise. - * - * This function will fail if no key field is specified or if the - * value of a key field is set to null because fields that are - * part of unique index they may not be null. - * - * Default: 0 - * - * @return integer the number of affected rows - */ - public function replace($tableName, array $data, array $keys) - { - $count = count($data); - $query = $values = ''; - $keys = $colnum = 0; - - for (reset($data); $colnum < $count; next($data), $colnum++) { - $name = key($data); - - if ($colnum > 0) { - $query .= ','; - $values.= ','; - } - - $query .= $name; - - if (isset($data[$name]['null']) && $data[$name]['null']) { - $value = 'NULL'; - } else { - $type = isset($data[$name]['type']) ? $data[$name]['type'] : null; - $value = $this->quote($data[$name]['value'], $type); - } - - $values .= $value; - - if (isset($data[$name]['key']) && $data[$name]['key']) { - if ($value === 'NULL') { - throw new Doctrine_Connection_Mysql_Exception('key value '.$name.' may not be NULL.'); - } - $keys++; - } - } - - if ($keys == 0) { - throw new Doctrine_Connection_Mysql_Exception('Not specified which fields are keys.'); - } - $query = 'REPLACE INTO ' . $tableName . ' (' . $query . ') VALUES (' . $values . ')'; - - return $this->exec($query); - } - - /** - * Constructs the MySql PDO DSN. - * - * Overrides Connection#_constructPdoDsn(). - * - * @return string The DSN. - */ - protected function _constructPdoDsn() - { - $dsn = 'mysql:'; - if (isset($this->_params['host'])) { - $dsn .= 'host=' . $this->_params['host'] . ';'; - } - if (isset($this->_params['port'])) { - $dsn .= 'port=' . $this->_params['port'] . ';'; - } - if (isset($this->_params['dbname'])) { - $dsn .= 'dbname=' . $this->_params['dbname'] . ';'; - } - if (isset($this->_params['unix_socket'])) { - $dsn .= 'unix_socket=' . $this->_params['unix_socket'] . ';'; - } - - return $dsn; - } -} diff --git a/lib/Doctrine/Connection/Oracle.php b/lib/Doctrine/Connection/Oracle.php deleted file mode 100644 index 2bc79c936..000000000 --- a/lib/Doctrine/Connection/Oracle.php +++ /dev/null @@ -1,52 +0,0 @@ -. - */ - -/** - * Doctrine_Connection_Oracle - * - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @link www.phpdoctrine.org - * @since 1.0 - * @version $Revision$ - * @author Konsta Vesterinen - * @deprecated - */ -class Doctrine_Connection_Oracle extends Doctrine_Connection -{ - /** - * @var string $driverName the name of this connection driver - */ - protected $driverName = 'Oracle'; - - public function __construct(array $params) - { - parent::__construct($params); - } - - /** - * Sets up the date/time format - * - */ - public function setDateFormat($format = 'YYYY-MM-DD HH24:MI:SS') - { - $this->exec('ALTER SESSION SET NLS_DATE_FORMAT = "' . $format . '"'); - } -} \ No newline at end of file diff --git a/lib/Doctrine/Connection/Pgsql.php b/lib/Doctrine/Connection/Pgsql.php deleted file mode 100644 index 393ef9d48..000000000 --- a/lib/Doctrine/Connection/Pgsql.php +++ /dev/null @@ -1,130 +0,0 @@ -. - */ - -#namespace Doctrine::DBAL::Connections; - -/** - * PgsqlConnection - * - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @author Konsta Vesterinen - * @author Lukas Smith (PEAR MDB2 library) - * @version $Revision$ - * @link www.phpdoctrine.org - * @since 1.0 - * @deprecated - */ -class Doctrine_Connection_Pgsql extends Doctrine_Connection_Common -{ - /** - * @var string $driverName the name of this connection driver - */ - protected $driverName = 'Pgsql'; - - /** - * the constructor - * - * @param Doctrine_Manager $manager - * @param PDO $pdo database handle - */ - public function __construct(array $params) - { - parent::__construct($params); - } - - /** - * Set the charset on the current connection - * - * @param string charset - * - * @return void - */ - public function setCharset($charset) - { - $query = 'SET NAMES '.$this->dbh->quote($charset); - $this->exec($query); - } - - /** - * convertBoolean - * 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 - * @deprecated Moved to PostgreSqlPlatform - */ - public function convertBooleans($item) - { - if (is_array($item)) { - foreach ($item as $key => $value) { - if (is_bool($value) || is_numeric($item)) { - $item[$key] = ($value) ? 'true' : 'false'; - } - } - } else { - if (is_bool($item) || is_numeric($item)) { - $item = ($item) ? 'true' : 'false'; - } - } - return $item; - } - - /** - * return version information about the server - * - * @param string $native determines if the raw version string should be returned - * @return array|string an array or string with version information - */ - /*public function getServerVersion($native = false) - { - $query = 'SHOW SERVER_VERSION'; - - $serverInfo = $this->fetchOne($query); - - if ( ! $native) { - $tmp = explode('.', $serverInfo, 3); - - if (empty($tmp[2]) && isset($tmp[1]) - && preg_match('/(\d+)(.*)/', $tmp[1], $tmp2) - ) { - $serverInfo = array( - 'major' => $tmp[0], - 'minor' => $tmp2[1], - 'patch' => null, - 'extra' => $tmp2[2], - 'native' => $serverInfo, - ); - } else { - $serverInfo = array( - 'major' => isset($tmp[0]) ? $tmp[0] : null, - 'minor' => isset($tmp[1]) ? $tmp[1] : null, - 'patch' => isset($tmp[2]) ? $tmp[2] : null, - 'extra' => null, - 'native' => $serverInfo, - ); - } - } - return $serverInfo; - }*/ -} \ No newline at end of file diff --git a/lib/Doctrine/Connection/Profiler.php b/lib/Doctrine/Connection/Profiler.php deleted file mode 100644 index 6c9b51c4d..000000000 --- a/lib/Doctrine/Connection/Profiler.php +++ /dev/null @@ -1,185 +0,0 @@ -. - */ - -/** - * Doctrine_Connection_Profiler - * - * @package Doctrine - * @subpackage Connection - * @author Konsta Vesterinen - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @link www.phpdoctrine.org - * @since 1.0 - * @version $Revision$ - * @deprecated - * @todo remove - */ -class Doctrine_Connection_Profiler implements Doctrine_Overloadable, IteratorAggregate, Countable -{ - /** - * @param array $listeners an array containing all availible listeners - */ - private $listeners = array('query', - 'prepare', - 'commit', - 'rollback', - 'connect', - 'begintransaction', - 'exec', - 'execute', - ); - - /** - * @param array $events an array containing all listened events - */ - private $events = array(); - - /** - * constructor - */ - public function __construct() { - - } - - /** - * setFilterQueryType - * - * @param integer $filter - * @return boolean - */ - public function setFilterQueryType() { - - } - /** - * method overloader - * this method is used for invoking different listeners, for the full - * list of availible listeners, see Doctrine_EventListener - * - * @param string $m the name of the method - * @param array $a method arguments - * @see Doctrine_EventListener - * @return boolean - */ - public function __call($m, $a) - { - // first argument should be an instance of Doctrine_Event - if ( ! ($a[0] instanceof Doctrine_Event)) { - throw new Doctrine_Connection_Profiler_Exception("Couldn't listen event. Event should be an instance of Doctrine_Event."); - } - - - if (substr($m, 0, 3) === 'pre') { - // pre-event listener found - $a[0]->start(); - - if ( ! in_array($a[0], $this->events, true)) { - $this->events[] = $a[0]; - } - } else { - // after-event listener found - $a[0]->end(); - } - /** - * If filtering by query type is enabled, only keep the query if - * it was one of the allowed types. - */ - /** - if ( ! is_null($this->filterTypes)) { - if ( ! ($a[0]->getQueryType() & $this->_filterTypes)) { - - } - } - */ - - } - - /** - * get - * - * @param mixed $key - * @return Doctrine_Event - */ - public function get($key) - { - if (isset($this->events[$key])) { - return $this->events[$key]; - } - return null; - } - - /** - * getAll - * returns all profiled events as an array - * - * @return array all events in an array - */ - public function getAll() - { - return $this->events; - } - - /** - * getIterator - * returns an iterator that iterates through the logged events - * - * @return ArrayIterator - */ - public function getIterator() - { - return new ArrayIterator($this->events); - } - - /** - * count - * - * @return integer - */ - public function count() - { - return count($this->events); - } - - /** - * pop the last event from the event stack - * - * @return Doctrine_Event - */ - public function pop() - { - return array_pop($this->events); - } - - /** - * Get the Doctrine_Event object for the last query that was run, regardless if it has - * ended or not. If the event has not ended, it's end time will be Null. - * - * @return Doctrine_Event - */ - public function lastEvent() - { - if (empty($this->events)) { - return false; - } - - end($this->events); - return current($this->events); - } -} \ No newline at end of file diff --git a/lib/Doctrine/Connection/Profiler/Exception.php b/lib/Doctrine/Connection/Profiler/Exception.php deleted file mode 100644 index 9eab3c125..000000000 --- a/lib/Doctrine/Connection/Profiler/Exception.php +++ /dev/null @@ -1,36 +0,0 @@ -. - */ - -/** - * Doctrine_Connection_Profiler_Exception - * - * @package Doctrine - * @subpackage Connection - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @link www.phpdoctrine.org - * @since 1.0 - * @version $Revision: 1345 $ - * @author Konsta Vesterinen - * @deprecated - */ -class Doctrine_Connection_Profiler_Exception extends Doctrine_Exception -{ -} \ No newline at end of file diff --git a/lib/Doctrine/Connection/Sqlite.php b/lib/Doctrine/Connection/Sqlite.php deleted file mode 100644 index 27386cfca..000000000 --- a/lib/Doctrine/Connection/Sqlite.php +++ /dev/null @@ -1,141 +0,0 @@ -. - */ - -#namespace Doctrine::DBAL::Connections; - -/** - * Doctrine_Connection_Sqlite - * - * @package Doctrine - * @subpackage Connection - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @author Konsta Vesterinen - * @author Lukas Smith (PEAR MDB2 library) - * @version $Revision$ - * @link www.phpdoctrine.org - * @since 1.0 - * @deprecated - */ -class Doctrine_Connection_Sqlite extends Doctrine_Connection_Common -{ - /** - * @var string $driverName the name of this connection driver - */ - protected $_driverName = 'Sqlite'; - - /** - * the constructor - * - * @param Doctrine_Manager $manager - * @param PDO $pdo database handle - */ - public function __construct(array $params) - { - parent::__construct($params); - if ($this->_isConnected) { - $this->_pdo->sqliteCreateFunction('mod', array('Doctrine_Expression_Sqlite', 'modImpl'), 2); - $this->_pdo->sqliteCreateFunction('md5', 'md5', 1); - $this->_pdo->sqliteCreateFunction('now', 'time', 0); - } - } - - /** - * initializes database functions missing in sqlite - * - * @see Doctrine_Expression - * @return void - */ - public function connect() - { - if ($this->_isConnected) { - return false; - } - - parent::connect(); - - $this->_pdo->sqliteCreateFunction('mod', array('Doctrine_Expression_Sqlite', 'modImpl'), 2); - $this->_pdo->sqliteCreateFunction('md5', 'md5', 1); - $this->_pdo->sqliteCreateFunction('now', 'time', 0); - } - - /** - * createDatabase - * - * @return void - */ - public function createDatabase() - { - 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'); - } - - $info = $this->getManager()->parseDsn($dsn); - - $this->export->createDatabase($info['database']); - - return 'Successfully created database for connection "' . $this->getName() . '" at path "' . $info['database'] . '"'; - } catch (Exception $e) { - return $e; - } - } - - /** - * dropDatabase - * - * @return void - */ - public function dropDatabase() - { - 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'); - } - - $info = $this->getManager()->parseDsn($dsn); - - $this->export->dropDatabase($info['database']); - - return 'Successfully dropped database for connection "' . $this->getName() . '" at path "' . $info['database'] . '"'; - } catch (Exception $e) { - return $e; - } - } - - /** - * Constructs the Sqlite PDO DSN. - * - * Overrides Connection#_constructPdoDsn(). - * - * @return string The DSN. - */ - protected function _constructPdoDsn() - { - $dsn = 'sqlite:'; - if (isset($this->_params['path'])) { - $dsn .= $this->_params['path']; - } else if (isset($this->_params['memory'])) { - $dsn .= ':memory:'; - } - - return $dsn; - } -} \ No newline at end of file diff --git a/lib/Doctrine/Connection/Statement.php b/lib/Doctrine/Connection/Statement.php deleted file mode 100644 index 7ed5d14d7..000000000 --- a/lib/Doctrine/Connection/Statement.php +++ /dev/null @@ -1,438 +0,0 @@ -. - */ - -#namespace Doctrine::DBAL; - -/** - * A thin wrapper around PDOStatement. - * - * @author Konsta Vesterinen - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @link www.phpdoctrine.org - * @since 1.0 - * @version $Revision: 1532 $ - * @todo Do we seriously need this wrapper? - */ -class Doctrine_Connection_Statement -{ - /** - * @var Doctrine_Connection $conn Doctrine_Connection object, every connection - * statement holds an instance of Doctrine_Connection - */ - protected $_conn; - - /** - * @var PDOStatement $_stmt PDOStatement object, boolean false or Doctrine_Adapter_Statement object - */ - protected $_stmt; - - /** - * constructor - * - * @param Doctrine_Connection $conn Doctrine_Connection object, every connection - * statement holds an instance of Doctrine_Connection - * @param mixed $stmt - */ - public function __construct(Doctrine_Connection $conn, $stmt) - { - $this->_conn = $conn; - $this->_stmt = $stmt; - - if ($stmt === false) { - throw new Doctrine_Exception('Unknown statement object given.'); - } - } - - /** - * getConnection - * returns the connection object this statement uses - * - * @return Doctrine_Connection - */ - public function getConnection() - { - return $this->_conn; - } - public function getStatement() - { - return $this->_stmt; - } - public function getQuery() - { - return $this->_stmt->queryString; - } - - /** - * Bind a column to a PHP variable - * - * @param mixed $column Number of the column (1-indexed) or name of the column in the result set. - * If using the column name, be aware that the name should match - * the case of the column, as returned by the driver. - * - * @param string $param Name of the PHP variable to which the column will be bound. - * @param integer $type Data type of the parameter, specified by the Doctrine::PARAM_* constants. - * @return boolean Returns TRUE on success or FALSE on failure - */ - public function bindColumn($column, $param, $type = null) - { - if ($type === null) { - return $this->_stmt->bindColumn($column, $param); - } else { - return $this->_stmt->bindColumn($column, $param, $type); - } - } - - /** - * bindValue - * Binds a value to a corresponding named or question mark - * placeholder in the SQL statement that was use to prepare the statement. - * - * @param mixed $param Parameter identifier. For a prepared statement using named placeholders, - * this will be a parameter name of the form :name. For a prepared statement - * using question mark placeholders, this will be the 1-indexed position of the parameter - * - * @param mixed $value The value to bind to the parameter. - * @param integer $type Explicit data type for the parameter using the Doctrine::PARAM_* constants. - * - * @return boolean Returns TRUE on success or FALSE on failure. - */ - public function bindValue($param, $value, $type = null) - { - if ($type === null) { - return $this->_stmt->bindValue($param, $value); - } else { - return $this->_stmt->bindValue($param, $value, $type); - } - } - - /** - * Binds a PHP variable to a corresponding named or question mark placeholder in the - * SQL statement that was use to prepare the statement. Unlike Doctrine_Adapter_Statement_Interface->bindValue(), - * the variable is bound as a reference and will only be evaluated at the time - * that Doctrine_Adapter_Statement_Interface->execute() is called. - * - * Most parameters are input parameters, that is, parameters that are - * used in a read-only fashion to build up the query. Some drivers support the invocation - * of stored procedures that return data as output parameters, and some also as input/output - * parameters that both send in data and are updated to receive it. - * - * @param mixed $param Parameter identifier. For a prepared statement using named placeholders, - * this will be a parameter name of the form :name. For a prepared statement - * using question mark placeholders, this will be the 1-indexed position of the parameter - * - * @param mixed $variable Name of the PHP variable to bind to the SQL statement parameter. - * - * @param integer $type Explicit data type for the parameter using the Doctrine::PARAM_* constants. To return - * an INOUT parameter from a stored procedure, use the bitwise OR operator to set the - * Doctrine::PARAM_INPUT_OUTPUT bits for the data_type parameter. - * - * @param integer $length Length of the data type. To indicate that a parameter is an OUT parameter - * from a stored procedure, you must explicitly set the length. - * @param mixed $driverOptions - * @return boolean Returns TRUE on success or FALSE on failure. - */ - public function bindParam($column, &$variable, $type = null, $length = null, $driverOptions = array()) - { - if ($type === null) { - return $this->_stmt->bindParam($column, $variable); - } else { - return $this->_stmt->bindParam($column, $variable, $type, $length, $driverOptions); - } - } - - /** - * Closes the cursor, enabling the statement to be executed again. - * - * @return boolean Returns TRUE on success or FALSE on failure. - */ - public function closeCursor() - { - return $this->_stmt->closeCursor(); - } - - /** - * Returns the number of columns in the result set - * - * @return integer Returns the number of columns in the result set represented - * by the Doctrine_Adapter_Statement_Interface object. If there is no result set, - * this method should return 0. - */ - public function columnCount() - { - return $this->_stmt->columnCount(); - } - - /** - * Fetch the SQLSTATE associated with the last operation on the statement handle - * - * @see Doctrine_Adapter_Interface::errorCode() - * @return string error code string - */ - public function errorCode() - { - return $this->_stmt->errorCode(); - } - - /** - * Fetch extended error information associated with the last operation on the statement handle - * - * @see Doctrine_Adapter_Interface::errorInfo() - * @return array error info array - */ - public function errorInfo() - { - return $this->_stmt->errorInfo(); - } - - /** - * Executes a prepared statement - * - * If the prepared statement included parameter markers, you must either: - * call PDOStatement->bindParam() to bind PHP variables to the parameter markers: - * bound variables pass their value as input and receive the output value, - * if any, of their associated parameter markers or pass an array of input-only - * parameter values - * - * - * @param array $params An array of values with as many elements as there are - * bound parameters in the SQL statement being executed. - * @return boolean Returns TRUE on success or FALSE on failure. - */ - public function execute($params = null) - { - try { - //$event = new Doctrine_Event($this, Doctrine_Event::STMT_EXECUTE, $this->getQuery(), $params); - //$this->_conn->getListener()->preStmtExecute($event); - - $result = true; - //if ( ! $event->skipOperation) { - $result = $this->_stmt->execute($params); - //$this->_conn->incrementQueryCount(); - //} - - //$this->_conn->getListener()->postStmtExecute($event); - - return $result; - } catch (PDOException $e) { - $this->_conn->rethrowException($e, $this); - } - - return false; - } - - /** - * fetch - * - * @see Doctrine::FETCH_* constants - * @param integer $fetchStyle Controls how the next row will be returned to the caller. - * This value must be one of the Doctrine::FETCH_* constants, - * defaulting to Doctrine::FETCH_BOTH - * - * @param integer $cursorOrientation For a PDOStatement object representing a scrollable cursor, - * this value determines which row will be returned to the caller. - * This value must be one of the Doctrine::FETCH_ORI_* constants, defaulting to - * Doctrine::FETCH_ORI_NEXT. To request a scrollable cursor for your - * Doctrine_Adapter_Statement_Interface object, - * you must set the Doctrine::ATTR_CURSOR attribute to Doctrine::CURSOR_SCROLL when you - * prepare the SQL statement with Doctrine_Adapter_Interface->prepare(). - * - * @param integer $cursorOffset For a Doctrine_Adapter_Statement_Interface object representing a scrollable cursor for which the - * $cursorOrientation parameter is set to Doctrine::FETCH_ORI_ABS, this value specifies - * the absolute number of the row in the result set that shall be fetched. - * - * For a Doctrine_Adapter_Statement_Interface object representing a scrollable cursor for - * which the $cursorOrientation parameter is set to Doctrine::FETCH_ORI_REL, this value - * specifies the row to fetch relative to the cursor position before - * Doctrine_Adapter_Statement_Interface->fetch() was called. - * - * @return mixed - */ - public function fetch($fetchMode = Doctrine::FETCH_BOTH, - $cursorOrientation = Doctrine::FETCH_ORI_NEXT, - $cursorOffset = null) - { - //$event = new Doctrine_Event($this, Doctrine_Event::STMT_FETCH, $this->getQuery()); - //$event->fetchMode = $fetchMode; - //$event->cursorOrientation = $cursorOrientation; - //$event->cursorOffset = $cursorOffset; - - //$data = $this->_conn->getListener()->preFetch($event); - - //if ( ! $event->skipOperation) { - $data = $this->_stmt->fetch($fetchMode, $cursorOrientation, $cursorOffset); - //} - - //$this->_conn->getListener()->postFetch($event); - - return $data; - } - - /** - * Returns an array containing all of the result set rows - * - * @param integer $fetchMode Controls how the next row will be returned to the caller. - * This value must be one of the Doctrine::FETCH_* constants, - * defaulting to Doctrine::FETCH_BOTH - * - * @param integer $columnIndex Returns the indicated 0-indexed column when the value of $fetchStyle is - * Doctrine::FETCH_COLUMN. Defaults to 0. - * - * @return array - */ - public function fetchAll($fetchMode = Doctrine::FETCH_BOTH, $columnIndex = null) - { - //$event = new Doctrine_Event($this, Doctrine_Event::STMT_FETCHALL, $this->getQuery()); - //$event->fetchMode = $fetchMode; - //$event->columnIndex = $columnIndex; - //$this->_conn->getListener()->preFetchAll($event); - - //if ( ! $event->skipOperation) { - if ($columnIndex !== null) { - $data = $this->_stmt->fetchAll($fetchMode, $columnIndex); - } else { - $data = $this->_stmt->fetchAll($fetchMode); - } - //$event->data = $data; - //} - - //$this->_conn->getListener()->postFetchAll($event); - - return $data; - } - - /** - * Returns a single column from the next row of a - * result set or FALSE if there are no more rows. - * - * @param integer $columnIndex 0-indexed number of the column you wish to retrieve from the row. If no - * value is supplied, Doctrine_Adapter_Statement_Interface->fetchColumn() - * fetches the first column. - * - * @return string returns a single column in the next row of a result set. - */ - public function fetchColumn($columnIndex = 0) - { - return $this->_stmt->fetchColumn($columnIndex); - } - - /** - * Fetches the next row and returns it as an object. - * - * Fetches the next row and returns it as an object. This function is an alternative to - * Doctrine_Adapter_Statement_Interface->fetch() with Doctrine::FETCH_CLASS or Doctrine::FETCH_OBJ style. - * - * @param string $className Name of the created class, defaults to stdClass. - * @param array $args Elements of this array are passed to the constructor. - * - * @return mixed an instance of the required class with property names that correspond - * to the column names or FALSE in case of an error. - */ - public function fetchObject($className = 'stdClass', $args = array()) - { - return $this->_stmt->fetchObject($className, $args); - } - - /** - * Retrieve a statement attribute - * - * @param integer $attribute - * @see Doctrine::ATTR_* constants - * @return mixed the attribute value - */ - public function getAttribute($attribute) - { - return $this->_stmt->getAttribute($attribute); - } - - /** - * Returns metadata for a column in a result set - * - * @param integer $column The 0-indexed column in the result set. - * - * @return array Associative meta data array with the following structure: - * - * native_type The PHP native type used to represent the column value. - * driver:decl_ type The SQL type used to represent the column value in the database. If the column in the result set is the result of a function, this value is not returned by PDOStatement->getColumnMeta(). - * flags Any flags set for this column. - * name The name of this column as returned by the database. - * len The length of this column. Normally -1 for types other than floating point decimals. - * precision The numeric precision of this column. Normally 0 for types other than floating point decimals. - * pdo_type The type of this column as represented by the PDO::PARAM_* constants. - */ - public function getColumnMeta($column) - { - return $this->_stmt->getColumnMeta($column); - } - - /** - * Advances to the next rowset in a multi-rowset statement handle - * - * Some database servers support stored procedures that return more than one rowset - * (also known as a result set). The nextRowset() method enables you to access the second - * and subsequent rowsets associated with a PDOStatement object. Each rowset can have a - * different set of columns from the preceding rowset. - * - * @return boolean Returns TRUE on success or FALSE on failure. - */ - public function nextRowset() - { - return $this->_stmt->nextRowset(); - } - - /** - * rowCount() returns the number of rows affected by the last DELETE, INSERT, or UPDATE statement - * executed by the corresponding object. - * - * If the last SQL statement executed by the associated Statement object was a SELECT statement, - * some databases may return the number of rows returned by that statement. However, - * this behaviour is not guaranteed for all databases and should not be - * relied on for portable applications. - * - * @return integer Returns the number of rows. - */ - public function rowCount() - { - return $this->_stmt->rowCount(); - } - - /** - * Set a statement attribute - * - * @param integer $attribute - * @param mixed $value the value of given attribute - * @return boolean Returns TRUE on success or FALSE on failure. - */ - public function setAttribute($attribute, $value) - { - return $this->_stmt->setAttribute($attribute, $value); - } - - /** - * Set the default fetch mode for this statement - * - * @param integer $mode The fetch mode must be one of the Doctrine::FETCH_* constants. - * @return boolean Returns 1 on success or FALSE on failure. - */ - public function setFetchMode($mode, $arg1 = null, $arg2 = null) - { - return $this->_stmt->setFetchMode($mode, $arg1, $arg2); - } -} diff --git a/lib/Doctrine/DBAL/Connection.php b/lib/Doctrine/DBAL/Connection.php index 2b920b560..4e12bc617 100644 --- a/lib/Doctrine/DBAL/Connection.php +++ b/lib/Doctrine/DBAL/Connection.php @@ -1,36 +1,979 @@ . + */ + +#namespace Doctrine::DBAL; + +#use Doctrine::Common::Configuration; +#use Doctrine::Common::EventManager; +#use Doctrine::DBAL::Exceptions::ConnectionException; /** - * Connection interface. - * Drivers must implement this interface. + * A wrapper around a Doctrine::DBAL::Connection that adds features like + * events, transaction isolation levels, configuration, emulated transaction nesting + * and more. * - * This includes the full PDO interface as well as custom extensions of - * Doctrine's DBAL. + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @since 1.0 + * @version $Revision: 4933 $ + * @author Konsta Vesterinen + * @author Lukas Smith (MDB2 library) + * @author Roman Borschel + * @todo + * 1) REPLICATION SUPPORT + * Replication support should be tackled at this layer (DBAL). + * There can be options that look like: + * 'slaves' => array( + * 'slave1' => array( + * user, pass etc. + * ), + * 'slave2' => array( + * user, pass etc. + * )), + * 'slaveConnectionResolver' => new MySlaveConnectionResolver(), + * 'masters' => array(...), + * 'masterConnectionResolver' => new MyMasterConnectionResolver() * - * @since 2.0 + * Doctrine::DBAL could ship with a simple standard broker that uses a primitive + * round-robin approach to distribution. User can provide its own brokers. + * @todo Rename to ConnectionWrapper */ -interface Doctrine_DBAL_Connection +class Doctrine_DBAL_Connection { const TRANSACTION_READ_UNCOMMITTED = 1; const TRANSACTION_READ_COMMITTED = 2; const TRANSACTION_REPEATABLE_READ = 3; const TRANSACTION_SERIALIZABLE = 4; - /* PDO interface */ - public function prepare($prepareString); - public function query($queryString); - public function quote($input); - public function exec($statement); - public function lastInsertId(); - public function beginTransaction(); - public function commit(); - public function rollBack(); - public function errorCode(); - public function errorInfo(); + /** + * The wrapped driver connection. + * + * @var Doctrine::DBAL::Driver::Connection + */ + protected $_conn; - /* Doctrine DBAL extensions */ - public function setTransactionIsolation($level); - public function getTransactionIsolation(); -} + /** + * The Configuration. + * + * @var Doctrine::Common::Configuration + */ + protected $_config; + + /** + * The EventManager. + * + * @var Doctrine::Commom::EventManager + */ + protected $_eventManager; + + /** + * The name of this connection driver. + * + * @var string $driverName + */ + protected $_driverName; + + /** + * Whether or not a connection has been established. + * + * @var boolean + */ + protected $_isConnected = false; + + /** + * Boolean flag that indicates whether identifiers should get quoted. + * + * @var boolean + */ + protected $_quoteIdentifiers; + + /** + * @var array + */ + protected $_serverInfo = array(); + + /** + * The transaction nesting level. + * + * @var integer + */ + protected $_transactionNestingLevel = 0; + + /** + * The currently active transaction isolation level. + * + * @var integer + */ + protected $_transactionIsolationLevel; + + /** + * The parameters used during creation of the Connection. + * + * @var array + */ + protected $_params = array(); + + /** + * List of all available drivers. + * + * @var array $availableDrivers + * @todo Move elsewhere. + */ + private static $_availableDrivers = array( + 'Mysql', 'Pgsql', 'Oracle', 'Informix', 'Mssql', 'Sqlite', 'Firebird' + ); + + /** + * The query count. Represents the number of executed database queries by the connection. + * + * @var integer + */ + protected $_queryCount = 0; + + /** + * The DatabasePlatform object that provides information about the + * database platform used by the connection. + * + * @var Doctrine::DBAL::Platforms::DatabasePlatform + */ + protected $_platform; -?> \ No newline at end of file + /** + * The transaction object. + * + * @var Doctrine::DBAL::Transaction + */ + protected $_transaction; + + /** + * The schema manager. + * + * @var Doctrine::DBAL::Schema::SchemaManager + */ + protected $_schemaManager; + + /** + * Constructor. + * Creates a new Connection. + * + * @param array $params The connection parameters. + */ + public function __construct(array $params, Doctrine_DBAL_Driver $driver, + Doctrine_Common_Configuration $config = null, Doctrine_Common_EventManager $eventManager = null) + { + $this->_driver = $driver; + $this->_params = $params; + + if (isset($params['pdo'])) { + $this->_conn = $params['pdo']; + $this->_isConnected = true; + } + + // Create default config and event manager if none given + if ( ! $config) { + $this->_config = new Doctrine_Common_Configuration(); + } + if ( ! $eventManager) { + $this->_eventManager = new Doctrine_Common_EventManager(); + } + + $this->_platform = $driver->getDatabasePlatform(); + $this->_transactionIsolationLevel = $this->_platform->getDefaultTransactionIsolationLevel(); + } + + /** + * Gets the Configuration used by the Connection. + * + * @return Configuration + */ + public function getConfiguration() + { + return $this->_config; + } + + /** + * Gets the EventManager used by the Connection. + * + * @return Doctrine::Common::EventManager + */ + public function getEventManager() + { + return $this->_eventManager; + } + + /** + * Gets the DatabasePlatform for the connection. + * + * @return Doctrine::DBAL::Platforms::DatabasePlatform + */ + public function getDatabasePlatform() + { + return $this->_platform; + } + + /** + * Returns an array of available PDO drivers + * @todo Move elsewhere. + */ + public static function getAvailableDrivers() + { + return PDO::getAvailableDrivers(); + } + + /** + * Gets the name of the instance driver + * + * @return void + */ + public function getDriverName() + { + return $this->_driverName; + } + + /** + * Gets the PDO handle used by the connection. + * + * @return PDO + */ + public function getPdo() + { + $this->connect(); + return $this->_conn; + } + + /** + * Establishes the connection with the database. + * + * @return boolean + */ + public function connect() + { + if ($this->_isConnected) { + return false; + } + + // TODO: the extension_loaded check can happen earlier, maybe in the factory + if ( ! extension_loaded('pdo')) { + throw new Doctrine_Connection_Exception("Couldn't locate driver named " . $e[0]); + } + + $driverOptions = isset($this->_params['driverOptions']) ? + $this->_params['driverOptions'] : array(); + $user = isset($this->_params['user']) ? + $this->_params['user'] : null; + $password = isset($this->_params['password']) ? + $this->_params['password'] : null; + $this->_conn = new PDO( + $this->_constructPdoDsn(), + $user, + $password, + $driverOptions + ); + $this->_conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + $this->_conn->setAttribute(PDO::ATTR_CASE, PDO::CASE_LOWER); + + $this->_isConnected = true; + + return true; + } + + /** + * Establishes the connection with the database. + * + * @return boolean + */ + public function connect2() + { + if ($this->_isConnected) { + return false; + } + + $driverOptions = isset($this->_params['driverOptions']) ? + $this->_params['driverOptions'] : array(); + $user = isset($this->_params['user']) ? + $this->_params['user'] : null; + $password = isset($this->_params['password']) ? + $this->_params['password'] : null; + + $this->_conn = $this->_driver->connect($this->_params, $user, $password, $driverOptions); + + $this->_conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + $this->_conn->setAttribute(PDO::ATTR_CASE, PDO::CASE_LOWER); + + $this->_isConnected = true; + + return true; + } + + /** + * Constructs the PDO DSN for use in the PDO constructor. + * Concrete connection implementations override this implementation to + * create the proper DSN. + * + * @return string + * @todo make abstract, implement in subclasses. + * @todo throw different exception? + */ + protected function _constructPdoDsn() + { + throw Doctrine_Exception::notImplemented('_constructPdoDsn', get_class($this)); + } + + /** + * 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 + * @param array $identifier An associateve array containing identifier fieldname-value pairs. + * @return integer The number of affected rows + */ + public function delete($tableName, array $identifier) + { + $criteria = array(); + foreach (array_keys($identifier) as $id) { + $criteria[] = $this->quoteIdentifier($id) . ' = ?'; + } + + $query = 'DELETE FROM ' + . $this->quoteIdentifier($tableName) + . ' WHERE ' . implode(' AND ', $criteria); + + return $this->exec($query, array_values($identifier)); + } + + /** + * 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 + */ + public function update($tableName, array $data, array $identifier) + { + if (empty($data)) { + return false; + } + + $set = array(); + foreach ($data as $columnName => $value) { + if ($value instanceof Doctrine_Expression) { + $set[] = $this->quoteIdentifier($columnName) . ' = ' . $value->getSql(); + unset($data[$columnName]); + } else { + $set[] = $this->quoteIdentifier($columnName) . ' = ?'; + } + } + + $params = array_merge(array_values($data), array_values($identifier)); + + $sql = 'UPDATE ' . $this->quoteIdentifier($tableName) + . ' SET ' . implode(', ', $set) + . ' WHERE ' . implode(' = ? AND ', array_keys($identifier)) + . ' = ?'; + + return $this->exec($sql, $params); + } + + /** + * Inserts a table row with specified data. + * + * @param string $table The table to insert data into. + * @param array $fields An associateve array containing fieldname-value pairs. + * @return mixed boolean false if empty value array was given, + * otherwise returns the number of affected rows + */ + public function insert($tableName, array $data) + { + if (empty($data)) { + return false; + } + + // column names are specified as array keys + $cols = array(); + // the query VALUES will contain either expressions (eg 'NOW()') or ? + $a = array(); + foreach ($data as $columnName => $value) { + $cols[] = $this->quoteIdentifier($columnName); + if ($value instanceof Doctrine_Expression) { + $a[] = $value->getSql(); + unset($data[$columnName]); + } else { + $a[] = '?'; + } + } + + $query = 'INSERT INTO ' . $this->quoteIdentifier($tableName) + . ' (' . implode(', ', $cols) . ') ' + . 'VALUES ('; + $query .= implode(', ', $a) . ')'; + + return $this->exec($query, array_values($data)); + } + + /** + * Set the charset on the current connection + * + * @param string charset + */ + public function setCharset($charset) + { + $this->exec($this->_platform->getSetCharsetSql($charset)); + } + + /** + * Quote a string so it can be safely used as a table or column name. + * + * 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 (`) -- due to MySQL + * + double quote (") -- due to Oracle + * + brackets ([ or ]) -- 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 + * @todo Moved to DatabasePlatform + * @deprecated + */ + public function quoteIdentifier($str) + { + return $this->_platform->quoteIdentifier($str); + } + + /** + * Quotes given input parameter. + * + * @param mixed $input Parameter to be quoted. + * @param string $type Type of the parameter. + * @return string The quoted parameter. + */ + public function quote($input, $type = null) + { + return $this->_conn->quote($input, $type); + } + + /** + * fetchAll + * + * @param string $statement sql query to be executed + * @param array $params prepared statement params + * @return array + */ + public function fetchAll($statement, array $params = array()) + { + return $this->execute($statement, $params)->fetchAll(PDO::FETCH_ASSOC); + } + + /** + * 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 + */ + public function fetchOne($statement, array $params = array(), $colnum = 0) + { + return $this->execute($statement, $params)->fetchColumn($colnum); + } + + /** + * 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->execute($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->execute($statement, $params)->fetch(PDO::FETCH_NUM); + } + + /** + * 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 + */ + public function fetchColumn($statement, array $params = array(), $colnum = 0) + { + return $this->execute($statement, $params)->fetchAll(PDO::FETCH_COLUMN, $colnum); + } + + /** + * 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->execute($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->execute($statement, $params)->fetchAll(PDO::FETCH_BOTH); + } + + /** + * prepare + * + * @param string $statement + */ + public function prepare($statement) + { + $this->connect(); + try { + $stmt = $this->_conn->prepare($statement); + return new Doctrine_DBAL_Statement($this, $stmt); + } catch (PDOException $e) { + $this->rethrowException($e, $this); + } + } + + /** + * Queries the database with limit and offset + * added to the query and returns a Doctrine_Connection_Statement object + * + * @param string $query + * @param integer $limit + * @param integer $offset + * @return Doctrine_Connection_Statement + */ + public function select($query, $limit = 0, $offset = 0) + { + if ($limit > 0 || $offset > 0) { + $query = $this->_platform->modifyLimitQuery($query, $limit, $offset); + } + return $this->execute($query); + } + + /** + * Executes an SQL SELECT query with the given parameters. + * + * @param string $query sql query + * @param array $params query parameters + * + * @return PDOStatement|Doctrine_Adapter_Statement + */ + public function execute($query, array $params = array()) + { + $this->connect(); + try { + if ( ! empty($params)) { + $stmt = $this->prepare($query); + $stmt->execute($params); + return $stmt; + } else { + $stmt = $this->_conn->query($query); + $this->_queryCount++; + return $stmt; + } + } catch (PDOException $e) { + $this->rethrowException($e, $this); + } + } + + /** + * Executes an SQL INSERT/UPDATE/DELETE query with the given parameters. + * + * @param string $query sql query + * @param array $params query parameters + * + * @return PDOStatement|Doctrine_Adapter_Statement + * @todo Rename to executeUpdate(). + */ + public function exec($query, array $params = array()) { + $this->connect(); + try { + if ( ! empty($params)) { + $stmt = $this->prepare($query); + $stmt->execute($params); + return $stmt->rowCount(); + } else { + $count = $this->_conn->exec($query); + $this->_queryCount++; + return $count; + } + } catch (PDOException $e) { + $this->rethrowException($e, $this); + } + } + + /** + * Wraps the given exception into a driver-specific exception and rethrows it. + * + * @throws Doctrine_Connection_Exception + */ + public function rethrowException(Exception $e, $invoker) + { + throw $exc; + } + + /** + * Returns the number of queries executed by the connection. + * + * @return integer + * @todo Better name: getQueryCount() + */ + public function getQueryCount() + { + return $this->_queryCount; + } + + /** + * Closes the connection. + * + * @return void + */ + public function close() + { + $this->clear(); + unset($this->_conn); + $this->_isConnected = false; + } + + /** + * Sets the transaction isolation level. + * + * @param integer $level The level to set. + */ + public function setTransactionIsolation($level) + { + $sql = ""; + switch ($level) { + case Doctrine_DBAL_Connection::TRANSACTION_READ_UNCOMMITTED: + $sql = $this->_platform->getSetTransactionIsolationReadUncommittedSql(); + break; + case Doctrine_DBAL_Connection::TRANSACTION_READ_COMMITTED: + $sql = $this->_platform->getSetTransactionIsolationReadCommittedSql(); + break; + case Doctrine_DBAL_Connection::TRANSACTION_REPEATABLE_READ: + $sql = $this->_platform->getSetTransactionIsolationRepeatableReadSql(); + break; + case Doctrine_DBAL_Connection::TRANSACTION_SERIALIZABLE: + $sql = $this->_platform->getSetTransactionIsolationSerializableSql(); + break; + default: + throw new Doctrine_Common_Exceptions_DoctrineException('isolation level is not supported: ' . $isolation); + } + $this->_transactionIsolationLevel = $level; + + return $this->exec($sql); + } + + /** + * Gets the currently active transaction isolation level. + * + * @return integer The current transaction isolation level. + */ + public function getTransactionIsolation() + { + return $this->_transactionIsolationLevel; + } + + /** + * Returns the current total transaction nesting level. + * + * @return integer The nesting level. A value of 0 means theres no active transaction. + */ + public function getTransactionNestingLevel() + { + return $this->_transactionNestingLevel; + } + + /** + * Fetch the SQLSTATE associated with the last operation on the database handle + * + * @return integer + */ + public function errorCode() + { + $this->connect(); + return $this->_conn->errorCode(); + } + + /** + * Fetch extended error information associated with the last operation on the database handle + * + * @return array + */ + public function errorInfo() + { + $this->connect(); + return $this->_conn->errorInfo(); + } + + /** + * 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($seqName = null) + { + return $this->_conn->lastInsertId($seqName); + } + + /** + * Start a transaction or set a savepoint. + * + * if trying to set a savepoint and there is no active transaction + * a new transaction is being started. + * + * @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 + */ + public function beginTransaction() + { + if ($this->_transactionNestingLevel == 0) { + return $this->_conn->beginTransaction(); + } + ++$this->_transactionNestingLevel; + return true; + } + + /** + * Commits 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. + * + * @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 + */ + public function commit() + { + if ($this->_transactionNestingLevel == 0) { + throw new Doctrine_Exception("Commit failed. There is no active transaction."); + } + + $this->connect(); + + if ($this->_transactionNestingLevel == 1) { + return $this->_conn->commit(); + } + --$this->_transactionNestingLevel; + + return true; + } + + /** + * 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. + * + * this method can be listened with onPreTransactionRollback and onTransactionRollback + * eventlistener methods + * + * @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. + */ + public function rollback() + { + if ($this->_transactionNestingLevel == 0) { + throw new Doctrine_Exception("Rollback failed. There is no active transaction."); + } + + $this->connect(); + + if ($this->_transactionNestingLevel == 1) { + $this->_transactionNestingLevel = 0; + return $this->_conn->rollback(); + + } + --$this->_transactionNestingLevel; + + return true; + } + + /** + * Quotes pattern (% and _) characters in a string) + * + * EXPERIMENTAL + * + * WARNING: this function is experimental and may change signature at + * any time until labelled as non-experimental + * + * @param string the input string to quote + * + * @return string quoted string + */ + protected function _escapePattern($text) + { + return $text; + } + + /** + * Removes any formatting in an sequence name using the 'seqname_format' option + * + * @param string $sqn string that containts name of a potential sequence + * @return string name of the sequence with possible formatting removed + */ + protected function _fixSequenceName($sqn) + { + $seqPattern = '/^'.preg_replace('/%s/', '([a-z0-9_]+)', $this->conn->getAttribute(Doctrine::ATTR_SEQNAME_FORMAT)).'$/i'; + $seqName = preg_replace($seqPattern, '\\1', $sqn); + + if ($seqName && ! strcasecmp($sqn, $this->getSequenceName($seqName))) { + return $seqName; + } + return $sqn; + } + + /** + * Removes any formatting in an index name using the 'idxname_format' option + * + * @param string $idx string that containts name of anl index + * @return string name of the index with possible formatting removed + */ + protected function _fixIndexName($idx) + { + $indexPattern = '/^'.preg_replace('/%s/', '([a-z0-9_]+)', $this->conn->getAttribute(Doctrine::ATTR_IDXNAME_FORMAT)).'$/i'; + $indexName = preg_replace($indexPattern, '\\1', $idx); + if ($indexName && ! strcasecmp($idx, $this->getIndexName($indexName))) { + return $indexName; + } + return $idx; + } + + /** + * adds sequence name formatting to a sequence name + * + * @param string name of the sequence + * @return string formatted sequence name + */ + protected function _getSequenceName($sqn) + { + return sprintf($this->conn->getAttribute(Doctrine::ATTR_SEQNAME_FORMAT), + preg_replace('/[^a-z0-9_\$.]/i', '_', $sqn)); + } + + /** + * adds index name formatting to a index name + * + * @param string name of the index + * @return string formatted index name + */ + protected function _getIndexName($idx) + { + return sprintf($this->conn->getAttribute(Doctrine::ATTR_IDXNAME_FORMAT), + preg_replace('/[^a-z0-9_\$]/i', '_', $idx)); + } + + /** + * adds table name formatting to a table name + * + * @param string name of the table + * @return string formatted table name + */ + protected function _getTableName($table) + { + return $table; + /* + return sprintf($this->conn->getAttribute(Doctrine::ATTR_TBLNAME_FORMAT), + $table);*/ + } + + /** + * returns a string representation of this object + * @return string + */ + public function __toString() + { + return Doctrine_Lib::getConnectionAsString($this); + } + + /** + * Gets the wrapped driver connection. + * + * @return Doctrine::DBAL::Driver::Connection + */ + public function getWrappedConnection() + { + return $this->_conn; + } + + /** + * Gets the SchemaManager that can be used to inspect or change the + * database schema through the connection. + * + * @return Doctrine::DBAL::Schema::SchemaManager + */ + public function getSchemaManager() + { + if ( ! $this->_schemaManager) { + $this->_schemaManager = $this->_driver->getSchemaManager(); + } + return $this->_schemaManager; + } +} diff --git a/lib/Doctrine/DBAL/Driver.php b/lib/Doctrine/DBAL/Driver.php index 0e663e391..2739f62b3 100644 --- a/lib/Doctrine/DBAL/Driver.php +++ b/lib/Doctrine/DBAL/Driver.php @@ -32,7 +32,7 @@ interface Doctrine_DBAL_Driver * * @return Doctrine::DBAL::SchemaManager */ - public function getSchemaManager(); + public function getSchemaManager(Doctrine_DBAL_Connection $conn); } ?> \ No newline at end of file diff --git a/lib/Doctrine/DBAL/Driver/Connection.php b/lib/Doctrine/DBAL/Driver/Connection.php new file mode 100644 index 000000000..15d58046e --- /dev/null +++ b/lib/Doctrine/DBAL/Driver/Connection.php @@ -0,0 +1,25 @@ + \ No newline at end of file diff --git a/lib/Doctrine/DBAL/Driver/PDOConnection.php b/lib/Doctrine/DBAL/Driver/PDOConnection.php new file mode 100644 index 000000000..1f6debeec --- /dev/null +++ b/lib/Doctrine/DBAL/Driver/PDOConnection.php @@ -0,0 +1,12 @@ +setAttribute(PDO::ATTR_STATEMENT_CLASS, array('Doctrine_DBAL_Driver_PDOStatement', array())); + } +} + +?> \ No newline at end of file diff --git a/lib/Doctrine/DBAL/Driver/PDOMsSql/Connection.php b/lib/Doctrine/DBAL/Driver/PDOMsSql/Connection.php index f6b739bf1..7352fcbb7 100644 --- a/lib/Doctrine/DBAL/Driver/PDOMsSql/Connection.php +++ b/lib/Doctrine/DBAL/Driver/PDOMsSql/Connection.php @@ -7,54 +7,8 @@ * * @since 2.0 */ -class Doctrine_DBAL_Driver_PDOMsSql_Connection extends PDO implements Doctrine_DBAL_Connection +class Doctrine_DBAL_Driver_PDOMsSql_Connection extends PDO implements Doctrine_DBAL_Driver_Connection { - private $_isolationLevel = Doctrine_DBAL_Connection::TRANSACTION_READ_COMMITTED; - - /** - * Set the transacton isolation level. - * - * @param string standard isolation level (SQL-92) - * portable modes: - * READ UNCOMMITTED (allows dirty reads) - * READ COMMITTED (prevents dirty reads) - * REPEATABLE READ (prevents nonrepeatable reads) - * SERIALIZABLE (prevents phantom reads) - * - * @link http://msdn2.microsoft.com/en-us/library/ms173763.aspx - * @throws PDOException if something fails at the PDO level - * @throws Doctrine_Transaction_Exception if using unknown isolation level or unknown wait option - * @return void - * @override - */ - public function setTransactionIsolation($level, $options = array()) { - $sql = ""; - switch ($level) { - case Doctrine_DBAL_Connection::TRANSACTION_READ_UNCOMMITTED: - $sql = 'READ UNCOMMITTED'; - break; - case Doctrine_DBAL_Connection::TRANSACTION_READ_COMMITTED: - $sql = 'READ COMMITTED'; - break; - case Doctrine_DBAL_Connection::TRANSACTION_REPEATABLE_READ: - $sql = 'REPEATABLE READ'; - break; - case Doctrine_DBAL_Connection::TRANSACTION_SERIALIZABLE: - $sql = 'SERIALIZABLE'; - break; - default: - throw new Doctrine_Transaction_Exception('isolation level is not supported: ' . $isolation); - } - - $this->_isolationLevel = $level; - $this->exec('SET TRANSACTION ISOLATION LEVEL ' . $sql); - } - - public function getTransactionIsolation() - { - return $this->_isolationLevel; - } - /** * Performs the rollback. * diff --git a/lib/Doctrine/DBAL/Driver/PDOMsSql/Driver.php b/lib/Doctrine/DBAL/Driver/PDOMsSql/Driver.php index c81fc74a1..978a51a04 100644 --- a/lib/Doctrine/DBAL/Driver/PDOMsSql/Driver.php +++ b/lib/Doctrine/DBAL/Driver/PDOMsSql/Driver.php @@ -9,7 +9,11 @@ class Doctrine_DBAL_Driver_PDOMsSql_Driver implements Doctrine_DBAL_Driver public function connect(array $params, $username = null, $password = null, array $driverOptions = array()) { - return new PDO($this->_constructPdoDsn($params), $username, $password, $driverOptions); + return new Doctrine_DBAL_Driver_MsSql_Connection( + $this->_constructPdoDsn($params), + $username, + $password, + $driverOptions); } /** diff --git a/lib/Doctrine/DBAL/Driver/PDOMySql/Connection.php b/lib/Doctrine/DBAL/Driver/PDOMySql/Connection.php deleted file mode 100644 index 19e204f28..000000000 --- a/lib/Doctrine/DBAL/Driver/PDOMySql/Connection.php +++ /dev/null @@ -1,57 +0,0 @@ -_isolationLevel = $level; - - return $this->exec('SET SESSION TRANSACTION ISOLATION LEVEL ' . $sql); - } - - /** - * getTransactionIsolation - * - * @return string returns the current session transaction isolation level - */ - public function getTransactionIsolation() - { - return $this->_isolationLevel; - } - -} - -?> \ No newline at end of file diff --git a/lib/Doctrine/DBAL/Driver/PDOMySql/Driver.php b/lib/Doctrine/DBAL/Driver/PDOMySql/Driver.php index 776c5841f..710db6555 100644 --- a/lib/Doctrine/DBAL/Driver/PDOMySql/Driver.php +++ b/lib/Doctrine/DBAL/Driver/PDOMySql/Driver.php @@ -9,7 +9,11 @@ class Doctrine_DBAL_Driver_PDOMySql_Driver implements Doctrine_DBAL_Driver public function connect(array $params, $username = null, $password = null, array $driverOptions = array()) { - return new PDO($this->_constructPdoDsn($params), $username, $password, $driverOptions); + return new Doctrine_DBAL_Driver_PDOConnection( + $this->_constructPdoDsn($params), + $username, + $password, + $driverOptions); } /** diff --git a/lib/Doctrine/DBAL/Driver/PDOOracle/Driver.php b/lib/Doctrine/DBAL/Driver/PDOOracle/Driver.php index 0cc558928..2f91b8915 100644 --- a/lib/Doctrine/DBAL/Driver/PDOOracle/Driver.php +++ b/lib/Doctrine/DBAL/Driver/PDOOracle/Driver.php @@ -9,7 +9,11 @@ class Doctrine_DBAL_Driver_PDOOracle_Driver implements Doctrine_DBAL_Driver public function connect(array $params, $username = null, $password = null, array $driverOptions = array()) { - return new PDO($this->_constructPdoDsn($params), $username, $password, $driverOptions); + return new Doctrine_DBAL_Driver_PDOConnection( + $this->_constructPdoDsn($params), + $username, + $password, + $driverOptions); } /** diff --git a/lib/Doctrine/DBAL/Driver/PDOPgSql/Driver.php b/lib/Doctrine/DBAL/Driver/PDOPgSql/Driver.php index 0051961d0..ff9b546a6 100644 --- a/lib/Doctrine/DBAL/Driver/PDOPgSql/Driver.php +++ b/lib/Doctrine/DBAL/Driver/PDOPgSql/Driver.php @@ -12,7 +12,11 @@ class Doctrine_DBAL_Driver_PDOPgSql_Driver implements Doctrine_DBAL_Driver public function connect(array $params, $username = null, $password = null, array $driverOptions = array()) { - return new PDO($this->_constructPdoDsn($params), $username, $password, $driverOptions); + return new Doctrine_DBAL_Driver_PDOConnection( + $this->_constructPdoDsn($params), + $username, + $password, + $driverOptions); } /** diff --git a/lib/Doctrine/DBAL/Driver/PDOSqlite/Driver.php b/lib/Doctrine/DBAL/Driver/PDOSqlite/Driver.php index 67ac60f2f..e155ba291 100644 --- a/lib/Doctrine/DBAL/Driver/PDOSqlite/Driver.php +++ b/lib/Doctrine/DBAL/Driver/PDOSqlite/Driver.php @@ -9,7 +9,11 @@ class Doctrine_DBAL_Driver_PDOSqlite_Driver implements Doctrine_DBAL_Driver public function connect(array $params, $username = null, $password = null, array $driverOptions = array()) { - return new PDO($this->_constructPdoDsn($params), $username, $password, $driverOptions); + return new Doctrine_DBAL_Driver_PDOConnection( + $this->_constructPdoDsn($params), + $username, + $password, + $driverOptions); } /** @@ -32,12 +36,12 @@ class Doctrine_DBAL_Driver_PDOSqlite_Driver implements Doctrine_DBAL_Driver public function getDatabasePlatform() { - return new Doctrine_DatabasePlatform_SqlitePlatform(); + return new Doctrine_DBAL_Platforms_SqlitePlatform(); } - public function getSchemaManager(Doctrine_Connection $conn) + public function getSchemaManager(Doctrine_DBAL_Connection $conn) { - return new Doctrine_Schema_SqliteSchemaManager($conn); + return new Doctrine_DBAL_Schema_SqliteSchemaManager($conn); } } diff --git a/lib/Doctrine/DBAL/Driver/PDOStatement.php b/lib/Doctrine/DBAL/Driver/PDOStatement.php new file mode 100644 index 000000000..3b8cab840 --- /dev/null +++ b/lib/Doctrine/DBAL/Driver/PDOStatement.php @@ -0,0 +1,6 @@ + \ No newline at end of file diff --git a/lib/Doctrine/DBAL/Statement.php b/lib/Doctrine/DBAL/Driver/Statement.php similarity index 97% rename from lib/Doctrine/DBAL/Statement.php rename to lib/Doctrine/DBAL/Driver/Statement.php index 053df8a6e..4ec28f54e 100644 --- a/lib/Doctrine/DBAL/Statement.php +++ b/lib/Doctrine/DBAL/Driver/Statement.php @@ -19,14 +19,13 @@ * . */ -#namespace Doctrine::DBAL; +#namespace Doctrine::DBAL::Driver; /** * Statement interface. * Drivers must implement this interface. * - * This includes the full PDOStatement interface as well as custom extensions of - * Doctrine's DBAL. + * This resembles the PDOStatement interface. * * @author Konsta Vesterinen * @author Roman Borschel @@ -35,7 +34,7 @@ * @since 2.0 * @version $Revision$ */ -interface Doctrine_DBAL_Statement +interface Doctrine_DBAL_Driver_Statement { /** * Bind a column to a PHP variable diff --git a/lib/Doctrine/DBAL/DriverManager.php b/lib/Doctrine/DBAL/DriverManager.php new file mode 100644 index 000000000..b3c9fd0ae --- /dev/null +++ b/lib/Doctrine/DBAL/DriverManager.php @@ -0,0 +1,116 @@ +. + */ + +#namespace Doctrine::DBAL; + +/** + * Factory for creating dbms-specific Connection instances. + * + * @author Roman Borschel + * @since 2.0 + */ +class Doctrine_DBAL_DriverManager +{ + /** + * List of supported drivers and their mappings to the driver class. + * + * @var array + */ + private $_drivers = array( + 'pdo_mysql' => 'Doctrine_DBAL_Driver_PDOMySql_Driver', + 'pdo_sqlite' => 'Doctrine_DBAL_Driver_PDOSqlite_Driver', + 'pdo_pgsql' => 'Doctrine_DBAL_Driver_PDOPgSql_Driver', + 'pdo_oracle' => 'Doctrine_DBAL_Driver_PDOOracle_Driver', + 'pdo_mssql' => 'Doctrine_DBAL_Driver_PDOMsSql_Driver', + 'pdo_firebird' => 'Doctrine_DBAL_Driver_PDOFirebird_Driver', + 'pdo_informix' => 'Doctrine_DBAL_Driver_PDOInformix_Driver', + ); + + public function __construct() + { + + } + + /** + * Creates a connection object with the specified parameters. + * + * @param array $params + * @return Connection + */ + public function getConnection(array $params, Doctrine_Common_Configuration $config = null, + Doctrine_Common_EventManager $eventManager = null) + { + // create default config and event manager, if not set + if ( ! $config) { + $config = new Doctrine_Common_Configuration(); + } + if ( ! $eventManager) { + $eventManager = new Doctrine_Common_EventManager(); + } + + // check for existing pdo object + if (isset($params['pdo']) && ! $params['pdo'] instanceof PDO) { + throw Doctrine_DBAL_Exceptions_DBALException::invalidPDOInstance(); + } else if (isset($params['pdo'])) { + $params['driver'] = $params['pdo']->getAttribute(PDO::ATTR_DRIVER_NAME); + } else { + $this->_checkParams($params); + } + if (isset($params['driverClass'])) { + $className = $params['driverClass']; + } else { + $className = $this->_drivers[$params['driver']]; + } + + $driver = new $className(); + + $wrapperClass = 'Doctrine_DBAL_Connection'; + if (isset($params['wrapperClass'])) { + $wrapperClass = $params['wrapperClass']; + } + + return new $wrapperClass($params, $driver, $config, $eventManager); + } + + /** + * Checks the list of parameters. + * + * @param array $params + */ + private function _checkParams(array $params) + { + // check existance of mandatory parameters + + // driver + if ( ! isset($params['driver']) && ! isset($params['driverClass'])) { + throw Doctrine_ConnectionFactory_Exception::driverRequired(); + } + + // check validity of parameters + + // driver + if ( isset($params['driver']) && ! isset($this->_drivers[$params['driver']])) { + throw Doctrine_DBAL_Exceptions_DBALException::unknownDriver($params['driver']); + } + } +} + +?> \ No newline at end of file diff --git a/lib/Doctrine/DBAL/Exceptions/DBALException.php b/lib/Doctrine/DBAL/Exceptions/DBALException.php new file mode 100644 index 000000000..c1b2a133d --- /dev/null +++ b/lib/Doctrine/DBAL/Exceptions/DBALException.php @@ -0,0 +1,30 @@ + + */ +class Doctrine_DBAL_Exceptions_DBALException extends Exception +{ + public static function invalidPDOInstance() + { + return new self("Invalid PDO instance provided on connection creation."); + } + + public static function driverRequired() + { + return new self("Please provide a driver or a driverClass to be able to start a Connection."); + } + + public static function unknownDriver($driver) + { + return new self("Unknown Connection driver '$driver'."); + } +} \ No newline at end of file diff --git a/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php b/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php index fadf89505..e1c705f07 100644 --- a/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php @@ -1774,6 +1774,48 @@ abstract class Doctrine_DBAL_Platforms_AbstractPlatform return 'SET NAMES ' . $this->quote($charset); } + /** + * Enter description here... + * + * @param unknown_type $level + */ + protected function _getTransactionIsolationLevelSql($level) + { + switch ($level) { + case Doctrine_DBAL_Connection::TRANSACTION_READ_UNCOMMITTED: + return 'READ UNCOMMITTED'; + case Doctrine_DBAL_Connection::TRANSACTION_READ_COMMITTED: + return 'READ COMMITTED'; + case Doctrine_DBAL_Connection::TRANSACTION_REPEATABLE_READ: + return 'REPEATABLE READ'; + case Doctrine_DBAL_Connection::TRANSACTION_SERIALIZABLE: + return 'SERIALIZABLE'; + default: + throw new Doctrine_Common_Exceptions_DoctrineException('isolation level is not supported: ' . $isolation); + } + } + + /** + * Enter description here... + * + * @param unknown_type $level + */ + public function getSetTransactionIsolationSql($level) + { + throw new Doctrine_Export_Exception('Set transaction isolation not supported by this platform.'); + } + + /** + * Gets the default transaction isolation level of the platform. + * + * @return integer The default isolation level. + * @see Doctrine::DBAL::Connection::TRANSACTION_* constants. + */ + public function getDefaultTransactionIsolationLevel() + { + return Doctrine_DBAL_Connection::TRANSACTION_READ_COMMITTED; + } + /* supports*() metods */ diff --git a/lib/Doctrine/DBAL/Platforms/FirebirdPlatform.php b/lib/Doctrine/DBAL/Platforms/FirebirdPlatform.php index 5ed5e6a5e..b50324d37 100644 --- a/lib/Doctrine/DBAL/Platforms/FirebirdPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/FirebirdPlatform.php @@ -257,6 +257,39 @@ class Doctrine_DBAL_Platforms_FirebirdPlatform extends Doctrine_DBAL_Platforms_A return 'SELECT GEN_ID(' . $this->quoteIdentifier($sequenceName) . ', 1) FROM RDB$DATABASE'; } + /** + * Enter description here... + * + * @param unknown_type $level + * @override + */ + protected function _getTransactionIsolationLevelSql($level) + { + switch ($level) { + case Doctrine_DBAL_Connection::TRANSACTION_READ_UNCOMMITTED: + return 'READ COMMITTED RECORD_VERSION'; + case Doctrine_DBAL_Connection::TRANSACTION_READ_COMMITTED: + return 'READ COMMITTED NO RECORD_VERSION'; + case Doctrine_DBAL_Connection::TRANSACTION_REPEATABLE_READ: + return 'SNAPSHOT'; + case Doctrine_DBAL_Connection::TRANSACTION_SERIALIZABLE: + return 'SNAPSHOT TABLE STABILITY'; + default: + return parent::_getTransactionIsolationLevelSql($level); + } + } + + /** + * Enter description here... + * + * @param unknown_type $level + * @override + */ + public function getSetTransactionIsolationSql($level) + { + return 'SET TRANSACTION ISOLATION LEVEL ' . $this->_getTransactionIsolationLevelSql($level); + } + } ?> \ No newline at end of file diff --git a/lib/Doctrine/DBAL/Platforms/MsSqlPlatform.php b/lib/Doctrine/DBAL/Platforms/MsSqlPlatform.php index 9637b4e16..b99f75ed3 100644 --- a/lib/Doctrine/DBAL/Platforms/MsSqlPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/MsSqlPlatform.php @@ -311,6 +311,17 @@ class Doctrine_DBAL_Platforms_MsSqlPlatform extends Doctrine_DBAL_Platforms_Abst return '[' . str_replace(']', ']]', $identifier) . ']'; } + /** + * Enter description here... + * + * @param unknown_type $level + * @override + */ + public function getSetTransactionIsolationSql($level) + { + return 'SET TRANSACTION ISOLATION LEVEL ' . $this->_getTransactionIsolationLevelSql($level); + } + } ?> \ No newline at end of file diff --git a/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php b/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php index 82288884c..01356846b 100644 --- a/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php @@ -1234,6 +1234,17 @@ class Doctrine_DBAL_Platforms_MySqlPlatform extends Doctrine_DBAL_Platforms_Abst $table = $this->quoteIdentifier($table, true); return 'DROP TABLE ' . $table; } + + /** + * Enter description here... + * + * @param unknown_type $level + * @override + */ + public function getSetTransactionIsolationSql($level) + { + return 'SET SESSION TRANSACTION ISOLATION LEVEL ' . $this->_getTransactionIsolationLevelSql($level); + } } ?> \ No newline at end of file diff --git a/lib/Doctrine/DBAL/Platforms/OraclePlatform.php b/lib/Doctrine/DBAL/Platforms/OraclePlatform.php index 228250f17..9fa021c87 100644 --- a/lib/Doctrine/DBAL/Platforms/OraclePlatform.php +++ b/lib/Doctrine/DBAL/Platforms/OraclePlatform.php @@ -344,6 +344,37 @@ class Doctrine_DBAL_Platforms_OraclePlatform extends Doctrine_DBAL_Platforms_Abs { return 'SELECT ' . $this->quoteIdentifier($sequenceName) . '.nextval FROM DUAL'; } + + /** + * Enter description here... + * + * @param unknown_type $level + * @override + */ + public function getSetTransactionIsolationSql($level) + { + return 'ALTER SESSION ISOLATION LEVEL ' . $this->_getTransactionIsolationLevelSql($level); + } + + /** + * Enter description here... + * + * @param unknown_type $level + * @override + */ + protected function _getTransactionIsolationLevelSql($level) + { + switch ($level) { + case Doctrine_DBAL_Connection::TRANSACTION_READ_UNCOMMITTED: + return 'READ COMMITTED'; + case Doctrine_DBAL_Connection::TRANSACTION_READ_COMMITTED: + case Doctrine_DBAL_Connection::TRANSACTION_REPEATABLE_READ: + case Doctrine_DBAL_Connection::TRANSACTION_SERIALIZABLE: + return 'SERIALIZABLE'; + default: + return parent::_getTransactionIsolationLevelSql($level); + } + } } ?> \ No newline at end of file diff --git a/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php b/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php index fee5913e6..04f6283a3 100644 --- a/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php @@ -989,6 +989,18 @@ class Doctrine_DBAL_Platforms_PostgreSqlPlatform extends Doctrine_DBAL_Platforms { return "SELECT NEXTVAL('" . $sequenceName . "')"; } + + /** + * Enter description here... + * + * @param unknown_type $level + * @override + */ + public function getSetTransactionIsolationSql($level) + { + return 'SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL ' + . $this->_getTransactionIsolationLevelSql($level); + } } ?> \ No newline at end of file diff --git a/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php b/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php index 7573b2c7a..76ec77919 100644 --- a/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php +++ b/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php @@ -360,6 +360,37 @@ class Doctrine_DBAL_Platforms_SqlitePlatform extends Doctrine_DBAL_Platforms_Abs 'unsigned' => $unsigned, 'fixed' => $fixed); } + + /** + * Enter description here... + * + * @param unknown_type $level + * @override + */ + protected function _getTransactionIsolationLevelSql($level) + { + switch ($level) { + case Doctrine_DBAL_Connection::TRANSACTION_READ_UNCOMMITTED: + return 0; + case Doctrine_DBAL_Connection::TRANSACTION_READ_COMMITTED: + case Doctrine_DBAL_Connection::TRANSACTION_REPEATABLE_READ: + case Doctrine_DBAL_Connection::TRANSACTION_SERIALIZABLE: + return 1; + default: + return parent::_getTransactionIsolationLevelSql($level); + } + } + + /** + * Enter description here... + * + * @param unknown_type $level + * @override + */ + public function getSetTransactionIsolationSql($level) + { + return 'PRAGMA read_uncommitted = ' . $this->_getTransactionIsolationLevelSql($level); + } } ?> \ No newline at end of file diff --git a/lib/Doctrine/ORM/EntityManager.php b/lib/Doctrine/ORM/EntityManager.php index 31fbf4ff2..1456565f5 100644 --- a/lib/Doctrine/ORM/EntityManager.php +++ b/lib/Doctrine/ORM/EntityManager.php @@ -148,7 +148,7 @@ class Doctrine_ORM_EntityManager * @param Doctrine_Connection $conn * @param string $name */ - protected function __construct(Doctrine_Connection $conn, $name, Doctrine_Common_Configuration $config, + protected function __construct(Doctrine_DBAL_Connection $conn, $name, Doctrine_Common_Configuration $config, Doctrine_Common_EventManager $eventManager) { $this->_conn = $conn; @@ -157,7 +157,7 @@ class Doctrine_ORM_EntityManager $this->_eventManager = $eventManager; $this->_metadataFactory = new Doctrine_ClassMetadata_Factory( $this, new Doctrine_ClassMetadata_CodeDriver()); - $this->_unitOfWork = new Doctrine_Connection_UnitOfWork($this); + $this->_unitOfWork = new Doctrine_ORM_UnitOfWork($this); $this->_nullObject = Doctrine_ORM_Internal_Null::$INSTANCE; } diff --git a/lib/Doctrine/Connection/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php similarity index 99% rename from lib/Doctrine/Connection/UnitOfWork.php rename to lib/Doctrine/ORM/UnitOfWork.php index eae509cd0..0f0e65ee8 100644 --- a/lib/Doctrine/Connection/UnitOfWork.php +++ b/lib/Doctrine/ORM/UnitOfWork.php @@ -1,6 +1,6 @@ * @author Roman Borschel * @todo Rename: Doctrine::ORM::UnitOfWork. * @todo Turn connection exceptions into UnitOfWorkExceptions. */ -class Doctrine_Connection_UnitOfWork +class Doctrine_ORM_UnitOfWork { /** * The identity map that holds references to all managed entities that have diff --git a/lib/Doctrine/Query/Parser.php b/lib/Doctrine/Query/Parser.php index 811c0ec0b..7a5b837db 100644 --- a/lib/Doctrine/Query/Parser.php +++ b/lib/Doctrine/Query/Parser.php @@ -130,7 +130,7 @@ class Doctrine_Query_Parser $this->_em = $query->getEntityManager(); $this->_input = $query->getDql(); $this->_scanner = new Doctrine_Query_Scanner($this->_input); - $this->_sqlBuilder = Doctrine_Query_SqlBuilder::fromConnection($this->_em); + $this->_sqlBuilder = new Doctrine_Query_SqlBuilder($this->_em); $this->_keywordTable = new Doctrine_Query_Token(); $this->_parserResult = new Doctrine_Query_ParserResult( diff --git a/lib/Doctrine/Query/SqlBuilder.php b/lib/Doctrine/Query/SqlBuilder.php index 8a2450733..bd7934964 100755 --- a/lib/Doctrine/Query/SqlBuilder.php +++ b/lib/Doctrine/Query/SqlBuilder.php @@ -21,7 +21,10 @@ */ /** - * Base class of each Sql Builder object + * The SqlBuilder. Creates SQL out of an AST. + * + * INTERNAL: For platform-specific SQL, the platform of the connection should be used. + * ($this->_connection->getDatabasePlatform()) * * @package Doctrine * @subpackage Query @@ -32,28 +35,17 @@ * @since 2.0 * @version $Revision$ */ -abstract class Doctrine_Query_SqlBuilder +class Doctrine_Query_SqlBuilder { - /** - * The Connection object. - * - * @var Doctrine_Connection - */ - protected $_connection; + protected $_em; + protected $_conn; - - public static function fromConnection(Doctrine_ORM_EntityManager $entityManager) + public function __construct(Doctrine_ORM_EntityManager $em) { - $connection = $entityManager->getConnection(); - - $className = "Doctrine_Query_SqlBuilder_" . $connection->getDriverName(); - $sqlBuilder = new $className(); - $sqlBuilder->_connection = $connection; - - return $sqlBuilder; + $this->_em = $em; + $this->_conn = $this->_em->getConnection(); } - /** * Retrieves the assocated Doctrine_Connection to this object. * @@ -64,23 +56,12 @@ abstract class Doctrine_Query_SqlBuilder return $this->_connection; } - /** * @nodoc */ public function quoteIdentifier($identifier) { - return $this->_connection->quoteIdentifier($identifier); + return $this->_conn->quoteIdentifier($identifier); } - - - - // Start Common SQL generations - // Here we follow the SQL-99 specifications available at: - // http://savage.net.au/SQL/sql-99.bnf - - - - // End of Common SQL generations } diff --git a/lib/Doctrine/Sequence/Db2.php b/lib/Doctrine/Sequence/Db2.php deleted file mode 100644 index c677c1acd..000000000 --- a/lib/Doctrine/Sequence/Db2.php +++ /dev/null @@ -1,124 +0,0 @@ -. - */ - -/** - * Doctrine_Sequence_Db2 - * - * @package Doctrine - * @subpackage Sequence - * @author Konsta Vesterinen - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @link www.phpdoctrine.org - * @since 1.0 - * @version $Revision$ - * @deprecated - */ -class Doctrine_Sequence_Db2 extends Doctrine_Sequence -{ - /** - * Return the most recent value from the specified sequence in the database. - * This is supported only on RDBMS brands that support sequences - * (e.g. Oracle, PostgreSQL, DB2). Other RDBMS brands return null. - * - * @param string $sequenceName - * @return integer - * @throws Doctrine_Adapter_Db2_Exception - */ - public function lastSequenceId($sequenceName) - { - $sql = 'SELECT PREVVAL FOR ' - . $this->quoteIdentifier($this->conn->formatter->getSequenceName($sequenceName)) - . ' AS VAL FROM SYSIBM.SYSDUMMY1'; - - $stmt = $this->query($sql); - $result = $stmt->fetchAll(Doctrine::FETCH_ASSOC); - if ($result) { - return $result[0]['VAL']; - } else { - return null; - } - } - - /** - * Generate a new value from the specified sequence in the database, and return it. - * This is supported only on RDBMS brands that support sequences - * (e.g. Oracle, PostgreSQL, DB2). Other RDBMS brands return null. - * - * @param string $sequenceName - * @return integer - * @throws Doctrine_Adapter_Db2_Exception - */ - public function nextSequenceId($sequenceName) - { - $this->_connect(); - $sql = 'SELECT NEXTVAL FOR ' - . $this->quoteIdentifier($this->conn->formatter->getSequenceName($sequenceName)) - . ' AS VAL FROM SYSIBM.SYSDUMMY1'; - $stmt = $this->query($sql); - $result = $stmt->fetchAll(Doctrine::FETCH_ASSOC); - if ($result) { - return $result[0]['VAL']; - } else { - return null; - } - } - - /** - * Gets the last ID generated automatically by an IDENTITY/AUTOINCREMENT column. - * - * As a convention, on RDBMS brands that support sequences - * (e.g. Oracle, PostgreSQL, DB2), this method forms the name of a sequence - * from the arguments and returns the last id generated by that sequence. - * On RDBMS brands that support IDENTITY/AUTOINCREMENT columns, this method - * returns the last value generated for such a column, and the table name - * argument is disregarded. - * - * The IDENTITY_VAL_LOCAL() function gives the last generated identity value - * in the current process, even if it was for a GENERATED column. - * - * @param string $tableName OPTIONAL - * @param string $primaryKey OPTIONAL - * @return integer - * @throws Doctrine_Adapter_Db2_Exception - */ - public function lastInsertId($tableName = null, $primaryKey = null) - { - $this->_connect(); - - if ($tableName !== null) { - $sequenceName = $tableName; - if ($primaryKey) { - $sequenceName .= "_$primaryKey"; - } - $sequenceName .= '_seq'; - return $this->lastSequenceId($sequenceName); - } - - $sql = 'SELECT IDENTITY_VAL_LOCAL() AS VAL FROM SYSIBM.SYSDUMMY1'; - $stmt = $this->query($sql); - $result = $stmt->fetchAll(Doctrine::FETCH_ASSOC); - if ($result) { - return $result[0]['VAL']; - } else { - return null; - } - } -} \ No newline at end of file diff --git a/lib/Doctrine/Sequence/Exception.php b/lib/Doctrine/Sequence/Exception.php deleted file mode 100644 index 7283bd036..000000000 --- a/lib/Doctrine/Sequence/Exception.php +++ /dev/null @@ -1,34 +0,0 @@ -. - */ -Doctrine::autoload('Doctrine_Exception'); -/** - * Doctrine_Sequence_Exception - * - * @package Doctrine - * @subpackage Sequence - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @link www.phpdoctrine.org - * @since 1.0 - * @version $Revision$ - * @author Konsta Vesterinen - */ -class Doctrine_Sequence_Exception extends Doctrine_Exception -{ } \ No newline at end of file diff --git a/lib/Doctrine/Sequence/Firebird.php b/lib/Doctrine/Sequence/Firebird.php deleted file mode 100644 index a0ff03041..000000000 --- a/lib/Doctrine/Sequence/Firebird.php +++ /dev/null @@ -1,107 +0,0 @@ -. - */ - -/** - * Doctrine_Sequence_Firebird - * - * @package Doctrine - * @subpackage Sequence - * @author Konsta Vesterinen - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @link www.phpdoctrine.org - * @since 1.0 - * @version $Revision$ - */ -class Doctrine_Sequence_Firebird extends Doctrine_Sequence -{ - /** - * Returns the next free id of a sequence. - * - * @param string $seqName name of the sequence - * @param bool when true missing sequences are automatic created - * - * @return integer next id in the given sequence - */ - public function nextID($seqName, $onDemand = true) - { - $sequenceName = $this->conn->quoteIdentifier($this->conn->formatter->getSequenceName($seqName), true); - - $query = 'SELECT GEN_ID(' . $sequenceName . ', 1) as the_value FROM RDB$DATABASE'; - try { - - $result = $this->conn->fetchOne($query); - - } catch(Doctrine_Connection_Exception $e) { - if ($onDemand && $e->getPortableCode() == Doctrine::ERR_NOSUCHTABLE) { - // Since we are creating the sequence on demand - // we know the first id = 1 so initialize the - // sequence at 2 - try { - $result = $this->conn->export->createSequence($seqName, 2); - } catch(Doctrine_Exception $e) { - throw new Doctrine_Sequence_Exception('on demand sequence ' . $seqName . ' could not be created'); - } - // First ID of a newly created sequence is 1 - // return 1; - // BUT generators are not always reset, so return the actual value - return $this->currID($seqName); - } - throw $e; - } - return $result; - } - - /** - * Returns the autoincrement ID if supported or $id or fetches the current - * ID in a sequence called: $table.(empty($field) ? '' : '_'.$field) - * - * @param string name of the table into which a new row was inserted - * @param string name of the field into which a new row was inserted - */ - public function lastInsertId($table = null, $field = null) - { - return $this->conn->getDbh()->lastInsertId(); - } - - /** - * Returns the current id of a sequence - * - * @param string $seqName name of the sequence - * - * @return integer current id in the given sequence - */ - public function currId($seqName) - { - $sequenceName = $this->conn->quoteIdentifier($this->conn->formatter->getSequenceName($seqName), true); - - - $query = 'SELECT GEN_ID(' . $sequenceName . ', 0) as the_value FROM RDB$DATABASE'; - try { - $value = $this->conn->fetchOne($query); - } catch(Doctrine_Connection_Exception $e) { - throw new Doctrine_Sequence_Exception('Unable to select from ' . $seqName); - } - if ( ! is_numeric($value)) { - throw new Doctrine_Sequence_Exception('could not find value in sequence table'); - } - return $value; - } -} \ No newline at end of file diff --git a/lib/Doctrine/Sequence/Informix.php b/lib/Doctrine/Sequence/Informix.php deleted file mode 100644 index 6e06c4511..000000000 --- a/lib/Doctrine/Sequence/Informix.php +++ /dev/null @@ -1,35 +0,0 @@ -. - */ - -/** - * Doctrine_Sequence_Informix - * - * @package Doctrine - * @subpackage Sequence - * @author Konsta Vesterinen - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @link www.phpdoctrine.org - * @since 1.0 - * @version $Revision$ - * @deprecated - */ -class Doctrine_Sequence_Informix extends Doctrine_Sequence -{ } \ No newline at end of file diff --git a/lib/Doctrine/Sequence/Mssql.php b/lib/Doctrine/Sequence/Mssql.php deleted file mode 100644 index 52d17c7a7..000000000 --- a/lib/Doctrine/Sequence/Mssql.php +++ /dev/null @@ -1,158 +0,0 @@ -. - */ - -/** - * Doctrine_Sequence_Mssql - * - * @package Doctrine - * @subpackage Sequence - * @author Konsta Vesterinen - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @link www.phpdoctrine.org - * @since 1.0 - * @version $Revision$ - * @deprecated - */ -class Doctrine_Sequence_Mssql extends Doctrine_Sequence -{ - /** - * Returns the next free id of a sequence - * - * @param string $seqName name of the sequence - * @param bool when true missing sequences are automatic created - * - * @return integer next id in the given sequence - */ - public function nextId($seqName, $onDemand = true) - { - $sequenceName = $this->conn->quoteIdentifier($this->conn->formatter->getSequenceName($seqName), true); - $seqcolName = $this->conn->quoteIdentifier($this->conn->getAttribute(Doctrine::ATTR_SEQCOL_NAME), true); - - - if ($this->checkSequence($sequenceName)) { - $query = 'SET IDENTITY_INSERT ' . $sequenceName . ' OFF ' - . 'INSERT INTO ' . $sequenceName . ' DEFAULT VALUES'; - } else { - $query = 'INSERT INTO ' . $sequenceName . ' (' . $seqcolName . ') VALUES (0)'; - } - - try { - - $this->conn->exec($query); - - } catch(Doctrine_Connection_Exception $e) { - if ($onDemand && $e->getPortableCode() == Doctrine::ERR_NOSUCHTABLE) { - // Since we are creating the sequence on demand - // we know the first id = 1 so initialize the - // sequence at 2 - try { - $result = $this->conn->export->createSequence($seqName, 2); - } catch(Doctrine_Exception $e) { - throw new Doctrine_Sequence_Exception('on demand sequence ' . $seqName . ' could not be created'); - } - - /** - * This could actually be a table that starts at 18.. oh well.. - * we will keep the fallback to return 1 in case we skip this.. which - * should really not happen.. otherwise the returned values is biased. - */ - if ($this->checkSequence($seqName)) { - return $this->lastInsertId($seqName); - } - - return 1; - } - throw $e; - } - - $value = $this->lastInsertId($sequenceName); - - if (is_numeric($value)) { - $query = 'DELETE FROM ' . $sequenceName . ' WHERE ' . $seqcolName . ' < ' . $value; - - try { - $this->conn->exec($query); - } catch (Doctrine_Connection_Exception $e) { - throw new Doctrine_Sequence_Exception('Could not delete previous sequence from ' . $sequenceName . - ' at ' . __FILE__ . ' in ' . __FUNCTION__ . ' with the message: ' . - $e->getMessage()); - } - } - return $value; - } - - /** - * Checks if there's a sequence that exists. - * - * @param string $seqName The sequence name to verify. - * @return bool $tableExists The value if the table exists or not - * @access private - */ - public function checkSequence($seqName) - { - $query = 'SELECT COUNT(1) FROM ' . $seqName; - try { - $this->conn->execute($query); - } catch (Doctrine_Connection_Exception $e) { - if ($e->getPortableCode() == Doctrine::ERR_NOSUCHTABLE) { - return false; - } - } - return true; - } - - /** - * Returns the autoincrement ID if supported or $id or fetches the current - * ID in a sequence called: $table.(empty($field) ? '' : '_'.$field) - * - * @param string name of the table into which a new row was inserted - * @param string name of the field into which a new row was inserted - */ - public function lastInsertId($table = null, $field = null) - { - $serverInfo = $this->conn->getServerVersion(); - if (is_array($serverInfo) - && ! is_null($serverInfo['major']) - && $serverInfo['major'] >= 8) { - - $query = 'SELECT SCOPE_IDENTITY()'; - - } else { - $query = 'SELECT @@IDENTITY'; - } - - return (string) floor((float) $this->conn->fetchOne($query)); - } - - /** - * Returns the current id of a sequence - * - * @param string $seqName name of the sequence - * - * @return integer current id in the given sequence - */ - public function currId($seqName) - { - $this->warnings[] = 'database does not support getting current - sequence value, the sequence value was incremented'; - return $this->nextId($seqName); - } -} \ No newline at end of file diff --git a/lib/Doctrine/Sequence/Mysql.php b/lib/Doctrine/Sequence/Mysql.php deleted file mode 100644 index 16bbadbdc..000000000 --- a/lib/Doctrine/Sequence/Mysql.php +++ /dev/null @@ -1,105 +0,0 @@ -. - */ - -#namespace Doctrine::DBAL::Sequencing; - -/** - * Doctrine_Sequence_Mysql - * - * @author Konsta Vesterinen - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @link www.phpdoctrine.org - * @since 1.0 - * @version $Revision$ - * @deprecated - */ -class Doctrine_Sequence_Mysql extends Doctrine_Sequence -{ - /** - * Returns the next free id of a sequence - * - * @param string $seqName name of the sequence - * @param bool when true missing sequences are automatic created - * - * @return integer next id in the given sequence - */ - public function nextId($seqName, $onDemand = true) - { - $sequenceName = $this->conn->quoteIdentifier($this->conn->formatter->getSequenceName($seqName), true); - $seqcolName = $this->conn->quoteIdentifier($this->conn->getAttribute(Doctrine::ATTR_SEQCOL_NAME), true); - $query = 'INSERT INTO ' . $sequenceName . ' (' . $seqcolName . ') VALUES (NULL)'; - - try { - $this->conn->exec($query); - } catch (Doctrine_Connection_Exception $e) { - if ($onDemand && $e->getPortableCode() == Doctrine::ERR_NOSUCHTABLE) { - try { - $this->conn->export->createSequence($seqName); - return $this->nextId($seqName, false); - } catch(Doctrine_Exception $e) { - throw new Doctrine_Sequence_Exception('on demand sequence ' . $seqName . ' could not be created'); - } - } - throw $e; - } - - $value = $this->lastInsertId(); - - if (is_numeric($value)) { - $query = 'DELETE FROM ' . $sequenceName . ' WHERE ' . $seqcolName . ' < ' . $value; - try { - $this->conn->exec($query); - } catch (Doctrine_Exception $e) { - throw new Doctrine_Sequence_Exception('could not delete previous sequence table values from ' . $seqName); - } - } - return $value; - } - - /** - * Returns the autoincrement ID if supported or $id or fetches the current - * ID in a sequence called: $table.(empty($field) ? '' : '_'.$field) - * - * @param string name of the table into which a new row was inserted - * @param string name of the field into which a new row was inserted - * @return integer|boolean - */ - public function lastInsertId($table = null, $field = null) - { - return $this->conn->getPdo()->lastInsertId(); - } - - /** - * Returns the current id of a sequence - * - * @param string $seqName name of the sequence - * - * @return integer current id in the given sequence - */ - public function currId($seqName) - { - $sequenceName = $this->conn->quoteIdentifier($this->conn->formatter->getSequenceName($seqName), true); - $seqcolName = $this->conn->quoteIdentifier($this->conn->getAttribute(Doctrine::ATTR_SEQCOL_NAME), true); - $query = 'SELECT MAX(' . $seqcolName . ') FROM ' . $sequenceName; - - return (int) $this->conn->fetchOne($query); - } -} diff --git a/lib/Doctrine/Sequence/Oracle.php b/lib/Doctrine/Sequence/Oracle.php deleted file mode 100644 index 93e047ba1..000000000 --- a/lib/Doctrine/Sequence/Oracle.php +++ /dev/null @@ -1,97 +0,0 @@ -. - */ - -/** - * Doctrine_Sequence_Oracle - * - * @package Doctrine - * @subpackage Sequence - * @author Konsta Vesterinen - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @link www.phpdoctrine.org - * @since 1.0 - * @version $Revision$ - * @deprecated - */ -class Doctrine_Sequence_Oracle extends Doctrine_Sequence -{ - /** - * Returns the next free id of a sequence - * - * @param string $seqName name of the sequence - * @param bool onDemand when true missing sequences are automatic created - * - * @return integer next id in the given sequence - */ - public function nextId($seqName, $onDemand = true) - { - $sequenceName = $this->conn->quoteIdentifier($this->conn->formatter->getSequenceName($seqName), true); - $query = 'SELECT ' . $sequenceName . '.nextval FROM DUAL'; - - try { - $result = $this->conn->fetchOne($query); - } catch(Doctrine_Connection_Exception $e) { - if ($onDemand && $e->getPortableCode() == Doctrine::ERR_NOSUCHTABLE) { - - try { - $result = $this->conn->export->createSequence($seqName); - } catch(Doctrine_Exception $e) { - throw new Doctrine_Sequence_Exception('on demand sequence ' . $seqName . ' could not be created'); - } - return $this->nextId($seqName, false); - } - throw $e; - } - return $result; - } - - /** - * Returns the autoincrement ID if supported or $id or fetches the current - * ID in a sequence called: $table.(empty($field) ? '' : '_'.$field) - * - * @param string name of the table into which a new row was inserted - * @param string name of the field into which a new row was inserted - */ - public function lastInsertId($table = null, $field = null) - { - $seqName = $table . (empty($field) ? '' : '_'.$field); - $sequenceName = $this->conn->quoteIdentifier($this->conn->formatter->getSequenceName($seqName), true); - - return $this->conn->fetchOne('SELECT ' . $sequenceName . '.currval'); - } - - /** - * Returns the current id of a sequence - * - * @param string $seqName name of the sequence - * - * @return integer current id in the given sequence - */ - public function currId($seqName) - { - $sequenceName = $this->conn->quoteIdentifier($this->conn->formatter->getSequenceName($seqName), true); - $query = 'SELECT (last_number-1) FROM user_sequences'; - $query .= ' WHERE sequence_name=' . $this->conn->quote($sequenceName, 'text'); - $query .= ' OR sequence_name=' . $this->conn->quote(strtoupper($sequenceName), 'text'); - - return $this->conn->fetchOne($query); - } -} \ No newline at end of file diff --git a/lib/Doctrine/Sequence/Pgsql.php b/lib/Doctrine/Sequence/Pgsql.php deleted file mode 100644 index 41a31a053..000000000 --- a/lib/Doctrine/Sequence/Pgsql.php +++ /dev/null @@ -1,96 +0,0 @@ -. - */ - -/** - * Doctrine_Sequence_Pgsql - * - * @package Doctrine - * @subpackage Sequence - * @author Konsta Vesterinen - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @link www.phpdoctrine.org - * @since 1.0 - * @version $Revision$ - * @deprecated - */ -class Doctrine_Sequence_Pgsql extends Doctrine_Sequence -{ - /** - * Returns the next free id of a sequence - * - * @param string $seqName name of the sequence - * @param bool onDemand when true missing sequences are automatic created - * - * @return integer next id in the given sequence - */ - public function nextId($seqName, $onDemand = true) - { - $sequenceName = $this->conn->quoteIdentifier($this->conn->formatter->getSequenceName($seqName), true); - - $query = "SELECT NEXTVAL('" . $sequenceName . "')"; - try { - $result = (int) $this->conn->fetchOne($query); - } catch (Doctrine_Connection_Exception $e) { - if ($onDemand && $e->getPortableCode() == Doctrine::ERR_NOSUCHTABLE) { - - try { - $result = $this->conn->export->createSequence($seqName); - } catch(Doctrine_Exception $e) { - throw new Doctrine_Sequence_Exception('on demand sequence ' . $seqName . ' could not be created'); - } - return $this->nextId($seqName, false); - } - } - return $result; - } - - /** - * lastInsertId - * - * Returns the autoincrement ID if supported or $id or fetches the current - * ID in a sequence called: $table.(empty($field) ? '' : '_'.$field) - * - * @param string name of the table into which a new row was inserted - * @param string name of the field into which a new row was inserted - * @return integer the autoincremented id - * @todo Why not use $this->conn->getDbh()->lastInsertId($sequenceName) ? - */ - public function lastInsertId($table = null, $field = null) - { - $seqName = $table . (empty($field) ? '' : '_' . $field); - $sequenceName = $this->conn->quoteIdentifier($this->conn->formatter->getSequenceName($seqName), true); - - return (int) $this->conn->fetchOne("SELECT CURRVAL('" . $sequenceName . "')"); - } - - /** - * Returns the current id of a sequence - * - * @param string $seqName name of the sequence - * - * @return integer current id in the given sequence - */ - public function currId($seqName) - { - $sequenceName = $this->conn->quoteIdentifier($this->conn->formatter->getSequenceName($seqName), true); - return (int) $this->conn->fetchOne('SELECT last_value FROM ' . $sequenceName); - } -} \ No newline at end of file diff --git a/lib/Doctrine/Sequence/Sqlite.php b/lib/Doctrine/Sequence/Sqlite.php deleted file mode 100644 index 6357782cd..000000000 --- a/lib/Doctrine/Sequence/Sqlite.php +++ /dev/null @@ -1,107 +0,0 @@ -. - */ - -/** - * Doctrine_Sequence_Sqlite - * - * @package Doctrine - * @subpackage Sequence - * @author Konsta Vesterinen - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @link www.phpdoctrine.org - * @since 1.0 - * @version $Revision$ - * @deprecated - */ -class Doctrine_Sequence_Sqlite extends Doctrine_Sequence -{ - /** - * Returns the next free id of a sequence. - * - * @param string $seqName name of the sequence - * @param bool $onDemand when true missing sequences are automatic created - * - * @return integer next id in the given sequence - */ - public function nextId($seqName, $onDemand = true) - { - $sequenceName = $this->conn->quoteIdentifier($this->conn->formatter->getSequenceName($seqName), true); - $seqcolName = $this->conn->quoteIdentifier($this->conn->getAttribute(Doctrine::ATTR_SEQCOL_NAME), true); - - $query = 'INSERT INTO ' . $sequenceName . ' (' . $seqcolName . ') VALUES (NULL)'; - - try { - $this->conn->exec($query); - } catch (Doctrine_Connection_Exception $e) { - if ($onDemand && $e->getPortableCode() == Doctrine::ERR_NOSUCHTABLE) { - try { - $this->conn->export->createSequence($seqName); - return $this->nextId($seqName, false); - } catch(Doctrine_Exception $e) { - throw new Doctrine_Sequence_Exception('on demand sequence ' . $seqName . ' could not be created'); - } - } - throw $e; - } - - $value = $this->lastInsertId(); - - if (is_numeric($value)) { - $query = 'DELETE FROM ' . $sequenceName . ' WHERE ' . $seqcolName . ' < ' . $value; - try { - $this->conn->exec($query); - } catch(Doctrine_Exception $e) { - throw new Doctrine_Sequence_Exception('could not delete previous sequence table values from ' . $seqName); - } - } - return $value; - } - - /** - * Returns the autoincrement ID if supported or $id or fetches the current - * ID in a sequence called: $table.(empty($field) ? '' : '_'.$field) - * - * @param string name of the table into which a new row was inserted - * @param string name of the field into which a new row was inserted - * @return integer|boolean - */ - public function lastInsertId($table = null, $field = null) - { - return $this->conn->getPdo()->lastInsertId(); - } - - /** - * Returns the current id of a sequence - * - * @param string $seqName name of the sequence - * - * @return integer current id in the given sequence - */ - public function currId($seqName) - { - $sequenceName = $this->conn->quoteIdentifier($this->conn->formatter->getSequenceName($seqName), true); - $seqcolName = $this->conn->quoteIdentifier($this->conn->getAttribute(Doctrine::ATTR_SEQCOL_NAME), true); - - $query = 'SELECT MAX(' . $seqcolName . ') FROM ' . $sequenceName; - - return (int) $this->conn->fetchOne($query); - } -} diff --git a/lib/Doctrine/Transaction/Exception.php b/lib/Doctrine/Transaction/Exception.php deleted file mode 100644 index 362380157..000000000 --- a/lib/Doctrine/Transaction/Exception.php +++ /dev/null @@ -1,35 +0,0 @@ -. - */ -Doctrine::autoload('Doctrine_Exception'); -/** - * Doctrine_Transaction_Exception - * - * @package Doctrine - * @subpackage Transaction - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @author Konsta Vesterinen - * @since 1.0 - * @version $Revision$ - * @link www.phpdoctrine.org - * @todo remove - */ -class Doctrine_Transaction_Exception extends Doctrine_Exception -{ } \ No newline at end of file diff --git a/lib/Doctrine/Transaction/Firebird.php b/lib/Doctrine/Transaction/Firebird.php deleted file mode 100644 index ff01d190d..000000000 --- a/lib/Doctrine/Transaction/Firebird.php +++ /dev/null @@ -1,142 +0,0 @@ -. - */ - -#namespace Doctrine::DBAL::Transactions; - -/** - * - * @author Konsta Vesterinen - * @author Lukas Smith (PEAR MDB2 library) - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @link www.phpdoctrine.org - * @since 1.0 - * @version $Revision$ - * @todo remove - */ -class Doctrine_Transaction_Firebird extends Doctrine_Transaction -{ - /** - * creates a new savepoint - * - * @param string $savepoint name of a savepoint to set - * @return void - * @override - */ - protected function createSavePoint($savepoint) - { - $query = 'SAVEPOINT ' . $savepoint; - - return $this->conn->execute($query); - } - - /** - * releases given savepoint - * - * @param string $savepoint name of a savepoint to release - * @return void - * @override - */ - protected function releaseSavePoint($savepoint) - { - $query = 'RELEASE SAVEPOINT ' . $savepoint; - - return $this->conn->execute($query); - } - - /** - * releases given savepoint - * - * @param string $savepoint name of a savepoint to rollback to - * @return void - * @override - */ - protected function rollbackSavePoint($savepoint) - { - $query = 'ROLLBACK TO SAVEPOINT '.$savepoint; - - return $this->conn->execute($query); - } - - /** - * Set the transacton isolation level. - * - * @param string standard isolation level (SQL-92) - * READ UNCOMMITTED (allows dirty reads) - * READ COMMITTED (prevents dirty reads) - * REPEATABLE READ (prevents nonrepeatable reads) - * SERIALIZABLE (prevents phantom reads) - * - * @param array some transaction options: - * 'wait' => 'WAIT' | 'NO WAIT' - * 'rw' => 'READ WRITE' | 'READ ONLY' - * - * @throws PDOException if something fails at the PDO level - * @throws Doctrine_Transaction_Exception if using unknown isolation level or unknown wait option - * @return void - * @override - */ - public function setIsolation($isolation, $options = array()) { - switch ($isolation) { - case 'READ UNCOMMITTED': - $nativeIsolation = 'READ COMMITTED RECORD_VERSION'; - break; - case 'READ COMMITTED': - $nativeIsolation = 'READ COMMITTED NO RECORD_VERSION'; - break; - case 'REPEATABLE READ': - $nativeIsolation = 'SNAPSHOT'; - break; - case 'SERIALIZABLE': - $nativeIsolation = 'SNAPSHOT TABLE STABILITY'; - break; - default: - throw new Doctrine_Transaction_Exception('isolation level is not supported: ' . $isolation); - } - - $rw = $wait = ''; - - if (isset($options['wait'])) { - switch ($options['wait']) { - case 'WAIT': - case 'NO WAIT': - $wait = ' ' . $options['wait']; - break; - default: - throw new Doctrine_Transaction_Exception('wait option is not supported: ' . $options['wait']); - } - } - - if (isset($options['rw'])) { - switch ($options['rw']) { - case 'READ ONLY': - case 'READ WRITE': - $rw = ' ' . $options['rw']; - break; - default: - throw new Doctrine_Transaction_Exception('wait option is not supported: ' . $options['rw']); - } - } - - $query = 'SET TRANSACTION' . $rw . $wait .' ISOLATION LEVEL ' . $nativeIsolation; - - $this->conn->execute($query); - } -} \ No newline at end of file diff --git a/lib/Doctrine/Transaction/Informix.php b/lib/Doctrine/Transaction/Informix.php deleted file mode 100644 index 465cde5e1..000000000 --- a/lib/Doctrine/Transaction/Informix.php +++ /dev/null @@ -1,33 +0,0 @@ -. - */ - -/** - * - * @author Konsta Vesterinen - * @author Lukas Smith (PEAR MDB2 library) - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @link www.phpdoctrine.org - * @since 1.0 - * @version $Revision$ - * @todo remove - */ -class Doctrine_Transaction_Informix extends Doctrine_Transaction -{ } \ No newline at end of file diff --git a/lib/Doctrine/Transaction/Mock.php b/lib/Doctrine/Transaction/Mock.php deleted file mode 100644 index 27d3ec893..000000000 --- a/lib/Doctrine/Transaction/Mock.php +++ /dev/null @@ -1,37 +0,0 @@ -. - */ -Doctrine::autoload('Doctrine_Transaction'); -/** - * Doctrine_Transaction_Mock - * This class is used for testing purposes - * - * @author Konsta Vesterinen - * @author Lukas Smith (PEAR MDB2 library) - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @package Doctrine - * @subpackage Transaction - * @link www.phpdoctrine.org - * @since 1.0 - * @version $Revision$ - * @todo remove - */ -class Doctrine_Transaction_Mock extends Doctrine_Transaction -{ } \ No newline at end of file diff --git a/lib/Doctrine/Transaction/Mssql.php b/lib/Doctrine/Transaction/Mssql.php deleted file mode 100644 index d3f0f9b7b..000000000 --- a/lib/Doctrine/Transaction/Mssql.php +++ /dev/null @@ -1,100 +0,0 @@ -. - */ - -/** - * - * @author Konsta Vesterinen - * @author Lukas Smith (PEAR MDB2 library) - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @package Doctrine - * @subpackage Transaction - * @link www.phpdoctrine.org - * @since 1.0 - * @version $Revision$ - * @todo remove - */ -class Doctrine_Transaction_Mssql extends Doctrine_Transaction -{ - /** - * Set the transacton isolation level. - * - * @param string standard isolation level (SQL-92) - * portable modes: - * READ UNCOMMITTED (allows dirty reads) - * READ COMMITTED (prevents dirty reads) - * REPEATABLE READ (prevents nonrepeatable reads) - * SERIALIZABLE (prevents phantom reads) - * mssql specific modes: - * SNAPSHOT - * - * @link http://msdn2.microsoft.com/en-us/library/ms173763.aspx - * @throws PDOException if something fails at the PDO level - * @throws Doctrine_Transaction_Exception if using unknown isolation level or unknown wait option - * @return void - * @override - */ - public function setIsolation($isolation, $options = array()) { - switch ($isolation) { - case 'READ UNCOMMITTED': - case 'READ COMMITTED': - case 'REPEATABLE READ': - case 'SERIALIZABLE': - case 'SNAPSHOT': - break; - default: - throw new Doctrine_Transaction_Exception('isolation level is not supported: ' . $isolation); - } - - $query = 'SET TRANSACTION ISOLATION LEVEL ' . $isolation; - - $this->conn->execute($query); - } - - /** - * Performs the rollback. - * - * @override - */ - protected function _doRollback() - { - $this->conn->getDbh()->exec('ROLLBACK TRANSACTION'); - } - - /** - * Performs the commit. - * - * @override - */ - protected function _doCommit() - { - $this->conn->getDbh()->exec('COMMIT TRANSACTION'); - } - - /** - * Begins a database transaction. - * - * @override - */ - protected function _doBeginTransaction() - { - $this->conn->getDbh()->exec('BEGIN TRANSACTION'); - } -} \ No newline at end of file diff --git a/lib/Doctrine/Transaction/Mysql.php b/lib/Doctrine/Transaction/Mysql.php deleted file mode 100644 index 0109a29f0..000000000 --- a/lib/Doctrine/Transaction/Mysql.php +++ /dev/null @@ -1,117 +0,0 @@ -. - */ - -/** - * - * @author Konsta Vesterinen - * @author Lukas Smith (PEAR MDB2 library) - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @package Doctrine - * @subpackage Transaction - * @link www.phpdoctrine.org - * @since 1.0 - * @version $Revision$ - * @todo remove - */ -class Doctrine_Transaction_Mysql extends Doctrine_Transaction -{ - /** - * createSavepoint - * creates a new savepoint - * - * @param string $savepoint name of a savepoint to set - * @return void - */ - protected function createSavePoint($savepoint) - { - $query = 'SAVEPOINT ' . $savepoint; - - return $this->conn->execute($query); - } - - /** - * releaseSavePoint - * releases given savepoint - * - * @param string $savepoint name of a savepoint to release - * @return void - */ - protected function releaseSavePoint($savepoint) - { - $query = 'RELEASE SAVEPOINT ' . $savepoint; - - return $this->conn->execute($query); - } - - /** - * rollbackSavePoint - * releases given savepoint - * - * @param string $savepoint name of a savepoint to rollback to - * @return void - */ - protected function rollbackSavePoint($savepoint) - { - $query = 'ROLLBACK TO SAVEPOINT ' . $savepoint; - - return $this->conn->execute($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) - * - * @throws Doctrine_Transaction_Exception if using unknown isolation level - * @throws PDOException if something fails at the PDO level - * @return void - */ - public function setIsolation($isolation) - { - switch ($isolation) { - case 'READ UNCOMMITTED': - case 'READ COMMITTED': - case 'REPEATABLE READ': - case 'SERIALIZABLE': - break; - default: - throw new Doctrine_Transaction_Exception('Isolation level ' . $isolation . ' is not supported.'); - } - - $query = 'SET SESSION TRANSACTION ISOLATION LEVEL ' . $isolation; - - return $this->conn->execute($query); - } - - /** - * getTransactionIsolation - * - * @return string returns the current session transaction isolation level - */ - public function getIsolation() - { - return $this->conn->fetchOne('SELECT @@tx_isolation'); - } -} \ No newline at end of file diff --git a/lib/Doctrine/Transaction/Oracle.php b/lib/Doctrine/Transaction/Oracle.php deleted file mode 100644 index d9b9bd1e6..000000000 --- a/lib/Doctrine/Transaction/Oracle.php +++ /dev/null @@ -1,108 +0,0 @@ -. - */ - -/** - * - * @author Konsta Vesterinen - * @author Lukas Smith (PEAR MDB2 library) - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @package Doctrine - * @subpackage Transaction - * @link www.phpdoctrine.org - * @since 1.0 - * @version $Revision$ - * @todo remove - */ -class Doctrine_Transaction_Oracle extends Doctrine_Transaction -{ - /** - * creates a new savepoint - * - * @param string $savepoint name of a savepoint to set - * @return void - * @override - */ - protected function createSavePoint($savepoint) - { - $query = 'SAVEPOINT ' . $savepoint; - - return $this->conn->execute($query); - } - - /** - * releases given savepoint - * - * @param string $savepoint name of a savepoint to release - * @return void - * @override - */ - protected function releaseSavePoint($savepoint) - { - // oracle doesn't support manual releasing of savepoints - return true; - } - - /** - * releases given savepoint - * - * @param string $savepoint name of a savepoint to rollback to - * @return void - * @override - */ - protected function rollbackSavePoint($savepoint) - { - $query = 'ROLLBACK TO SAVEPOINT ' . $savepoint; - - return $this->conn->execute($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) - * @throws PDOException if something fails at the PDO level - * @throws Doctrine_Transaction_Exception if using unknown isolation level - * @return void - * @override - */ - public function setIsolation($isolation) - { - switch ($isolation) { - case 'READ UNCOMMITTED': - $isolation = 'READ COMMITTED'; - break; - case 'READ COMMITTED': - case 'REPEATABLE READ': - case 'SERIALIZABLE': - $isolation = 'SERIALIZABLE'; - break; - default: - throw new Doctrine_Transaction_Exception('Isolation level ' . $isolation . ' is not supported.'); - } - - $query = 'ALTER SESSION ISOLATION LEVEL ' . $isolation; - return $this->conn->execute($query); - } -} \ No newline at end of file diff --git a/lib/Doctrine/Transaction/Pgsql.php b/lib/Doctrine/Transaction/Pgsql.php deleted file mode 100644 index 8310a398b..000000000 --- a/lib/Doctrine/Transaction/Pgsql.php +++ /dev/null @@ -1,110 +0,0 @@ -. - */ - -/** - * - * @author Konsta Vesterinen - * @author Paul Cooper (PEAR MDB2 Pgsql driver) - * @author Lukas Smith (PEAR MDB2 library) - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @package Doctrine - * @subpackage Transaction - * @link www.phpdoctrine.org - * @since 1.0 - * @version $Revision$ - * @todo remove - */ -class Doctrine_Transaction_Pgsql extends Doctrine_Transaction -{ - /** - * createSavepoint - * creates a new savepoint - * - * @param string $savepoint name of a savepoint to set - * @return void - * @override - */ - protected function createSavePoint($savepoint) - { - $query = 'SAVEPOINT ' . $savepoint; - - return $this->conn->execute($query); - } - - /** - * releaseSavePoint - * releases given savepoint - * - * @param string $savepoint name of a savepoint to release - * @return void - * @override - */ - protected function releaseSavePoint($savepoint) - { - $query = 'RELEASE SAVEPOINT ' . $savepoint; - - return $this->conn->execute($query); - } - - /** - * rollbackSavePoint - * releases given savepoint - * - * @param string $savepoint name of a savepoint to rollback to - * @return void - * @override - */ - protected function rollbackSavePoint($savepoint) - { - $query = 'ROLLBACK TO SAVEPOINT ' . $savepoint; - - return $this->conn->execute($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) - * @throws PDOException if something fails at the PDO level - * @throws Doctrine_Transaction_Exception if using unknown isolation level or unknown wait option - * @return void - * @override - */ - public function setIsolation($isolation) - { - switch ($isolation) { - case 'READ UNCOMMITTED': - case 'READ COMMITTED': - case 'REPEATABLE READ': - case 'SERIALIZABLE': - break; - default: - throw new Doctrine_Transaction_Exception('Isolation level '.$isolation.' is not supported.'); - } - - $query = 'SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL ' . $isolation; - return $this->conn->execute($query); - } -} \ No newline at end of file diff --git a/lib/Doctrine/Transaction/Sqlite.php b/lib/Doctrine/Transaction/Sqlite.php deleted file mode 100644 index fe642cf23..000000000 --- a/lib/Doctrine/Transaction/Sqlite.php +++ /dev/null @@ -1,68 +0,0 @@ -. - */ - -/** - * - * @author Konsta Vesterinen - * @author Lukas Smith (PEAR MDB2 library) - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @package Doctrine - * @subpackage Transaction - * @link www.phpdoctrine.org - * @since 1.0 - * @version $Revision$ - * @todo remove - */ -class Doctrine_Transaction_Sqlite extends Doctrine_Transaction -{ - /** - * 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 PDOException if something fails at the PDO level - * @throws Doctrine_Transaction_Exception if using unknown isolation level - * @return void - * @override - */ - public function setIsolation($isolation) - { - switch ($isolation) { - case 'READ UNCOMMITTED': - $isolation = 0; - break; - case 'READ COMMITTED': - case 'REPEATABLE READ': - case 'SERIALIZABLE': - $isolation = 1; - break; - default: - throw new Doctrine_Transaction_Exception('Isolation level ' . $isolation . 'is not supported.'); - } - - $query = 'PRAGMA read_uncommitted = ' . $isolation; - - return $this->conn->execute($query); - } -} \ No newline at end of file diff --git a/tests/lib/Doctrine_OrmTestCase.php b/tests/lib/Doctrine_OrmTestCase.php index a6f529181..021f4b2ab 100644 --- a/tests/lib/Doctrine_OrmTestCase.php +++ b/tests/lib/Doctrine_OrmTestCase.php @@ -1,6 +1,6 @@ 'Doctrine_ConnectionMock', + 'driverClass' => 'Doctrine_DriverMock', + 'wrapperClass' => 'Doctrine_ConnectionMock', 'user' => 'john', 'password' => 'wayne' ); diff --git a/tests/lib/Doctrine_OrmTestSuite.php b/tests/lib/Doctrine_OrmTestSuite.php index 02a2dd637..d04ad07df 100644 --- a/tests/lib/Doctrine_OrmTestSuite.php +++ b/tests/lib/Doctrine_OrmTestSuite.php @@ -13,7 +13,8 @@ class Doctrine_OrmTestSuite extends Doctrine_TestSuite $config = new Doctrine_Common_Configuration(); $eventManager = new Doctrine_Common_EventManager(); $connectionOptions = array( - 'driverClass' => 'Doctrine_ConnectionMock', + 'driverClass' => 'Doctrine_DriverMock', + 'wrapperClass' => 'Doctrine_ConnectionMock', 'user' => 'john', 'password' => 'wayne' ); diff --git a/tests/lib/Doctrine_TestUtil.php b/tests/lib/Doctrine_TestUtil.php index fc0bf4ea4..254c06898 100644 --- a/tests/lib/Doctrine_TestUtil.php +++ b/tests/lib/Doctrine_TestUtil.php @@ -19,7 +19,7 @@ class Doctrine_TestUtil //return Doctrine_Manager::connection($dsn, 'testconn'); } else { $params = array( - 'driver' => 'sqlite', + 'driver' => 'pdo_sqlite', 'memory' => true ); } diff --git a/tests/lib/mocks/Doctrine_ConnectionMock.php b/tests/lib/mocks/Doctrine_ConnectionMock.php index bb14fdb41..1866be7ad 100644 --- a/tests/lib/mocks/Doctrine_ConnectionMock.php +++ b/tests/lib/mocks/Doctrine_ConnectionMock.php @@ -3,16 +3,15 @@ require_once 'lib/mocks/Doctrine_SequenceMock.php'; require_once 'lib/mocks/Doctrine_DatabasePlatformMock.php'; -class Doctrine_ConnectionMock extends Doctrine_Connection +class Doctrine_ConnectionMock extends Doctrine_DBAL_Connection { - protected $_driverName = 'Mysql'; private $_platformMock; private $_lastInsertId = 0; private $_inserts = array(); - public function __construct(array $params) - { - parent::__construct($params); + public function __construct() { + $this->_platformMock = new Doctrine_DatabasePlatformMock(); + $this->_platform = $this->_platformMock; } /** @@ -20,9 +19,6 @@ class Doctrine_ConnectionMock extends Doctrine_Connection */ public function getDatabasePlatform() { - if ( ! $this->_platformMock) { - $this->_platformMock = new Doctrine_DatabasePlatformMock(); - } return $this->_platformMock; } diff --git a/tests/lib/mocks/Doctrine_DriverConnectionMock.php b/tests/lib/mocks/Doctrine_DriverConnectionMock.php new file mode 100644 index 000000000..3c1a56963 --- /dev/null +++ b/tests/lib/mocks/Doctrine_DriverConnectionMock.php @@ -0,0 +1,17 @@ + \ No newline at end of file diff --git a/tests/lib/mocks/Doctrine_DriverMock.php b/tests/lib/mocks/Doctrine_DriverMock.php new file mode 100644 index 000000000..c30229a3a --- /dev/null +++ b/tests/lib/mocks/Doctrine_DriverMock.php @@ -0,0 +1,33 @@ + \ No newline at end of file