]>
jfr.im git - z_archive/KronOS.git/blob - system/database/drivers/pdo/pdo_driver.php
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 */