blob: d08e47f2601f4138489275b014fd142ed20003af [file] [log] [blame]
admin7b613c72006-09-24 18:05:17 +00001<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
2/**
3 * Code Igniter
4 *
5 * An open source application development framework for PHP 4.3.2 or newer
6 *
7 * @package CodeIgniter
8 * @author Rick Ellis
9 * @copyright Copyright (c) 2006, pMachine, Inc.
admine334c472006-10-21 19:44:22 +000010 * @license http://www.codeignitor.com/user_guide/license.html
admin7b613c72006-09-24 18:05:17 +000011 * @link http://www.codeigniter.com
12 * @since Version 1.0
13 * @filesource
14 */
admine334c472006-10-21 19:44:22 +000015
admin7b613c72006-09-24 18:05:17 +000016// ------------------------------------------------------------------------
17
18/**
19 * Database Driver Class
admine334c472006-10-21 19:44:22 +000020 *
admin7b613c72006-09-24 18:05:17 +000021 * This is the platform-independent base DB implementation class.
22 * This class will not be called directly. Rather, the adapter
23 * class for the specific database will extend and instantiate it.
24 *
25 * @package CodeIgniter
26 * @subpackage Drivers
27 * @category Database
28 * @author Rick Ellis
29 * @link http://www.codeigniter.com/user_guide/database/
30 */
31class CI_DB_driver {
32
33 var $username;
34 var $password;
35 var $hostname;
36 var $database;
37 var $dbdriver = 'mysql';
38 var $dbprefix = '';
39 var $port = '';
40 var $pconnect = FALSE;
41 var $conn_id = FALSE;
42 var $result_id = FALSE;
43 var $db_debug = FALSE;
44 var $benchmark = 0;
45 var $query_count = 0;
46 var $bind_marker = '?';
47 var $queries = array();
admine8f6eb62006-10-02 06:46:16 +000048 var $data_cache = array();
admin7b613c72006-09-24 18:05:17 +000049 var $trans_enabled = TRUE;
50 var $_trans_depth = 0;
51 var $_trans_failure = FALSE; // Used with transactions to determine if a rollback should occur
admin6871d952006-10-04 00:36:18 +000052 var $cache_on = FALSE;
53 var $cachedir = '';
adminc5f7fa32006-10-06 02:10:23 +000054 var $cache_autodel = FALSE;
adminc2e3cd72006-10-05 04:22:30 +000055 var $CACHE; // The cache class object
admin7b613c72006-09-24 18:05:17 +000056
admin6871d952006-10-04 00:36:18 +000057
58 // These are use with Oracle
59 var $stmt_id;
60 var $curs_id;
61 var $limit_used;
admin7b613c72006-09-24 18:05:17 +000062
admine8f6eb62006-10-02 06:46:16 +000063
admin7b613c72006-09-24 18:05:17 +000064
65 /**
66 * Constructor. Accepts one parameter containing the database
admine334c472006-10-21 19:44:22 +000067 * connection settings.
admin7b613c72006-09-24 18:05:17 +000068 *
admine334c472006-10-21 19:44:22 +000069 * Database settings can be passed as discreet
70 * parameters or as a data source name in the first
admin7b613c72006-09-24 18:05:17 +000071 * parameter. DSNs must have this prototype:
72 * $dsn = 'driver://username:password@hostname/database';
73 *
74 * @param mixed. Can be an array or a DSN string
75 */
76 function CI_DB_driver($params)
77 {
78 $this->initialize($params);
79 log_message('debug', 'Database Driver Class Initialized');
80 }
81
82 // --------------------------------------------------------------------
83
84 /**
85 * Initialize Database Settings
86 *
87 * @access private Called by the constructor
88 * @param mixed
89 * @return void
90 */
91 function initialize($params = '')
admin6871d952006-10-04 00:36:18 +000092 {
admin7b613c72006-09-24 18:05:17 +000093 if (is_array($params))
94 {
admin6871d952006-10-04 00:36:18 +000095 $defaults = array(
admine334c472006-10-21 19:44:22 +000096 'hostname' => '',
97 'username' => '',
98 'password' => '',
99 'database' => '',
admin25701d72006-10-24 22:34:33 +0000100 'conn_id' => FALSE,
admine334c472006-10-21 19:44:22 +0000101 'dbdriver' => 'mysql',
102 'dbprefix' => '',
103 'port' => '',
104 'pconnect' => FALSE,
105 'db_debug' => FALSE,
106 'cachedir' => '',
admin6871d952006-10-04 00:36:18 +0000107 'cache_on' => FALSE
108 );
109
110 foreach ($defaults as $key => $val)
admin7b613c72006-09-24 18:05:17 +0000111 {
112 $this->$key = ( ! isset($params[$key])) ? $val : $params[$key];
113 }
114 }
115 elseif (strpos($params, '://'))
116 {
117 if (FALSE === ($dsn = @parse_url($params)))
118 {
119 log_message('error', 'Invalid DB Connection String');
120
121 if ($this->db_debug)
122 {
123 return $this->display_error('db_invalid_connection_str');
124 }
125 return FALSE;
126 }
127
128 $this->hostname = ( ! isset($dsn['host'])) ? '' : rawurldecode($dsn['host']);
129 $this->username = ( ! isset($dsn['user'])) ? '' : rawurldecode($dsn['user']);
130 $this->password = ( ! isset($dsn['pass'])) ? '' : rawurldecode($dsn['pass']);
131 $this->database = ( ! isset($dsn['path'])) ? '' : rawurldecode(substr($dsn['path'], 1));
132 }
admin6871d952006-10-04 00:36:18 +0000133
admin25701d72006-10-24 22:34:33 +0000134 // If an existing DB connection resource is supplied
135 // there is no need to connect and select the database
136 if (is_resource($this->conn_id))
137 {
138 return TRUE;
139 }
140
admin6871d952006-10-04 00:36:18 +0000141 // Connect to the database
142 $this->conn_id = ($this->pconnect == FALSE) ? $this->db_connect() : $this->db_pconnect();
admin25701d72006-10-24 22:34:33 +0000143
144 // No connection? Throw an error
admin6871d952006-10-04 00:36:18 +0000145 if ( ! $this->conn_id)
admine334c472006-10-21 19:44:22 +0000146 {
admin7b613c72006-09-24 18:05:17 +0000147 log_message('error', 'Unable to connect to the database');
148
admin6871d952006-10-04 00:36:18 +0000149 if ($this->db_debug)
150 {
admin7b613c72006-09-24 18:05:17 +0000151 $this->display_error('db_unable_to_connect');
admin6871d952006-10-04 00:36:18 +0000152 }
admin25701d72006-10-24 22:34:33 +0000153 return FALSE;
admin6871d952006-10-04 00:36:18 +0000154 }
admin25701d72006-10-24 22:34:33 +0000155
156 // Select the database
157 if ( ! $this->db_select())
admin7b613c72006-09-24 18:05:17 +0000158 {
admin25701d72006-10-24 22:34:33 +0000159 log_message('error', 'Unable to select database: '.$this->database);
160
161 if ($this->db_debug)
admin7b613c72006-09-24 18:05:17 +0000162 {
admin25701d72006-10-24 22:34:33 +0000163 $this->display_error('db_unable_to_select', $this->database);
164 }
165 return FALSE;
166 }
167
168 return TRUE;
admin7b613c72006-09-24 18:05:17 +0000169 }
admin88a8ad12006-10-07 03:16:32 +0000170
admin7b613c72006-09-24 18:05:17 +0000171 // --------------------------------------------------------------------
172
173 /**
admin9cd4e8e2006-09-25 23:26:25 +0000174 * The name of the platform in use (mysql, mssql, etc...)
175 *
176 * @access public
admine334c472006-10-21 19:44:22 +0000177 * @return string
admin9cd4e8e2006-09-25 23:26:25 +0000178 */
179 function platform()
180 {
181 return $this->dbdriver;
182 }
183
184 // --------------------------------------------------------------------
185
186 /**
admine334c472006-10-21 19:44:22 +0000187 * Database Version Number. Returns a string containing the
admin9cd4e8e2006-09-25 23:26:25 +0000188 * version of the database being used
189 *
190 * @access public
191 * @return string
192 */
193 function version()
194 {
195 if (FALSE === ($sql = $this->_version()))
196 {
admin6871d952006-10-04 00:36:18 +0000197 if ($this->db_debug)
198 {
admin9cd4e8e2006-09-25 23:26:25 +0000199 return $this->display_error('db_unsupported_function');
admin6871d952006-10-04 00:36:18 +0000200 }
201 return FALSE;
admin9cd4e8e2006-09-25 23:26:25 +0000202 }
203
admin6871d952006-10-04 00:36:18 +0000204 if ($this->dbdriver == 'oci8')
205 {
admin9cd4e8e2006-09-25 23:26:25 +0000206 return $sql;
207 }
208
209 $query = $this->query($sql);
210 $row = $query->row();
211 return $row->ver;
212 }
213
214 // --------------------------------------------------------------------
215
216 /**
admin7b613c72006-09-24 18:05:17 +0000217 * Execute the query
218 *
admine334c472006-10-21 19:44:22 +0000219 * Accepts an SQL string as input and returns a result object upon
220 * successful execution of a "read" type query. Returns boolean TRUE
221 * upon successful execution of a "write" type query. Returns boolean
222 * FALSE upon failure, and if the $db_debug variable is set to TRUE
admin7b613c72006-09-24 18:05:17 +0000223 * will raise an error.
admine334c472006-10-21 19:44:22 +0000224 *
admin7b613c72006-09-24 18:05:17 +0000225 * @access public
226 * @param string An SQL query string
227 * @param array An array of binding data
admine334c472006-10-21 19:44:22 +0000228 * @return mixed
admin7b613c72006-09-24 18:05:17 +0000229 */
admin6871d952006-10-04 00:36:18 +0000230 function query($sql, $binds = FALSE, $return_object = TRUE)
admindb8a3742006-10-04 07:43:35 +0000231 {
admin7b613c72006-09-24 18:05:17 +0000232 if ($sql == '')
233 {
admin6871d952006-10-04 00:36:18 +0000234 if ($this->db_debug)
235 {
admin7b613c72006-09-24 18:05:17 +0000236 log_message('error', 'Invalid query: '.$sql);
237 return $this->display_error('db_invalid_query');
admin6871d952006-10-04 00:36:18 +0000238 }
239 return FALSE;
admin7b613c72006-09-24 18:05:17 +0000240 }
241
admine334c472006-10-21 19:44:22 +0000242 // Is query caching enabled? If the query is a "read type"
243 // we will load the caching class and return the previously
admin0c405652006-10-04 18:37:57 +0000244 // cached query if it exists
admin6871d952006-10-04 00:36:18 +0000245 if ($this->cache_on == TRUE AND stristr($sql, 'SELECT'))
admin0c405652006-10-04 18:37:57 +0000246 {
247 if ($this->_cache_init())
admine8f6eb62006-10-02 06:46:16 +0000248 {
admin36e64422006-10-22 01:30:50 +0000249 $this->load_rdriver();
adminc2e3cd72006-10-05 04:22:30 +0000250 if (FALSE !== ($cache = $this->CACHE->read($sql)))
admin0c405652006-10-04 18:37:57 +0000251 {
252 return $cache;
253 }
admine8f6eb62006-10-02 06:46:16 +0000254 }
255 }
256
admin7b613c72006-09-24 18:05:17 +0000257 // Compile binds if needed
258 if ($binds !== FALSE)
259 {
260 $sql = $this->compile_binds($sql, $binds);
261 }
262
admin6871d952006-10-04 00:36:18 +0000263 // Save the query for debugging
264 $this->queries[] = $sql;
admin7b613c72006-09-24 18:05:17 +0000265
266 // Start the Query Timer
admin6871d952006-10-04 00:36:18 +0000267 $time_start = list($sm, $ss) = explode(' ', microtime());
admine334c472006-10-21 19:44:22 +0000268
admin7b613c72006-09-24 18:05:17 +0000269 // Run the Query
admin6871d952006-10-04 00:36:18 +0000270 if (FALSE === ($this->result_id = $this->simple_query($sql)))
admine334c472006-10-21 19:44:22 +0000271 {
admin6871d952006-10-04 00:36:18 +0000272 // This will trigger a rollback if transactions are being used
273 $this->_trans_failure = TRUE;
274
275 if ($this->db_debug)
276 {
adminbb1d4392006-09-24 20:14:38 +0000277 log_message('error', 'Query error: '.$this->_error_message());
admin7b613c72006-09-24 18:05:17 +0000278 return $this->display_error(
279 array(
admine334c472006-10-21 19:44:22 +0000280 'Error Number: '.$this->_error_number(),
adminbb1d4392006-09-24 20:14:38 +0000281 $this->_error_message(),
admin7b613c72006-09-24 18:05:17 +0000282 $sql
283 )
284 );
admin6871d952006-10-04 00:36:18 +0000285 }
admine334c472006-10-21 19:44:22 +0000286
admin6871d952006-10-04 00:36:18 +0000287 return FALSE;
288 }
289
admin7b613c72006-09-24 18:05:17 +0000290 // Stop and aggregate the query time results
291 $time_end = list($em, $es) = explode(' ', microtime());
292 $this->benchmark += ($em + $es) - ($sm + $ss);
293
294 // Increment the query counter
admin6871d952006-10-04 00:36:18 +0000295 $this->query_count++;
296
admin7b613c72006-09-24 18:05:17 +0000297 // Was the query a "write" type?
298 // If so we'll simply return true
299 if ($this->is_write_type($sql) === TRUE)
admindb8a3742006-10-04 07:43:35 +0000300 {
301 // If caching is enabled we'll auto-cleanup any
302 // existing files related to this particular URI
admina658e312006-10-06 01:29:36 +0000303 if ($this->cache_on == TRUE AND $this->cache_autodel == TRUE AND $this->_cache_init())
admindb8a3742006-10-04 07:43:35 +0000304 {
adminc2e3cd72006-10-05 04:22:30 +0000305 $this->CACHE->delete();
admindb8a3742006-10-04 07:43:35 +0000306 }
307
admin7b613c72006-09-24 18:05:17 +0000308 return TRUE;
309 }
310
admine334c472006-10-21 19:44:22 +0000311 // Return TRUE if we don't need to create a result object
admin7b613c72006-09-24 18:05:17 +0000312 // Currently only the Oracle driver uses this when stored
313 // procedures are used
314 if ($return_object !== TRUE)
315 {
316 return TRUE;
317 }
admindb8a3742006-10-04 07:43:35 +0000318
319 // Load and instantiate the result driver
admindb8a3742006-10-04 07:43:35 +0000320
adminc2e3cd72006-10-05 04:22:30 +0000321 $driver = $this->load_rdriver();
322 $RES = new $driver();
admin6871d952006-10-04 00:36:18 +0000323 $RES->conn_id = $this->conn_id;
admin6871d952006-10-04 00:36:18 +0000324 $RES->result_id = $this->result_id;
325
326 if ($this->dbdriver == 'oci8')
327 {
adminc2e3cd72006-10-05 04:22:30 +0000328 $RES->stmt_id = $this->stmt_id;
329 $RES->curs_id = NULL;
330 $RES->limit_used = $this->limit_used;
admin6871d952006-10-04 00:36:18 +0000331 }
admindb8a3742006-10-04 07:43:35 +0000332
admine334c472006-10-21 19:44:22 +0000333 // Is query caching enabled? If so, we'll serialize the
adminc2e3cd72006-10-05 04:22:30 +0000334 // result object and save it to a cache file.
admin0c405652006-10-04 18:37:57 +0000335 if ($this->cache_on == TRUE AND $this->_cache_init())
adminc2e3cd72006-10-05 04:22:30 +0000336 {
337 // We'll create a new instance of the result object
338 // only without the platform specific driver since
339 // we can't use it with cached data (the query result
340 // resource ID won't be any good once we've cached the
341 // result object, so we'll have to compile the data
342 // and save it)
343 $CR = new CI_DB_result();
344 $CR->num_rows = $RES->num_rows();
345 $CR->result_object = $RES->result_object();
346 $CR->result_array = $RES->result_array();
admina658e312006-10-06 01:29:36 +0000347
348 // Reset these since cached objects can not utilize resource IDs.
349 $CR->conn_id = NULL;
350 $CR->result_id = NULL;
adminc2e3cd72006-10-05 04:22:30 +0000351
352 $this->CACHE->write($sql, $CR);
admindb8a3742006-10-04 07:43:35 +0000353 }
354
admin7b613c72006-09-24 18:05:17 +0000355 return $RES;
356 }
admindb8a3742006-10-04 07:43:35 +0000357
358 // --------------------------------------------------------------------
359
360 /**
361 * Load the result drivers
admine334c472006-10-21 19:44:22 +0000362 *
admindb8a3742006-10-04 07:43:35 +0000363 * @access public
admine334c472006-10-21 19:44:22 +0000364 * @return string the name of the result class
admindb8a3742006-10-04 07:43:35 +0000365 */
366 function load_rdriver()
367 {
368 $driver = 'CI_DB_'.$this->dbdriver.'_result';
369
370 if ( ! class_exists($driver))
371 {
372 include_once(BASEPATH.'database/DB_result'.EXT);
373 include_once(BASEPATH.'database/drivers/'.$this->dbdriver.'/'.$this->dbdriver.'_result'.EXT);
374 }
375
376 return $driver;
377 }
admin7b613c72006-09-24 18:05:17 +0000378
379 // --------------------------------------------------------------------
380
381 /**
admine334c472006-10-21 19:44:22 +0000382 * Simple Query
adminfafe28b2006-10-21 19:08:17 +0000383 * This is a simplified version of the query() function. Internally
admin7b613c72006-09-24 18:05:17 +0000384 * we only use it when running transaction commands since they do
385 * not require all the features of the main query() function.
admine334c472006-10-21 19:44:22 +0000386 *
admin7b613c72006-09-24 18:05:17 +0000387 * @access public
388 * @param string the sql query
admine334c472006-10-21 19:44:22 +0000389 * @return mixed
admin7b613c72006-09-24 18:05:17 +0000390 */
391 function simple_query($sql)
392 {
393 if ( ! $this->conn_id)
394 {
395 $this->initialize();
396 }
397
admin40037182006-10-11 19:16:58 +0000398 return $this->_execute($sql);
admin7b613c72006-09-24 18:05:17 +0000399 }
400
401 // --------------------------------------------------------------------
402
403 /**
404 * Disable Transactions
405 * This permits transactions to be disabled at run-time.
admine334c472006-10-21 19:44:22 +0000406 *
admin7b613c72006-09-24 18:05:17 +0000407 * @access public
admine334c472006-10-21 19:44:22 +0000408 * @return void
admin7b613c72006-09-24 18:05:17 +0000409 */
410 function trans_off()
411 {
412 $this->trans_enabled = FALSE;
413 }
414
415 // --------------------------------------------------------------------
416
417 /**
418 * Start Transaction
admine334c472006-10-21 19:44:22 +0000419 *
admin7b613c72006-09-24 18:05:17 +0000420 * @access public
admine334c472006-10-21 19:44:22 +0000421 * @return void
admin7b613c72006-09-24 18:05:17 +0000422 */
423 function trans_start($test_mode = FALSE)
424 {
425 if ( ! $this->trans_enabled)
426 {
427 return FALSE;
428 }
429
430 // When transactions are nested we only begin/commit/rollback the outermost ones
431 if ($this->_trans_depth > 0)
432 {
433 $this->_trans_depth += 1;
434 return;
435 }
436
437 $this->trans_begin($test_mode);
438 }
439
440 // --------------------------------------------------------------------
441
442 /**
443 * Complete Transaction
admine334c472006-10-21 19:44:22 +0000444 *
admin7b613c72006-09-24 18:05:17 +0000445 * @access public
admine334c472006-10-21 19:44:22 +0000446 * @return bool
admin7b613c72006-09-24 18:05:17 +0000447 */
448 function trans_complete()
449 {
450 if ( ! $this->trans_enabled)
451 {
452 return FALSE;
453 }
454
455 // When transactions are nested we only begin/commit/rollback the outermost ones
456 if ($this->_trans_depth > 1)
457 {
458 $this->_trans_depth -= 1;
459 return TRUE;
460 }
461
462 // The query() function will set this flag to TRUE in the event that a query failed
463 if ($this->_trans_failure === TRUE)
464 {
465 $this->trans_rollback();
466
467 if ($this->db_debug)
468 {
469 return $this->display_error('db_transaction_failure');
470 }
471 return FALSE;
472 }
473
474 $this->trans_commit();
475 return TRUE;
476 }
477
478 // --------------------------------------------------------------------
479
480 /**
481 * Lets you retrieve the transaction flag to determine if it has failed
admine334c472006-10-21 19:44:22 +0000482 *
admin7b613c72006-09-24 18:05:17 +0000483 * @access public
admine334c472006-10-21 19:44:22 +0000484 * @return bool
admin7b613c72006-09-24 18:05:17 +0000485 */
486 function trans_status()
487 {
488 return $this->_trans_failure;
489 }
490
491 // --------------------------------------------------------------------
492
493 /**
494 * Compile Bindings
admine334c472006-10-21 19:44:22 +0000495 *
admin7b613c72006-09-24 18:05:17 +0000496 * @access public
497 * @param string the sql statement
498 * @param array an array of bind data
admine334c472006-10-21 19:44:22 +0000499 * @return string
admin7b613c72006-09-24 18:05:17 +0000500 */
501 function compile_binds($sql, $binds)
502 {
503 if (FALSE === strpos($sql, $this->bind_marker))
504 {
505 return $sql;
506 }
507
508 if ( ! is_array($binds))
509 {
510 $binds = array($binds);
511 }
512
513 foreach ($binds as $val)
514 {
515 $val = $this->escape($val);
516
517 // Just in case the replacement string contains the bind
518 // character we'll temporarily replace it with a marker
519 $val = str_replace($this->bind_marker, '{%bind_marker%}', $val);
520 $sql = preg_replace("#".preg_quote($this->bind_marker, '#')."#", str_replace('$', '\$', $val), $sql, 1);
521 }
522
523 return str_replace('{%bind_marker%}', $this->bind_marker, $sql);
524 }
525
526 // --------------------------------------------------------------------
527
528 /**
admine334c472006-10-21 19:44:22 +0000529 * Determines if a query is a "write" type.
530 *
admin7b613c72006-09-24 18:05:17 +0000531 * @access public
532 * @param string An SQL query string
admine334c472006-10-21 19:44:22 +0000533 * @return boolean
admin7b613c72006-09-24 18:05:17 +0000534 */
535 function is_write_type($sql)
536 {
admine334c472006-10-21 19:44:22 +0000537 if ( ! preg_match('/^\s*"?(INSERT|UPDATE|DELETE|REPLACE|CREATE|DROP|LOAD DATA|COPY|ALTER|GRANT|REVOKE|LOCK|UNLOCK)\s+/i', $sql))
admin7b613c72006-09-24 18:05:17 +0000538 {
539 return FALSE;
540 }
541 return TRUE;
542 }
543
544 // --------------------------------------------------------------------
545
546 /**
admine334c472006-10-21 19:44:22 +0000547 * Calculate the aggregate query elapsed time
548 *
admin7b613c72006-09-24 18:05:17 +0000549 * @access public
adminfafe28b2006-10-21 19:08:17 +0000550 * @param integer The number of decimal places
admine334c472006-10-21 19:44:22 +0000551 * @return integer
admin7b613c72006-09-24 18:05:17 +0000552 */
553 function elapsed_time($decimals = 6)
554 {
555 return number_format($this->benchmark, $decimals);
556 }
557
558 // --------------------------------------------------------------------
559
560 /**
561 * Returns the total number of queries
admine334c472006-10-21 19:44:22 +0000562 *
admin7b613c72006-09-24 18:05:17 +0000563 * @access public
admine334c472006-10-21 19:44:22 +0000564 * @return integer
admin7b613c72006-09-24 18:05:17 +0000565 */
566 function total_queries()
567 {
568 return $this->query_count;
569 }
570
571 // --------------------------------------------------------------------
572
573 /**
574 * Returns the last query that was executed
admine334c472006-10-21 19:44:22 +0000575 *
admin7b613c72006-09-24 18:05:17 +0000576 * @access public
admine334c472006-10-21 19:44:22 +0000577 * @return void
admin7b613c72006-09-24 18:05:17 +0000578 */
579 function last_query()
580 {
581 return end($this->queries);
582 }
583
584 // --------------------------------------------------------------------
585
586 /**
587 * "Smart" Escape String
588 *
589 * Escapes data based on type
590 * Sets boolean and null types
admine334c472006-10-21 19:44:22 +0000591 *
admin7b613c72006-09-24 18:05:17 +0000592 * @access public
593 * @param string
admine334c472006-10-21 19:44:22 +0000594 * @return integer
admin7b613c72006-09-24 18:05:17 +0000595 */
596 function escape($str)
597 {
598 switch (gettype($str))
599 {
600 case 'string' : $str = "'".$this->escape_str($str)."'";
601 break;
602 case 'boolean' : $str = ($str === FALSE) ? 0 : 1;
603 break;
604 default : $str = ($str === NULL) ? 'NULL' : $str;
605 break;
606 }
607
608 return $str;
adminbb1d4392006-09-24 20:14:38 +0000609 }
610
admin9cd4e8e2006-09-25 23:26:25 +0000611 // --------------------------------------------------------------------
612
613 /**
614 * Primary
615 *
616 * Retrieves the primary key. It assumes that the row in the first
617 * position is the primary key
admine334c472006-10-21 19:44:22 +0000618 *
admin9cd4e8e2006-09-25 23:26:25 +0000619 * @access public
620 * @param string the table name
admine334c472006-10-21 19:44:22 +0000621 * @return string
admin9cd4e8e2006-09-25 23:26:25 +0000622 */
623 function primary($table = '')
624 {
admin606f99c2006-10-11 23:48:41 +0000625 $fields = $this->list_fields($table);
admin9cd4e8e2006-09-25 23:26:25 +0000626
627 if ( ! is_array($fields))
628 {
629 return FALSE;
630 }
631
632 return current($fields);
633 }
634
635 // --------------------------------------------------------------------
636
admin3dd978f2006-09-30 19:24:45 +0000637 /**
638 * Returns an array of table names
admine334c472006-10-21 19:44:22 +0000639 *
admin3dd978f2006-09-30 19:24:45 +0000640 * @access public
admine334c472006-10-21 19:44:22 +0000641 * @return array
admin3dd978f2006-09-30 19:24:45 +0000642 */
643 function list_tables()
644 {
645 // Is there a cached result?
admine8f6eb62006-10-02 06:46:16 +0000646 if (isset($this->data_cache['table_names']))
admin3dd978f2006-09-30 19:24:45 +0000647 {
admine8f6eb62006-10-02 06:46:16 +0000648 return $this->data_cache['table_names'];
admin3dd978f2006-09-30 19:24:45 +0000649 }
650
651 if (FALSE === ($sql = $this->_list_tables()))
652 {
admin6871d952006-10-04 00:36:18 +0000653 if ($this->db_debug)
654 {
admin3dd978f2006-09-30 19:24:45 +0000655 return $this->display_error('db_unsupported_function');
admin6871d952006-10-04 00:36:18 +0000656 }
657 return FALSE;
admin3dd978f2006-09-30 19:24:45 +0000658 }
659
660 $retval = array();
661 $query = $this->query($sql);
662
663 if ($query->num_rows() > 0)
664 {
665 foreach($query->result_array() as $row)
666 {
667 if (isset($row['TABLE_NAME']))
668 {
669 $retval[] = $row['TABLE_NAME'];
670 }
671 else
672 {
673 $retval[] = array_shift($row);
674 }
675 }
676 }
677
admin7099a582006-10-10 17:47:59 +0000678 $this->data_cache['table_names'] = $retval;
679 return $this->data_cache['table_names'];
admin3dd978f2006-09-30 19:24:45 +0000680 }
681
682 // --------------------------------------------------------------------
683
684 /**
685 * Determine if a particular table exists
686 * @access public
687 * @return boolean
688 */
689 function table_exists($table_name)
690 {
691 return ( ! in_array($this->dbprefix.$table_name, $this->list_tables())) ? FALSE : TRUE;
692 }
693
694 // --------------------------------------------------------------------
695
admin9cd4e8e2006-09-25 23:26:25 +0000696 /**
697 * Fetch MySQL Field Names
698 *
699 * @access public
700 * @param string the table name
admine334c472006-10-21 19:44:22 +0000701 * @return array
admin9cd4e8e2006-09-25 23:26:25 +0000702 */
admin6871d952006-10-04 00:36:18 +0000703 function list_fields($table = '')
704 {
admin3ed8c512006-09-29 23:26:28 +0000705 // Is there a cached result?
admine8f6eb62006-10-02 06:46:16 +0000706 if (isset($this->data_cache['field_names'][$table]))
admin3ed8c512006-09-29 23:26:28 +0000707 {
admine8f6eb62006-10-02 06:46:16 +0000708 return $this->data_cache['field_names'][$table];
admin3ed8c512006-09-29 23:26:28 +0000709 }
admin6871d952006-10-04 00:36:18 +0000710
711 if ($table == '')
712 {
admin9cd4e8e2006-09-25 23:26:25 +0000713 if ($this->db_debug)
714 {
715 return $this->display_error('db_field_param_missing');
716 }
717 return FALSE;
admin6871d952006-10-04 00:36:18 +0000718 }
719
admin9cd4e8e2006-09-25 23:26:25 +0000720 if (FALSE === ($sql = $this->_list_columns($this->dbprefix.$table)))
721 {
admin6871d952006-10-04 00:36:18 +0000722 if ($this->db_debug)
723 {
admin9cd4e8e2006-09-25 23:26:25 +0000724 return $this->display_error('db_unsupported_function');
admin6871d952006-10-04 00:36:18 +0000725 }
726 return FALSE;
admin9cd4e8e2006-09-25 23:26:25 +0000727 }
admin6871d952006-10-04 00:36:18 +0000728
729 $query = $this->query($sql);
730
731 $retval = array();
admin9cd4e8e2006-09-25 23:26:25 +0000732 foreach($query->result_array() as $row)
733 {
734 if (isset($row['COLUMN_NAME']))
735 {
736 $retval[] = $row['COLUMN_NAME'];
737 }
738 else
739 {
740 $retval[] = current($row);
admin6871d952006-10-04 00:36:18 +0000741 }
admin9cd4e8e2006-09-25 23:26:25 +0000742 }
admin6871d952006-10-04 00:36:18 +0000743
admin7099a582006-10-10 17:47:59 +0000744 $this->data_cache['field_names'][$table] = $retval;
745 return $this->data_cache['field_names'][$table];
admin6871d952006-10-04 00:36:18 +0000746 }
adminb2a9cec2006-10-01 03:38:04 +0000747
748 // --------------------------------------------------------------------
749
750 /**
751 * Determine if a particular field exists
752 * @access public
753 * @param string
754 * @param string
755 * @return boolean
756 */
757 function field_exists($field_name, $table_name)
758 {
759 return ( ! in_array($field_name, $this->list_fields($table_name))) ? FALSE : TRUE;
760 }
admin6871d952006-10-04 00:36:18 +0000761
admin3dd978f2006-09-30 19:24:45 +0000762 // --------------------------------------------------------------------
763
764 /**
765 * DEPRECATED - use list_fields()
766 */
admine334c472006-10-21 19:44:22 +0000767 function field_names($table = '')
admin6871d952006-10-04 00:36:18 +0000768 {
769 return $this->list_fields($table);
770 }
admin9cd4e8e2006-09-25 23:26:25 +0000771
772 // --------------------------------------------------------------------
773
774 /**
775 * Returns an object with field data
admine334c472006-10-21 19:44:22 +0000776 *
admin9cd4e8e2006-09-25 23:26:25 +0000777 * @access public
778 * @param string the table name
admine334c472006-10-21 19:44:22 +0000779 * @return object
admin9cd4e8e2006-09-25 23:26:25 +0000780 */
781 function field_data($table = '')
782 {
admin6871d952006-10-04 00:36:18 +0000783 if ($table == '')
784 {
admin9cd4e8e2006-09-25 23:26:25 +0000785 if ($this->db_debug)
786 {
787 return $this->display_error('db_field_param_missing');
788 }
789 return FALSE;
admin6871d952006-10-04 00:36:18 +0000790 }
791
admin9cd4e8e2006-09-25 23:26:25 +0000792 $query = $this->query($this->_field_data($this->dbprefix.$table));
793 return $query->field_data();
794 }
795
adminbb1d4392006-09-24 20:14:38 +0000796 // --------------------------------------------------------------------
797
798 /**
799 * Generate an insert string
admine334c472006-10-21 19:44:22 +0000800 *
adminbb1d4392006-09-24 20:14:38 +0000801 * @access public
802 * @param string the table upon which the query will be performed
803 * @param array an associative array data of key/values
admine334c472006-10-21 19:44:22 +0000804 * @return string
adminbb1d4392006-09-24 20:14:38 +0000805 */
806 function insert_string($table, $data)
807 {
admine334c472006-10-21 19:44:22 +0000808 $fields = array();
adminbb1d4392006-09-24 20:14:38 +0000809 $values = array();
810
admine334c472006-10-21 19:44:22 +0000811 foreach($data as $key => $val)
adminbb1d4392006-09-24 20:14:38 +0000812 {
813 $fields[] = $key;
814 $values[] = $this->escape($val);
815 }
816
817 return $this->_insert($this->dbprefix.$table, $fields, $values);
818 }
819
820 // --------------------------------------------------------------------
821
822 /**
823 * Generate an update string
admine334c472006-10-21 19:44:22 +0000824 *
adminbb1d4392006-09-24 20:14:38 +0000825 * @access public
826 * @param string the table upon which the query will be performed
827 * @param array an associative array data of key/values
828 * @param mixed the "where" statement
admine334c472006-10-21 19:44:22 +0000829 * @return string
adminbb1d4392006-09-24 20:14:38 +0000830 */
831 function update_string($table, $data, $where)
832 {
833 if ($where == '')
834 return false;
835
836 $fields = array();
admine334c472006-10-21 19:44:22 +0000837 foreach($data as $key => $val)
adminbb1d4392006-09-24 20:14:38 +0000838 {
839 $fields[$key] = $this->escape($val);
840 }
841
842 if ( ! is_array($where))
843 {
844 $dest = array($where);
845 }
846 else
847 {
848 $dest = array();
849 foreach ($where as $key => $val)
850 {
851 $prefix = (count($dest) == 0) ? '' : ' AND ';
852
853 if ($val != '')
854 {
855 if ( ! $this->_has_operator($key))
856 {
857 $key .= ' =';
858 }
859
860 $val = ' '.$this->escape($val);
861 }
862
863 $dest[] = $prefix.$key.$val;
864 }
865 }
866
867 return $this->_update($this->dbprefix.$table, $fields, $dest);
admin6871d952006-10-04 00:36:18 +0000868 }
admin7b613c72006-09-24 18:05:17 +0000869
870 // --------------------------------------------------------------------
871
872 /**
873 * Enables a native PHP function to be run, using a platform agnostic wrapper.
admine334c472006-10-21 19:44:22 +0000874 *
admin7b613c72006-09-24 18:05:17 +0000875 * @access public
876 * @param string the function name
877 * @param mixed any parameters needed by the function
admine334c472006-10-21 19:44:22 +0000878 * @return mixed
admin7b613c72006-09-24 18:05:17 +0000879 */
880 function call_function($function)
881 {
882 $driver = ($this->dbdriver == 'postgre') ? 'pg_' : $this->dbdriver.'_';
883
884 if (FALSE === strpos($driver, $function))
885 {
886 $function = $driver.$function;
887 }
888
889 if ( ! function_exists($function))
admine334c472006-10-21 19:44:22 +0000890 {
admin7b613c72006-09-24 18:05:17 +0000891 if ($this->db_debug)
892 {
893 return $this->display_error('db_unsupported_function');
894 }
895 return FALSE;
896 }
897 else
898 {
adminee54c112006-09-28 17:13:38 +0000899 $args = (func_num_args() > 1) ? array_splice(func_get_args(), 1) : null;
900
admine334c472006-10-21 19:44:22 +0000901 return call_user_func_array($function, $args);
admin7b613c72006-09-24 18:05:17 +0000902 }
903 }
adminc5f7fa32006-10-06 02:10:23 +0000904
905 // --------------------------------------------------------------------
906
907 /**
908 * Set Cache Directory Path
909 *
910 * @access public
911 * @param string the path to the cache directory
912 * @return void
913 */
914 function cache_set_path($path = '')
915 {
916 $this->cachedir = $path;
917 }
918
admine8f6eb62006-10-02 06:46:16 +0000919 // --------------------------------------------------------------------
920
921 /**
922 * Enable Query Caching
923 *
924 * @access public
925 * @return void
926 */
927 function cache_on()
928 {
admin7099a582006-10-10 17:47:59 +0000929 $this->cache_on = TRUE;
930 return TRUE;
admine8f6eb62006-10-02 06:46:16 +0000931 }
932
933 // --------------------------------------------------------------------
934
935 /**
936 * Disable Query Caching
937 *
938 * @access public
939 * @return void
940 */
941 function cache_off()
942 {
admin7099a582006-10-10 17:47:59 +0000943 $this->cache_on = FALSE;
944 return FALSE;
admine8f6eb62006-10-02 06:46:16 +0000945 }
adminfa708172006-10-04 18:42:42 +0000946
adminc5f7fa32006-10-06 02:10:23 +0000947
adminfa708172006-10-04 18:42:42 +0000948 // --------------------------------------------------------------------
949
950 /**
adminc5f7fa32006-10-06 02:10:23 +0000951 * Delete the cache files associated with a particular URI
adminfa708172006-10-04 18:42:42 +0000952 *
953 * @access public
adminfa708172006-10-04 18:42:42 +0000954 * @return void
955 */
admin1b0ab462006-10-10 23:30:21 +0000956 function cache_delete($segment_one = '', $segment_two = '')
adminfa708172006-10-04 18:42:42 +0000957 {
adminc5f7fa32006-10-06 02:10:23 +0000958 if ( ! $this->_cache_init())
959 {
960 return FALSE;
961 }
admin1b0ab462006-10-10 23:30:21 +0000962 return $this->CACHE->delete($segment_one, $segment_two);
adminc5f7fa32006-10-06 02:10:23 +0000963 }
964
965 // --------------------------------------------------------------------
966
967 /**
968 * Delete All cache files
969 *
970 * @access public
971 * @return void
972 */
973 function cache_delete_all()
974 {
975 if ( ! $this->_cache_init())
976 {
977 return FALSE;
978 }
979
980 return $this->CACHE->delete_all();
adminfa708172006-10-04 18:42:42 +0000981 }
admin0c405652006-10-04 18:37:57 +0000982
admin6871d952006-10-04 00:36:18 +0000983 // --------------------------------------------------------------------
984
985 /**
admin0c405652006-10-04 18:37:57 +0000986 * Initialize the Cache Class
admin6871d952006-10-04 00:36:18 +0000987 *
admin0c405652006-10-04 18:37:57 +0000988 * @access private
989 * @return void
990 */
991 function _cache_init()
admin6871d952006-10-04 00:36:18 +0000992 {
adminc2e3cd72006-10-05 04:22:30 +0000993 if (is_object($this->CACHE) AND class_exists('CI_DB_Cache'))
admindb8a3742006-10-04 07:43:35 +0000994 {
admin0c405652006-10-04 18:37:57 +0000995 return TRUE;
admindb8a3742006-10-04 07:43:35 +0000996 }
997
adminfa708172006-10-04 18:42:42 +0000998 if ( ! @include_once(BASEPATH.'database/DB_cache'.EXT))
admin6871d952006-10-04 00:36:18 +0000999 {
adminfa708172006-10-04 18:42:42 +00001000 return $this->cache_off();
admin6871d952006-10-04 00:36:18 +00001001 }
1002
adminc2e3cd72006-10-05 04:22:30 +00001003 $this->CACHE = new CI_DB_Cache;
admin6871d952006-10-04 00:36:18 +00001004 return TRUE;
1005 }
1006
admindb8a3742006-10-04 07:43:35 +00001007
1008 // --------------------------------------------------------------------
1009
1010 /**
admin7b613c72006-09-24 18:05:17 +00001011 * Close DB Connection
admine334c472006-10-21 19:44:22 +00001012 *
admin7b613c72006-09-24 18:05:17 +00001013 * @access public
admine334c472006-10-21 19:44:22 +00001014 * @return void
admin7b613c72006-09-24 18:05:17 +00001015 */
admin6871d952006-10-04 00:36:18 +00001016 function close()
1017 {
1018 if (is_resource($this->conn_id))
1019 {
1020 $this->_close($this->conn_id);
admine334c472006-10-21 19:44:22 +00001021 }
admin7b613c72006-09-24 18:05:17 +00001022 $this->conn_id = FALSE;
admin6871d952006-10-04 00:36:18 +00001023 }
admin7b613c72006-09-24 18:05:17 +00001024
1025 // --------------------------------------------------------------------
1026
1027 /**
1028 * Display an error message
admine334c472006-10-21 19:44:22 +00001029 *
admin7b613c72006-09-24 18:05:17 +00001030 * @access public
1031 * @param string the error message
1032 * @param string any "swap" values
1033 * @param boolean whether to localize the message
admine334c472006-10-21 19:44:22 +00001034 * @return string sends the application/error_db.php template
admin7b613c72006-09-24 18:05:17 +00001035 */
admine334c472006-10-21 19:44:22 +00001036 function display_error($error = '', $swap = '', $native = FALSE)
admin6871d952006-10-04 00:36:18 +00001037 {
admin7b613c72006-09-24 18:05:17 +00001038 $LANG = new CI_Language();
1039 $LANG->load('db');
1040
1041 $heading = 'MySQL Error';
1042
1043 if ($native == TRUE)
1044 {
1045 $message = $error;
1046 }
1047 else
1048 {
1049 $message = ( ! is_array($error)) ? array(str_replace('%s', $swap, $LANG->line($error))) : $error;
1050 }
1051
1052 if ( ! class_exists('CI_Exceptions'))
1053 {
1054 include_once(BASEPATH.'libraries/Exceptions'.EXT);
1055 }
1056
1057 $error = new CI_Exceptions();
1058 echo $error->show_error('An Error Was Encountered', $message, 'error_db');
1059 exit;
1060
admine334c472006-10-21 19:44:22 +00001061 }
admin7b613c72006-09-24 18:05:17 +00001062
1063}
1064
1065?>