blob: a4131fd73415849d01072a96a7c888b3ccefd99a [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.
10 * @license http://www.codeignitor.com/user_guide/license.html
11 * @link http://www.codeigniter.com
12 * @since Version 1.0
13 * @filesource
14 */
15
16// ------------------------------------------------------------------------
17
18/**
19 * Database Driver Class
20 *
21 * 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
67 * connection settings.
68 *
69 * Database settings can be passed as discreet
70 * parameters or as a data source name in the first
71 * 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(
96 'hostname' => '',
97 'username' => '',
98 'password' => '',
99 'database' => '',
100 'dbdriver' => 'mysql',
101 'dbprefix' => '',
102 'port' => '',
103 'pconnect' => FALSE,
104 'db_debug' => FALSE,
105 'cachedir' => '',
106 '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();
135
136 if ( ! $this->conn_id)
137 {
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 }
158
adminfd2750b2006-10-06 17:29:12 +0000159 // --------------------------------------------------------------------
160
161 /**
162 * Load the Utilities Class
163 *
164 * @access public
165 * @return string
166 */
167 function load_utilities()
admin88a8ad12006-10-07 03:16:32 +0000168 {
adminfd2750b2006-10-06 17:29:12 +0000169 require_once(BASEPATH.'database/DB_utility'.EXT);
170 require_once(BASEPATH.'database/drivers/'.$this->dbdriver.'/'.$this->dbdriver.'_utility'.EXT);
171 $class = 'CI_DB_'.$this->dbdriver.'_utility';
admin88a8ad12006-10-07 03:16:32 +0000172
173 $CI =& get_instance();
174 $CI->dbutil = new $class();
admin606f99c2006-10-11 23:48:41 +0000175 $CI->_ci_assign_to_models();
adminfd2750b2006-10-06 17:29:12 +0000176 }
admin7b613c72006-09-24 18:05:17 +0000177
178 // --------------------------------------------------------------------
179
180 /**
admin9cd4e8e2006-09-25 23:26:25 +0000181 * The name of the platform in use (mysql, mssql, etc...)
182 *
183 * @access public
184 * @return string
185 */
186 function platform()
187 {
188 return $this->dbdriver;
189 }
190
191 // --------------------------------------------------------------------
192
193 /**
194 * Database Version Number. Returns a string containing the
195 * version of the database being used
196 *
197 * @access public
198 * @return string
199 */
200 function version()
201 {
202 if (FALSE === ($sql = $this->_version()))
203 {
admin6871d952006-10-04 00:36:18 +0000204 if ($this->db_debug)
205 {
admin9cd4e8e2006-09-25 23:26:25 +0000206 return $this->display_error('db_unsupported_function');
admin6871d952006-10-04 00:36:18 +0000207 }
208 return FALSE;
admin9cd4e8e2006-09-25 23:26:25 +0000209 }
210
admin6871d952006-10-04 00:36:18 +0000211 if ($this->dbdriver == 'oci8')
212 {
admin9cd4e8e2006-09-25 23:26:25 +0000213 return $sql;
214 }
215
216 $query = $this->query($sql);
217 $row = $query->row();
218 return $row->ver;
219 }
220
221 // --------------------------------------------------------------------
222
223 /**
admin7b613c72006-09-24 18:05:17 +0000224 * Execute the query
225 *
226 * Accepts an SQL string as input and returns a result object upon
227 * successful execution of a "read" type query. Returns boolean TRUE
228 * upon successful execution of a "write" type query. Returns boolean
229 * FALSE upon failure, and if the $db_debug variable is set to TRUE
230 * will raise an error.
231 *
232 * @access public
233 * @param string An SQL query string
234 * @param array An array of binding data
235 * @return mixed
236 */
admin6871d952006-10-04 00:36:18 +0000237 function query($sql, $binds = FALSE, $return_object = TRUE)
admindb8a3742006-10-04 07:43:35 +0000238 {
admin7b613c72006-09-24 18:05:17 +0000239 if ($sql == '')
240 {
admin6871d952006-10-04 00:36:18 +0000241 if ($this->db_debug)
242 {
admin7b613c72006-09-24 18:05:17 +0000243 log_message('error', 'Invalid query: '.$sql);
244 return $this->display_error('db_invalid_query');
admin6871d952006-10-04 00:36:18 +0000245 }
246 return FALSE;
admin7b613c72006-09-24 18:05:17 +0000247 }
248
admin0c405652006-10-04 18:37:57 +0000249 // Is query caching enabled? If the query is a "read type"
250 // we will load the caching class and return the previously
251 // cached query if it exists
admin6871d952006-10-04 00:36:18 +0000252 if ($this->cache_on == TRUE AND stristr($sql, 'SELECT'))
admin0c405652006-10-04 18:37:57 +0000253 {
254 if ($this->_cache_init())
admine8f6eb62006-10-02 06:46:16 +0000255 {
adminc2e3cd72006-10-05 04:22:30 +0000256 if (FALSE !== ($cache = $this->CACHE->read($sql)))
admin0c405652006-10-04 18:37:57 +0000257 {
258 return $cache;
259 }
admine8f6eb62006-10-02 06:46:16 +0000260 }
261 }
262
admin7b613c72006-09-24 18:05:17 +0000263 // Compile binds if needed
264 if ($binds !== FALSE)
265 {
266 $sql = $this->compile_binds($sql, $binds);
267 }
268
admin6871d952006-10-04 00:36:18 +0000269 // Save the query for debugging
270 $this->queries[] = $sql;
admin7b613c72006-09-24 18:05:17 +0000271
272 // Start the Query Timer
admin6871d952006-10-04 00:36:18 +0000273 $time_start = list($sm, $ss) = explode(' ', microtime());
274
admin7b613c72006-09-24 18:05:17 +0000275 // Run the Query
admin6871d952006-10-04 00:36:18 +0000276 if (FALSE === ($this->result_id = $this->simple_query($sql)))
277 {
278 // This will trigger a rollback if transactions are being used
279 $this->_trans_failure = TRUE;
280
281 if ($this->db_debug)
282 {
adminbb1d4392006-09-24 20:14:38 +0000283 log_message('error', 'Query error: '.$this->_error_message());
admin7b613c72006-09-24 18:05:17 +0000284 return $this->display_error(
285 array(
adminbb1d4392006-09-24 20:14:38 +0000286 'Error Number: '.$this->_error_number(),
287 $this->_error_message(),
admin7b613c72006-09-24 18:05:17 +0000288 $sql
289 )
290 );
admin6871d952006-10-04 00:36:18 +0000291 }
292
293 return FALSE;
294 }
295
admin7b613c72006-09-24 18:05:17 +0000296 // Stop and aggregate the query time results
297 $time_end = list($em, $es) = explode(' ', microtime());
298 $this->benchmark += ($em + $es) - ($sm + $ss);
299
300 // Increment the query counter
admin6871d952006-10-04 00:36:18 +0000301 $this->query_count++;
302
admin7b613c72006-09-24 18:05:17 +0000303 // Was the query a "write" type?
304 // If so we'll simply return true
305 if ($this->is_write_type($sql) === TRUE)
admindb8a3742006-10-04 07:43:35 +0000306 {
307 // If caching is enabled we'll auto-cleanup any
308 // existing files related to this particular URI
admina658e312006-10-06 01:29:36 +0000309 if ($this->cache_on == TRUE AND $this->cache_autodel == TRUE AND $this->_cache_init())
admindb8a3742006-10-04 07:43:35 +0000310 {
adminc2e3cd72006-10-05 04:22:30 +0000311 $this->CACHE->delete();
admindb8a3742006-10-04 07:43:35 +0000312 }
313
admin7b613c72006-09-24 18:05:17 +0000314 return TRUE;
315 }
316
317 // Return TRUE if we don't need to create a result object
318 // Currently only the Oracle driver uses this when stored
319 // procedures are used
320 if ($return_object !== TRUE)
321 {
322 return TRUE;
323 }
admindb8a3742006-10-04 07:43:35 +0000324
325 // Load and instantiate the result driver
admindb8a3742006-10-04 07:43:35 +0000326
adminc2e3cd72006-10-05 04:22:30 +0000327 $driver = $this->load_rdriver();
328 $RES = new $driver();
admin6871d952006-10-04 00:36:18 +0000329 $RES->conn_id = $this->conn_id;
admin6871d952006-10-04 00:36:18 +0000330 $RES->result_id = $this->result_id;
331
332 if ($this->dbdriver == 'oci8')
333 {
adminc2e3cd72006-10-05 04:22:30 +0000334 $RES->stmt_id = $this->stmt_id;
335 $RES->curs_id = NULL;
336 $RES->limit_used = $this->limit_used;
admin6871d952006-10-04 00:36:18 +0000337 }
admindb8a3742006-10-04 07:43:35 +0000338
339 // Is query caching enabled? If so, we'll serialize the
adminc2e3cd72006-10-05 04:22:30 +0000340 // result object and save it to a cache file.
admin0c405652006-10-04 18:37:57 +0000341 if ($this->cache_on == TRUE AND $this->_cache_init())
adminc2e3cd72006-10-05 04:22:30 +0000342 {
343 // We'll create a new instance of the result object
344 // only without the platform specific driver since
345 // we can't use it with cached data (the query result
346 // resource ID won't be any good once we've cached the
347 // result object, so we'll have to compile the data
348 // and save it)
349 $CR = new CI_DB_result();
350 $CR->num_rows = $RES->num_rows();
351 $CR->result_object = $RES->result_object();
352 $CR->result_array = $RES->result_array();
admina658e312006-10-06 01:29:36 +0000353
354 // Reset these since cached objects can not utilize resource IDs.
355 $CR->conn_id = NULL;
356 $CR->result_id = NULL;
adminc2e3cd72006-10-05 04:22:30 +0000357
358 $this->CACHE->write($sql, $CR);
admindb8a3742006-10-04 07:43:35 +0000359 }
360
admin7b613c72006-09-24 18:05:17 +0000361 return $RES;
362 }
admindb8a3742006-10-04 07:43:35 +0000363
364 // --------------------------------------------------------------------
365
366 /**
367 * Load the result drivers
368 *
369 * @access public
370 * @return string the name of the result class
371 */
372 function load_rdriver()
373 {
374 $driver = 'CI_DB_'.$this->dbdriver.'_result';
375
376 if ( ! class_exists($driver))
377 {
378 include_once(BASEPATH.'database/DB_result'.EXT);
379 include_once(BASEPATH.'database/drivers/'.$this->dbdriver.'/'.$this->dbdriver.'_result'.EXT);
380 }
381
382 return $driver;
383 }
admin7b613c72006-09-24 18:05:17 +0000384
385 // --------------------------------------------------------------------
386
387 /**
388 * Simple Query
389 * This is a simiplified version of the query() function. Internally
390 * we only use it when running transaction commands since they do
391 * not require all the features of the main query() function.
392 *
393 * @access public
394 * @param string the sql query
395 * @return mixed
396 */
397 function simple_query($sql)
398 {
399 if ( ! $this->conn_id)
400 {
401 $this->initialize();
402 }
403
admin40037182006-10-11 19:16:58 +0000404 return $this->_execute($sql);
admin7b613c72006-09-24 18:05:17 +0000405 }
406
407 // --------------------------------------------------------------------
408
409 /**
410 * Disable Transactions
411 * This permits transactions to be disabled at run-time.
412 *
413 * @access public
414 * @return void
415 */
416 function trans_off()
417 {
418 $this->trans_enabled = FALSE;
419 }
420
421 // --------------------------------------------------------------------
422
423 /**
424 * Start Transaction
425 *
426 * @access public
427 * @return void
428 */
429 function trans_start($test_mode = FALSE)
430 {
431 if ( ! $this->trans_enabled)
432 {
433 return FALSE;
434 }
435
436 // When transactions are nested we only begin/commit/rollback the outermost ones
437 if ($this->_trans_depth > 0)
438 {
439 $this->_trans_depth += 1;
440 return;
441 }
442
443 $this->trans_begin($test_mode);
444 }
445
446 // --------------------------------------------------------------------
447
448 /**
449 * Complete Transaction
450 *
451 * @access public
452 * @return bool
453 */
454 function trans_complete()
455 {
456 if ( ! $this->trans_enabled)
457 {
458 return FALSE;
459 }
460
461 // When transactions are nested we only begin/commit/rollback the outermost ones
462 if ($this->_trans_depth > 1)
463 {
464 $this->_trans_depth -= 1;
465 return TRUE;
466 }
467
468 // The query() function will set this flag to TRUE in the event that a query failed
469 if ($this->_trans_failure === TRUE)
470 {
471 $this->trans_rollback();
472
473 if ($this->db_debug)
474 {
475 return $this->display_error('db_transaction_failure');
476 }
477 return FALSE;
478 }
479
480 $this->trans_commit();
481 return TRUE;
482 }
483
484 // --------------------------------------------------------------------
485
486 /**
487 * Lets you retrieve the transaction flag to determine if it has failed
488 *
489 * @access public
490 * @return bool
491 */
492 function trans_status()
493 {
494 return $this->_trans_failure;
495 }
496
497 // --------------------------------------------------------------------
498
499 /**
500 * Compile Bindings
501 *
502 * @access public
503 * @param string the sql statement
504 * @param array an array of bind data
505 * @return string
506 */
507 function compile_binds($sql, $binds)
508 {
509 if (FALSE === strpos($sql, $this->bind_marker))
510 {
511 return $sql;
512 }
513
514 if ( ! is_array($binds))
515 {
516 $binds = array($binds);
517 }
518
519 foreach ($binds as $val)
520 {
521 $val = $this->escape($val);
522
523 // Just in case the replacement string contains the bind
524 // character we'll temporarily replace it with a marker
525 $val = str_replace($this->bind_marker, '{%bind_marker%}', $val);
526 $sql = preg_replace("#".preg_quote($this->bind_marker, '#')."#", str_replace('$', '\$', $val), $sql, 1);
527 }
528
529 return str_replace('{%bind_marker%}', $this->bind_marker, $sql);
530 }
531
532 // --------------------------------------------------------------------
533
534 /**
535 * Determines if a query is a "write" type.
536 *
537 * @access public
538 * @param string An SQL query string
539 * @return boolean
540 */
541 function is_write_type($sql)
542 {
543 if ( ! preg_match('/^\s*"?(INSERT|UPDATE|DELETE|REPLACE|CREATE|DROP|LOAD DATA|COPY|ALTER|GRANT|REVOKE|LOCK|UNLOCK)\s+/i', $sql))
544 {
545 return FALSE;
546 }
547 return TRUE;
548 }
549
550 // --------------------------------------------------------------------
551
552 /**
553 * Calculate the aggregate query elapsed time
554 *
555 * @access public
556 * @param intiger The number of decimal places
557 * @return integer
558 */
559 function elapsed_time($decimals = 6)
560 {
561 return number_format($this->benchmark, $decimals);
562 }
563
564 // --------------------------------------------------------------------
565
566 /**
567 * Returns the total number of queries
568 *
569 * @access public
570 * @return integer
571 */
572 function total_queries()
573 {
574 return $this->query_count;
575 }
576
577 // --------------------------------------------------------------------
578
579 /**
580 * Returns the last query that was executed
581 *
582 * @access public
583 * @return void
584 */
585 function last_query()
586 {
587 return end($this->queries);
588 }
589
590 // --------------------------------------------------------------------
591
592 /**
593 * "Smart" Escape String
594 *
595 * Escapes data based on type
596 * Sets boolean and null types
597 *
598 * @access public
599 * @param string
600 * @return integer
601 */
602 function escape($str)
603 {
604 switch (gettype($str))
605 {
606 case 'string' : $str = "'".$this->escape_str($str)."'";
607 break;
608 case 'boolean' : $str = ($str === FALSE) ? 0 : 1;
609 break;
610 default : $str = ($str === NULL) ? 'NULL' : $str;
611 break;
612 }
613
614 return $str;
adminbb1d4392006-09-24 20:14:38 +0000615 }
616
admin9cd4e8e2006-09-25 23:26:25 +0000617
618
619 // --------------------------------------------------------------------
620
621 /**
622 * Primary
623 *
624 * Retrieves the primary key. It assumes that the row in the first
625 * position is the primary key
626 *
627 * @access public
628 * @param string the table name
629 * @return string
630 */
631 function primary($table = '')
632 {
admin606f99c2006-10-11 23:48:41 +0000633 $fields = $this->list_fields($table);
admin9cd4e8e2006-09-25 23:26:25 +0000634
635 if ( ! is_array($fields))
636 {
637 return FALSE;
638 }
639
640 return current($fields);
641 }
642
643 // --------------------------------------------------------------------
644
admin3dd978f2006-09-30 19:24:45 +0000645 /**
646 * Returns an array of table names
647 *
648 * @access public
649 * @return array
650 */
651 function list_tables()
652 {
653 // Is there a cached result?
admine8f6eb62006-10-02 06:46:16 +0000654 if (isset($this->data_cache['table_names']))
admin3dd978f2006-09-30 19:24:45 +0000655 {
admine8f6eb62006-10-02 06:46:16 +0000656 return $this->data_cache['table_names'];
admin3dd978f2006-09-30 19:24:45 +0000657 }
658
659 if (FALSE === ($sql = $this->_list_tables()))
660 {
admin6871d952006-10-04 00:36:18 +0000661 if ($this->db_debug)
662 {
admin3dd978f2006-09-30 19:24:45 +0000663 return $this->display_error('db_unsupported_function');
admin6871d952006-10-04 00:36:18 +0000664 }
665 return FALSE;
admin3dd978f2006-09-30 19:24:45 +0000666 }
667
668 $retval = array();
669 $query = $this->query($sql);
670
671 if ($query->num_rows() > 0)
672 {
673 foreach($query->result_array() as $row)
674 {
675 if (isset($row['TABLE_NAME']))
676 {
677 $retval[] = $row['TABLE_NAME'];
678 }
679 else
680 {
681 $retval[] = array_shift($row);
682 }
683 }
684 }
685
admin7099a582006-10-10 17:47:59 +0000686 $this->data_cache['table_names'] = $retval;
687 return $this->data_cache['table_names'];
admin3dd978f2006-09-30 19:24:45 +0000688 }
689
690 // --------------------------------------------------------------------
691
692 /**
693 * Determine if a particular table exists
694 * @access public
695 * @return boolean
696 */
697 function table_exists($table_name)
698 {
699 return ( ! in_array($this->dbprefix.$table_name, $this->list_tables())) ? FALSE : TRUE;
700 }
701
702 // --------------------------------------------------------------------
703
admin9cd4e8e2006-09-25 23:26:25 +0000704 /**
705 * Fetch MySQL Field Names
706 *
707 * @access public
708 * @param string the table name
709 * @return array
710 */
admin6871d952006-10-04 00:36:18 +0000711 function list_fields($table = '')
712 {
admin3ed8c512006-09-29 23:26:28 +0000713 // Is there a cached result?
admine8f6eb62006-10-02 06:46:16 +0000714 if (isset($this->data_cache['field_names'][$table]))
admin3ed8c512006-09-29 23:26:28 +0000715 {
admine8f6eb62006-10-02 06:46:16 +0000716 return $this->data_cache['field_names'][$table];
admin3ed8c512006-09-29 23:26:28 +0000717 }
admin6871d952006-10-04 00:36:18 +0000718
719 if ($table == '')
720 {
admin9cd4e8e2006-09-25 23:26:25 +0000721 if ($this->db_debug)
722 {
723 return $this->display_error('db_field_param_missing');
724 }
725 return FALSE;
admin6871d952006-10-04 00:36:18 +0000726 }
727
admin9cd4e8e2006-09-25 23:26:25 +0000728 if (FALSE === ($sql = $this->_list_columns($this->dbprefix.$table)))
729 {
admin6871d952006-10-04 00:36:18 +0000730 if ($this->db_debug)
731 {
admin9cd4e8e2006-09-25 23:26:25 +0000732 return $this->display_error('db_unsupported_function');
admin6871d952006-10-04 00:36:18 +0000733 }
734 return FALSE;
admin9cd4e8e2006-09-25 23:26:25 +0000735 }
admin6871d952006-10-04 00:36:18 +0000736
737 $query = $this->query($sql);
738
739 $retval = array();
admin9cd4e8e2006-09-25 23:26:25 +0000740 foreach($query->result_array() as $row)
741 {
742 if (isset($row['COLUMN_NAME']))
743 {
744 $retval[] = $row['COLUMN_NAME'];
745 }
746 else
747 {
748 $retval[] = current($row);
admin6871d952006-10-04 00:36:18 +0000749 }
admin9cd4e8e2006-09-25 23:26:25 +0000750 }
admin6871d952006-10-04 00:36:18 +0000751
admin7099a582006-10-10 17:47:59 +0000752 $this->data_cache['field_names'][$table] = $retval;
753 return $this->data_cache['field_names'][$table];
admin6871d952006-10-04 00:36:18 +0000754 }
adminb2a9cec2006-10-01 03:38:04 +0000755
756 // --------------------------------------------------------------------
757
758 /**
759 * Determine if a particular field exists
760 * @access public
761 * @param string
762 * @param string
763 * @return boolean
764 */
765 function field_exists($field_name, $table_name)
766 {
767 return ( ! in_array($field_name, $this->list_fields($table_name))) ? FALSE : TRUE;
768 }
admin6871d952006-10-04 00:36:18 +0000769
admin3dd978f2006-09-30 19:24:45 +0000770 // --------------------------------------------------------------------
771
772 /**
773 * DEPRECATED - use list_fields()
774 */
admin6871d952006-10-04 00:36:18 +0000775 function field_names($table = '')
776 {
777 return $this->list_fields($table);
778 }
admin9cd4e8e2006-09-25 23:26:25 +0000779
780 // --------------------------------------------------------------------
781
782 /**
783 * Returns an object with field data
784 *
785 * @access public
786 * @param string the table name
787 * @return object
788 */
789 function field_data($table = '')
790 {
admin6871d952006-10-04 00:36:18 +0000791 if ($table == '')
792 {
admin9cd4e8e2006-09-25 23:26:25 +0000793 if ($this->db_debug)
794 {
795 return $this->display_error('db_field_param_missing');
796 }
797 return FALSE;
admin6871d952006-10-04 00:36:18 +0000798 }
799
admin9cd4e8e2006-09-25 23:26:25 +0000800 $query = $this->query($this->_field_data($this->dbprefix.$table));
801 return $query->field_data();
802 }
803
adminbb1d4392006-09-24 20:14:38 +0000804 // --------------------------------------------------------------------
805
806 /**
807 * Generate an insert string
808 *
809 * @access public
810 * @param string the table upon which the query will be performed
811 * @param array an associative array data of key/values
812 * @return string
813 */
814 function insert_string($table, $data)
815 {
admin6871d952006-10-04 00:36:18 +0000816 $fields = array();
adminbb1d4392006-09-24 20:14:38 +0000817 $values = array();
818
819 foreach($data as $key => $val)
820 {
821 $fields[] = $key;
822 $values[] = $this->escape($val);
823 }
824
825 return $this->_insert($this->dbprefix.$table, $fields, $values);
826 }
827
828 // --------------------------------------------------------------------
829
830 /**
831 * Generate an update string
832 *
833 * @access public
834 * @param string the table upon which the query will be performed
835 * @param array an associative array data of key/values
836 * @param mixed the "where" statement
837 * @return string
838 */
839 function update_string($table, $data, $where)
840 {
841 if ($where == '')
842 return false;
843
844 $fields = array();
845 foreach($data as $key => $val)
846 {
847 $fields[$key] = $this->escape($val);
848 }
849
850 if ( ! is_array($where))
851 {
852 $dest = array($where);
853 }
854 else
855 {
856 $dest = array();
857 foreach ($where as $key => $val)
858 {
859 $prefix = (count($dest) == 0) ? '' : ' AND ';
860
861 if ($val != '')
862 {
863 if ( ! $this->_has_operator($key))
864 {
865 $key .= ' =';
866 }
867
868 $val = ' '.$this->escape($val);
869 }
870
871 $dest[] = $prefix.$key.$val;
872 }
873 }
874
875 return $this->_update($this->dbprefix.$table, $fields, $dest);
admin6871d952006-10-04 00:36:18 +0000876 }
admin7b613c72006-09-24 18:05:17 +0000877
878 // --------------------------------------------------------------------
879
880 /**
881 * Enables a native PHP function to be run, using a platform agnostic wrapper.
882 *
883 * @access public
884 * @param string the function name
885 * @param mixed any parameters needed by the function
886 * @return mixed
887 */
888 function call_function($function)
889 {
890 $driver = ($this->dbdriver == 'postgre') ? 'pg_' : $this->dbdriver.'_';
891
892 if (FALSE === strpos($driver, $function))
893 {
894 $function = $driver.$function;
895 }
896
897 if ( ! function_exists($function))
898 {
899 if ($this->db_debug)
900 {
901 return $this->display_error('db_unsupported_function');
902 }
903 return FALSE;
904 }
905 else
906 {
adminee54c112006-09-28 17:13:38 +0000907 $args = (func_num_args() > 1) ? array_splice(func_get_args(), 1) : null;
908
admin7b613c72006-09-24 18:05:17 +0000909 return call_user_func_array($function, $args);
910 }
911 }
adminc5f7fa32006-10-06 02:10:23 +0000912
913 // --------------------------------------------------------------------
914
915 /**
916 * Set Cache Directory Path
917 *
918 * @access public
919 * @param string the path to the cache directory
920 * @return void
921 */
922 function cache_set_path($path = '')
923 {
924 $this->cachedir = $path;
925 }
926
admine8f6eb62006-10-02 06:46:16 +0000927 // --------------------------------------------------------------------
928
929 /**
930 * Enable Query Caching
931 *
932 * @access public
933 * @return void
934 */
935 function cache_on()
936 {
admin7099a582006-10-10 17:47:59 +0000937 $this->cache_on = TRUE;
938 return TRUE;
admine8f6eb62006-10-02 06:46:16 +0000939 }
940
941 // --------------------------------------------------------------------
942
943 /**
944 * Disable Query Caching
945 *
946 * @access public
947 * @return void
948 */
949 function cache_off()
950 {
admin7099a582006-10-10 17:47:59 +0000951 $this->cache_on = FALSE;
952 return FALSE;
admine8f6eb62006-10-02 06:46:16 +0000953 }
adminfa708172006-10-04 18:42:42 +0000954
adminc5f7fa32006-10-06 02:10:23 +0000955
adminfa708172006-10-04 18:42:42 +0000956 // --------------------------------------------------------------------
957
958 /**
adminc5f7fa32006-10-06 02:10:23 +0000959 * Delete the cache files associated with a particular URI
adminfa708172006-10-04 18:42:42 +0000960 *
961 * @access public
adminfa708172006-10-04 18:42:42 +0000962 * @return void
963 */
admin1b0ab462006-10-10 23:30:21 +0000964 function cache_delete($segment_one = '', $segment_two = '')
adminfa708172006-10-04 18:42:42 +0000965 {
adminc5f7fa32006-10-06 02:10:23 +0000966 if ( ! $this->_cache_init())
967 {
968 return FALSE;
969 }
admin1b0ab462006-10-10 23:30:21 +0000970 return $this->CACHE->delete($segment_one, $segment_two);
adminc5f7fa32006-10-06 02:10:23 +0000971 }
972
973 // --------------------------------------------------------------------
974
975 /**
976 * Delete All cache files
977 *
978 * @access public
979 * @return void
980 */
981 function cache_delete_all()
982 {
983 if ( ! $this->_cache_init())
984 {
985 return FALSE;
986 }
987
988 return $this->CACHE->delete_all();
adminfa708172006-10-04 18:42:42 +0000989 }
admin0c405652006-10-04 18:37:57 +0000990
admin6871d952006-10-04 00:36:18 +0000991 // --------------------------------------------------------------------
992
993 /**
admin0c405652006-10-04 18:37:57 +0000994 * Initialize the Cache Class
admin6871d952006-10-04 00:36:18 +0000995 *
admin0c405652006-10-04 18:37:57 +0000996 * @access private
997 * @return void
998 */
999 function _cache_init()
admin6871d952006-10-04 00:36:18 +00001000 {
adminc2e3cd72006-10-05 04:22:30 +00001001 if (is_object($this->CACHE) AND class_exists('CI_DB_Cache'))
admindb8a3742006-10-04 07:43:35 +00001002 {
admin0c405652006-10-04 18:37:57 +00001003 return TRUE;
admindb8a3742006-10-04 07:43:35 +00001004 }
1005
adminfa708172006-10-04 18:42:42 +00001006 if ( ! @include_once(BASEPATH.'database/DB_cache'.EXT))
admin6871d952006-10-04 00:36:18 +00001007 {
adminfa708172006-10-04 18:42:42 +00001008 return $this->cache_off();
admin6871d952006-10-04 00:36:18 +00001009 }
1010
adminc2e3cd72006-10-05 04:22:30 +00001011 $this->CACHE = new CI_DB_Cache;
admin6871d952006-10-04 00:36:18 +00001012 return TRUE;
1013 }
1014
admindb8a3742006-10-04 07:43:35 +00001015
1016 // --------------------------------------------------------------------
1017
1018 /**
admin7b613c72006-09-24 18:05:17 +00001019 * Close DB Connection
1020 *
1021 * @access public
1022 * @return void
1023 */
admin6871d952006-10-04 00:36:18 +00001024 function close()
1025 {
1026 if (is_resource($this->conn_id))
1027 {
1028 $this->_close($this->conn_id);
admin7b613c72006-09-24 18:05:17 +00001029 }
1030 $this->conn_id = FALSE;
admin6871d952006-10-04 00:36:18 +00001031 }
admin7b613c72006-09-24 18:05:17 +00001032
1033 // --------------------------------------------------------------------
1034
1035 /**
1036 * Display an error message
1037 *
1038 * @access public
1039 * @param string the error message
1040 * @param string any "swap" values
1041 * @param boolean whether to localize the message
1042 * @return string sends the application/errror_db.php template
1043 */
admin6871d952006-10-04 00:36:18 +00001044 function display_error($error = '', $swap = '', $native = FALSE)
1045 {
admin7b613c72006-09-24 18:05:17 +00001046 $LANG = new CI_Language();
1047 $LANG->load('db');
1048
1049 $heading = 'MySQL Error';
1050
1051 if ($native == TRUE)
1052 {
1053 $message = $error;
1054 }
1055 else
1056 {
1057 $message = ( ! is_array($error)) ? array(str_replace('%s', $swap, $LANG->line($error))) : $error;
1058 }
1059
1060 if ( ! class_exists('CI_Exceptions'))
1061 {
1062 include_once(BASEPATH.'libraries/Exceptions'.EXT);
1063 }
1064
1065 $error = new CI_Exceptions();
1066 echo $error->show_error('An Error Was Encountered', $message, 'error_db');
1067 exit;
1068
admin6871d952006-10-04 00:36:18 +00001069 }
admin7b613c72006-09-24 18:05:17 +00001070
1071}
1072
1073?>