blob: 848d4f1c6edb6afdeb05ac592e7875788855cfd3 [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 }
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
165 * @return string
166 */
167 function platform()
168 {
169 return $this->dbdriver;
170 }
171
172 // --------------------------------------------------------------------
173
174 /**
175 * Database Version Number. Returns a string containing the
176 * 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 *
207 * 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
211 * will raise an error.
212 *
213 * @access public
214 * @param string An SQL query string
215 * @param array An array of binding data
216 * @return mixed
217 */
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
admin0c405652006-10-04 18:37:57 +0000230 // Is query caching enabled? If the query is a "read type"
231 // we will load the caching class and return the previously
232 // 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 {
adminc2e3cd72006-10-05 04:22:30 +0000237 if (FALSE !== ($cache = $this->CACHE->read($sql)))
admin0c405652006-10-04 18:37:57 +0000238 {
239 return $cache;
240 }
admine8f6eb62006-10-02 06:46:16 +0000241 }
242 }
243
admin7b613c72006-09-24 18:05:17 +0000244 // Compile binds if needed
245 if ($binds !== FALSE)
246 {
247 $sql = $this->compile_binds($sql, $binds);
248 }
249
admin6871d952006-10-04 00:36:18 +0000250 // Save the query for debugging
251 $this->queries[] = $sql;
admin7b613c72006-09-24 18:05:17 +0000252
253 // Start the Query Timer
admin6871d952006-10-04 00:36:18 +0000254 $time_start = list($sm, $ss) = explode(' ', microtime());
255
admin7b613c72006-09-24 18:05:17 +0000256 // Run the Query
admin6871d952006-10-04 00:36:18 +0000257 if (FALSE === ($this->result_id = $this->simple_query($sql)))
258 {
259 // This will trigger a rollback if transactions are being used
260 $this->_trans_failure = TRUE;
261
262 if ($this->db_debug)
263 {
adminbb1d4392006-09-24 20:14:38 +0000264 log_message('error', 'Query error: '.$this->_error_message());
admin7b613c72006-09-24 18:05:17 +0000265 return $this->display_error(
266 array(
adminbb1d4392006-09-24 20:14:38 +0000267 'Error Number: '.$this->_error_number(),
268 $this->_error_message(),
admin7b613c72006-09-24 18:05:17 +0000269 $sql
270 )
271 );
admin6871d952006-10-04 00:36:18 +0000272 }
273
274 return FALSE;
275 }
276
admin7b613c72006-09-24 18:05:17 +0000277 // Stop and aggregate the query time results
278 $time_end = list($em, $es) = explode(' ', microtime());
279 $this->benchmark += ($em + $es) - ($sm + $ss);
280
281 // Increment the query counter
admin6871d952006-10-04 00:36:18 +0000282 $this->query_count++;
283
admin7b613c72006-09-24 18:05:17 +0000284 // Was the query a "write" type?
285 // If so we'll simply return true
286 if ($this->is_write_type($sql) === TRUE)
admindb8a3742006-10-04 07:43:35 +0000287 {
288 // If caching is enabled we'll auto-cleanup any
289 // existing files related to this particular URI
admina658e312006-10-06 01:29:36 +0000290 if ($this->cache_on == TRUE AND $this->cache_autodel == TRUE AND $this->_cache_init())
admindb8a3742006-10-04 07:43:35 +0000291 {
adminc2e3cd72006-10-05 04:22:30 +0000292 $this->CACHE->delete();
admindb8a3742006-10-04 07:43:35 +0000293 }
294
admin7b613c72006-09-24 18:05:17 +0000295 return TRUE;
296 }
297
298 // Return TRUE if we don't need to create a result object
299 // Currently only the Oracle driver uses this when stored
300 // procedures are used
301 if ($return_object !== TRUE)
302 {
303 return TRUE;
304 }
admindb8a3742006-10-04 07:43:35 +0000305
306 // Load and instantiate the result driver
admindb8a3742006-10-04 07:43:35 +0000307
adminc2e3cd72006-10-05 04:22:30 +0000308 $driver = $this->load_rdriver();
309 $RES = new $driver();
admin6871d952006-10-04 00:36:18 +0000310 $RES->conn_id = $this->conn_id;
admin6871d952006-10-04 00:36:18 +0000311 $RES->result_id = $this->result_id;
312
313 if ($this->dbdriver == 'oci8')
314 {
adminc2e3cd72006-10-05 04:22:30 +0000315 $RES->stmt_id = $this->stmt_id;
316 $RES->curs_id = NULL;
317 $RES->limit_used = $this->limit_used;
admin6871d952006-10-04 00:36:18 +0000318 }
admindb8a3742006-10-04 07:43:35 +0000319
320 // Is query caching enabled? If so, we'll serialize the
adminc2e3cd72006-10-05 04:22:30 +0000321 // result object and save it to a cache file.
admin0c405652006-10-04 18:37:57 +0000322 if ($this->cache_on == TRUE AND $this->_cache_init())
adminc2e3cd72006-10-05 04:22:30 +0000323 {
324 // We'll create a new instance of the result object
325 // only without the platform specific driver since
326 // we can't use it with cached data (the query result
327 // resource ID won't be any good once we've cached the
328 // result object, so we'll have to compile the data
329 // and save it)
330 $CR = new CI_DB_result();
331 $CR->num_rows = $RES->num_rows();
332 $CR->result_object = $RES->result_object();
333 $CR->result_array = $RES->result_array();
admina658e312006-10-06 01:29:36 +0000334
335 // Reset these since cached objects can not utilize resource IDs.
336 $CR->conn_id = NULL;
337 $CR->result_id = NULL;
adminc2e3cd72006-10-05 04:22:30 +0000338
339 $this->CACHE->write($sql, $CR);
admindb8a3742006-10-04 07:43:35 +0000340 }
341
admin7b613c72006-09-24 18:05:17 +0000342 return $RES;
343 }
admindb8a3742006-10-04 07:43:35 +0000344
345 // --------------------------------------------------------------------
346
347 /**
348 * Load the result drivers
349 *
350 * @access public
351 * @return string the name of the result class
352 */
353 function load_rdriver()
354 {
355 $driver = 'CI_DB_'.$this->dbdriver.'_result';
356
357 if ( ! class_exists($driver))
358 {
359 include_once(BASEPATH.'database/DB_result'.EXT);
360 include_once(BASEPATH.'database/drivers/'.$this->dbdriver.'/'.$this->dbdriver.'_result'.EXT);
361 }
362
363 return $driver;
364 }
admin7b613c72006-09-24 18:05:17 +0000365
366 // --------------------------------------------------------------------
367
368 /**
369 * Simple Query
370 * This is a simiplified version of the query() function. Internally
371 * we only use it when running transaction commands since they do
372 * not require all the features of the main query() function.
373 *
374 * @access public
375 * @param string the sql query
376 * @return mixed
377 */
378 function simple_query($sql)
379 {
380 if ( ! $this->conn_id)
381 {
382 $this->initialize();
383 }
384
admin40037182006-10-11 19:16:58 +0000385 return $this->_execute($sql);
admin7b613c72006-09-24 18:05:17 +0000386 }
387
388 // --------------------------------------------------------------------
389
390 /**
391 * Disable Transactions
392 * This permits transactions to be disabled at run-time.
393 *
394 * @access public
395 * @return void
396 */
397 function trans_off()
398 {
399 $this->trans_enabled = FALSE;
400 }
401
402 // --------------------------------------------------------------------
403
404 /**
405 * Start Transaction
406 *
407 * @access public
408 * @return void
409 */
410 function trans_start($test_mode = FALSE)
411 {
412 if ( ! $this->trans_enabled)
413 {
414 return FALSE;
415 }
416
417 // When transactions are nested we only begin/commit/rollback the outermost ones
418 if ($this->_trans_depth > 0)
419 {
420 $this->_trans_depth += 1;
421 return;
422 }
423
424 $this->trans_begin($test_mode);
425 }
426
427 // --------------------------------------------------------------------
428
429 /**
430 * Complete Transaction
431 *
432 * @access public
433 * @return bool
434 */
435 function trans_complete()
436 {
437 if ( ! $this->trans_enabled)
438 {
439 return FALSE;
440 }
441
442 // When transactions are nested we only begin/commit/rollback the outermost ones
443 if ($this->_trans_depth > 1)
444 {
445 $this->_trans_depth -= 1;
446 return TRUE;
447 }
448
449 // The query() function will set this flag to TRUE in the event that a query failed
450 if ($this->_trans_failure === TRUE)
451 {
452 $this->trans_rollback();
453
454 if ($this->db_debug)
455 {
456 return $this->display_error('db_transaction_failure');
457 }
458 return FALSE;
459 }
460
461 $this->trans_commit();
462 return TRUE;
463 }
464
465 // --------------------------------------------------------------------
466
467 /**
468 * Lets you retrieve the transaction flag to determine if it has failed
469 *
470 * @access public
471 * @return bool
472 */
473 function trans_status()
474 {
475 return $this->_trans_failure;
476 }
477
478 // --------------------------------------------------------------------
479
480 /**
481 * Compile Bindings
482 *
483 * @access public
484 * @param string the sql statement
485 * @param array an array of bind data
486 * @return string
487 */
488 function compile_binds($sql, $binds)
489 {
490 if (FALSE === strpos($sql, $this->bind_marker))
491 {
492 return $sql;
493 }
494
495 if ( ! is_array($binds))
496 {
497 $binds = array($binds);
498 }
499
500 foreach ($binds as $val)
501 {
502 $val = $this->escape($val);
503
504 // Just in case the replacement string contains the bind
505 // character we'll temporarily replace it with a marker
506 $val = str_replace($this->bind_marker, '{%bind_marker%}', $val);
507 $sql = preg_replace("#".preg_quote($this->bind_marker, '#')."#", str_replace('$', '\$', $val), $sql, 1);
508 }
509
510 return str_replace('{%bind_marker%}', $this->bind_marker, $sql);
511 }
512
513 // --------------------------------------------------------------------
514
515 /**
516 * Determines if a query is a "write" type.
517 *
518 * @access public
519 * @param string An SQL query string
520 * @return boolean
521 */
522 function is_write_type($sql)
523 {
524 if ( ! preg_match('/^\s*"?(INSERT|UPDATE|DELETE|REPLACE|CREATE|DROP|LOAD DATA|COPY|ALTER|GRANT|REVOKE|LOCK|UNLOCK)\s+/i', $sql))
525 {
526 return FALSE;
527 }
528 return TRUE;
529 }
530
531 // --------------------------------------------------------------------
532
533 /**
534 * Calculate the aggregate query elapsed time
535 *
536 * @access public
537 * @param intiger The number of decimal places
538 * @return integer
539 */
540 function elapsed_time($decimals = 6)
541 {
542 return number_format($this->benchmark, $decimals);
543 }
544
545 // --------------------------------------------------------------------
546
547 /**
548 * Returns the total number of queries
549 *
550 * @access public
551 * @return integer
552 */
553 function total_queries()
554 {
555 return $this->query_count;
556 }
557
558 // --------------------------------------------------------------------
559
560 /**
561 * Returns the last query that was executed
562 *
563 * @access public
564 * @return void
565 */
566 function last_query()
567 {
568 return end($this->queries);
569 }
570
571 // --------------------------------------------------------------------
572
573 /**
574 * "Smart" Escape String
575 *
576 * Escapes data based on type
577 * Sets boolean and null types
578 *
579 * @access public
580 * @param string
581 * @return integer
582 */
583 function escape($str)
584 {
585 switch (gettype($str))
586 {
587 case 'string' : $str = "'".$this->escape_str($str)."'";
588 break;
589 case 'boolean' : $str = ($str === FALSE) ? 0 : 1;
590 break;
591 default : $str = ($str === NULL) ? 'NULL' : $str;
592 break;
593 }
594
595 return $str;
adminbb1d4392006-09-24 20:14:38 +0000596 }
597
admin9cd4e8e2006-09-25 23:26:25 +0000598
599
600 // --------------------------------------------------------------------
601
602 /**
603 * Primary
604 *
605 * Retrieves the primary key. It assumes that the row in the first
606 * position is the primary key
607 *
608 * @access public
609 * @param string the table name
610 * @return string
611 */
612 function primary($table = '')
613 {
admin606f99c2006-10-11 23:48:41 +0000614 $fields = $this->list_fields($table);
admin9cd4e8e2006-09-25 23:26:25 +0000615
616 if ( ! is_array($fields))
617 {
618 return FALSE;
619 }
620
621 return current($fields);
622 }
623
624 // --------------------------------------------------------------------
625
admin3dd978f2006-09-30 19:24:45 +0000626 /**
627 * Returns an array of table names
628 *
629 * @access public
630 * @return array
631 */
632 function list_tables()
633 {
634 // Is there a cached result?
admine8f6eb62006-10-02 06:46:16 +0000635 if (isset($this->data_cache['table_names']))
admin3dd978f2006-09-30 19:24:45 +0000636 {
admine8f6eb62006-10-02 06:46:16 +0000637 return $this->data_cache['table_names'];
admin3dd978f2006-09-30 19:24:45 +0000638 }
639
640 if (FALSE === ($sql = $this->_list_tables()))
641 {
admin6871d952006-10-04 00:36:18 +0000642 if ($this->db_debug)
643 {
admin3dd978f2006-09-30 19:24:45 +0000644 return $this->display_error('db_unsupported_function');
admin6871d952006-10-04 00:36:18 +0000645 }
646 return FALSE;
admin3dd978f2006-09-30 19:24:45 +0000647 }
648
649 $retval = array();
650 $query = $this->query($sql);
651
652 if ($query->num_rows() > 0)
653 {
654 foreach($query->result_array() as $row)
655 {
656 if (isset($row['TABLE_NAME']))
657 {
658 $retval[] = $row['TABLE_NAME'];
659 }
660 else
661 {
662 $retval[] = array_shift($row);
663 }
664 }
665 }
666
admin7099a582006-10-10 17:47:59 +0000667 $this->data_cache['table_names'] = $retval;
668 return $this->data_cache['table_names'];
admin3dd978f2006-09-30 19:24:45 +0000669 }
670
671 // --------------------------------------------------------------------
672
673 /**
674 * Determine if a particular table exists
675 * @access public
676 * @return boolean
677 */
678 function table_exists($table_name)
679 {
680 return ( ! in_array($this->dbprefix.$table_name, $this->list_tables())) ? FALSE : TRUE;
681 }
682
683 // --------------------------------------------------------------------
684
admin9cd4e8e2006-09-25 23:26:25 +0000685 /**
686 * Fetch MySQL Field Names
687 *
688 * @access public
689 * @param string the table name
690 * @return array
691 */
admin6871d952006-10-04 00:36:18 +0000692 function list_fields($table = '')
693 {
admin3ed8c512006-09-29 23:26:28 +0000694 // Is there a cached result?
admine8f6eb62006-10-02 06:46:16 +0000695 if (isset($this->data_cache['field_names'][$table]))
admin3ed8c512006-09-29 23:26:28 +0000696 {
admine8f6eb62006-10-02 06:46:16 +0000697 return $this->data_cache['field_names'][$table];
admin3ed8c512006-09-29 23:26:28 +0000698 }
admin6871d952006-10-04 00:36:18 +0000699
700 if ($table == '')
701 {
admin9cd4e8e2006-09-25 23:26:25 +0000702 if ($this->db_debug)
703 {
704 return $this->display_error('db_field_param_missing');
705 }
706 return FALSE;
admin6871d952006-10-04 00:36:18 +0000707 }
708
admin9cd4e8e2006-09-25 23:26:25 +0000709 if (FALSE === ($sql = $this->_list_columns($this->dbprefix.$table)))
710 {
admin6871d952006-10-04 00:36:18 +0000711 if ($this->db_debug)
712 {
admin9cd4e8e2006-09-25 23:26:25 +0000713 return $this->display_error('db_unsupported_function');
admin6871d952006-10-04 00:36:18 +0000714 }
715 return FALSE;
admin9cd4e8e2006-09-25 23:26:25 +0000716 }
admin6871d952006-10-04 00:36:18 +0000717
718 $query = $this->query($sql);
719
720 $retval = array();
admin9cd4e8e2006-09-25 23:26:25 +0000721 foreach($query->result_array() as $row)
722 {
723 if (isset($row['COLUMN_NAME']))
724 {
725 $retval[] = $row['COLUMN_NAME'];
726 }
727 else
728 {
729 $retval[] = current($row);
admin6871d952006-10-04 00:36:18 +0000730 }
admin9cd4e8e2006-09-25 23:26:25 +0000731 }
admin6871d952006-10-04 00:36:18 +0000732
admin7099a582006-10-10 17:47:59 +0000733 $this->data_cache['field_names'][$table] = $retval;
734 return $this->data_cache['field_names'][$table];
admin6871d952006-10-04 00:36:18 +0000735 }
adminb2a9cec2006-10-01 03:38:04 +0000736
737 // --------------------------------------------------------------------
738
739 /**
740 * Determine if a particular field exists
741 * @access public
742 * @param string
743 * @param string
744 * @return boolean
745 */
746 function field_exists($field_name, $table_name)
747 {
748 return ( ! in_array($field_name, $this->list_fields($table_name))) ? FALSE : TRUE;
749 }
admin6871d952006-10-04 00:36:18 +0000750
admin3dd978f2006-09-30 19:24:45 +0000751 // --------------------------------------------------------------------
752
753 /**
754 * DEPRECATED - use list_fields()
755 */
admin6871d952006-10-04 00:36:18 +0000756 function field_names($table = '')
757 {
758 return $this->list_fields($table);
759 }
admin9cd4e8e2006-09-25 23:26:25 +0000760
761 // --------------------------------------------------------------------
762
763 /**
764 * Returns an object with field data
765 *
766 * @access public
767 * @param string the table name
768 * @return object
769 */
770 function field_data($table = '')
771 {
admin6871d952006-10-04 00:36:18 +0000772 if ($table == '')
773 {
admin9cd4e8e2006-09-25 23:26:25 +0000774 if ($this->db_debug)
775 {
776 return $this->display_error('db_field_param_missing');
777 }
778 return FALSE;
admin6871d952006-10-04 00:36:18 +0000779 }
780
admin9cd4e8e2006-09-25 23:26:25 +0000781 $query = $this->query($this->_field_data($this->dbprefix.$table));
782 return $query->field_data();
783 }
784
adminbb1d4392006-09-24 20:14:38 +0000785 // --------------------------------------------------------------------
786
787 /**
788 * Generate an insert string
789 *
790 * @access public
791 * @param string the table upon which the query will be performed
792 * @param array an associative array data of key/values
793 * @return string
794 */
795 function insert_string($table, $data)
796 {
admin6871d952006-10-04 00:36:18 +0000797 $fields = array();
adminbb1d4392006-09-24 20:14:38 +0000798 $values = array();
799
800 foreach($data as $key => $val)
801 {
802 $fields[] = $key;
803 $values[] = $this->escape($val);
804 }
805
806 return $this->_insert($this->dbprefix.$table, $fields, $values);
807 }
808
809 // --------------------------------------------------------------------
810
811 /**
812 * Generate an update string
813 *
814 * @access public
815 * @param string the table upon which the query will be performed
816 * @param array an associative array data of key/values
817 * @param mixed the "where" statement
818 * @return string
819 */
820 function update_string($table, $data, $where)
821 {
822 if ($where == '')
823 return false;
824
825 $fields = array();
826 foreach($data as $key => $val)
827 {
828 $fields[$key] = $this->escape($val);
829 }
830
831 if ( ! is_array($where))
832 {
833 $dest = array($where);
834 }
835 else
836 {
837 $dest = array();
838 foreach ($where as $key => $val)
839 {
840 $prefix = (count($dest) == 0) ? '' : ' AND ';
841
842 if ($val != '')
843 {
844 if ( ! $this->_has_operator($key))
845 {
846 $key .= ' =';
847 }
848
849 $val = ' '.$this->escape($val);
850 }
851
852 $dest[] = $prefix.$key.$val;
853 }
854 }
855
856 return $this->_update($this->dbprefix.$table, $fields, $dest);
admin6871d952006-10-04 00:36:18 +0000857 }
admin7b613c72006-09-24 18:05:17 +0000858
859 // --------------------------------------------------------------------
860
861 /**
862 * Enables a native PHP function to be run, using a platform agnostic wrapper.
863 *
864 * @access public
865 * @param string the function name
866 * @param mixed any parameters needed by the function
867 * @return mixed
868 */
869 function call_function($function)
870 {
871 $driver = ($this->dbdriver == 'postgre') ? 'pg_' : $this->dbdriver.'_';
872
873 if (FALSE === strpos($driver, $function))
874 {
875 $function = $driver.$function;
876 }
877
878 if ( ! function_exists($function))
879 {
880 if ($this->db_debug)
881 {
882 return $this->display_error('db_unsupported_function');
883 }
884 return FALSE;
885 }
886 else
887 {
adminee54c112006-09-28 17:13:38 +0000888 $args = (func_num_args() > 1) ? array_splice(func_get_args(), 1) : null;
889
admin7b613c72006-09-24 18:05:17 +0000890 return call_user_func_array($function, $args);
891 }
892 }
adminc5f7fa32006-10-06 02:10:23 +0000893
894 // --------------------------------------------------------------------
895
896 /**
897 * Set Cache Directory Path
898 *
899 * @access public
900 * @param string the path to the cache directory
901 * @return void
902 */
903 function cache_set_path($path = '')
904 {
905 $this->cachedir = $path;
906 }
907
admine8f6eb62006-10-02 06:46:16 +0000908 // --------------------------------------------------------------------
909
910 /**
911 * Enable Query Caching
912 *
913 * @access public
914 * @return void
915 */
916 function cache_on()
917 {
admin7099a582006-10-10 17:47:59 +0000918 $this->cache_on = TRUE;
919 return TRUE;
admine8f6eb62006-10-02 06:46:16 +0000920 }
921
922 // --------------------------------------------------------------------
923
924 /**
925 * Disable Query Caching
926 *
927 * @access public
928 * @return void
929 */
930 function cache_off()
931 {
admin7099a582006-10-10 17:47:59 +0000932 $this->cache_on = FALSE;
933 return FALSE;
admine8f6eb62006-10-02 06:46:16 +0000934 }
adminfa708172006-10-04 18:42:42 +0000935
adminc5f7fa32006-10-06 02:10:23 +0000936
adminfa708172006-10-04 18:42:42 +0000937 // --------------------------------------------------------------------
938
939 /**
adminc5f7fa32006-10-06 02:10:23 +0000940 * Delete the cache files associated with a particular URI
adminfa708172006-10-04 18:42:42 +0000941 *
942 * @access public
adminfa708172006-10-04 18:42:42 +0000943 * @return void
944 */
admin1b0ab462006-10-10 23:30:21 +0000945 function cache_delete($segment_one = '', $segment_two = '')
adminfa708172006-10-04 18:42:42 +0000946 {
adminc5f7fa32006-10-06 02:10:23 +0000947 if ( ! $this->_cache_init())
948 {
949 return FALSE;
950 }
admin1b0ab462006-10-10 23:30:21 +0000951 return $this->CACHE->delete($segment_one, $segment_two);
adminc5f7fa32006-10-06 02:10:23 +0000952 }
953
954 // --------------------------------------------------------------------
955
956 /**
957 * Delete All cache files
958 *
959 * @access public
960 * @return void
961 */
962 function cache_delete_all()
963 {
964 if ( ! $this->_cache_init())
965 {
966 return FALSE;
967 }
968
969 return $this->CACHE->delete_all();
adminfa708172006-10-04 18:42:42 +0000970 }
admin0c405652006-10-04 18:37:57 +0000971
admin6871d952006-10-04 00:36:18 +0000972 // --------------------------------------------------------------------
973
974 /**
admin0c405652006-10-04 18:37:57 +0000975 * Initialize the Cache Class
admin6871d952006-10-04 00:36:18 +0000976 *
admin0c405652006-10-04 18:37:57 +0000977 * @access private
978 * @return void
979 */
980 function _cache_init()
admin6871d952006-10-04 00:36:18 +0000981 {
adminc2e3cd72006-10-05 04:22:30 +0000982 if (is_object($this->CACHE) AND class_exists('CI_DB_Cache'))
admindb8a3742006-10-04 07:43:35 +0000983 {
admin0c405652006-10-04 18:37:57 +0000984 return TRUE;
admindb8a3742006-10-04 07:43:35 +0000985 }
986
adminfa708172006-10-04 18:42:42 +0000987 if ( ! @include_once(BASEPATH.'database/DB_cache'.EXT))
admin6871d952006-10-04 00:36:18 +0000988 {
adminfa708172006-10-04 18:42:42 +0000989 return $this->cache_off();
admin6871d952006-10-04 00:36:18 +0000990 }
991
adminc2e3cd72006-10-05 04:22:30 +0000992 $this->CACHE = new CI_DB_Cache;
admin6871d952006-10-04 00:36:18 +0000993 return TRUE;
994 }
995
admindb8a3742006-10-04 07:43:35 +0000996
997 // --------------------------------------------------------------------
998
999 /**
admin7b613c72006-09-24 18:05:17 +00001000 * Close DB Connection
1001 *
1002 * @access public
1003 * @return void
1004 */
admin6871d952006-10-04 00:36:18 +00001005 function close()
1006 {
1007 if (is_resource($this->conn_id))
1008 {
1009 $this->_close($this->conn_id);
admin7b613c72006-09-24 18:05:17 +00001010 }
1011 $this->conn_id = FALSE;
admin6871d952006-10-04 00:36:18 +00001012 }
admin7b613c72006-09-24 18:05:17 +00001013
1014 // --------------------------------------------------------------------
1015
1016 /**
1017 * Display an error message
1018 *
1019 * @access public
1020 * @param string the error message
1021 * @param string any "swap" values
1022 * @param boolean whether to localize the message
1023 * @return string sends the application/errror_db.php template
1024 */
admin6871d952006-10-04 00:36:18 +00001025 function display_error($error = '', $swap = '', $native = FALSE)
1026 {
admin7b613c72006-09-24 18:05:17 +00001027 $LANG = new CI_Language();
1028 $LANG->load('db');
1029
1030 $heading = 'MySQL Error';
1031
1032 if ($native == TRUE)
1033 {
1034 $message = $error;
1035 }
1036 else
1037 {
1038 $message = ( ! is_array($error)) ? array(str_replace('%s', $swap, $LANG->line($error))) : $error;
1039 }
1040
1041 if ( ! class_exists('CI_Exceptions'))
1042 {
1043 include_once(BASEPATH.'libraries/Exceptions'.EXT);
1044 }
1045
1046 $error = new CI_Exceptions();
1047 echo $error->show_error('An Error Was Encountered', $message, 'error_db');
1048 exit;
1049
admin6871d952006-10-04 00:36:18 +00001050 }
admin7b613c72006-09-24 18:05:17 +00001051
1052}
1053
1054?>