1
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
5
* An open source application development framework for PHP 5.1.6 or newer
8
* @copyright Copyright (c) 2008 - 2011, EllisLab, Inc.
9
* @license http://codeigniter.com/user_guide/license.html
10
* @author EllisLab Dev Team
11
* @link http://codeigniter.com
12
* @since Version 2.1.2
16
// ------------------------------------------------------------------------
19
* PDO Database Adapter Class
21
* Note: _DB is an extender class that the app controller
22
* creates dynamically based on whether the active record
23
* class is being used or not.
25
* @package CodeIgniter
28
* @author EllisLab Dev Team
29
* @link http://codeigniter.com/user_guide/database/
31
class CI_DB_pdo_driver extends CI_DB {
33
var $dbdriver = 'pdo';
35
// the character used to excape - not necessary for PDO
36
var $_escape_char = '';
37
var $_like_escape_str;
38
var $_like_escape_chr;
42
* The syntax to count rows is slightly different across different
43
* database engines, so this string appears in each driver and is
44
* used for the count_all() and count_all_results() functions.
46
var $_count_string = "SELECT COUNT(*) AS ";
49
var $options = array();
51
function __construct($params)
53
parent::__construct($params);
55
// clause and character used for LIKE escape sequences
56
if (strpos($this->hostname, 'mysql') !== FALSE)
58
$this->_like_escape_str = '';
59
$this->_like_escape_chr = '';
61
//Prior to this version, the charset can't be set in the dsn
64
$this->hostname .= ";charset={$this->char_set}";
67
//Set the charset with the connection options
68
$this->options['PDO::MYSQL_ATTR_INIT_COMMAND'] = "SET NAMES {$this->char_set}";
70
elseif (strpos($this->hostname, 'odbc') !== FALSE)
72
$this->_like_escape_str = " {escape '%s'} ";
73
$this->_like_escape_chr = '!';
77
$this->_like_escape_str = " ESCAPE '%s' ";
78
$this->_like_escape_chr = '!';
81
empty($this->database) OR $this->hostname .= ';dbname='.$this->database;
83
$this->trans_enabled = FALSE;
85
$this->_random_keyword = ' RND('.time().')'; // database specific random keyword
89
* Non-persistent database connection
91
* @access private called by the base class
96
$this->options['PDO::ATTR_ERRMODE'] = PDO::ERRMODE_SILENT;
98
return new PDO($this->hostname, $this->username, $this->password, $this->options);
101
// --------------------------------------------------------------------
104
* Persistent database connection
106
* @access private called by the base class
109
function db_pconnect()
111
$this->options['PDO::ATTR_ERRMODE'] = PDO::ERRMODE_SILENT;
112
$this->options['PDO::ATTR_PERSISTENT'] = TRUE;
114
return new PDO($this->hostname, $this->username, $this->password, $this->options);
117
// --------------------------------------------------------------------
122
* Keep / reestablish the db connection if no queries have been
123
* sent for a length of time exceeding the server's idle timeout
130
if ($this->db->db_debug)
132
return $this->db->display_error('db_unsuported_feature');
137
// --------------------------------------------------------------------
140
* Select the database
142
* @access private called by the base class
147
// Not needed for PDO
151
// --------------------------------------------------------------------
154
* Set client character set
161
function db_set_charset($charset, $collation)
163
// @todo - add support if needed
167
// --------------------------------------------------------------------
170
* Version number query string
177
return $this->conn_id->getAttribute(PDO::ATTR_CLIENT_VERSION);
180
// --------------------------------------------------------------------
185
* @access private called by the base class
186
* @param string an SQL query
189
function _execute($sql)
191
$sql = $this->_prep_query($sql);
192
$result_id = $this->conn_id->prepare($sql);
193
$result_id->execute();
195
if (is_object($result_id))
197
if (is_numeric(stripos($sql, 'SELECT')))
199
$this->affect_rows = count($result_id->fetchAll());
200
$result_id->execute();
204
$this->affect_rows = $result_id->rowCount();
209
$this->affect_rows = 0;
215
// --------------------------------------------------------------------
220
* If needed, each database adapter can prep the query string
222
* @access private called by execute()
223
* @param string an SQL query
226
function _prep_query($sql)
231
// --------------------------------------------------------------------
239
function trans_begin($test_mode = FALSE)
241
if ( ! $this->trans_enabled)
246
// When transactions are nested we only begin/commit/rollback the outermost ones
247
if ($this->_trans_depth > 0)
252
// Reset the transaction failure flag.
253
// If the $test_mode flag is set to TRUE transactions will be rolled back
254
// even if the queries produce a successful result.
255
$this->_trans_failure = (bool) ($test_mode === TRUE);
257
return $this->conn_id->beginTransaction();
260
// --------------------------------------------------------------------
268
function trans_commit()
270
if ( ! $this->trans_enabled)
275
// When transactions are nested we only begin/commit/rollback the outermost ones
276
if ($this->_trans_depth > 0)
281
$ret = $this->conn->commit();
285
// --------------------------------------------------------------------
288
* Rollback Transaction
293
function trans_rollback()
295
if ( ! $this->trans_enabled)
300
// When transactions are nested we only begin/commit/rollback the outermost ones
301
if ($this->_trans_depth > 0)
306
$ret = $this->conn_id->rollBack();
310
// --------------------------------------------------------------------
317
* @param bool whether or not the string will be used in a LIKE condition
320
function escape_str($str, $like = FALSE)
324
foreach ($str as $key => $val)
326
$str[$key] = $this->escape_str($val, $like);
333
$str = $this->conn_id->quote($str);
335
//If there are duplicated quotes, trim them away
336
if (strpos($str, "'") === 0)
338
$str = substr($str, 1, -1);
341
// escape LIKE condition wildcards
344
$str = str_replace( array('%', '_', $this->_like_escape_chr),
345
array($this->_like_escape_chr.'%', $this->_like_escape_chr.'_', $this->_like_escape_chr.$this->_like_escape_chr),
352
// --------------------------------------------------------------------
360
function affected_rows()
362
return $this->affect_rows;
365
// --------------------------------------------------------------------
373
function insert_id($name=NULL)
375
//Convenience method for postgres insertid
376
if (strpos($this->hostname, 'pgsql') !== FALSE)
378
$v = $this->_version();
380
$table = func_num_args() > 0 ? func_get_arg(0) : NULL;
382
if ($table == NULL && $v >= '8.1')
384
$sql='SELECT LASTVAL() as ins_id';
386
$query = $this->query($sql);
387
$row = $query->row();
392
return $this->conn_id->lastInsertId($name);
396
// --------------------------------------------------------------------
401
* Generates a platform-specific query string that counts all records in
402
* the specified database
408
function count_all($table = '')
415
$query = $this->query($this->_count_string . $this->_protect_identifiers('numrows') . " FROM " . $this->_protect_identifiers($table, TRUE, NULL, FALSE));
417
if ($query->num_rows() == 0)
422
$row = $query->row();
423
$this->_reset_select();
424
return (int) $row->numrows;
427
// --------------------------------------------------------------------
432
* Generates a platform-specific query string so that the table names can be fetched
438
function _list_tables($prefix_limit = FALSE)
440
$sql = "SHOW TABLES FROM `".$this->database."`";
442
if ($prefix_limit !== FALSE AND $this->dbprefix != '')
444
//$sql .= " LIKE '".$this->escape_like_str($this->dbprefix)."%' ".sprintf($this->_like_escape_str, $this->_like_escape_chr);
445
return FALSE; // not currently supported
451
// --------------------------------------------------------------------
456
* Generates a platform-specific query string so that the column names can be fetched
459
* @param string the table name
462
function _list_columns($table = '')
464
return "SHOW COLUMNS FROM ".$table;
467
// --------------------------------------------------------------------
472
* Generates a platform-specific query so that the column data can be retrieved
475
* @param string the table name
478
function _field_data($table)
480
return "SELECT TOP 1 FROM ".$table;
483
// --------------------------------------------------------------------
486
* The error message string
491
function _error_message()
493
$error_array = $this->conn_id->errorInfo();
494
return $error_array[2];
497
// --------------------------------------------------------------------
500
* The error message number
505
function _error_number()
507
return $this->conn_id->errorCode();
510
// --------------------------------------------------------------------
513
* Escape the SQL Identifiers
515
* This function escapes column and table names
521
function _escape_identifiers($item)
523
if ($this->_escape_char == '')
528
foreach ($this->_reserved_identifiers as $id)
530
if (strpos($item, '.'.$id) !== FALSE)
532
$str = $this->_escape_char. str_replace('.', $this->_escape_char.'.', $item);
534
// remove duplicates if the user already included the escape
535
return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
539
if (strpos($item, '.') !== FALSE)
541
$str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;
546
$str = $this->_escape_char.$item.$this->_escape_char;
549
// remove duplicates if the user already included the escape
550
return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
553
// --------------------------------------------------------------------
558
* This function implicitly groups FROM tables so there is no confusion
559
* about operator precedence in harmony with SQL standards
565
function _from_tables($tables)
567
if ( ! is_array($tables))
569
$tables = array($tables);
572
return (count($tables) == 1) ? $tables[0] : '('.implode(', ', $tables).')';
575
// --------------------------------------------------------------------
580
* Generates a platform-specific insert string from the supplied data
583
* @param string the table name
584
* @param array the insert keys
585
* @param array the insert values
588
function _insert($table, $keys, $values)
590
return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
593
// --------------------------------------------------------------------
596
* Insert_batch statement
598
* Generates a platform-specific insert string from the supplied data
601
* @param string the table name
602
* @param array the insert keys
603
* @param array the insert values
606
function _insert_batch($table, $keys, $values)
608
return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES ".implode(', ', $values);
611
// --------------------------------------------------------------------
616
* Generates a platform-specific update string from the supplied data
619
* @param string the table name
620
* @param array the update data
621
* @param array the where clause
622
* @param array the orderby clause
623
* @param array the limit clause
626
function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
628
foreach ($values as $key => $val)
630
$valstr[] = $key." = ".$val;
633
$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
635
$orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';
637
$sql = "UPDATE ".$table." SET ".implode(', ', $valstr);
639
$sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';
641
$sql .= $orderby.$limit;
646
// --------------------------------------------------------------------
649
* Update_Batch statement
651
* Generates a platform-specific batch update string from the supplied data
654
* @param string the table name
655
* @param array the update data
656
* @param array the where clause
659
function _update_batch($table, $values, $index, $where = NULL)
662
$where = ($where != '' AND count($where) >=1) ? implode(" ", $where).' AND ' : '';
664
foreach ($values as $key => $val)
666
$ids[] = $val[$index];
668
foreach (array_keys($val) as $field)
670
if ($field != $index)
672
$final[$field][] = 'WHEN '.$index.' = '.$val[$index].' THEN '.$val[$field];
677
$sql = "UPDATE ".$table." SET ";
680
foreach ($final as $k => $v)
682
$cases .= $k.' = CASE '."\n";
688
$cases .= 'ELSE '.$k.' END, ';
691
$sql .= substr($cases, 0, -2);
693
$sql .= ' WHERE '.$where.$index.' IN ('.implode(',', $ids).')';
699
// --------------------------------------------------------------------
704
* Generates a platform-specific truncate string from the supplied data
705
* If the database does not support the truncate() command
706
* This function maps to "DELETE FROM table"
709
* @param string the table name
712
function _truncate($table)
714
return $this->_delete($table);
717
// --------------------------------------------------------------------
722
* Generates a platform-specific delete string from the supplied data
725
* @param string the table name
726
* @param array the where clause
727
* @param string the limit clause
730
function _delete($table, $where = array(), $like = array(), $limit = FALSE)
734
if (count($where) > 0 OR count($like) > 0)
736
$conditions = "\nWHERE ";
737
$conditions .= implode("\n", $this->ar_where);
739
if (count($where) > 0 && count($like) > 0)
741
$conditions .= " AND ";
743
$conditions .= implode("\n", $like);
746
$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
748
return "DELETE FROM ".$table.$conditions.$limit;
751
// --------------------------------------------------------------------
756
* Generates a platform-specific LIMIT clause
759
* @param string the sql query string
760
* @param integer the number of rows to limit the query to
761
* @param integer the offset value
764
function _limit($sql, $limit, $offset)
766
if (strpos($this->hostname, 'cubrid') !== FALSE || strpos($this->hostname, 'sqlite') !== FALSE)
777
return $sql."LIMIT ".$offset.$limit;
781
$sql .= "LIMIT ".$limit;
785
$sql .= " OFFSET ".$offset;
792
// --------------------------------------------------------------------
795
* Close DB Connection
801
function _close($conn_id)
803
$this->conn_id = null;
811
/* End of file pdo_driver.php */
812
/* Location: ./system/database/drivers/pdo/pdo_driver.php */
b'\\ No newline at end of file'