123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253 |
- <?php
- /**
- * PDO database connection.
- *
- * @package Kohana/Database
- * @category Drivers
- * @author Kohana Team
- * @copyright (c) Kohana Team
- * @license https://koseven.ga/LICENSE.md
- */
- class Kohana_Database_PDO extends Database {
- // PDO uses no quoting for identifiers
- protected $_identifier = '';
- public function __construct($name, array $config)
- {
- parent::__construct($name, $config);
- if (isset($this->_config['identifier']))
- {
- // Allow the identifier to be overloaded per-connection
- $this->_identifier = (string) $this->_config['identifier'];
- }
- }
- public function connect()
- {
- if ($this->_connection)
- return;
- // Extract the connection parameters, adding required variabels
- extract($this->_config['connection'] + [
- 'dsn' => '',
- 'username' => NULL,
- 'password' => NULL,
- 'persistent' => FALSE,
- ]);
- // Clear the connection parameters for security
- unset($this->_config['connection']);
- // Force PDO to use exceptions for all errors
- $options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION;
- if ( ! empty($persistent))
- {
- // Make the connection persistent
- $options[PDO::ATTR_PERSISTENT] = TRUE;
- }
- try
- {
- // Create a new PDO connection
- $this->_connection = new PDO($dsn, $username, $password, $options);
- }
- catch (PDOException $e)
- {
- throw new Database_Exception(':error',
- [':error' => $e->getMessage()],
- $e->getCode());
- }
- if ( ! empty($this->_config['charset']))
- {
- // Set the character set
- $this->set_charset($this->_config['charset']);
- }
- }
- /**
- * Create or redefine a SQL aggregate function.
- *
- * [!!] Works only with SQLite
- *
- * @link http://php.net/manual/function.pdo-sqlitecreateaggregate
- *
- * @param string $name Name of the SQL function to be created or redefined
- * @param callback $step Called for each row of a result set
- * @param callback $final Called after all rows of a result set have been processed
- * @param integer $arguments Number of arguments that the SQL function takes
- *
- * @return boolean
- */
- public function create_aggregate($name, $step, $final, $arguments = -1)
- {
- $this->_connection or $this->connect();
- return $this->_connection->sqliteCreateAggregate(
- $name, $step, $final, $arguments
- );
- }
- /**
- * Create or redefine a SQL function.
- *
- * [!!] Works only with SQLite
- *
- * @link http://php.net/manual/function.pdo-sqlitecreatefunction
- *
- * @param string $name Name of the SQL function to be created or redefined
- * @param callback $callback Callback which implements the SQL function
- * @param integer $arguments Number of arguments that the SQL function takes
- *
- * @return boolean
- */
- public function create_function($name, $callback, $arguments = -1)
- {
- $this->_connection or $this->connect();
- return $this->_connection->sqliteCreateFunction(
- $name, $callback, $arguments
- );
- }
- public function disconnect()
- {
- // Destroy the PDO object
- $this->_connection = NULL;
- return parent::disconnect();
- }
- public function set_charset($charset)
- {
- // Make sure the database is connected
- $this->_connection OR $this->connect();
- // This SQL-92 syntax is not supported by all drivers
- $this->_connection->exec('SET NAMES '.$this->quote($charset));
- }
- public function query($type, $sql, $as_object = FALSE, array $params = NULL)
- {
- // Make sure the database is connected
- $this->_connection or $this->connect();
- if (Kohana::$profiling)
- {
- // Benchmark this query for the current instance
- $benchmark = Profiler::start("Database ({$this->_instance})", $sql);
- }
- try
- {
- $result = $this->_connection->query($sql);
- }
- catch (Exception $e)
- {
- if (isset($benchmark))
- {
- // This benchmark is worthless
- Profiler::delete($benchmark);
- }
- // Convert the exception in a database exception
- throw new Database_Exception(':error [ :query ]',
- [
- ':error' => $e->getMessage(),
- ':query' => $sql
- ],
- $e->getCode());
- }
- if (isset($benchmark))
- {
- Profiler::stop($benchmark);
- }
- // Set the last query
- $this->last_query = $sql;
- if ($type === Database::SELECT)
- {
- // Convert the result into an array, as PDOStatement::rowCount is not reliable
- if ($as_object === FALSE)
- {
- $result->setFetchMode(PDO::FETCH_ASSOC);
- }
- elseif (is_string($as_object))
- {
- $result->setFetchMode(PDO::FETCH_CLASS, $as_object, $params);
- }
- else
- {
- $result->setFetchMode(PDO::FETCH_CLASS, 'stdClass');
- }
- $result = $result->fetchAll();
- // Return an iterator of results
- return new Database_Result_Cached($result, $sql, $as_object, $params);
- }
- elseif ($type === Database::INSERT)
- {
- // Return a list of insert id and rows created
- return [
- $this->_connection->lastInsertId(),
- $result->rowCount(),
- ];
- }
- else
- {
- // Return the number of rows affected
- return $result->rowCount();
- }
- }
- public function begin($mode = NULL)
- {
- // Make sure the database is connected
- $this->_connection or $this->connect();
- return $this->_connection->beginTransaction();
- }
- public function commit()
- {
- // Make sure the database is connected
- $this->_connection or $this->connect();
- return $this->_connection->commit();
- }
- public function rollback()
- {
- // Make sure the database is connected
- $this->_connection or $this->connect();
- return $this->_connection->rollBack();
- }
- public function list_tables($like = NULL)
- {
- throw new Kohana_Exception('Database method :method is not supported by :class',
- [':method' => __FUNCTION__, ':class' => __CLASS__]);
- }
- public function list_columns($table, $like = NULL, $add_prefix = TRUE)
- {
- throw new Kohana_Exception('Database method :method is not supported by :class',
- [':method' => __FUNCTION__, ':class' => __CLASS__]);
- }
- public function escape($value)
- {
- // Make sure the database is connected
- $this->_connection or $this->connect();
- return $this->_connection->quote($value);
- }
- } // End Database_PDO
|