|
|
@@ -14,17 +14,24 @@
|
|
|
*/
|
|
|
namespace Cake\Database;
|
|
|
|
|
|
+use Cake\Database\Query;
|
|
|
+use Cake\Database\Statement\PDOStatement;
|
|
|
use InvalidArgumentException;
|
|
|
use PDO;
|
|
|
+use PDOException;
|
|
|
|
|
|
/**
|
|
|
* Represents a database driver containing all specificities for
|
|
|
* a database engine including its SQL dialect.
|
|
|
- *
|
|
|
- * @property \PDO|null $_connection
|
|
|
*/
|
|
|
-abstract class Driver
|
|
|
+abstract class Driver implements DriverInterface
|
|
|
{
|
|
|
+ /**
|
|
|
+ * Instance of PDO.
|
|
|
+ *
|
|
|
+ * @var \PDO|null
|
|
|
+ */
|
|
|
+ protected $_connection;
|
|
|
|
|
|
/**
|
|
|
* Configuration data.
|
|
|
@@ -72,112 +79,169 @@ abstract class Driver
|
|
|
/**
|
|
|
* Establishes a connection to the database server
|
|
|
*
|
|
|
+ * @param string $dsn A Driver-specific PDO-DSN
|
|
|
+ * @param array $config configuration to be used for creating connection
|
|
|
* @return bool true on success
|
|
|
*/
|
|
|
+ protected function _connect($dsn, array $config)
|
|
|
+ {
|
|
|
+ $connection = new PDO(
|
|
|
+ $dsn,
|
|
|
+ $config['username'],
|
|
|
+ $config['password'],
|
|
|
+ $config['flags']
|
|
|
+ );
|
|
|
+ $this->setConnection($connection);
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * {@inheritDoc}
|
|
|
+ */
|
|
|
abstract public function connect();
|
|
|
|
|
|
/**
|
|
|
- * Disconnects from database server
|
|
|
- *
|
|
|
- * @return void
|
|
|
+ * {@inheritDoc}
|
|
|
*/
|
|
|
- abstract public function disconnect();
|
|
|
+ public function disconnect()
|
|
|
+ {
|
|
|
+ $this->_connection = null;
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
* Returns correct connection resource or object that is internally used
|
|
|
- * If first argument is passed,
|
|
|
+ * If first argument is passed, it will set internal connection object or
|
|
|
+ * result to the value passed.
|
|
|
+ *
|
|
|
+ * @param mixed $connection The PDO connection instance.
|
|
|
+ * @return mixed Connection object used internally.
|
|
|
+ * @deprecated 3.6.0 Use getConnection()/setConnection() instead.
|
|
|
+ */
|
|
|
+ public function connection($connection = null)
|
|
|
+ {
|
|
|
+ deprecationWarning(
|
|
|
+ get_called_class() . '::connection() is deprecated. ' .
|
|
|
+ 'Use setConnection()/getConnection() instead.'
|
|
|
+ );
|
|
|
+ if ($connection !== null) {
|
|
|
+ $this->_connection = $connection;
|
|
|
+ }
|
|
|
+
|
|
|
+ return $this->_connection;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Get the internal PDO connection instance.
|
|
|
*
|
|
|
- * @param null|\PDO $connection The connection object
|
|
|
* @return \PDO
|
|
|
*/
|
|
|
- abstract public function connection($connection = null);
|
|
|
+ public function getConnection()
|
|
|
+ {
|
|
|
+ return $this->_connection;
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
- * Returns whether php is able to use this driver for connecting to database
|
|
|
+ * Set the internal PDO connection instance.
|
|
|
*
|
|
|
- * @return bool true if it is valid to use this driver
|
|
|
+ * @param \PDO $connection PDO instance.
|
|
|
+ * @return $this
|
|
|
+ */
|
|
|
+ public function setConnection($connection)
|
|
|
+ {
|
|
|
+ $this->_connection = $connection;
|
|
|
+
|
|
|
+ return $this;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * {@inheritDoc}
|
|
|
*/
|
|
|
abstract public function enabled();
|
|
|
|
|
|
/**
|
|
|
- * Prepares a sql statement to be executed
|
|
|
- *
|
|
|
- * @param string|\Cake\Database\Query $query The query to convert into a statement.
|
|
|
- * @return \Cake\Database\StatementInterface
|
|
|
+ * {@inheritDoc}
|
|
|
*/
|
|
|
- abstract public function prepare($query);
|
|
|
+ public function prepare($query)
|
|
|
+ {
|
|
|
+ $this->connect();
|
|
|
+ $isObject = $query instanceof Query;
|
|
|
+ $statement = $this->_connection->prepare($isObject ? $query->sql() : $query);
|
|
|
+
|
|
|
+ return new PDOStatement($statement, $this);
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
- * Starts a transaction
|
|
|
- *
|
|
|
- * @return bool true on success, false otherwise
|
|
|
+ * {@inheritDoc}
|
|
|
*/
|
|
|
- abstract public function beginTransaction();
|
|
|
+ public function beginTransaction()
|
|
|
+ {
|
|
|
+ $this->connect();
|
|
|
+ if ($this->_connection->inTransaction()) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ return $this->_connection->beginTransaction();
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
- * Commits a transaction
|
|
|
- *
|
|
|
- * @return bool true on success, false otherwise
|
|
|
+ * {@inheritDoc}
|
|
|
*/
|
|
|
- abstract public function commitTransaction();
|
|
|
+ public function commitTransaction()
|
|
|
+ {
|
|
|
+ $this->connect();
|
|
|
+ if (!$this->_connection->inTransaction()) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ return $this->_connection->commit();
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
- * Rollsback a transaction
|
|
|
- *
|
|
|
- * @return bool true on success, false otherwise
|
|
|
+ * {@inheritDoc}
|
|
|
*/
|
|
|
- abstract public function rollbackTransaction();
|
|
|
+ public function rollbackTransaction()
|
|
|
+ {
|
|
|
+ $this->connect();
|
|
|
+ if (!$this->_connection->inTransaction()) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ return $this->_connection->rollBack();
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
- * Get the SQL for releasing a save point.
|
|
|
- *
|
|
|
- * @param string $name The table name
|
|
|
- * @return string
|
|
|
+ * {@inheritDoc}
|
|
|
*/
|
|
|
abstract public function releaseSavePointSQL($name);
|
|
|
|
|
|
/**
|
|
|
- * Get the SQL for creating a save point.
|
|
|
- *
|
|
|
- * @param string $name The table name
|
|
|
- * @return string
|
|
|
+ * {@inheritDoc}
|
|
|
*/
|
|
|
abstract public function savePointSQL($name);
|
|
|
|
|
|
/**
|
|
|
- * Get the SQL for rollingback a save point.
|
|
|
- *
|
|
|
- * @param string $name The table name
|
|
|
- * @return string
|
|
|
+ * {@inheritDoc}
|
|
|
*/
|
|
|
abstract public function rollbackSavePointSQL($name);
|
|
|
|
|
|
/**
|
|
|
- * Get the SQL for disabling foreign keys
|
|
|
- *
|
|
|
- * @return string
|
|
|
+ * {@inheritDoc}
|
|
|
*/
|
|
|
abstract public function disableForeignKeySQL();
|
|
|
|
|
|
/**
|
|
|
- * Get the SQL for enabling foreign keys
|
|
|
- *
|
|
|
- * @return string
|
|
|
+ * {@inheritDoc}
|
|
|
*/
|
|
|
abstract public function enableForeignKeySQL();
|
|
|
|
|
|
/**
|
|
|
- * Returns whether the driver supports adding or dropping constraints
|
|
|
- * to already created tables.
|
|
|
- *
|
|
|
- * @return bool true if driver supports dynamic constraints
|
|
|
+ * {@inheritDoc}
|
|
|
*/
|
|
|
abstract public function supportsDynamicConstraints();
|
|
|
|
|
|
/**
|
|
|
- * Returns whether this driver supports save points for nested transactions
|
|
|
- *
|
|
|
- * @return bool true if save points are supported, false otherwise
|
|
|
+ * {@inheritDoc}
|
|
|
*/
|
|
|
public function supportsSavePoints()
|
|
|
{
|
|
|
@@ -185,62 +249,44 @@ abstract class Driver
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Returns a value in a safe representation to be used in a query string
|
|
|
- *
|
|
|
- * @param mixed $value The value to quote.
|
|
|
- * @param string $type Type to be used for determining kind of quoting to perform
|
|
|
- * @return string
|
|
|
+ * {@inheritDoc}
|
|
|
*/
|
|
|
- abstract public function quote($value, $type);
|
|
|
+ public function quote($value, $type)
|
|
|
+ {
|
|
|
+ $this->connect();
|
|
|
+
|
|
|
+ return $this->_connection->quote($value, $type);
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
- * Checks if the driver supports quoting
|
|
|
+ * Checks if the driver supports quoting, as PDO_ODBC does not support it.
|
|
|
*
|
|
|
* @return bool
|
|
|
*/
|
|
|
public function supportsQuoting()
|
|
|
{
|
|
|
- return true;
|
|
|
+ $this->connect();
|
|
|
+
|
|
|
+ return $this->_connection->getAttribute(PDO::ATTR_DRIVER_NAME) !== 'odbc';
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Returns a callable function that will be used to transform a passed Query object.
|
|
|
- * This function, in turn, will return an instance of a Query object that has been
|
|
|
- * transformed to accommodate any specificities of the SQL dialect in use.
|
|
|
- *
|
|
|
- * @param string $type the type of query to be transformed
|
|
|
- * (select, insert, update, delete)
|
|
|
- * @return callable
|
|
|
+ * {@inheritDoc}
|
|
|
*/
|
|
|
abstract public function queryTranslator($type);
|
|
|
|
|
|
/**
|
|
|
- * Get the schema dialect.
|
|
|
- *
|
|
|
- * Used by Cake\Database\Schema package to reflect schema and
|
|
|
- * generate schema.
|
|
|
- *
|
|
|
- * If all the tables that use this Driver specify their
|
|
|
- * own schemas, then this may return null.
|
|
|
- *
|
|
|
- * @return \Cake\Database\Schema\BaseSchema
|
|
|
+ * {@inheritDoc}
|
|
|
*/
|
|
|
abstract public function schemaDialect();
|
|
|
|
|
|
/**
|
|
|
- * Quotes a database identifier (a column name, table name, etc..) to
|
|
|
- * be used safely in queries without the risk of using reserved words
|
|
|
- *
|
|
|
- * @param string $identifier The identifier expression to quote.
|
|
|
- * @return string
|
|
|
+ * {@inheritDoc}
|
|
|
*/
|
|
|
abstract public function quoteIdentifier($identifier);
|
|
|
|
|
|
/**
|
|
|
- * Escapes values for use in schema definitions.
|
|
|
- *
|
|
|
- * @param mixed $value The value to escape.
|
|
|
- * @return string String for use in schema definitions.
|
|
|
+ * {@inheritDoc}
|
|
|
*/
|
|
|
public function schemaValue($value)
|
|
|
{
|
|
|
@@ -267,9 +313,7 @@ abstract class Driver
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Returns the schema name that's being used
|
|
|
- *
|
|
|
- * @return string
|
|
|
+ * {@inheritDoc}
|
|
|
*/
|
|
|
public function schema()
|
|
|
{
|
|
|
@@ -277,33 +321,39 @@ abstract class Driver
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Returns last id generated for a table or sequence in database
|
|
|
- *
|
|
|
- * @param string|null $table table name or sequence to get last insert value from
|
|
|
- * @param string|null $column the name of the column representing the primary key
|
|
|
- * @return string|int
|
|
|
+ * {@inheritDoc}
|
|
|
*/
|
|
|
public function lastInsertId($table = null, $column = null)
|
|
|
{
|
|
|
+ $this->connect();
|
|
|
+
|
|
|
+ if ($this->_connection instanceof PDO) {
|
|
|
+ return $this->_connection->lastInsertId($table);
|
|
|
+ }
|
|
|
+
|
|
|
return $this->_connection->lastInsertId($table, $column);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Check whether or not the driver is connected.
|
|
|
- *
|
|
|
- * @return bool
|
|
|
+ * {@inheritDoc}
|
|
|
*/
|
|
|
public function isConnected()
|
|
|
{
|
|
|
- return $this->_connection !== null;
|
|
|
+ if ($this->_connection === null) {
|
|
|
+ $connected = false;
|
|
|
+ } else {
|
|
|
+ try {
|
|
|
+ $connected = $this->_connection->query('SELECT 1');
|
|
|
+ } catch (PDOException $e) {
|
|
|
+ $connected = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return (bool)$connected;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Sets whether or not this driver should automatically quote identifiers
|
|
|
- * in queries.
|
|
|
- *
|
|
|
- * @param bool $enable Whether to enable auto quoting
|
|
|
- * @return $this
|
|
|
+ * {@inheritDoc}
|
|
|
*/
|
|
|
public function enableAutoQuoting($enable = true)
|
|
|
{
|
|
|
@@ -313,10 +363,7 @@ abstract class Driver
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Returns whether or not this driver should automatically quote identifiers
|
|
|
- * in queries
|
|
|
- *
|
|
|
- * @return bool
|
|
|
+ * {@inheritDoc}
|
|
|
*/
|
|
|
public function isAutoQuotingEnabled()
|
|
|
{
|
|
|
@@ -348,13 +395,7 @@ abstract class Driver
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Transforms the passed query to this Driver's dialect and returns an instance
|
|
|
- * of the transformed query and the full compiled SQL string
|
|
|
- *
|
|
|
- * @param \Cake\Database\Query $query The query to compile.
|
|
|
- * @param \Cake\Database\ValueBinder $generator The value binder to use.
|
|
|
- * @return array containing 2 entries. The first entity is the transformed query
|
|
|
- * and the second one the compiled SQL
|
|
|
+ * {@inheritDoc}
|
|
|
*/
|
|
|
public function compileQuery(Query $query, ValueBinder $generator)
|
|
|
{
|
|
|
@@ -366,9 +407,7 @@ abstract class Driver
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Returns an instance of a QueryCompiler
|
|
|
- *
|
|
|
- * @return \Cake\Database\QueryCompiler
|
|
|
+ * {@inheritDoc}
|
|
|
*/
|
|
|
public function newCompiler()
|
|
|
{
|