blob: 139dbf7db00e081925f50c22a0f33a910747848b [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' => '',
100 'dbdriver' => 'mysql',
101 'dbprefix' => '',
102 'port' => '',
103 'pconnect' => FALSE,
104 'db_debug' => FALSE,
105 'cachedir' => '',
admin6871d952006-10-04 00:36:18 +0000106 'cache_on' => FALSE
107 );
108
109 foreach ($defaults as $key => $val)
admin7b613c72006-09-24 18:05:17 +0000110 {
111 $this->$key = ( ! isset($params[$key])) ? $val : $params[$key];
112 }
113 }
114 elseif (strpos($params, '://'))
115 {
116 if (FALSE === ($dsn = @parse_url($params)))
117 {
118 log_message('error', 'Invalid DB Connection String');
119
120 if ($this->db_debug)
121 {
122 return $this->display_error('db_invalid_connection_str');
123 }
124 return FALSE;
125 }
126
127 $this->hostname = ( ! isset($dsn['host'])) ? '' : rawurldecode($dsn['host']);
128 $this->username = ( ! isset($dsn['user'])) ? '' : rawurldecode($dsn['user']);
129 $this->password = ( ! isset($dsn['pass'])) ? '' : rawurldecode($dsn['pass']);
130 $this->database = ( ! isset($dsn['path'])) ? '' : rawurldecode(substr($dsn['path'], 1));
131 }
admin6871d952006-10-04 00:36:18 +0000132
133 // Connect to the database
134 $this->conn_id = ($this->pconnect == FALSE) ? $this->db_connect() : $this->db_pconnect();
admine334c472006-10-21 19:44:22 +0000135
admin6871d952006-10-04 00:36:18 +0000136 if ( ! $this->conn_id)
admine334c472006-10-21 19:44:22 +0000137 {
admin7b613c72006-09-24 18:05:17 +0000138 log_message('error', 'Unable to connect to the database');
139
admin6871d952006-10-04 00:36:18 +0000140 if ($this->db_debug)
141 {
admin7b613c72006-09-24 18:05:17 +0000142 $this->display_error('db_unable_to_connect');
admin6871d952006-10-04 00:36:18 +0000143 }
144 }
admin7b613c72006-09-24 18:05:17 +0000145 else
146 {
147 if ( ! $this->db_select())
148 {
149 log_message('error', 'Unable to select database: '.$this->database);
150
151 if ($this->db_debug)
152 {
153 $this->display_error('db_unable_to_select', $this->database);
154 }
155 }
admin6871d952006-10-04 00:36:18 +0000156 }
admin7b613c72006-09-24 18:05:17 +0000157 }
admin88a8ad12006-10-07 03:16:32 +0000158
admin7b613c72006-09-24 18:05:17 +0000159 // --------------------------------------------------------------------
160
161 /**
admin9cd4e8e2006-09-25 23:26:25 +0000162 * The name of the platform in use (mysql, mssql, etc...)
163 *
164 * @access public
admine334c472006-10-21 19:44:22 +0000165 * @return string
admin9cd4e8e2006-09-25 23:26:25 +0000166 */
167 function platform()
168 {
169 return $this->dbdriver;
170 }
171
172 // --------------------------------------------------------------------
173
174 /**
admine334c472006-10-21 19:44:22 +0000175 * Database Version Number. Returns a string containing the
admin9cd4e8e2006-09-25 23:26:25 +0000176 * version of the database being used
177 *
178 * @access public
179 * @return string
180 */
181 function version()
182 {
183 if (FALSE === ($sql = $this->_version()))
184 {
admin6871d952006-10-04 00:36:18 +0000185 if ($this->db_debug)
186 {
admin9cd4e8e2006-09-25 23:26:25 +0000187 return $this->display_error('db_unsupported_function');
admin6871d952006-10-04 00:36:18 +0000188 }
189 return FALSE;
admin9cd4e8e2006-09-25 23:26:25 +0000190 }
191
admin6871d952006-10-04 00:36:18 +0000192 if ($this->dbdriver == 'oci8')
193 {
admin9cd4e8e2006-09-25 23:26:25 +0000194 return $sql;
195 }
196
197 $query = $this->query($sql);
198 $row = $query->row();
199 return $row->ver;
200 }
201
202 // --------------------------------------------------------------------
203
204 /**
admin7b613c72006-09-24 18:05:17 +0000205 * Execute the query
206 *
admine334c472006-10-21 19:44:22 +0000207 * Accepts an SQL string as input and returns a result object upon
208 * successful execution of a "read" type query. Returns boolean TRUE
209 * upon successful execution of a "write" type query. Returns boolean
210 * FALSE upon failure, and if the $db_debug variable is set to TRUE
admin7b613c72006-09-24 18:05:17 +0000211 * will raise an error.
admine334c472006-10-21 19:44:22 +0000212 *
admin7b613c72006-09-24 18:05:17 +0000213 * @access public
214 * @param string An SQL query string
215 * @param array An array of binding data
admine334c472006-10-21 19:44:22 +0000216 * @return mixed
admin7b613c72006-09-24 18:05:17 +0000217 */
admin6871d952006-10-04 00:36:18 +0000218 function query($sql, $binds = FALSE, $return_object = TRUE)
admindb8a3742006-10-04 07:43:35 +0000219 {
admin7b613c72006-09-24 18:05:17 +0000220 if ($sql == '')
221 {
admin6871d952006-10-04 00:36:18 +0000222 if ($this->db_debug)
223 {
admin7b613c72006-09-24 18:05:17 +0000224 log_message('error', 'Invalid query: '.$sql);
225 return $this->display_error('db_invalid_query');
admin6871d952006-10-04 00:36:18 +0000226 }
227 return FALSE;
admin7b613c72006-09-24 18:05:17 +0000228 }
229
admine334c472006-10-21 19:44:22 +0000230 // Is query caching enabled? If the query is a "read type"
231 // we will load the caching class and return the previously
admin0c405652006-10-04 18:37:57 +0000232 // cached query if it exists
admin6871d952006-10-04 00:36:18 +0000233 if ($this->cache_on == TRUE AND stristr($sql, 'SELECT'))
admin0c405652006-10-04 18:37:57 +0000234 {
235 if ($this->_cache_init())
admine8f6eb62006-10-02 06:46:16 +0000236 {
admin36e64422006-10-22 01:30:50 +0000237 $this->load_rdriver();
adminc2e3cd72006-10-05 04:22:30 +0000238 if (FALSE !== ($cache = $this->CACHE->read($sql)))
admin0c405652006-10-04 18:37:57 +0000239 {
240 return $cache;
241 }
admine8f6eb62006-10-02 06:46:16 +0000242 }
243 }
244
admin7b613c72006-09-24 18:05:17 +0000245 // Compile binds if needed
246 if ($binds !== FALSE)
247 {
248 $sql = $this->compile_binds($sql, $binds);
249 }
250
admin6871d952006-10-04 00:36:18 +0000251 // Save the query for debugging
252 $this->queries[] = $sql;
admin7b613c72006-09-24 18:05:17 +0000253
254 // Start the Query Timer
admin6871d952006-10-04 00:36:18 +0000255 $time_start = list($sm, $ss) = explode(' ', microtime());
admine334c472006-10-21 19:44:22 +0000256
admin7b613c72006-09-24 18:05:17 +0000257 // Run the Query
admin6871d952006-10-04 00:36:18 +0000258 if (FALSE === ($this->result_id = $this->simple_query($sql)))
admine334c472006-10-21 19:44:22 +0000259 {
admin6871d952006-10-04 00:36:18 +0000260 // This will trigger a rollback if transactions are being used
261 $this->_trans_failure = TRUE;
262
263 if ($this->db_debug)
264 {
adminbb1d4392006-09-24 20:14:38 +0000265 log_message('error', 'Query error: '.$this->_error_message());
admin7b613c72006-09-24 18:05:17 +0000266 return $this->display_error(
267 array(
admine334c472006-10-21 19:44:22 +0000268 'Error Number: '.$this->_error_number(),
adminbb1d4392006-09-24 20:14:38 +0000269 $this->_error_message(),
admin7b613c72006-09-24 18:05:17 +0000270 $sql
271 )
272 );
admin6871d952006-10-04 00:36:18 +0000273 }
admine334c472006-10-21 19:44:22 +0000274
admin6871d952006-10-04 00:36:18 +0000275 return FALSE;
276 }
277
admin7b613c72006-09-24 18:05:17 +0000278 // Stop and aggregate the query time results
279 $time_end = list($em, $es) = explode(' ', microtime());
280 $this->benchmark += ($em + $es) - ($sm + $ss);
281
282 // Increment the query counter
admin6871d952006-10-04 00:36:18 +0000283 $this->query_count++;
284
admin7b613c72006-09-24 18:05:17 +0000285 // Was the query a "write" type?
286 // If so we'll simply return true
287 if ($this->is_write_type($sql) === TRUE)
admindb8a3742006-10-04 07:43:35 +0000288 {
289 // If caching is enabled we'll auto-cleanup any
290 // existing files related to this particular URI
admina658e312006-10-06 01:29:36 +0000291 if ($this->cache_on == TRUE AND $this->cache_autodel == TRUE AND $this->_cache_init())
admindb8a3742006-10-04 07:43:35 +0000292 {
adminc2e3cd72006-10-05 04:22:30 +0000293 $this->CACHE->delete();
admindb8a3742006-10-04 07:43:35 +0000294 }
295
admin7b613c72006-09-24 18:05:17 +0000296 return TRUE;
297 }
298
admine334c472006-10-21 19:44:22 +0000299 // Return TRUE if we don't need to create a result object
admin7b613c72006-09-24 18:05:17 +0000300 // Currently only the Oracle driver uses this when stored
301 // procedures are used
302 if ($return_object !== TRUE)
303 {
304 return TRUE;
305 }
admindb8a3742006-10-04 07:43:35 +0000306
307 // Load and instantiate the result driver
admindb8a3742006-10-04 07:43:35 +0000308
adminc2e3cd72006-10-05 04:22:30 +0000309 $driver = $this->load_rdriver();
310 $RES = new $driver();
admin6871d952006-10-04 00:36:18 +0000311 $RES->conn_id = $this->conn_id;
admin6871d952006-10-04 00:36:18 +0000312 $RES->result_id = $this->result_id;
313
314 if ($this->dbdriver == 'oci8')
315 {
adminc2e3cd72006-10-05 04:22:30 +0000316 $RES->stmt_id = $this->stmt_id;
317 $RES->curs_id = NULL;
318 $RES->limit_used = $this->limit_used;
admin6871d952006-10-04 00:36:18 +0000319 }
admindb8a3742006-10-04 07:43:35 +0000320
admine334c472006-10-21 19:44:22 +0000321 // Is query caching enabled? If so, we'll serialize the
adminc2e3cd72006-10-05 04:22:30 +0000322 // result object and save it to a cache file.
admin0c405652006-10-04 18:37:57 +0000323 if ($this->cache_on == TRUE AND $this->_cache_init())
adminc2e3cd72006-10-05 04:22:30 +0000324 {
325 // We'll create a new instance of the result object
326 // only without the platform specific driver since
327 // we can't use it with cached data (the query result
328 // resource ID won't be any good once we've cached the
329 // result object, so we'll have to compile the data
330 // and save it)
331 $CR = new CI_DB_result();
332 $CR->num_rows = $RES->num_rows();
333 $CR->result_object = $RES->result_object();
334 $CR->result_array = $RES->result_array();
admina658e312006-10-06 01:29:36 +0000335
336 // Reset these since cached objects can not utilize resource IDs.
337 $CR->conn_id = NULL;
338 $CR->result_id = NULL;
adminc2e3cd72006-10-05 04:22:30 +0000339
340 $this->CACHE->write($sql, $CR);
admindb8a3742006-10-04 07:43:35 +0000341 }
342
admin7b613c72006-09-24 18:05:17 +0000343 return $RES;
344 }
admindb8a3742006-10-04 07:43:35 +0000345
346 // --------------------------------------------------------------------
347
348 /**
349 * Load the result drivers
admine334c472006-10-21 19:44:22 +0000350 *
admindb8a3742006-10-04 07:43:35 +0000351 * @access public
admine334c472006-10-21 19:44:22 +0000352 * @return string the name of the result class
admindb8a3742006-10-04 07:43:35 +0000353 */
354 function load_rdriver()
355 {
356 $driver = 'CI_DB_'.$this->dbdriver.'_result';
357
358 if ( ! class_exists($driver))
359 {
360 include_once(BASEPATH.'database/DB_result'.EXT);
361 include_once(BASEPATH.'database/drivers/'.$this->dbdriver.'/'.$this->dbdriver.'_result'.EXT);
362 }
363
364 return $driver;
365 }
admin7b613c72006-09-24 18:05:17 +0000366
367 // --------------------------------------------------------------------
368
369 /**
admine334c472006-10-21 19:44:22 +0000370 * Simple Query
adminfafe28b2006-10-21 19:08:17 +0000371 * This is a simplified version of the query() function. Internally
admin7b613c72006-09-24 18:05:17 +0000372 * we only use it when running transaction commands since they do
373 * not require all the features of the main query() function.
admine334c472006-10-21 19:44:22 +0000374 *
admin7b613c72006-09-24 18:05:17 +0000375 * @access public
376 * @param string the sql query
admine334c472006-10-21 19:44:22 +0000377 * @return mixed
admin7b613c72006-09-24 18:05:17 +0000378 */
379 function simple_query($sql)
380 {
381 if ( ! $this->conn_id)
382 {
383 $this->initialize();
384 }
385
admin40037182006-10-11 19:16:58 +0000386 return $this->_execute($sql);
admin7b613c72006-09-24 18:05:17 +0000387 }
388
389 // --------------------------------------------------------------------
390
391 /**
392 * Disable Transactions
393 * This permits transactions to be disabled at run-time.
admine334c472006-10-21 19:44:22 +0000394 *
admin7b613c72006-09-24 18:05:17 +0000395 * @access public
admine334c472006-10-21 19:44:22 +0000396 * @return void
admin7b613c72006-09-24 18:05:17 +0000397 */
398 function trans_off()
399 {
400 $this->trans_enabled = FALSE;
401 }
402
403 // --------------------------------------------------------------------
404
405 /**
406 * Start Transaction
admine334c472006-10-21 19:44:22 +0000407 *
admin7b613c72006-09-24 18:05:17 +0000408 * @access public
admine334c472006-10-21 19:44:22 +0000409 * @return void
admin7b613c72006-09-24 18:05:17 +0000410 */
411 function trans_start($test_mode = FALSE)
412 {
413 if ( ! $this->trans_enabled)
414 {
415 return FALSE;
416 }
417
418 // When transactions are nested we only begin/commit/rollback the outermost ones
419 if ($this->_trans_depth > 0)
420 {
421 $this->_trans_depth += 1;
422 return;
423 }
424
425 $this->trans_begin($test_mode);
426 }
427
428 // --------------------------------------------------------------------
429
430 /**
431 * Complete Transaction
admine334c472006-10-21 19:44:22 +0000432 *
admin7b613c72006-09-24 18:05:17 +0000433 * @access public
admine334c472006-10-21 19:44:22 +0000434 * @return bool
admin7b613c72006-09-24 18:05:17 +0000435 */
436 function trans_complete()
437 {
438 if ( ! $this->trans_enabled)
439 {
440 return FALSE;
441 }
442
443 // When transactions are nested we only begin/commit/rollback the outermost ones
444 if ($this->_trans_depth > 1)
445 {
446 $this->_trans_depth -= 1;
447 return TRUE;
448 }
449
450 // The query() function will set this flag to TRUE in the event that a query failed
451 if ($this->_trans_failure === TRUE)
452 {
453 $this->trans_rollback();
454
455 if ($this->db_debug)
456 {
457 return $this->display_error('db_transaction_failure');
458 }
459 return FALSE;
460 }
461
462 $this->trans_commit();
463 return TRUE;
464 }
465
466 // --------------------------------------------------------------------
467
468 /**
469 * Lets you retrieve the transaction flag to determine if it has failed
admine334c472006-10-21 19:44:22 +0000470 *
admin7b613c72006-09-24 18:05:17 +0000471 * @access public
admine334c472006-10-21 19:44:22 +0000472 * @return bool
admin7b613c72006-09-24 18:05:17 +0000473 */
474 function trans_status()
475 {
476 return $this->_trans_failure;
477 }
478
479 // --------------------------------------------------------------------
480
481 /**
482 * Compile Bindings
admine334c472006-10-21 19:44:22 +0000483 *
admin7b613c72006-09-24 18:05:17 +0000484 * @access public
485 * @param string the sql statement
486 * @param array an array of bind data
admine334c472006-10-21 19:44:22 +0000487 * @return string
admin7b613c72006-09-24 18:05:17 +0000488 */
489 function compile_binds($sql, $binds)
490 {
491 if (FALSE === strpos($sql, $this->bind_marker))
492 {
493 return $sql;
494 }
495
496 if ( ! is_array($binds))
497 {
498 $binds = array($binds);
499 }
500
501 foreach ($binds as $val)
502 {
503 $val = $this->escape($val);
504
505 // Just in case the replacement string contains the bind
506 // character we'll temporarily replace it with a marker
507 $val = str_replace($this->bind_marker, '{%bind_marker%}', $val);
508 $sql = preg_replace("#".preg_quote($this->bind_marker, '#')."#", str_replace('$', '\$', $val), $sql, 1);
509 }
510
511 return str_replace('{%bind_marker%}', $this->bind_marker, $sql);
512 }
513
514 // --------------------------------------------------------------------
515
516 /**
admine334c472006-10-21 19:44:22 +0000517 * Determines if a query is a "write" type.
518 *
admin7b613c72006-09-24 18:05:17 +0000519 * @access public
520 * @param string An SQL query string
admine334c472006-10-21 19:44:22 +0000521 * @return boolean
admin7b613c72006-09-24 18:05:17 +0000522 */
523 function is_write_type($sql)
524 {
admine334c472006-10-21 19:44:22 +0000525 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 +0000526 {
527 return FALSE;
528 }
529 return TRUE;
530 }
531
532 // --------------------------------------------------------------------
533
534 /**
admine334c472006-10-21 19:44:22 +0000535 * Calculate the aggregate query elapsed time
536 *
admin7b613c72006-09-24 18:05:17 +0000537 * @access public
adminfafe28b2006-10-21 19:08:17 +0000538 * @param integer The number of decimal places
admine334c472006-10-21 19:44:22 +0000539 * @return integer
admin7b613c72006-09-24 18:05:17 +0000540 */
541 function elapsed_time($decimals = 6)
542 {
543 return number_format($this->benchmark, $decimals);
544 }
545
546 // --------------------------------------------------------------------
547
548 /**
549 * Returns the total number of queries
admine334c472006-10-21 19:44:22 +0000550 *
admin7b613c72006-09-24 18:05:17 +0000551 * @access public
admine334c472006-10-21 19:44:22 +0000552 * @return integer
admin7b613c72006-09-24 18:05:17 +0000553 */
554 function total_queries()
555 {
556 return $this->query_count;
557 }
558
559 // --------------------------------------------------------------------
560
561 /**
562 * Returns the last query that was executed
admine334c472006-10-21 19:44:22 +0000563 *
admin7b613c72006-09-24 18:05:17 +0000564 * @access public
admine334c472006-10-21 19:44:22 +0000565 * @return void
admin7b613c72006-09-24 18:05:17 +0000566 */
567 function last_query()
568 {
569 return end($this->queries);
570 }
571
572 // --------------------------------------------------------------------
573
574 /**
575 * "Smart" Escape String
576 *
577 * Escapes data based on type
578 * Sets boolean and null types
admine334c472006-10-21 19:44:22 +0000579 *
admin7b613c72006-09-24 18:05:17 +0000580 * @access public
581 * @param string
admine334c472006-10-21 19:44:22 +0000582 * @return integer
admin7b613c72006-09-24 18:05:17 +0000583 */
584 function escape($str)
585 {
586 switch (gettype($str))
587 {
588 case 'string' : $str = "'".$this->escape_str($str)."'";
589 break;
590 case 'boolean' : $str = ($str === FALSE) ? 0 : 1;
591 break;
592 default : $str = ($str === NULL) ? 'NULL' : $str;
593 break;
594 }
595
596 return $str;
adminbb1d4392006-09-24 20:14:38 +0000597 }
598
admin9cd4e8e2006-09-25 23:26:25 +0000599 // --------------------------------------------------------------------
600
601 /**
602 * Primary
603 *
604 * Retrieves the primary key. It assumes that the row in the first
605 * position is the primary key
admine334c472006-10-21 19:44:22 +0000606 *
admin9cd4e8e2006-09-25 23:26:25 +0000607 * @access public
608 * @param string the table name
admine334c472006-10-21 19:44:22 +0000609 * @return string
admin9cd4e8e2006-09-25 23:26:25 +0000610 */
611 function primary($table = '')
612 {
admin606f99c2006-10-11 23:48:41 +0000613 $fields = $this->list_fields($table);
admin9cd4e8e2006-09-25 23:26:25 +0000614
615 if ( ! is_array($fields))
616 {
617 return FALSE;
618 }
619
620 return current($fields);
621 }
622
623 // --------------------------------------------------------------------
624
admin3dd978f2006-09-30 19:24:45 +0000625 /**
626 * Returns an array of table names
admine334c472006-10-21 19:44:22 +0000627 *
admin3dd978f2006-09-30 19:24:45 +0000628 * @access public
admine334c472006-10-21 19:44:22 +0000629 * @return array
admin3dd978f2006-09-30 19:24:45 +0000630 */
631 function list_tables()
632 {
633 // Is there a cached result?
admine8f6eb62006-10-02 06:46:16 +0000634 if (isset($this->data_cache['table_names']))
admin3dd978f2006-09-30 19:24:45 +0000635 {
admine8f6eb62006-10-02 06:46:16 +0000636 return $this->data_cache['table_names'];
admin3dd978f2006-09-30 19:24:45 +0000637 }
638
639 if (FALSE === ($sql = $this->_list_tables()))
640 {
admin6871d952006-10-04 00:36:18 +0000641 if ($this->db_debug)
642 {
admin3dd978f2006-09-30 19:24:45 +0000643 return $this->display_error('db_unsupported_function');
admin6871d952006-10-04 00:36:18 +0000644 }
645 return FALSE;
admin3dd978f2006-09-30 19:24:45 +0000646 }
647
648 $retval = array();
649 $query = $this->query($sql);
650
651 if ($query->num_rows() > 0)
652 {
653 foreach($query->result_array() as $row)
654 {
655 if (isset($row['TABLE_NAME']))
656 {
657 $retval[] = $row['TABLE_NAME'];
658 }
659 else
660 {
661 $retval[] = array_shift($row);
662 }
663 }
664 }
665
admin7099a582006-10-10 17:47:59 +0000666 $this->data_cache['table_names'] = $retval;
667 return $this->data_cache['table_names'];
admin3dd978f2006-09-30 19:24:45 +0000668 }
669
670 // --------------------------------------------------------------------
671
672 /**
673 * Determine if a particular table exists
674 * @access public
675 * @return boolean
676 */
677 function table_exists($table_name)
678 {
679 return ( ! in_array($this->dbprefix.$table_name, $this->list_tables())) ? FALSE : TRUE;
680 }
681
682 // --------------------------------------------------------------------
683
admin9cd4e8e2006-09-25 23:26:25 +0000684 /**
685 * Fetch MySQL Field Names
686 *
687 * @access public
688 * @param string the table name
admine334c472006-10-21 19:44:22 +0000689 * @return array
admin9cd4e8e2006-09-25 23:26:25 +0000690 */
admin6871d952006-10-04 00:36:18 +0000691 function list_fields($table = '')
692 {
admin3ed8c512006-09-29 23:26:28 +0000693 // Is there a cached result?
admine8f6eb62006-10-02 06:46:16 +0000694 if (isset($this->data_cache['field_names'][$table]))
admin3ed8c512006-09-29 23:26:28 +0000695 {
admine8f6eb62006-10-02 06:46:16 +0000696 return $this->data_cache['field_names'][$table];
admin3ed8c512006-09-29 23:26:28 +0000697 }
admin6871d952006-10-04 00:36:18 +0000698
699 if ($table == '')
700 {
admin9cd4e8e2006-09-25 23:26:25 +0000701 if ($this->db_debug)
702 {
703 return $this->display_error('db_field_param_missing');
704 }
705 return FALSE;
admin6871d952006-10-04 00:36:18 +0000706 }
707
admin9cd4e8e2006-09-25 23:26:25 +0000708 if (FALSE === ($sql = $this->_list_columns($this->dbprefix.$table)))
709 {
admin6871d952006-10-04 00:36:18 +0000710 if ($this->db_debug)
711 {
admin9cd4e8e2006-09-25 23:26:25 +0000712 return $this->display_error('db_unsupported_function');
admin6871d952006-10-04 00:36:18 +0000713 }
714 return FALSE;
admin9cd4e8e2006-09-25 23:26:25 +0000715 }
admin6871d952006-10-04 00:36:18 +0000716
717 $query = $this->query($sql);
718
719 $retval = array();
admin9cd4e8e2006-09-25 23:26:25 +0000720 foreach($query->result_array() as $row)
721 {
722 if (isset($row['COLUMN_NAME']))
723 {
724 $retval[] = $row['COLUMN_NAME'];
725 }
726 else
727 {
728 $retval[] = current($row);
admin6871d952006-10-04 00:36:18 +0000729 }
admin9cd4e8e2006-09-25 23:26:25 +0000730 }
admin6871d952006-10-04 00:36:18 +0000731
admin7099a582006-10-10 17:47:59 +0000732 $this->data_cache['field_names'][$table] = $retval;
733 return $this->data_cache['field_names'][$table];
admin6871d952006-10-04 00:36:18 +0000734 }
adminb2a9cec2006-10-01 03:38:04 +0000735
736 // --------------------------------------------------------------------
737
738 /**
739 * Determine if a particular field exists
740 * @access public
741 * @param string
742 * @param string
743 * @return boolean
744 */
745 function field_exists($field_name, $table_name)
746 {
747 return ( ! in_array($field_name, $this->list_fields($table_name))) ? FALSE : TRUE;
748 }
admin6871d952006-10-04 00:36:18 +0000749
admin3dd978f2006-09-30 19:24:45 +0000750 // --------------------------------------------------------------------
751
752 /**
753 * DEPRECATED - use list_fields()
754 */
admine334c472006-10-21 19:44:22 +0000755 function field_names($table = '')
admin6871d952006-10-04 00:36:18 +0000756 {
757 return $this->list_fields($table);
758 }
admin9cd4e8e2006-09-25 23:26:25 +0000759
760 // --------------------------------------------------------------------
761
762 /**
763 * Returns an object with field data
admine334c472006-10-21 19:44:22 +0000764 *
admin9cd4e8e2006-09-25 23:26:25 +0000765 * @access public
766 * @param string the table name
admine334c472006-10-21 19:44:22 +0000767 * @return object
admin9cd4e8e2006-09-25 23:26:25 +0000768 */
769 function field_data($table = '')
770 {
admin6871d952006-10-04 00:36:18 +0000771 if ($table == '')
772 {
admin9cd4e8e2006-09-25 23:26:25 +0000773 if ($this->db_debug)
774 {
775 return $this->display_error('db_field_param_missing');
776 }
777 return FALSE;
admin6871d952006-10-04 00:36:18 +0000778 }
779
admin9cd4e8e2006-09-25 23:26:25 +0000780 $query = $this->query($this->_field_data($this->dbprefix.$table));
781 return $query->field_data();
782 }
783
adminbb1d4392006-09-24 20:14:38 +0000784 // --------------------------------------------------------------------
785
786 /**
787 * Generate an insert string
admine334c472006-10-21 19:44:22 +0000788 *
adminbb1d4392006-09-24 20:14:38 +0000789 * @access public
790 * @param string the table upon which the query will be performed
791 * @param array an associative array data of key/values
admine334c472006-10-21 19:44:22 +0000792 * @return string
adminbb1d4392006-09-24 20:14:38 +0000793 */
794 function insert_string($table, $data)
795 {
admine334c472006-10-21 19:44:22 +0000796 $fields = array();
adminbb1d4392006-09-24 20:14:38 +0000797 $values = array();
798
admine334c472006-10-21 19:44:22 +0000799 foreach($data as $key => $val)
adminbb1d4392006-09-24 20:14:38 +0000800 {
801 $fields[] = $key;
802 $values[] = $this->escape($val);
803 }
804
805 return $this->_insert($this->dbprefix.$table, $fields, $values);
806 }
807
808 // --------------------------------------------------------------------
809
810 /**
811 * Generate an update string
admine334c472006-10-21 19:44:22 +0000812 *
adminbb1d4392006-09-24 20:14:38 +0000813 * @access public
814 * @param string the table upon which the query will be performed
815 * @param array an associative array data of key/values
816 * @param mixed the "where" statement
admine334c472006-10-21 19:44:22 +0000817 * @return string
adminbb1d4392006-09-24 20:14:38 +0000818 */
819 function update_string($table, $data, $where)
820 {
821 if ($where == '')
822 return false;
823
824 $fields = array();
admine334c472006-10-21 19:44:22 +0000825 foreach($data as $key => $val)
adminbb1d4392006-09-24 20:14:38 +0000826 {
827 $fields[$key] = $this->escape($val);
828 }
829
830 if ( ! is_array($where))
831 {
832 $dest = array($where);
833 }
834 else
835 {
836 $dest = array();
837 foreach ($where as $key => $val)
838 {
839 $prefix = (count($dest) == 0) ? '' : ' AND ';
840
841 if ($val != '')
842 {
843 if ( ! $this->_has_operator($key))
844 {
845 $key .= ' =';
846 }
847
848 $val = ' '.$this->escape($val);
849 }
850
851 $dest[] = $prefix.$key.$val;
852 }
853 }
854
855 return $this->_update($this->dbprefix.$table, $fields, $dest);
admin6871d952006-10-04 00:36:18 +0000856 }
admin7b613c72006-09-24 18:05:17 +0000857
858 // --------------------------------------------------------------------
859
860 /**
861 * Enables a native PHP function to be run, using a platform agnostic wrapper.
admine334c472006-10-21 19:44:22 +0000862 *
admin7b613c72006-09-24 18:05:17 +0000863 * @access public
864 * @param string the function name
865 * @param mixed any parameters needed by the function
admine334c472006-10-21 19:44:22 +0000866 * @return mixed
admin7b613c72006-09-24 18:05:17 +0000867 */
868 function call_function($function)
869 {
870 $driver = ($this->dbdriver == 'postgre') ? 'pg_' : $this->dbdriver.'_';
871
872 if (FALSE === strpos($driver, $function))
873 {
874 $function = $driver.$function;
875 }
876
877 if ( ! function_exists($function))
admine334c472006-10-21 19:44:22 +0000878 {
admin7b613c72006-09-24 18:05:17 +0000879 if ($this->db_debug)
880 {
881 return $this->display_error('db_unsupported_function');
882 }
883 return FALSE;
884 }
885 else
886 {
adminee54c112006-09-28 17:13:38 +0000887 $args = (func_num_args() > 1) ? array_splice(func_get_args(), 1) : null;
888
admine334c472006-10-21 19:44:22 +0000889 return call_user_func_array($function, $args);
admin7b613c72006-09-24 18:05:17 +0000890 }
891 }
adminc5f7fa32006-10-06 02:10:23 +0000892
893 // --------------------------------------------------------------------
894
895 /**
896 * Set Cache Directory Path
897 *
898 * @access public
899 * @param string the path to the cache directory
900 * @return void
901 */
902 function cache_set_path($path = '')
903 {
904 $this->cachedir = $path;
905 }
906
admine8f6eb62006-10-02 06:46:16 +0000907 // --------------------------------------------------------------------
908
909 /**
910 * Enable Query Caching
911 *
912 * @access public
913 * @return void
914 */
915 function cache_on()
916 {
admin7099a582006-10-10 17:47:59 +0000917 $this->cache_on = TRUE;
918 return TRUE;
admine8f6eb62006-10-02 06:46:16 +0000919 }
920
921 // --------------------------------------------------------------------
922
923 /**
924 * Disable Query Caching
925 *
926 * @access public
927 * @return void
928 */
929 function cache_off()
930 {
admin7099a582006-10-10 17:47:59 +0000931 $this->cache_on = FALSE;
932 return FALSE;
admine8f6eb62006-10-02 06:46:16 +0000933 }
adminfa708172006-10-04 18:42:42 +0000934
adminc5f7fa32006-10-06 02:10:23 +0000935
adminfa708172006-10-04 18:42:42 +0000936 // --------------------------------------------------------------------
937
938 /**
adminc5f7fa32006-10-06 02:10:23 +0000939 * Delete the cache files associated with a particular URI
adminfa708172006-10-04 18:42:42 +0000940 *
941 * @access public
adminfa708172006-10-04 18:42:42 +0000942 * @return void
943 */
admin1b0ab462006-10-10 23:30:21 +0000944 function cache_delete($segment_one = '', $segment_two = '')
adminfa708172006-10-04 18:42:42 +0000945 {
adminc5f7fa32006-10-06 02:10:23 +0000946 if ( ! $this->_cache_init())
947 {
948 return FALSE;
949 }
admin1b0ab462006-10-10 23:30:21 +0000950 return $this->CACHE->delete($segment_one, $segment_two);
adminc5f7fa32006-10-06 02:10:23 +0000951 }
952
953 // --------------------------------------------------------------------
954
955 /**
956 * Delete All cache files
957 *
958 * @access public
959 * @return void
960 */
961 function cache_delete_all()
962 {
963 if ( ! $this->_cache_init())
964 {
965 return FALSE;
966 }
967
968 return $this->CACHE->delete_all();
adminfa708172006-10-04 18:42:42 +0000969 }
admin0c405652006-10-04 18:37:57 +0000970
admin6871d952006-10-04 00:36:18 +0000971 // --------------------------------------------------------------------
972
973 /**
admin0c405652006-10-04 18:37:57 +0000974 * Initialize the Cache Class
admin6871d952006-10-04 00:36:18 +0000975 *
admin0c405652006-10-04 18:37:57 +0000976 * @access private
977 * @return void
978 */
979 function _cache_init()
admin6871d952006-10-04 00:36:18 +0000980 {
adminc2e3cd72006-10-05 04:22:30 +0000981 if (is_object($this->CACHE) AND class_exists('CI_DB_Cache'))
admindb8a3742006-10-04 07:43:35 +0000982 {
admin0c405652006-10-04 18:37:57 +0000983 return TRUE;
admindb8a3742006-10-04 07:43:35 +0000984 }
985
adminfa708172006-10-04 18:42:42 +0000986 if ( ! @include_once(BASEPATH.'database/DB_cache'.EXT))
admin6871d952006-10-04 00:36:18 +0000987 {
adminfa708172006-10-04 18:42:42 +0000988 return $this->cache_off();
admin6871d952006-10-04 00:36:18 +0000989 }
990
adminc2e3cd72006-10-05 04:22:30 +0000991 $this->CACHE = new CI_DB_Cache;
admin6871d952006-10-04 00:36:18 +0000992 return TRUE;
993 }
994
admindb8a3742006-10-04 07:43:35 +0000995
996 // --------------------------------------------------------------------
997
998 /**
admin7b613c72006-09-24 18:05:17 +0000999 * Close DB Connection
admine334c472006-10-21 19:44:22 +00001000 *
admin7b613c72006-09-24 18:05:17 +00001001 * @access public
admine334c472006-10-21 19:44:22 +00001002 * @return void
admin7b613c72006-09-24 18:05:17 +00001003 */
admin6871d952006-10-04 00:36:18 +00001004 function close()
1005 {
1006 if (is_resource($this->conn_id))
1007 {
1008 $this->_close($this->conn_id);
admine334c472006-10-21 19:44:22 +00001009 }
admin7b613c72006-09-24 18:05:17 +00001010 $this->conn_id = FALSE;
admin6871d952006-10-04 00:36:18 +00001011 }
admin7b613c72006-09-24 18:05:17 +00001012
1013 // --------------------------------------------------------------------
1014
1015 /**
1016 * Display an error message
admine334c472006-10-21 19:44:22 +00001017 *
admin7b613c72006-09-24 18:05:17 +00001018 * @access public
1019 * @param string the error message
1020 * @param string any "swap" values
1021 * @param boolean whether to localize the message
admine334c472006-10-21 19:44:22 +00001022 * @return string sends the application/error_db.php template
admin7b613c72006-09-24 18:05:17 +00001023 */
admine334c472006-10-21 19:44:22 +00001024 function display_error($error = '', $swap = '', $native = FALSE)
admin6871d952006-10-04 00:36:18 +00001025 {
admin7b613c72006-09-24 18:05:17 +00001026 $LANG = new CI_Language();
1027 $LANG->load('db');
1028
1029 $heading = 'MySQL Error';
1030
1031 if ($native == TRUE)
1032 {
1033 $message = $error;
1034 }
1035 else
1036 {
1037 $message = ( ! is_array($error)) ? array(str_replace('%s', $swap, $LANG->line($error))) : $error;
1038 }
1039
1040 if ( ! class_exists('CI_Exceptions'))
1041 {
1042 include_once(BASEPATH.'libraries/Exceptions'.EXT);
1043 }
1044
1045 $error = new CI_Exceptions();
1046 echo $error->show_error('An Error Was Encountered', $message, 'error_db');
1047 exit;
1048
admine334c472006-10-21 19:44:22 +00001049 }
admin7b613c72006-09-24 18:05:17 +00001050
1051}
1052
1053?>