1
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
5
* An open source application development framework for PHP 5.1.6 or newer
8
* @author ExpressionEngine Dev Team
9
* @copyright Copyright (c) 2008 - 2011, EllisLab, Inc.
10
* @license http://codeigniter.com/user_guide/license.html
11
* @link http://codeigniter.com
16
// ------------------------------------------------------------------------
21
* This is the platform-independent base Active Record implementation class.
23
* @package CodeIgniter
26
* @author ExpressionEngine Dev Team
27
* @link http://codeigniter.com/user_guide/database/
29
class CI_DB_active_record extends CI_DB_driver {
31
var $ar_select = array();
32
var $ar_distinct = FALSE;
33
var $ar_from = array();
34
var $ar_join = array();
35
var $ar_where = array();
36
var $ar_like = array();
37
var $ar_groupby = array();
38
var $ar_having = array();
39
var $ar_keys = array();
40
var $ar_limit = FALSE;
41
var $ar_offset = FALSE;
42
var $ar_order = FALSE;
43
var $ar_orderby = array();
44
var $ar_set = array();
45
var $ar_wherein = array();
46
var $ar_aliased_tables = array();
47
var $ar_store_array = array();
49
// Active Record Caching variables
50
var $ar_caching = FALSE;
51
var $ar_cache_exists = array();
52
var $ar_cache_select = array();
53
var $ar_cache_from = array();
54
var $ar_cache_join = array();
55
var $ar_cache_where = array();
56
var $ar_cache_like = array();
57
var $ar_cache_groupby = array();
58
var $ar_cache_having = array();
59
var $ar_cache_orderby = array();
60
var $ar_cache_set = array();
62
var $ar_no_escape = array();
63
var $ar_cache_no_escape = array();
65
// --------------------------------------------------------------------
70
* Generates the SELECT portion of the query
75
public function select($select = '*', $escape = NULL)
77
if (is_string($select))
79
$select = explode(',', $select);
82
foreach ($select as $val)
88
$this->ar_select[] = $val;
89
$this->ar_no_escape[] = $escape;
91
if ($this->ar_caching === TRUE)
93
$this->ar_cache_select[] = $val;
94
$this->ar_cache_exists[] = 'select';
95
$this->ar_cache_no_escape[] = $escape;
102
// --------------------------------------------------------------------
107
* Generates a SELECT MAX(field) portion of a query
109
* @param string the field
110
* @param string an alias
113
public function select_max($select = '', $alias = '')
115
return $this->_max_min_avg_sum($select, $alias, 'MAX');
118
// --------------------------------------------------------------------
123
* Generates a SELECT MIN(field) portion of a query
125
* @param string the field
126
* @param string an alias
129
public function select_min($select = '', $alias = '')
131
return $this->_max_min_avg_sum($select, $alias, 'MIN');
134
// --------------------------------------------------------------------
139
* Generates a SELECT AVG(field) portion of a query
141
* @param string the field
142
* @param string an alias
145
public function select_avg($select = '', $alias = '')
147
return $this->_max_min_avg_sum($select, $alias, 'AVG');
150
// --------------------------------------------------------------------
155
* Generates a SELECT SUM(field) portion of a query
157
* @param string the field
158
* @param string an alias
161
public function select_sum($select = '', $alias = '')
163
return $this->_max_min_avg_sum($select, $alias, 'SUM');
166
// --------------------------------------------------------------------
169
* Processing Function for the four functions above:
176
* @param string the field
177
* @param string an alias
180
protected function _max_min_avg_sum($select = '', $alias = '', $type = 'MAX')
182
if ( ! is_string($select) OR $select == '')
184
$this->display_error('db_invalid_query');
187
$type = strtoupper($type);
189
if ( ! in_array($type, array('MAX', 'MIN', 'AVG', 'SUM')))
191
show_error('Invalid function type: '.$type);
196
$alias = $this->_create_alias_from_table(trim($select));
199
$sql = $type.'('.$this->_protect_identifiers(trim($select)).') AS '.$alias;
201
$this->ar_select[] = $sql;
203
if ($this->ar_caching === TRUE)
205
$this->ar_cache_select[] = $sql;
206
$this->ar_cache_exists[] = 'select';
212
// --------------------------------------------------------------------
215
* Determines the alias name based on the table
220
protected function _create_alias_from_table($item)
222
if (strpos($item, '.') !== FALSE)
224
return end(explode('.', $item));
230
// --------------------------------------------------------------------
235
* Sets a flag which tells the query string compiler to add DISTINCT
240
public function distinct($val = TRUE)
242
$this->ar_distinct = (is_bool($val)) ? $val : TRUE;
246
// --------------------------------------------------------------------
251
* Generates the FROM portion of the query
253
* @param mixed can be a string or array
256
public function from($from)
258
foreach ((array) $from as $val)
260
if (strpos($val, ',') !== FALSE)
262
foreach (explode(',', $val) as $v)
265
$this->_track_aliases($v);
267
$this->ar_from[] = $this->_protect_identifiers($v, TRUE, NULL, FALSE);
269
if ($this->ar_caching === TRUE)
271
$this->ar_cache_from[] = $this->_protect_identifiers($v, TRUE, NULL, FALSE);
272
$this->ar_cache_exists[] = 'from';
281
// Extract any aliases that might exist. We use this information
282
// in the _protect_identifiers to know whether to add a table prefix
283
$this->_track_aliases($val);
285
$this->ar_from[] = $this->_protect_identifiers($val, TRUE, NULL, FALSE);
287
if ($this->ar_caching === TRUE)
289
$this->ar_cache_from[] = $this->_protect_identifiers($val, TRUE, NULL, FALSE);
290
$this->ar_cache_exists[] = 'from';
298
// --------------------------------------------------------------------
303
* Generates the JOIN portion of the query
306
* @param string the join condition
307
* @param string the type of join
310
public function join($table, $cond, $type = '')
314
$type = strtoupper(trim($type));
316
if ( ! in_array($type, array('LEFT', 'RIGHT', 'OUTER', 'INNER', 'LEFT OUTER', 'RIGHT OUTER')))
326
// Extract any aliases that might exist. We use this information
327
// in the _protect_identifiers to know whether to add a table prefix
328
$this->_track_aliases($table);
330
// Strip apart the condition and protect the identifiers
331
if (preg_match('/([\w\.]+)([\W\s]+)(.+)/', $cond, $match))
333
$match[1] = $this->_protect_identifiers($match[1]);
334
$match[3] = $this->_protect_identifiers($match[3]);
336
$cond = $match[1].$match[2].$match[3];
339
// Assemble the JOIN statement
340
$join = $type.'JOIN '.$this->_protect_identifiers($table, TRUE, NULL, FALSE).' ON '.$cond;
342
$this->ar_join[] = $join;
343
if ($this->ar_caching === TRUE)
345
$this->ar_cache_join[] = $join;
346
$this->ar_cache_exists[] = 'join';
352
// --------------------------------------------------------------------
357
* Generates the WHERE portion of the query. Separates
358
* multiple calls with AND
364
public function where($key, $value = NULL, $escape = TRUE)
366
return $this->_where($key, $value, 'AND ', $escape);
369
// --------------------------------------------------------------------
374
* Generates the WHERE portion of the query. Separates
375
* multiple calls with OR
381
public function or_where($key, $value = NULL, $escape = TRUE)
383
return $this->_where($key, $value, 'OR ', $escape);
386
// --------------------------------------------------------------------
391
* Called by where() or or_where()
398
protected function _where($key, $value = NULL, $type = 'AND ', $escape = NULL)
400
if ( ! is_array($key))
402
$key = array($key => $value);
405
// If the escape value was not set will will base it on the global setting
406
if ( ! is_bool($escape))
408
$escape = $this->_protect_identifiers;
411
foreach ($key as $k => $v)
413
$prefix = (count($this->ar_where) == 0 AND count($this->ar_cache_where) == 0) ? '' : $type;
415
if (is_null($v) && ! $this->_has_operator($k))
417
// value appears not to have been set, assign the test to IS NULL
423
if ($escape === TRUE)
425
$k = $this->_protect_identifiers($k, FALSE, $escape);
427
$v = ' '.$this->escape($v);
430
if ( ! $this->_has_operator($k))
437
$k = $this->_protect_identifiers($k, FALSE, $escape);
440
$this->ar_where[] = $prefix.$k.$v;
442
if ($this->ar_caching === TRUE)
444
$this->ar_cache_where[] = $prefix.$k.$v;
445
$this->ar_cache_exists[] = 'where';
453
// --------------------------------------------------------------------
458
* Generates a WHERE field IN ('item', 'item') SQL query joined with
461
* @param string The field to search
462
* @param array The values searched on
465
public function where_in($key = NULL, $values = NULL)
467
return $this->_where_in($key, $values);
470
// --------------------------------------------------------------------
475
* Generates a WHERE field IN ('item', 'item') SQL query joined with
478
* @param string The field to search
479
* @param array The values searched on
482
public function or_where_in($key = NULL, $values = NULL)
484
return $this->_where_in($key, $values, FALSE, 'OR ');
487
// --------------------------------------------------------------------
492
* Generates a WHERE field NOT IN ('item', 'item') SQL query joined
493
* with AND if appropriate
495
* @param string The field to search
496
* @param array The values searched on
499
public function where_not_in($key = NULL, $values = NULL)
501
return $this->_where_in($key, $values, TRUE);
504
// --------------------------------------------------------------------
509
* Generates a WHERE field NOT IN ('item', 'item') SQL query joined
510
* with OR if appropriate
512
* @param string The field to search
513
* @param array The values searched on
516
public function or_where_not_in($key = NULL, $values = NULL)
518
return $this->_where_in($key, $values, TRUE, 'OR ');
521
// --------------------------------------------------------------------
526
* Called by where_in, where_in_or, where_not_in, where_not_in_or
528
* @param string The field to search
529
* @param array The values searched on
530
* @param boolean If the statement would be IN or NOT IN
534
protected function _where_in($key = NULL, $values = NULL, $not = FALSE, $type = 'AND ')
536
if ($key === NULL OR $values === NULL)
541
if ( ! is_array($values))
543
$values = array($values);
546
$not = ($not) ? ' NOT' : '';
548
foreach ($values as $value)
550
$this->ar_wherein[] = $this->escape($value);
553
$prefix = (count($this->ar_where) == 0) ? '' : $type;
555
$where_in = $prefix . $this->_protect_identifiers($key) . $not . " IN (" . implode(", ", $this->ar_wherein) . ") ";
557
$this->ar_where[] = $where_in;
558
if ($this->ar_caching === TRUE)
560
$this->ar_cache_where[] = $where_in;
561
$this->ar_cache_exists[] = 'where';
564
// reset the array for multiple calls
565
$this->ar_wherein = array();
569
// --------------------------------------------------------------------
574
* Generates a %LIKE% portion of the query. Separates
575
* multiple calls with AND
581
public function like($field, $match = '', $side = 'both')
583
return $this->_like($field, $match, 'AND ', $side);
586
// --------------------------------------------------------------------
591
* Generates a NOT LIKE portion of the query. Separates
592
* multiple calls with AND
598
public function not_like($field, $match = '', $side = 'both')
600
return $this->_like($field, $match, 'AND ', $side, 'NOT');
603
// --------------------------------------------------------------------
608
* Generates a %LIKE% portion of the query. Separates
609
* multiple calls with OR
615
public function or_like($field, $match = '', $side = 'both')
617
return $this->_like($field, $match, 'OR ', $side);
620
// --------------------------------------------------------------------
625
* Generates a NOT LIKE portion of the query. Separates
626
* multiple calls with OR
632
public function or_not_like($field, $match = '', $side = 'both')
634
return $this->_like($field, $match, 'OR ', $side, 'NOT');
637
// --------------------------------------------------------------------
642
* Called by like() or orlike()
649
protected function _like($field, $match = '', $type = 'AND ', $side = 'both', $not = '')
651
if ( ! is_array($field))
653
$field = array($field => $match);
656
foreach ($field as $k => $v)
658
$k = $this->_protect_identifiers($k);
660
$prefix = (count($this->ar_like) == 0) ? '' : $type;
662
$v = $this->escape_like_str($v);
666
$like_statement = $prefix." $k $not LIKE '{$v}'";
668
elseif ($side == 'before')
670
$like_statement = $prefix." $k $not LIKE '%{$v}'";
672
elseif ($side == 'after')
674
$like_statement = $prefix." $k $not LIKE '{$v}%'";
678
$like_statement = $prefix." $k $not LIKE '%{$v}%'";
681
// some platforms require an escape sequence definition for LIKE wildcards
682
if ($this->_like_escape_str != '')
684
$like_statement = $like_statement.sprintf($this->_like_escape_str, $this->_like_escape_chr);
687
$this->ar_like[] = $like_statement;
688
if ($this->ar_caching === TRUE)
690
$this->ar_cache_like[] = $like_statement;
691
$this->ar_cache_exists[] = 'like';
698
// --------------------------------------------------------------------
706
public function group_by($by)
710
$by = explode(',', $by);
713
foreach ($by as $val)
719
$this->ar_groupby[] = $this->_protect_identifiers($val);
721
if ($this->ar_caching === TRUE)
723
$this->ar_cache_groupby[] = $this->_protect_identifiers($val);
724
$this->ar_cache_exists[] = 'groupby';
731
// --------------------------------------------------------------------
734
* Sets the HAVING value
736
* Separates multiple calls with AND
742
public function having($key, $value = '', $escape = TRUE)
744
return $this->_having($key, $value, 'AND ', $escape);
747
// --------------------------------------------------------------------
750
* Sets the OR HAVING value
752
* Separates multiple calls with OR
758
public function or_having($key, $value = '', $escape = TRUE)
760
return $this->_having($key, $value, 'OR ', $escape);
763
// --------------------------------------------------------------------
766
* Sets the HAVING values
768
* Called by having() or or_having()
774
protected function _having($key, $value = '', $type = 'AND ', $escape = TRUE)
776
if ( ! is_array($key))
778
$key = array($key => $value);
781
foreach ($key as $k => $v)
783
$prefix = (count($this->ar_having) == 0) ? '' : $type;
785
if ($escape === TRUE)
787
$k = $this->_protect_identifiers($k);
790
if ( ! $this->_has_operator($k))
797
$v = ' '.$this->escape($v);
800
$this->ar_having[] = $prefix.$k.$v;
801
if ($this->ar_caching === TRUE)
803
$this->ar_cache_having[] = $prefix.$k.$v;
804
$this->ar_cache_exists[] = 'having';
811
// --------------------------------------------------------------------
814
* Sets the ORDER BY value
817
* @param string direction: asc or desc
820
public function order_by($orderby, $direction = '')
822
if (strtolower($direction) == 'random')
824
$orderby = ''; // Random results want or don't need a field name
825
$direction = $this->_random_keyword;
827
elseif (trim($direction) != '')
829
$direction = (in_array(strtoupper(trim($direction)), array('ASC', 'DESC'), TRUE)) ? ' '.$direction : ' ASC';
833
if (strpos($orderby, ',') !== FALSE)
836
foreach (explode(',', $orderby) as $part)
839
if ( ! in_array($part, $this->ar_aliased_tables))
841
$part = $this->_protect_identifiers(trim($part));
847
$orderby = implode(', ', $temp);
849
else if ($direction != $this->_random_keyword)
851
$orderby = $this->_protect_identifiers($orderby);
854
$orderby_statement = $orderby.$direction;
856
$this->ar_orderby[] = $orderby_statement;
857
if ($this->ar_caching === TRUE)
859
$this->ar_cache_orderby[] = $orderby_statement;
860
$this->ar_cache_exists[] = 'orderby';
866
// --------------------------------------------------------------------
869
* Sets the LIMIT value
871
* @param integer the limit value
872
* @param integer the offset value
875
public function limit($value, $offset = '')
877
$this->ar_limit = (int) $value;
881
$this->ar_offset = (int) $offset;
887
// --------------------------------------------------------------------
890
* Sets the OFFSET value
892
* @param integer the offset value
895
public function offset($offset)
897
$this->ar_offset = $offset;
901
// --------------------------------------------------------------------
904
* The "set" function. Allows key/value pairs to be set for inserting or updating
911
public function set($key, $value = '', $escape = TRUE)
913
$key = $this->_object_to_array($key);
915
if ( ! is_array($key))
917
$key = array($key => $value);
920
foreach ($key as $k => $v)
922
if ($escape === FALSE)
924
$this->ar_set[$this->_protect_identifiers($k)] = $v;
928
$this->ar_set[$this->_protect_identifiers($k, FALSE, TRUE)] = $this->escape($v);
935
// --------------------------------------------------------------------
940
* Compiles the select statement based on the other functions called
943
* @param string the table
944
* @param string the limit clause
945
* @param string the offset clause
948
public function get($table = '', $limit = null, $offset = null)
952
$this->_track_aliases($table);
956
if ( ! is_null($limit))
958
$this->limit($limit, $offset);
961
$sql = $this->_compile_select();
963
$result = $this->query($sql);
964
$this->_reset_select();
969
* "Count All Results" query
971
* Generates a platform-specific query string that counts all records
972
* returned by an Active Record query.
977
public function count_all_results($table = '')
981
$this->_track_aliases($table);
985
$sql = $this->_compile_select($this->_count_string . $this->_protect_identifiers('numrows'));
987
$query = $this->query($sql);
988
$this->_reset_select();
990
if ($query->num_rows() == 0)
995
$row = $query->row();
996
return (int) $row->numrows;
999
// --------------------------------------------------------------------
1004
* Allows the where clause, limit and offset to be added directly
1006
* @param string the where clause
1007
* @param string the limit clause
1008
* @param string the offset clause
1011
public function get_where($table = '', $where = null, $limit = null, $offset = null)
1015
$this->from($table);
1018
if ( ! is_null($where))
1020
$this->where($where);
1023
if ( ! is_null($limit))
1025
$this->limit($limit, $offset);
1028
$sql = $this->_compile_select();
1030
$result = $this->query($sql);
1031
$this->_reset_select();
1035
// --------------------------------------------------------------------
1040
* Compiles batch insert strings and runs the queries
1042
* @param string the table to retrieve the results from
1043
* @param array an associative array of insert values
1046
public function insert_batch($table = '', $set = NULL)
1048
if ( ! is_null($set))
1050
$this->set_insert_batch($set);
1053
if (count($this->ar_set) == 0)
1055
if ($this->db_debug)
1057
//No valid data array. Folds in cases where keys and values did not match up
1058
return $this->display_error('db_must_use_set');
1065
if ( ! isset($this->ar_from[0]))
1067
if ($this->db_debug)
1069
return $this->display_error('db_must_set_table');
1074
$table = $this->ar_from[0];
1078
for ($i = 0, $total = count($this->ar_set); $i < $total; $i = $i + 100)
1081
$sql = $this->_insert_batch($this->_protect_identifiers($table, TRUE, NULL, FALSE), $this->ar_keys, array_slice($this->ar_set, $i, 100));
1088
$this->_reset_write();
1094
// --------------------------------------------------------------------
1097
* The "set_insert_batch" function. Allows key/value pairs to be set for batch inserts
1104
public function set_insert_batch($key, $value = '', $escape = TRUE)
1106
$key = $this->_object_to_array_batch($key);
1108
if ( ! is_array($key))
1110
$key = array($key => $value);
1113
$keys = array_keys(current($key));
1116
foreach ($key as $row)
1118
if (count(array_diff($keys, array_keys($row))) > 0 OR count(array_diff(array_keys($row), $keys)) > 0)
1120
// batch function above returns an error on an empty array
1121
$this->ar_set[] = array();
1125
ksort($row); // puts $row in the same order as our keys
1127
if ($escape === FALSE)
1129
$this->ar_set[] = '('.implode(',', $row).')';
1135
foreach ($row as $value)
1137
$clean[] = $this->escape($value);
1140
$this->ar_set[] = '('.implode(',', $clean).')';
1144
foreach ($keys as $k)
1146
$this->ar_keys[] = $this->_protect_identifiers($k);
1152
// --------------------------------------------------------------------
1157
* Compiles an insert string and runs the query
1159
* @param string the table to insert data into
1160
* @param array an associative array of insert values
1163
function insert($table = '', $set = NULL)
1165
if ( ! is_null($set))
1170
if (count($this->ar_set) == 0)
1172
if ($this->db_debug)
1174
return $this->display_error('db_must_use_set');
1181
if ( ! isset($this->ar_from[0]))
1183
if ($this->db_debug)
1185
return $this->display_error('db_must_set_table');
1190
$table = $this->ar_from[0];
1193
$sql = $this->_insert($this->_protect_identifiers($table, TRUE, NULL, FALSE), array_keys($this->ar_set), array_values($this->ar_set));
1195
$this->_reset_write();
1196
return $this->query($sql);
1199
// --------------------------------------------------------------------
1204
* Compiles an replace into string and runs the query
1206
* @param string the table to replace data into
1207
* @param array an associative array of insert values
1210
public function replace($table = '', $set = NULL)
1212
if ( ! is_null($set))
1217
if (count($this->ar_set) == 0)
1219
if ($this->db_debug)
1221
return $this->display_error('db_must_use_set');
1228
if ( ! isset($this->ar_from[0]))
1230
if ($this->db_debug)
1232
return $this->display_error('db_must_set_table');
1237
$table = $this->ar_from[0];
1240
$sql = $this->_replace($this->_protect_identifiers($table, TRUE, NULL, FALSE), array_keys($this->ar_set), array_values($this->ar_set));
1242
$this->_reset_write();
1243
return $this->query($sql);
1246
// --------------------------------------------------------------------
1251
* Compiles an update string and runs the query
1253
* @param string the table to retrieve the results from
1254
* @param array an associative array of update values
1255
* @param mixed the where clause
1258
public function update($table = '', $set = NULL, $where = NULL, $limit = NULL)
1260
// Combine any cached components with the current statements
1261
$this->_merge_cache();
1263
if ( ! is_null($set))
1268
if (count($this->ar_set) == 0)
1270
if ($this->db_debug)
1272
return $this->display_error('db_must_use_set');
1279
if ( ! isset($this->ar_from[0]))
1281
if ($this->db_debug)
1283
return $this->display_error('db_must_set_table');
1288
$table = $this->ar_from[0];
1293
$this->where($where);
1298
$this->limit($limit);
1301
$sql = $this->_update($this->_protect_identifiers($table, TRUE, NULL, FALSE), $this->ar_set, $this->ar_where, $this->ar_orderby, $this->ar_limit);
1303
$this->_reset_write();
1304
return $this->query($sql);
1308
// --------------------------------------------------------------------
1313
* Compiles an update string and runs the query
1315
* @param string the table to retrieve the results from
1316
* @param array an associative array of update values
1317
* @param string the where key
1320
public function update_batch($table = '', $set = NULL, $index = NULL)
1322
// Combine any cached components with the current statements
1323
$this->_merge_cache();
1325
if (is_null($index))
1327
if ($this->db_debug)
1329
return $this->display_error('db_must_use_index');
1335
if ( ! is_null($set))
1337
$this->set_update_batch($set, $index);
1340
if (count($this->ar_set) == 0)
1342
if ($this->db_debug)
1344
return $this->display_error('db_must_use_set');
1352
if ( ! isset($this->ar_from[0]))
1354
if ($this->db_debug)
1356
return $this->display_error('db_must_set_table');
1361
$table = $this->ar_from[0];
1365
for ($i = 0, $total = count($this->ar_set); $i < $total; $i = $i + 100)
1367
$sql = $this->_update_batch($this->_protect_identifiers($table, TRUE, NULL, FALSE), array_slice($this->ar_set, $i, 100), $this->_protect_identifiers($index), $this->ar_where);
1372
$this->_reset_write();
1375
// --------------------------------------------------------------------
1378
* The "set_update_batch" function. Allows key/value pairs to be set for batch updating
1385
public function set_update_batch($key, $index = '', $escape = TRUE)
1387
$key = $this->_object_to_array_batch($key);
1389
if ( ! is_array($key))
1394
foreach ($key as $k => $v)
1399
foreach ($v as $k2 => $v2)
1410
if ($escape === FALSE)
1412
$clean[$this->_protect_identifiers($k2)] = $v2;
1416
$clean[$this->_protect_identifiers($k2)] = $this->escape($v2);
1420
if ($index_set == FALSE)
1422
return $this->display_error('db_batch_missing_index');
1425
$this->ar_set[] = $clean;
1431
// --------------------------------------------------------------------
1436
* Compiles a delete string and runs "DELETE FROM table"
1438
* @param string the table to empty
1441
public function empty_table($table = '')
1445
if ( ! isset($this->ar_from[0]))
1447
if ($this->db_debug)
1449
return $this->display_error('db_must_set_table');
1454
$table = $this->ar_from[0];
1458
$table = $this->_protect_identifiers($table, TRUE, NULL, FALSE);
1461
$sql = $this->_delete($table);
1463
$this->_reset_write();
1465
return $this->query($sql);
1468
// --------------------------------------------------------------------
1473
* Compiles a truncate string and runs the query
1474
* If the database does not support the truncate() command
1475
* This function maps to "DELETE FROM table"
1477
* @param string the table to truncate
1480
public function truncate($table = '')
1484
if ( ! isset($this->ar_from[0]))
1486
if ($this->db_debug)
1488
return $this->display_error('db_must_set_table');
1493
$table = $this->ar_from[0];
1497
$table = $this->_protect_identifiers($table, TRUE, NULL, FALSE);
1500
$sql = $this->_truncate($table);
1502
$this->_reset_write();
1504
return $this->query($sql);
1507
// --------------------------------------------------------------------
1512
* Compiles a delete string and runs the query
1514
* @param mixed the table(s) to delete from. String or array
1515
* @param mixed the where clause
1516
* @param mixed the limit clause
1520
public function delete($table = '', $where = '', $limit = NULL, $reset_data = TRUE)
1522
// Combine any cached components with the current statements
1523
$this->_merge_cache();
1527
if ( ! isset($this->ar_from[0]))
1529
if ($this->db_debug)
1531
return $this->display_error('db_must_set_table');
1536
$table = $this->ar_from[0];
1538
elseif (is_array($table))
1540
foreach ($table as $single_table)
1542
$this->delete($single_table, $where, $limit, FALSE);
1545
$this->_reset_write();
1550
$table = $this->_protect_identifiers($table, TRUE, NULL, FALSE);
1555
$this->where($where);
1560
$this->limit($limit);
1563
if (count($this->ar_where) == 0 && count($this->ar_wherein) == 0 && count($this->ar_like) == 0)
1565
if ($this->db_debug)
1567
return $this->display_error('db_del_must_use_where');
1573
$sql = $this->_delete($table, $this->ar_where, $this->ar_like, $this->ar_limit);
1577
$this->_reset_write();
1580
return $this->query($sql);
1583
// --------------------------------------------------------------------
1588
* Prepends a database prefix if one exists in configuration
1590
* @param string the table
1593
public function dbprefix($table = '')
1597
$this->display_error('db_table_name_required');
1600
return $this->dbprefix.$table;
1603
// --------------------------------------------------------------------
1608
* Set's the DB Prefix to something new without needing to reconnect
1610
* @param string the prefix
1613
public function set_dbprefix($prefix = '')
1615
return $this->dbprefix = $prefix;
1618
// --------------------------------------------------------------------
1623
* Used to track SQL statements written with aliased tables.
1625
* @param string The table to inspect
1628
protected function _track_aliases($table)
1630
if (is_array($table))
1632
foreach ($table as $t)
1634
$this->_track_aliases($t);
1639
// Does the string contain a comma? If so, we need to separate
1640
// the string into discreet statements
1641
if (strpos($table, ',') !== FALSE)
1643
return $this->_track_aliases(explode(',', $table));
1646
// if a table alias is used we can recognize it by a space
1647
if (strpos($table, " ") !== FALSE)
1649
// if the alias is written with the AS keyword, remove it
1650
$table = preg_replace('/\s+AS\s+/i', ' ', $table);
1653
$table = trim(strrchr($table, " "));
1655
// Store the alias, if it doesn't already exist
1656
if ( ! in_array($table, $this->ar_aliased_tables))
1658
$this->ar_aliased_tables[] = $table;
1663
// --------------------------------------------------------------------
1666
* Compile the SELECT statement
1668
* Generates a query string based on which functions were used.
1669
* Should not be called directly. The get() function calls it.
1673
protected function _compile_select($select_override = FALSE)
1675
// Combine any cached components with the current statements
1676
$this->_merge_cache();
1678
// ----------------------------------------------------------------
1680
// Write the "select" portion of the query
1682
if ($select_override !== FALSE)
1684
$sql = $select_override;
1688
$sql = ( ! $this->ar_distinct) ? 'SELECT ' : 'SELECT DISTINCT ';
1690
if (count($this->ar_select) == 0)
1696
// Cycle through the "select" portion of the query and prep each column name.
1697
// The reason we protect identifiers here rather then in the select() function
1698
// is because until the user calls the from() function we don't know if there are aliases
1699
foreach ($this->ar_select as $key => $val)
1701
$no_escape = isset($this->ar_no_escape[$key]) ? $this->ar_no_escape[$key] : NULL;
1702
$this->ar_select[$key] = $this->_protect_identifiers($val, FALSE, $no_escape);
1705
$sql .= implode(', ', $this->ar_select);
1709
// ----------------------------------------------------------------
1711
// Write the "FROM" portion of the query
1713
if (count($this->ar_from) > 0)
1717
$sql .= $this->_from_tables($this->ar_from);
1720
// ----------------------------------------------------------------
1722
// Write the "JOIN" portion of the query
1724
if (count($this->ar_join) > 0)
1728
$sql .= implode("\n", $this->ar_join);
1731
// ----------------------------------------------------------------
1733
// Write the "WHERE" portion of the query
1735
if (count($this->ar_where) > 0 OR count($this->ar_like) > 0)
1740
$sql .= implode("\n", $this->ar_where);
1742
// ----------------------------------------------------------------
1744
// Write the "LIKE" portion of the query
1746
if (count($this->ar_like) > 0)
1748
if (count($this->ar_where) > 0)
1753
$sql .= implode("\n", $this->ar_like);
1756
// ----------------------------------------------------------------
1758
// Write the "GROUP BY" portion of the query
1760
if (count($this->ar_groupby) > 0)
1762
$sql .= "\nGROUP BY ";
1764
$sql .= implode(', ', $this->ar_groupby);
1767
// ----------------------------------------------------------------
1769
// Write the "HAVING" portion of the query
1771
if (count($this->ar_having) > 0)
1773
$sql .= "\nHAVING ";
1774
$sql .= implode("\n", $this->ar_having);
1777
// ----------------------------------------------------------------
1779
// Write the "ORDER BY" portion of the query
1781
if (count($this->ar_orderby) > 0)
1783
$sql .= "\nORDER BY ";
1784
$sql .= implode(', ', $this->ar_orderby);
1786
if ($this->ar_order !== FALSE)
1788
$sql .= ($this->ar_order == 'desc') ? ' DESC' : ' ASC';
1792
// ----------------------------------------------------------------
1794
// Write the "LIMIT" portion of the query
1796
if (is_numeric($this->ar_limit))
1799
$sql = $this->_limit($sql, $this->ar_limit, $this->ar_offset);
1805
// --------------------------------------------------------------------
1810
* Takes an object as input and converts the class variables to array key/vals
1815
public function _object_to_array($object)
1817
if ( ! is_object($object))
1823
foreach (get_object_vars($object) as $key => $val)
1825
// There are some built in keys we need to ignore for this conversion
1826
if ( ! is_object($val) && ! is_array($val) && $key != '_parent_name')
1828
$array[$key] = $val;
1835
// --------------------------------------------------------------------
1840
* Takes an object as input and converts the class variables to array key/vals
1845
public function _object_to_array_batch($object)
1847
if ( ! is_object($object))
1853
$out = get_object_vars($object);
1854
$fields = array_keys($out);
1856
foreach ($fields as $val)
1858
// There are some built in keys we need to ignore for this conversion
1859
if ($val != '_parent_name')
1863
foreach ($out[$val] as $data)
1865
$array[$i][$val] = $data;
1874
// --------------------------------------------------------------------
1883
public function start_cache()
1885
$this->ar_caching = TRUE;
1888
// --------------------------------------------------------------------
1897
public function stop_cache()
1899
$this->ar_caching = FALSE;
1902
// --------------------------------------------------------------------
1907
* Empties the AR cache
1912
public function flush_cache()
1914
$this->_reset_run(array(
1915
'ar_cache_select' => array(),
1916
'ar_cache_from' => array(),
1917
'ar_cache_join' => array(),
1918
'ar_cache_where' => array(),
1919
'ar_cache_like' => array(),
1920
'ar_cache_groupby' => array(),
1921
'ar_cache_having' => array(),
1922
'ar_cache_orderby' => array(),
1923
'ar_cache_set' => array(),
1924
'ar_cache_exists' => array(),
1925
'ar_cache_no_escape' => array()
1929
// --------------------------------------------------------------------
1934
* When called, this function merges any cached AR arrays with
1935
* locally called ones.
1939
protected function _merge_cache()
1941
if (count($this->ar_cache_exists) == 0)
1946
foreach ($this->ar_cache_exists as $val)
1948
$ar_variable = 'ar_'.$val;
1949
$ar_cache_var = 'ar_cache_'.$val;
1951
if (count($this->$ar_cache_var) == 0)
1956
$this->$ar_variable = array_unique(array_merge($this->$ar_cache_var, $this->$ar_variable));
1959
// If we are "protecting identifiers" we need to examine the "from"
1960
// portion of the query to determine if there are any aliases
1961
if ($this->_protect_identifiers === TRUE AND count($this->ar_cache_from) > 0)
1963
$this->_track_aliases($this->ar_from);
1966
$this->ar_no_escape = $this->ar_cache_no_escape;
1969
// --------------------------------------------------------------------
1972
* Resets the active record values. Called by the get() function
1974
* @param array An array of fields to reset
1977
protected function _reset_run($ar_reset_items)
1979
foreach ($ar_reset_items as $item => $default_value)
1981
if ( ! in_array($item, $this->ar_store_array))
1983
$this->$item = $default_value;
1988
// --------------------------------------------------------------------
1991
* Resets the active record values. Called by the get() function
1995
protected function _reset_select()
1997
$ar_reset_items = array(
1998
'ar_select' => array(),
1999
'ar_from' => array(),
2000
'ar_join' => array(),
2001
'ar_where' => array(),
2002
'ar_like' => array(),
2003
'ar_groupby' => array(),
2004
'ar_having' => array(),
2005
'ar_orderby' => array(),
2006
'ar_wherein' => array(),
2007
'ar_aliased_tables' => array(),
2008
'ar_no_escape' => array(),
2009
'ar_distinct' => FALSE,
2010
'ar_limit' => FALSE,
2011
'ar_offset' => FALSE,
2012
'ar_order' => FALSE,
2015
$this->_reset_run($ar_reset_items);
2018
// --------------------------------------------------------------------
2021
* Resets the active record "write" values.
2023
* Called by the insert() update() insert_batch() update_batch() and delete() functions
2027
protected function _reset_write()
2029
$ar_reset_items = array(
2030
'ar_set' => array(),
2031
'ar_from' => array(),
2032
'ar_where' => array(),
2033
'ar_like' => array(),
2034
'ar_orderby' => array(),
2035
'ar_keys' => array(),
2036
'ar_limit' => FALSE,
2040
$this->_reset_run($ar_reset_items);
2044
/* End of file DB_active_rec.php */
2045
/* Location: ./system/database/DB_active_rec.php */
b'\\ No newline at end of file'