diff options
Diffstat (limited to 'system/database/drivers/pdo/pdo_driver.php')
-rw-r--r-- | system/database/drivers/pdo/pdo_driver.php | 426 |
1 files changed, 426 insertions, 0 deletions
diff --git a/system/database/drivers/pdo/pdo_driver.php b/system/database/drivers/pdo/pdo_driver.php new file mode 100644 index 000000000..705b16560 --- /dev/null +++ b/system/database/drivers/pdo/pdo_driver.php @@ -0,0 +1,426 @@ +<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); +/** + * CodeIgniter + * + * An open source application development framework for PHP 5.2.4 or newer + * + * NOTICE OF LICENSE + * + * Licensed under the Open Software License version 3.0 + * + * This source file is subject to the Open Software License (OSL 3.0) that is + * bundled with this package in the files license.txt / license.rst. It is + * also available through the world wide web at this URL: + * http://opensource.org/licenses/OSL-3.0 + * If you did not receive a copy of the license and are unable to obtain it + * through the world wide web, please send an email to + * licensing@ellislab.com so we can send you a copy immediately. + * + * @package CodeIgniter + * @author EllisLab Dev Team + * @copyright Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/) + * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) + * @link http://codeigniter.com + * @since Version 2.1.0 + * @filesource + */ + +/** + * PDO Database Adapter Class + * + * Note: _DB is an extender class that the app controller + * creates dynamically based on whether the query builder + * class is being used or not. + * + * @package CodeIgniter + * @subpackage Drivers + * @category Database + * @author EllisLab Dev Team + * @link http://codeigniter.com/user_guide/database/ + */ +class CI_DB_pdo_driver extends CI_DB { + + public $dbdriver = 'pdo'; + + // The character used to escaping + protected $_escape_char = '"'; + + // clause and character used for LIKE escape sequences + protected $_like_escape_str = " ESCAPE '%s' "; + protected $_like_escape_chr = '!'; + + protected $_random_keyword; + + public $trans_enabled = FALSE; + + // need to track the PDO options + public $options = array(); + + /** + * Constructor + * + * Validates the DSN string and/or detects the subdriver + * + * @param array + * @return void + */ + public function __construct($params) + { + parent::__construct($params); + + if (preg_match('/([^;]+):/', $this->dsn, $match) && count($match) === 2) + { + // If there is a minimum valid dsn string pattern found, we're done + // This is for general PDO users, who tend to have a full DSN string. + $this->subdriver = $match[1]; + return; + } + // Legacy support for DSN specified in the hostname field + elseif (preg_match('/([^;]+):/', $this->hostname, $match) && count($match) === 2) + { + $this->dsn = $this->hostname; + $this->hostname = NULL; + $this->subdriver = $match[1]; + return; + } + elseif (in_array($this->subdriver, array('mssql', 'sybase'), TRUE)) + { + $this->subdriver = 'dblib'; + } + elseif ($this->subdriver === '4D') + { + $this->subdriver = '4d'; + } + elseif ( ! in_array($this->subdriver, array('4d', 'cubrid', 'dblib', 'firebird', 'ibm', 'informix', 'mysql', 'oci', 'odbc', 'sqlite', 'sqlsrv'), TRUE)) + { + log_message('error', 'PDO: Invalid or non-existent subdriver'); + + if ($this->db_debug) + { + show_error('Invalid or non-existent PDO subdriver'); + } + } + + $this->dsn = NULL; + } + + // -------------------------------------------------------------------- + + /** + * Non-persistent database connection + * + * @param bool + * @return object + */ + public function db_connect($persistent = FALSE) + { + $this->options[PDO::ATTR_PERSISTENT] = $persistent; + + // Connecting... + try + { + return @new PDO($this->dsn, $this->username, $this->password, $this->options); + } + catch (PDOException $e) + { + if ($this->db_debug && empty($this->failover)) + { + $this->display_error($e->getMessage(), '', TRUE); + } + + return FALSE; + } + } + + // -------------------------------------------------------------------- + + /** + * Persistent database connection + * + * @return object + */ + public function db_pconnect() + { + return $this->db_connect(TRUE); + } + + // -------------------------------------------------------------------- + + /** + * Database version number + * + * @return string + */ + public function version() + { + if (isset($this->data_cache['version'])) + { + return $this->data_cache['version']; + } + + // Not all subdrivers support the getAttribute() method + try + { + return $this->data_cache['version'] = $this->conn_id->getAttribute(PDO::ATTR_SERVER_VERSION); + } + catch (PDOException $e) + { + return parent::version(); + } + } + + // -------------------------------------------------------------------- + + /** + * Execute the query + * + * @param string an SQL query + * @return mixed + */ + protected function _execute($sql) + { + return $this->conn_id->query($sql); + } + + // -------------------------------------------------------------------- + + /** + * Begin Transaction + * + * @return bool + */ + public function trans_begin($test_mode = FALSE) + { + // When transactions are nested we only begin/commit/rollback the outermost ones + if ( ! $this->trans_enabled OR $this->_trans_depth > 0) + { + return TRUE; + } + + // Reset the transaction failure flag. + // If the $test_mode flag is set to TRUE transactions will be rolled back + // even if the queries produce a successful result. + $this->_trans_failure = ($test_mode === TRUE); + + return $this->conn_id->beginTransaction(); + } + + // -------------------------------------------------------------------- + + /** + * Commit Transaction + * + * @return bool + */ + public function trans_commit() + { + // When transactions are nested we only begin/commit/rollback the outermost ones + if ( ! $this->trans_enabled OR $this->_trans_depth > 0) + { + return TRUE; + } + + return $this->conn_id->commit(); + } + + // -------------------------------------------------------------------- + + /** + * Rollback Transaction + * + * @return bool + */ + public function trans_rollback() + { + // When transactions are nested we only begin/commit/rollback the outermost ones + if ( ! $this->trans_enabled OR $this->_trans_depth > 0) + { + return TRUE; + } + + return $this->conn_id->rollBack(); + } + + // -------------------------------------------------------------------- + + /** + * Escape String + * + * @param string + * @param bool whether or not the string will be used in a LIKE condition + * @return string + */ + public function escape_str($str, $like = FALSE) + { + if (is_array($str)) + { + foreach ($str as $key => $val) + { + $str[$key] = $this->escape_str($val, $like); + } + + return $str; + } + + // Escape the string + $str = $this->conn_id->quote($str); + + // If there are duplicated quotes, trim them away + if ($str[0] === "'") + { + $str = substr($str, 1, -1); + } + + // escape LIKE condition wildcards + if ($like === TRUE) + { + return str_replace(array($this->_like_escape_chr, '%', '_'), + array($this->_like_escape_chr.$this->_like_escape_chr, $this->_like_escape_chr.'%', $this->_like_escape_chr.'_'), + $str); + } + + return $str; + } + + // -------------------------------------------------------------------- + + /** + * Affected Rows + * + * @return int + */ + public function affected_rows() + { + return is_object($this->result_id) ? $this->result_id->rowCount() : 0; + } + + // -------------------------------------------------------------------- + + /** + * Insert ID + * + * @param string + * @return int + */ + public function insert_id($name = NULL) + { + return $this->conn_id->lastInsertId($name); + } + + // -------------------------------------------------------------------- + + /** + * Field data query + * + * Generates a platform-specific query so that the column data can be retrieved + * + * @param string the table name + * @return string + */ + protected function _field_data($table) + { + return 'SELECT TOP 1 * FROM '.$this->protect_identifiers($table); + } + + // -------------------------------------------------------------------- + + /** + * Error + * + * Returns an array containing code and message of the last + * database error that has occured. + * + * @return array + */ + public function error() + { + $error = array('code' => '00000', 'message' => ''); + $pdo_error = $this->conn_id->errorInfo(); + + if (empty($pdo_error[0])) + { + return $error; + } + + $error['code'] = isset($pdo_error[1]) ? $pdo_error[0].'/'.$pdo_error[1] : $pdo_error[0]; + if (isset($pdo_error[2])) + { + $error['message'] = $pdo_error[2]; + } + + return $error; + } + + // -------------------------------------------------------------------- + + /** + * Update_Batch statement + * + * Generates a platform-specific batch update string from the supplied data + * + * @param string the table name + * @param array the update data + * @param array the where clause + * @return string + */ + protected function _update_batch($table, $values, $index, $where = NULL) + { + $ids = array(); + $where = ($where !== '' && count($where) >=1) ? implode(' ', $where).' AND ' : ''; + + foreach ($values as $key => $val) + { + $ids[] = $val[$index]; + + foreach (array_keys($val) as $field) + { + if ($field !== $index) + { + $final[$field][] = 'WHEN '.$index.' = '.$val[$index].' THEN '.$val[$field]; + } + } + } + + $sql = 'UPDATE '.$table.' SET '; + $cases = ''; + + foreach ($final as $k => $v) + { + $cases .= $k.' = CASE '."\n"; + + foreach ($v as $row) + { + $cases .= $row."\n"; + } + + $cases .= 'ELSE '.$k.' END, '; + } + + $sql .= substr($cases, 0, -2); + $sql .= ' WHERE '.$where.$index.' IN ('.implode(',', $ids).')'; + + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Truncate statement + * + * Generates a platform-specific truncate string from the supplied data + * + * If the database does not support the truncate() command, + * then this method maps to 'DELETE FROM table' + * + * @param string the table name + * @return string + */ + protected function _truncate($table) + { + return 'TRUNCATE TABLE '.$table; + } + +} + +/* End of file pdo_driver.php */ +/* Location: ./system/database/drivers/pdo/pdo_driver.php */ |