blob: 953cc954840e4918b7ed39075d1543870368a31d [file] [log] [blame]
Derek Allard2067d1a2008-11-13 22:59:24 +00001<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
2/**
3 * CodeIgniter
4 *
5 * An open source application development framework for PHP 4.3.2 or newer
6 *
7 * @package CodeIgniter
8 * @author ExpressionEngine Dev Team
Derek Jones7f3719f2010-01-05 13:35:37 +00009 * @copyright Copyright (c) 2008 - 2010, EllisLab, Inc.
Derek Allard2067d1a2008-11-13 22:59:24 +000010 * @license http://codeigniter.com/user_guide/license.html
11 * @link http://codeigniter.com
12 * @since Version 1.0
13 * @filesource
14 */
15
16// ------------------------------------------------------------------------
17
18/**
19 * Active Record Class
20 *
21 * This is the platform-independent base Active Record implementation class.
22 *
23 * @package CodeIgniter
24 * @subpackage Drivers
25 * @category Database
26 * @author ExpressionEngine Dev Team
27 * @link http://codeigniter.com/user_guide/database/
28 */
29class CI_DB_active_record extends CI_DB_driver {
30
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_limit = FALSE;
40 var $ar_offset = FALSE;
41 var $ar_order = FALSE;
42 var $ar_orderby = array();
43 var $ar_set = array();
44 var $ar_wherein = array();
45 var $ar_aliased_tables = array();
46 var $ar_store_array = array();
47
48 // Active Record Caching variables
49 var $ar_caching = FALSE;
50 var $ar_cache_exists = array();
51 var $ar_cache_select = array();
52 var $ar_cache_from = array();
53 var $ar_cache_join = array();
54 var $ar_cache_where = array();
55 var $ar_cache_like = array();
56 var $ar_cache_groupby = array();
57 var $ar_cache_having = array();
58 var $ar_cache_orderby = array();
59 var $ar_cache_set = array();
60
61
62 // --------------------------------------------------------------------
63
64 /**
65 * Select
66 *
67 * Generates the SELECT portion of the query
68 *
69 * @access public
70 * @param string
71 * @return object
72 */
73 function select($select = '*', $escape = NULL)
74 {
75 // Set the global value if this was sepecified
76 if (is_bool($escape))
77 {
78 $this->_protect_identifiers = $escape;
79 }
80
81 if (is_string($select))
82 {
83 $select = explode(',', $select);
84 }
85
86 foreach ($select as $val)
87 {
88 $val = trim($val);
89
90 if ($val != '')
91 {
92 $this->ar_select[] = $val;
93
94 if ($this->ar_caching === TRUE)
95 {
96 $this->ar_cache_select[] = $val;
97 $this->ar_cache_exists[] = 'select';
98 }
99 }
100 }
101 return $this;
102 }
103
104 // --------------------------------------------------------------------
105
106 /**
107 * Select Max
108 *
109 * Generates a SELECT MAX(field) portion of a query
110 *
111 * @access public
112 * @param string the field
113 * @param string an alias
114 * @return object
115 */
116 function select_max($select = '', $alias = '')
117 {
118 return $this->_max_min_avg_sum($select, $alias, 'MAX');
119 }
120
121 // --------------------------------------------------------------------
122
123 /**
124 * Select Min
125 *
126 * Generates a SELECT MIN(field) portion of a query
127 *
128 * @access public
129 * @param string the field
130 * @param string an alias
131 * @return object
132 */
133 function select_min($select = '', $alias = '')
134 {
135 return $this->_max_min_avg_sum($select, $alias, 'MIN');
136 }
137
138 // --------------------------------------------------------------------
139
140 /**
141 * Select Average
142 *
143 * Generates a SELECT AVG(field) portion of a query
144 *
145 * @access public
146 * @param string the field
147 * @param string an alias
148 * @return object
149 */
150 function select_avg($select = '', $alias = '')
151 {
152 return $this->_max_min_avg_sum($select, $alias, 'AVG');
153 }
154
155 // --------------------------------------------------------------------
156
157 /**
158 * Select Sum
159 *
160 * Generates a SELECT SUM(field) portion of a query
161 *
162 * @access public
163 * @param string the field
164 * @param string an alias
165 * @return object
166 */
167 function select_sum($select = '', $alias = '')
168 {
169 return $this->_max_min_avg_sum($select, $alias, 'SUM');
170 }
171
172 // --------------------------------------------------------------------
173
174 /**
175 * Processing Function for the four functions above:
176 *
177 * select_max()
178 * select_min()
179 * select_avg()
180 * select_sum()
181 *
182 * @access public
183 * @param string the field
184 * @param string an alias
185 * @return object
186 */
187 function _max_min_avg_sum($select = '', $alias = '', $type = 'MAX')
188 {
189 if ( ! is_string($select) OR $select == '')
190 {
191 $this->display_error('db_invalid_query');
192 }
193
194 $type = strtoupper($type);
195
196 if ( ! in_array($type, array('MAX', 'MIN', 'AVG', 'SUM')))
197 {
198 show_error('Invalid function type: '.$type);
199 }
200
201 if ($alias == '')
202 {
203 $alias = $this->_create_alias_from_table(trim($select));
204 }
205
206 $sql = $type.'('.$this->_protect_identifiers(trim($select)).') AS '.$alias;
207
208 $this->ar_select[] = $sql;
209
210 if ($this->ar_caching === TRUE)
211 {
212 $this->ar_cache_select[] = $sql;
213 $this->ar_cache_exists[] = 'select';
214 }
215
216 return $this;
217 }
218
219 // --------------------------------------------------------------------
220
221 /**
222 * Determines the alias name based on the table
223 *
224 * @access private
225 * @param string
226 * @return string
227 */
228 function _create_alias_from_table($item)
229 {
230 if (strpos($item, '.') !== FALSE)
231 {
232 return end(explode('.', $item));
233 }
234
235 return $item;
236 }
237
238 // --------------------------------------------------------------------
239
240 /**
241 * DISTINCT
242 *
243 * Sets a flag which tells the query string compiler to add DISTINCT
244 *
245 * @access public
246 * @param bool
247 * @return object
248 */
249 function distinct($val = TRUE)
250 {
251 $this->ar_distinct = (is_bool($val)) ? $val : TRUE;
252 return $this;
253 }
254
255 // --------------------------------------------------------------------
256
257 /**
258 * From
259 *
260 * Generates the FROM portion of the query
261 *
262 * @access public
263 * @param mixed can be a string or array
264 * @return object
265 */
266 function from($from)
267 {
268 foreach ((array)$from as $val)
269 {
270 if (strpos($val, ',') !== FALSE)
271 {
272 foreach (explode(',', $val) as $v)
273 {
274 $v = trim($v);
275 $this->_track_aliases($v);
276
277 $this->ar_from[] = $this->_protect_identifiers($v, TRUE, NULL, FALSE);
278
279 if ($this->ar_caching === TRUE)
280 {
281 $this->ar_cache_from[] = $this->_protect_identifiers($v, TRUE, NULL, FALSE);
282 $this->ar_cache_exists[] = 'from';
283 }
284 }
285
286 }
287 else
288 {
289 $val = trim($val);
290
291 // Extract any aliases that might exist. We use this information
292 // in the _protect_identifiers to know whether to add a table prefix
293 $this->_track_aliases($val);
294
295 $this->ar_from[] = $this->_protect_identifiers($val, TRUE, NULL, FALSE);
296
297 if ($this->ar_caching === TRUE)
298 {
299 $this->ar_cache_from[] = $this->_protect_identifiers($val, TRUE, NULL, FALSE);
300 $this->ar_cache_exists[] = 'from';
301 }
302 }
303 }
304
305 return $this;
306 }
307
308 // --------------------------------------------------------------------
309
310 /**
311 * Join
312 *
313 * Generates the JOIN portion of the query
314 *
315 * @access public
316 * @param string
317 * @param string the join condition
318 * @param string the type of join
319 * @return object
320 */
321 function join($table, $cond, $type = '')
322 {
323 if ($type != '')
324 {
325 $type = strtoupper(trim($type));
326
327 if ( ! in_array($type, array('LEFT', 'RIGHT', 'OUTER', 'INNER', 'LEFT OUTER', 'RIGHT OUTER')))
328 {
329 $type = '';
330 }
331 else
332 {
333 $type .= ' ';
334 }
335 }
336
337 // Extract any aliases that might exist. We use this information
338 // in the _protect_identifiers to know whether to add a table prefix
339 $this->_track_aliases($table);
340
341 // Strip apart the condition and protect the identifiers
342 if (preg_match('/([\w\.]+)([\W\s]+)(.+)/', $cond, $match))
343 {
344 $match[1] = $this->_protect_identifiers($match[1]);
345 $match[3] = $this->_protect_identifiers($match[3]);
346
347 $cond = $match[1].$match[2].$match[3];
348 }
349
350 // Assemble the JOIN statement
351 $join = $type.'JOIN '.$this->_protect_identifiers($table, TRUE, NULL, FALSE).' ON '.$cond;
352
353 $this->ar_join[] = $join;
354 if ($this->ar_caching === TRUE)
355 {
356 $this->ar_cache_join[] = $join;
357 $this->ar_cache_exists[] = 'join';
358 }
359
360 return $this;
361 }
362
363 // --------------------------------------------------------------------
364
365 /**
366 * Where
367 *
368 * Generates the WHERE portion of the query. Separates
369 * multiple calls with AND
370 *
371 * @access public
372 * @param mixed
373 * @param mixed
374 * @return object
375 */
376 function where($key, $value = NULL, $escape = TRUE)
377 {
378 return $this->_where($key, $value, 'AND ', $escape);
379 }
380
381 // --------------------------------------------------------------------
382
383 /**
384 * OR Where
385 *
386 * Generates the WHERE portion of the query. Separates
387 * multiple calls with OR
388 *
389 * @access public
390 * @param mixed
391 * @param mixed
392 * @return object
393 */
394 function or_where($key, $value = NULL, $escape = TRUE)
395 {
396 return $this->_where($key, $value, 'OR ', $escape);
397 }
398
399 // --------------------------------------------------------------------
400
401 /**
Derek Allard2067d1a2008-11-13 22:59:24 +0000402 * Where
403 *
404 * Called by where() or orwhere()
405 *
406 * @access private
407 * @param mixed
408 * @param mixed
409 * @param string
410 * @return object
411 */
412 function _where($key, $value = NULL, $type = 'AND ', $escape = NULL)
413 {
414 if ( ! is_array($key))
415 {
416 $key = array($key => $value);
417 }
418
419 // If the escape value was not set will will base it on the global setting
420 if ( ! is_bool($escape))
421 {
422 $escape = $this->_protect_identifiers;
423 }
424
425 foreach ($key as $k => $v)
426 {
427 $prefix = (count($this->ar_where) == 0 AND count($this->ar_cache_where) == 0) ? '' : $type;
428
429 if (is_null($v) && ! $this->_has_operator($k))
430 {
431 // value appears not to have been set, assign the test to IS NULL
432 $k .= ' IS NULL';
433 }
434
435 if ( ! is_null($v))
436 {
437 if ($escape === TRUE)
438 {
439 $k = $this->_protect_identifiers($k, FALSE, $escape);
440
441 $v = ' '.$this->escape($v);
442 }
443
444 if ( ! $this->_has_operator($k))
445 {
446 $k .= ' =';
447 }
448 }
449 else
450 {
451 $k = $this->_protect_identifiers($k, FALSE, $escape);
452 }
453
454 $this->ar_where[] = $prefix.$k.$v;
455
456 if ($this->ar_caching === TRUE)
457 {
458 $this->ar_cache_where[] = $prefix.$k.$v;
459 $this->ar_cache_exists[] = 'where';
460 }
461
462 }
463
464 return $this;
465 }
466
467 // --------------------------------------------------------------------
468
469 /**
470 * Where_in
471 *
472 * Generates a WHERE field IN ('item', 'item') SQL query joined with
473 * AND if appropriate
474 *
475 * @access public
476 * @param string The field to search
477 * @param array The values searched on
478 * @return object
479 */
480 function where_in($key = NULL, $values = NULL)
481 {
482 return $this->_where_in($key, $values);
483 }
484
485 // --------------------------------------------------------------------
486
487 /**
488 * Where_in_or
489 *
490 * Generates a WHERE field IN ('item', 'item') SQL query joined with
491 * OR if appropriate
492 *
493 * @access public
494 * @param string The field to search
495 * @param array The values searched on
496 * @return object
497 */
498 function or_where_in($key = NULL, $values = NULL)
499 {
500 return $this->_where_in($key, $values, FALSE, 'OR ');
501 }
502
503 // --------------------------------------------------------------------
504
505 /**
506 * Where_not_in
507 *
508 * Generates a WHERE field NOT IN ('item', 'item') SQL query joined
509 * with AND if appropriate
510 *
511 * @access public
512 * @param string The field to search
513 * @param array The values searched on
514 * @return object
515 */
516 function where_not_in($key = NULL, $values = NULL)
517 {
518 return $this->_where_in($key, $values, TRUE);
519 }
520
521 // --------------------------------------------------------------------
522
523 /**
524 * Where_not_in_or
525 *
526 * Generates a WHERE field NOT IN ('item', 'item') SQL query joined
527 * with OR if appropriate
528 *
529 * @access public
530 * @param string The field to search
531 * @param array The values searched on
532 * @return object
533 */
534 function or_where_not_in($key = NULL, $values = NULL)
535 {
536 return $this->_where_in($key, $values, TRUE, 'OR ');
537 }
538
539 // --------------------------------------------------------------------
540
541 /**
542 * Where_in
543 *
544 * Called by where_in, where_in_or, where_not_in, where_not_in_or
545 *
546 * @access public
547 * @param string The field to search
548 * @param array The values searched on
549 * @param boolean If the statement would be IN or NOT IN
550 * @param string
551 * @return object
552 */
553 function _where_in($key = NULL, $values = NULL, $not = FALSE, $type = 'AND ')
554 {
555 if ($key === NULL OR $values === NULL)
556 {
557 return;
558 }
559
560 if ( ! is_array($values))
561 {
562 $values = array($values);
563 }
564
565 $not = ($not) ? ' NOT' : '';
566
567 foreach ($values as $value)
568 {
569 $this->ar_wherein[] = $this->escape($value);
570 }
571
572 $prefix = (count($this->ar_where) == 0) ? '' : $type;
573
574 $where_in = $prefix . $this->_protect_identifiers($key) . $not . " IN (" . implode(", ", $this->ar_wherein) . ") ";
575
576 $this->ar_where[] = $where_in;
577 if ($this->ar_caching === TRUE)
578 {
579 $this->ar_cache_where[] = $where_in;
580 $this->ar_cache_exists[] = 'where';
581 }
582
583 // reset the array for multiple calls
584 $this->ar_wherein = array();
585 return $this;
586 }
587
588 // --------------------------------------------------------------------
589
590 /**
591 * Like
592 *
593 * Generates a %LIKE% portion of the query. Separates
594 * multiple calls with AND
595 *
596 * @access public
597 * @param mixed
598 * @param mixed
599 * @return object
600 */
601 function like($field, $match = '', $side = 'both')
602 {
603 return $this->_like($field, $match, 'AND ', $side);
604 }
605
606 // --------------------------------------------------------------------
607
608 /**
609 * Not Like
610 *
611 * Generates a NOT LIKE portion of the query. Separates
612 * multiple calls with AND
613 *
614 * @access public
615 * @param mixed
616 * @param mixed
617 * @return object
618 */
619 function not_like($field, $match = '', $side = 'both')
620 {
621 return $this->_like($field, $match, 'AND ', $side, 'NOT');
622 }
623
624 // --------------------------------------------------------------------
625
626 /**
627 * OR Like
628 *
629 * Generates a %LIKE% portion of the query. Separates
630 * multiple calls with OR
631 *
632 * @access public
633 * @param mixed
634 * @param mixed
635 * @return object
636 */
637 function or_like($field, $match = '', $side = 'both')
638 {
639 return $this->_like($field, $match, 'OR ', $side);
640 }
641
642 // --------------------------------------------------------------------
643
644 /**
645 * OR Not Like
646 *
647 * Generates a NOT LIKE portion of the query. Separates
648 * multiple calls with OR
649 *
650 * @access public
651 * @param mixed
652 * @param mixed
653 * @return object
654 */
655 function or_not_like($field, $match = '', $side = 'both')
656 {
657 return $this->_like($field, $match, 'OR ', $side, 'NOT');
658 }
659
660 // --------------------------------------------------------------------
661
662 /**
Derek Allard2067d1a2008-11-13 22:59:24 +0000663 * Like
664 *
665 * Called by like() or orlike()
666 *
667 * @access private
668 * @param mixed
669 * @param mixed
670 * @param string
671 * @return object
672 */
673 function _like($field, $match = '', $type = 'AND ', $side = 'both', $not = '')
674 {
675 if ( ! is_array($field))
676 {
677 $field = array($field => $match);
678 }
679
680 foreach ($field as $k => $v)
681 {
682 $k = $this->_protect_identifiers($k);
683
684 $prefix = (count($this->ar_like) == 0) ? '' : $type;
685
Derek Jonese4ed5832009-02-20 21:44:59 +0000686 $v = $this->escape_like_str($v);
Derek Allard2067d1a2008-11-13 22:59:24 +0000687
688 if ($side == 'before')
689 {
690 $like_statement = $prefix." $k $not LIKE '%{$v}'";
691 }
692 elseif ($side == 'after')
693 {
694 $like_statement = $prefix." $k $not LIKE '{$v}%'";
695 }
696 else
697 {
698 $like_statement = $prefix." $k $not LIKE '%{$v}%'";
699 }
Derek Jonesd10e8962010-03-02 17:10:36 -0600700
Derek Jonese4ed5832009-02-20 21:44:59 +0000701 // some platforms require an escape sequence definition for LIKE wildcards
702 if ($this->_like_escape_str != '')
703 {
Greg Aker0d424892010-01-26 02:14:44 +0000704 $like_statement = $like_statement.sprintf($this->_like_escape_str, $this->_like_escape_chr);
Derek Jonese4ed5832009-02-20 21:44:59 +0000705 }
Derek Jonesd10e8962010-03-02 17:10:36 -0600706
Derek Allard2067d1a2008-11-13 22:59:24 +0000707 $this->ar_like[] = $like_statement;
708 if ($this->ar_caching === TRUE)
709 {
710 $this->ar_cache_like[] = $like_statement;
711 $this->ar_cache_exists[] = 'like';
712 }
713
714 }
715 return $this;
716 }
717
718 // --------------------------------------------------------------------
719
720 /**
721 * GROUP BY
722 *
723 * @access public
724 * @param string
725 * @return object
726 */
727 function group_by($by)
728 {
729 if (is_string($by))
730 {
731 $by = explode(',', $by);
732 }
733
734 foreach ($by as $val)
735 {
736 $val = trim($val);
737
738 if ($val != '')
739 {
740 $this->ar_groupby[] = $this->_protect_identifiers($val);
741
742 if ($this->ar_caching === TRUE)
743 {
744 $this->ar_cache_groupby[] = $this->_protect_identifiers($val);
745 $this->ar_cache_exists[] = 'groupby';
746 }
747 }
748 }
749 return $this;
750 }
751
752 // --------------------------------------------------------------------
753
754 /**
Derek Allard2067d1a2008-11-13 22:59:24 +0000755 * Sets the HAVING value
756 *
757 * Separates multiple calls with AND
758 *
759 * @access public
760 * @param string
761 * @param string
762 * @return object
763 */
764 function having($key, $value = '', $escape = TRUE)
765 {
766 return $this->_having($key, $value, 'AND ', $escape);
767 }
Greg Aker88f8d9f2010-08-06 13:01:38 -0500768
Derek Allard2067d1a2008-11-13 22:59:24 +0000769 // --------------------------------------------------------------------
770
771 /**
772 * Sets the OR HAVING value
773 *
774 * Separates multiple calls with OR
775 *
776 * @access public
777 * @param string
778 * @param string
779 * @return object
780 */
781 function or_having($key, $value = '', $escape = TRUE)
782 {
783 return $this->_having($key, $value, 'OR ', $escape);
784 }
785
786 // --------------------------------------------------------------------
787
788 /**
789 * Sets the HAVING values
790 *
791 * Called by having() or or_having()
792 *
793 * @access private
794 * @param string
795 * @param string
796 * @return object
797 */
798 function _having($key, $value = '', $type = 'AND ', $escape = TRUE)
799 {
800 if ( ! is_array($key))
801 {
802 $key = array($key => $value);
803 }
804
805 foreach ($key as $k => $v)
806 {
807 $prefix = (count($this->ar_having) == 0) ? '' : $type;
808
809 if ($escape === TRUE)
810 {
811 $k = $this->_protect_identifiers($k);
812 }
813
814 if ( ! $this->_has_operator($k))
815 {
816 $k .= ' = ';
817 }
818
819 if ($v != '')
820 {
821 $v = ' '.$this->escape_str($v);
822 }
823
824 $this->ar_having[] = $prefix.$k.$v;
825 if ($this->ar_caching === TRUE)
826 {
827 $this->ar_cache_having[] = $prefix.$k.$v;
828 $this->ar_cache_exists[] = 'having';
829 }
830 }
831
832 return $this;
833 }
834
835 // --------------------------------------------------------------------
836
837 /**
838 * Sets the ORDER BY value
839 *
840 * @access public
841 * @param string
842 * @param string direction: asc or desc
843 * @return object
844 */
845 function order_by($orderby, $direction = '')
846 {
847 if (strtolower($direction) == 'random')
848 {
849 $orderby = ''; // Random results want or don't need a field name
850 $direction = $this->_random_keyword;
851 }
852 elseif (trim($direction) != '')
853 {
854 $direction = (in_array(strtoupper(trim($direction)), array('ASC', 'DESC'), TRUE)) ? ' '.$direction : ' ASC';
855 }
856
857
858 if (strpos($orderby, ',') !== FALSE)
859 {
860 $temp = array();
861 foreach (explode(',', $orderby) as $part)
862 {
863 $part = trim($part);
864 if ( ! in_array($part, $this->ar_aliased_tables))
865 {
866 $part = $this->_protect_identifiers(trim($part));
867 }
868
869 $temp[] = $part;
870 }
871
872 $orderby = implode(', ', $temp);
873 }
Derek Allarde37ab382009-02-03 16:13:57 +0000874 else if ($direction != $this->_random_keyword)
Derek Allard2067d1a2008-11-13 22:59:24 +0000875 {
876 $orderby = $this->_protect_identifiers($orderby);
877 }
878
879 $orderby_statement = $orderby.$direction;
880
881 $this->ar_orderby[] = $orderby_statement;
882 if ($this->ar_caching === TRUE)
883 {
884 $this->ar_cache_orderby[] = $orderby_statement;
885 $this->ar_cache_exists[] = 'orderby';
886 }
887
888 return $this;
889 }
890
891 // --------------------------------------------------------------------
892
893 /**
Derek Allard2067d1a2008-11-13 22:59:24 +0000894 * Sets the LIMIT value
895 *
896 * @access public
897 * @param integer the limit value
898 * @param integer the offset value
899 * @return object
900 */
901 function limit($value, $offset = '')
902 {
903 $this->ar_limit = $value;
904
905 if ($offset != '')
906 {
907 $this->ar_offset = $offset;
908 }
909
910 return $this;
911 }
912
913 // --------------------------------------------------------------------
914
915 /**
916 * Sets the OFFSET value
917 *
918 * @access public
919 * @param integer the offset value
920 * @return object
921 */
922 function offset($offset)
923 {
924 $this->ar_offset = $offset;
925 return $this;
926 }
927
928 // --------------------------------------------------------------------
929
930 /**
931 * The "set" function. Allows key/value pairs to be set for inserting or updating
932 *
933 * @access public
934 * @param mixed
935 * @param string
936 * @param boolean
937 * @return object
938 */
939 function set($key, $value = '', $escape = TRUE)
940 {
941 $key = $this->_object_to_array($key);
942
943 if ( ! is_array($key))
944 {
945 $key = array($key => $value);
946 }
947
948 foreach ($key as $k => $v)
949 {
950 if ($escape === FALSE)
951 {
952 $this->ar_set[$this->_protect_identifiers($k)] = $v;
953 }
954 else
955 {
956 $this->ar_set[$this->_protect_identifiers($k)] = $this->escape($v);
957 }
958 }
959
960 return $this;
961 }
962
963 // --------------------------------------------------------------------
964
965 /**
966 * Get
967 *
968 * Compiles the select statement based on the other functions called
969 * and runs the query
970 *
971 * @access public
972 * @param string the table
973 * @param string the limit clause
974 * @param string the offset clause
975 * @return object
976 */
977 function get($table = '', $limit = null, $offset = null)
978 {
979 if ($table != '')
980 {
981 $this->_track_aliases($table);
982 $this->from($table);
983 }
984
985 if ( ! is_null($limit))
986 {
987 $this->limit($limit, $offset);
988 }
989
990 $sql = $this->_compile_select();
991
992 $result = $this->query($sql);
993 $this->_reset_select();
994 return $result;
995 }
996
997 /**
998 * "Count All Results" query
999 *
1000 * Generates a platform-specific query string that counts all records
1001 * returned by an Active Record query.
1002 *
1003 * @access public
1004 * @param string
1005 * @return string
1006 */
1007 function count_all_results($table = '')
1008 {
1009 if ($table != '')
1010 {
1011 $this->_track_aliases($table);
1012 $this->from($table);
1013 }
1014
1015 $sql = $this->_compile_select($this->_count_string . $this->_protect_identifiers('numrows'));
1016
1017 $query = $this->query($sql);
1018 $this->_reset_select();
1019
1020 if ($query->num_rows() == 0)
1021 {
1022 return '0';
1023 }
1024
1025 $row = $query->row();
1026 return $row->numrows;
1027 }
1028
1029 // --------------------------------------------------------------------
1030
1031 /**
1032 * Get_Where
1033 *
1034 * Allows the where clause, limit and offset to be added directly
1035 *
1036 * @access public
1037 * @param string the where clause
1038 * @param string the limit clause
1039 * @param string the offset clause
1040 * @return object
1041 */
1042 function get_where($table = '', $where = null, $limit = null, $offset = null)
1043 {
1044 if ($table != '')
1045 {
1046 $this->from($table);
1047 }
1048
1049 if ( ! is_null($where))
1050 {
1051 $this->where($where);
1052 }
1053
1054 if ( ! is_null($limit))
1055 {
1056 $this->limit($limit, $offset);
1057 }
1058
1059 $sql = $this->_compile_select();
1060
1061 $result = $this->query($sql);
1062 $this->_reset_select();
1063 return $result;
1064 }
1065
1066 // --------------------------------------------------------------------
1067
1068 /**
Derek Jonesd10e8962010-03-02 17:10:36 -06001069 * Insert_Batch
1070 *
1071 * Compiles batch insert strings and runs the queries
1072 *
1073 * @access public
1074 * @param string the table to retrieve the results from
1075 * @param array an associative array of insert values
1076 * @return object
1077 */
1078 function insert_batch($table = '', $set = NULL)
1079 {
1080 if ( ! is_null($set))
1081 {
1082 $this->set_insert_batch($set);
1083 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001084
Derek Jonesd10e8962010-03-02 17:10:36 -06001085 if (count($this->ar_set) == 0)
1086 {
1087 if ($this->db_debug)
1088 {
1089 //No valid data array. Folds in cases where keys and values did not match up
1090 return $this->display_error('db_must_use_set');
1091 }
1092 return FALSE;
1093 }
1094
1095 if ($table == '')
1096 {
1097 if ( ! isset($this->ar_from[0]))
1098 {
1099 if ($this->db_debug)
1100 {
1101 return $this->display_error('db_must_set_table');
1102 }
1103 return FALSE;
1104 }
1105
1106 $table = $this->ar_from[0];
1107 }
1108
1109 // Batch this baby
1110 for ($i = 0, $total = count($this->ar_set); $i < $total; $i = $i + 100)
1111 {
1112
1113 $sql = $this->_insert_batch($this->_protect_identifiers($table, TRUE, NULL, FALSE), $this->ar_keys, array_slice($this->ar_set, $i, 100));
1114
1115 //echo $sql;
1116
1117 $this->query($sql);
1118 }
1119
1120 $this->_reset_write();
1121
1122
1123 return TRUE;
1124 }
1125
1126 // --------------------------------------------------------------------
1127
1128 /**
1129 * The "set_insert_batch" function. Allows key/value pairs to be set for batch inserts
1130 *
1131 * @access public
1132 * @param mixed
1133 * @param string
1134 * @param boolean
1135 * @return object
1136 */
1137
1138 function set_insert_batch($key, $value = '', $escape = TRUE)
1139 {
1140 $key = $this->_object_to_array_batch($key);
1141
1142 if ( ! is_array($key))
1143 {
1144 $key = array($key => $value);
1145 }
1146
1147 $keys = array_keys(current($key));
1148 sort($keys);
1149
1150 foreach ($key as $row)
1151 {
1152 if (count(array_diff($keys, array_keys($row))) > 0 OR count(array_diff(array_keys($row), $keys)) > 0)
1153 {
1154 // batch function above returns an error on an empty array
1155 $this->ar_set[] = array();
1156 return;
1157 }
1158
1159 ksort($row); // puts $row in the same order as our keys
1160
1161 if ($escape === FALSE)
1162 {
1163 $this->ar_set[] = '('.implode(',', $row).')';
1164 }
1165 else
1166 {
1167 $clean = array();
1168
1169 foreach($row as $value)
1170 {
1171 $clean[] = $this->escape($value);
1172 }
1173
1174 $this->ar_set[] = '('.implode(',', $clean).')';
1175 }
1176 }
1177
1178 foreach ($keys as $k)
1179 {
1180 $this->ar_keys[] = $this->_protect_identifiers($k);
1181 }
1182
1183 return $this;
1184 }
1185
Derek Allard2067d1a2008-11-13 22:59:24 +00001186 // --------------------------------------------------------------------
1187
1188 /**
1189 * Insert
1190 *
1191 * Compiles an insert string and runs the query
1192 *
1193 * @access public
1194 * @param string the table to retrieve the results from
1195 * @param array an associative array of insert values
1196 * @return object
1197 */
1198 function insert($table = '', $set = NULL)
1199 {
1200 if ( ! is_null($set))
1201 {
1202 $this->set($set);
1203 }
1204
1205 if (count($this->ar_set) == 0)
1206 {
1207 if ($this->db_debug)
1208 {
1209 return $this->display_error('db_must_use_set');
1210 }
1211 return FALSE;
1212 }
1213
1214 if ($table == '')
1215 {
1216 if ( ! isset($this->ar_from[0]))
1217 {
1218 if ($this->db_debug)
1219 {
1220 return $this->display_error('db_must_set_table');
1221 }
1222 return FALSE;
1223 }
1224
1225 $table = $this->ar_from[0];
1226 }
1227
1228 $sql = $this->_insert($this->_protect_identifiers($table, TRUE, NULL, FALSE), array_keys($this->ar_set), array_values($this->ar_set));
1229
1230 $this->_reset_write();
1231 return $this->query($sql);
1232 }
1233
Derek Jonesd10e8962010-03-02 17:10:36 -06001234 function replace($table = '', $set = NULL)
1235 {
1236 if ( ! is_null($set))
1237 {
1238 $this->set($set);
1239 }
1240
1241 if (count($this->ar_set) == 0)
1242 {
1243 if ($this->db_debug)
1244 {
1245 return $this->display_error('db_must_use_set');
1246 }
1247 return FALSE;
1248 }
1249
1250 if ($table == '')
1251 {
1252 if ( ! isset($this->ar_from[0]))
1253 {
1254 if ($this->db_debug)
1255 {
1256 return $this->display_error('db_must_set_table');
1257 }
1258 return FALSE;
1259 }
1260
1261 $table = $this->ar_from[0];
1262 }
1263
1264 $sql = $this->_replace($this->_protect_identifiers($table, TRUE, NULL, FALSE), array_keys($this->ar_set), array_values($this->ar_set));
1265
1266 $this->_reset_write();
1267 return $this->query($sql);
1268 }
1269
Derek Allard2067d1a2008-11-13 22:59:24 +00001270 // --------------------------------------------------------------------
1271
1272 /**
1273 * Update
1274 *
1275 * Compiles an update string and runs the query
1276 *
1277 * @access public
1278 * @param string the table to retrieve the results from
1279 * @param array an associative array of update values
1280 * @param mixed the where clause
1281 * @return object
1282 */
1283 function update($table = '', $set = NULL, $where = NULL, $limit = NULL)
1284 {
1285 // Combine any cached components with the current statements
1286 $this->_merge_cache();
1287
1288 if ( ! is_null($set))
1289 {
1290 $this->set($set);
1291 }
1292
1293 if (count($this->ar_set) == 0)
1294 {
1295 if ($this->db_debug)
1296 {
1297 return $this->display_error('db_must_use_set');
1298 }
1299 return FALSE;
1300 }
1301
1302 if ($table == '')
1303 {
1304 if ( ! isset($this->ar_from[0]))
1305 {
1306 if ($this->db_debug)
1307 {
1308 return $this->display_error('db_must_set_table');
1309 }
1310 return FALSE;
1311 }
1312
1313 $table = $this->ar_from[0];
1314 }
1315
1316 if ($where != NULL)
1317 {
1318 $this->where($where);
1319 }
1320
1321 if ($limit != NULL)
1322 {
1323 $this->limit($limit);
1324 }
1325
1326 $sql = $this->_update($this->_protect_identifiers($table, TRUE, NULL, FALSE), $this->ar_set, $this->ar_where, $this->ar_orderby, $this->ar_limit);
1327
1328 $this->_reset_write();
1329 return $this->query($sql);
1330 }
1331
Derek Jonesd10e8962010-03-02 17:10:36 -06001332
1333 // --------------------------------------------------------------------
1334
1335 /**
1336 * Update_Batch
1337 *
1338 * Compiles an update string and runs the query
1339 *
1340 * @access public
1341 * @param string the table to retrieve the results from
1342 * @param array an associative array of update values
1343 * @param string the where key
1344 * @return object
1345 */
1346 function update_batch($table = '', $set = NULL, $index = NULL)
1347 {
1348 // Combine any cached components with the current statements
1349 $this->_merge_cache();
1350
1351 if (is_null($index))
1352 {
1353 if ($this->db_debug)
1354 {
1355 return $this->display_error('db_myst_use_index');
1356 }
1357
1358 return FALSE;
1359 }
1360
1361 if ( ! is_null($set))
1362 {
1363 $this->set_update_batch($set, $index);
1364 }
1365
1366 if (count($this->ar_set) == 0)
1367 {
1368 if ($this->db_debug)
1369 {
1370 return $this->display_error('db_must_use_set');
1371 }
1372
1373 return FALSE;
1374 }
1375
1376 if ($table == '')
1377 {
1378 if ( ! isset($this->ar_from[0]))
1379 {
1380 if ($this->db_debug)
1381 {
1382 return $this->display_error('db_must_set_table');
1383 }
1384 return FALSE;
1385 }
1386
1387 $table = $this->ar_from[0];
1388 }
1389
1390 // Batch this baby
1391 for ($i = 0, $total = count($this->ar_set); $i < $total; $i = $i + 100)
1392 {
1393 $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);
1394
1395 $this->query($sql);
1396 }
1397
1398 $this->_reset_write();
1399 }
1400
1401 // --------------------------------------------------------------------
1402
1403 /**
1404 * The "set_update_batch" function. Allows key/value pairs to be set for batch updating
1405 *
1406 * @access public
1407 * @param array
1408 * @param string
1409 * @param boolean
1410 * @return object
1411 */
1412
1413 function set_update_batch($key, $index = '', $escape = TRUE)
1414 {
1415 $key = $this->_object_to_array_batch($key);
1416
1417 if ( ! is_array($key))
1418 {
1419 // @todo error
1420 }
1421
1422 foreach ($key as $k => $v)
1423 {
1424 $index_set = FALSE;
1425 $clean = array();
1426
1427 foreach($v as $k2 => $v2)
1428 {
1429 if ($k2 == $index)
1430 {
1431 $index_set = TRUE;
1432 }
1433 else
1434 {
1435 $not[] = $k.'-'.$v;
1436 }
1437
1438 if ($escape === FALSE)
1439 {
1440 $clean[$this->_protect_identifiers($k2)] = $v2;
1441 }
1442 else
1443 {
1444 $clean[$this->_protect_identifiers($k2)] = $this->escape($v2);
1445 }
1446 }
1447
1448 if ($index_set == FALSE)
1449 {
1450 return $this->display_error('db_batch_missing_index');
1451 }
1452
1453 $this->ar_set[] = $clean;
1454 }
1455
1456 return $this;
1457 }
1458
Derek Allard2067d1a2008-11-13 22:59:24 +00001459 // --------------------------------------------------------------------
1460
1461 /**
1462 * Empty Table
1463 *
1464 * Compiles a delete string and runs "DELETE FROM table"
1465 *
1466 * @access public
1467 * @param string the table to empty
1468 * @return object
1469 */
1470 function empty_table($table = '')
1471 {
1472 if ($table == '')
1473 {
1474 if ( ! isset($this->ar_from[0]))
1475 {
1476 if ($this->db_debug)
1477 {
1478 return $this->display_error('db_must_set_table');
1479 }
1480 return FALSE;
1481 }
1482
1483 $table = $this->ar_from[0];
1484 }
1485 else
1486 {
1487 $table = $this->_protect_identifiers($table, TRUE, NULL, FALSE);
1488 }
1489
1490 $sql = $this->_delete($table);
1491
1492 $this->_reset_write();
1493
1494 return $this->query($sql);
1495 }
1496
1497 // --------------------------------------------------------------------
1498
1499 /**
1500 * Truncate
1501 *
1502 * Compiles a truncate string and runs the query
1503 * If the database does not support the truncate() command
1504 * This function maps to "DELETE FROM table"
1505 *
1506 * @access public
1507 * @param string the table to truncate
1508 * @return object
1509 */
1510 function truncate($table = '')
1511 {
1512 if ($table == '')
1513 {
1514 if ( ! isset($this->ar_from[0]))
1515 {
1516 if ($this->db_debug)
1517 {
1518 return $this->display_error('db_must_set_table');
1519 }
1520 return FALSE;
1521 }
1522
1523 $table = $this->ar_from[0];
1524 }
1525 else
1526 {
1527 $table = $this->_protect_identifiers($table, TRUE, NULL, FALSE);
1528 }
1529
1530 $sql = $this->_truncate($table);
1531
1532 $this->_reset_write();
1533
1534 return $this->query($sql);
1535 }
1536
1537 // --------------------------------------------------------------------
1538
1539 /**
1540 * Delete
1541 *
1542 * Compiles a delete string and runs the query
1543 *
1544 * @access public
1545 * @param mixed the table(s) to delete from. String or array
1546 * @param mixed the where clause
1547 * @param mixed the limit clause
1548 * @param boolean
1549 * @return object
1550 */
1551 function delete($table = '', $where = '', $limit = NULL, $reset_data = TRUE)
1552 {
1553 // Combine any cached components with the current statements
1554 $this->_merge_cache();
1555
1556 if ($table == '')
1557 {
1558 if ( ! isset($this->ar_from[0]))
1559 {
1560 if ($this->db_debug)
1561 {
1562 return $this->display_error('db_must_set_table');
1563 }
1564 return FALSE;
1565 }
1566
1567 $table = $this->ar_from[0];
1568 }
1569 elseif (is_array($table))
1570 {
1571 foreach($table as $single_table)
1572 {
1573 $this->delete($single_table, $where, $limit, FALSE);
1574 }
1575
1576 $this->_reset_write();
1577 return;
1578 }
1579 else
1580 {
1581 $table = $this->_protect_identifiers($table, TRUE, NULL, FALSE);
1582 }
1583
1584 if ($where != '')
1585 {
1586 $this->where($where);
1587 }
1588
1589 if ($limit != NULL)
1590 {
1591 $this->limit($limit);
1592 }
1593
Derek Allard03d783b2009-05-03 19:45:45 +00001594 if (count($this->ar_where) == 0 && count($this->ar_wherein) == 0 && count($this->ar_like) == 0)
Derek Allard2067d1a2008-11-13 22:59:24 +00001595 {
1596 if ($this->db_debug)
1597 {
1598 return $this->display_error('db_del_must_use_where');
1599 }
1600
1601 return FALSE;
1602 }
1603
1604 $sql = $this->_delete($table, $this->ar_where, $this->ar_like, $this->ar_limit);
1605
1606 if ($reset_data)
1607 {
1608 $this->_reset_write();
1609 }
1610
1611 return $this->query($sql);
1612 }
1613
1614 // --------------------------------------------------------------------
1615
1616 /**
1617 * DB Prefix
1618 *
1619 * Prepends a database prefix if one exists in configuration
1620 *
1621 * @access public
1622 * @param string the table
1623 * @return string
1624 */
1625 function dbprefix($table = '')
1626 {
1627 if ($table == '')
1628 {
1629 $this->display_error('db_table_name_required');
1630 }
1631
1632 return $this->dbprefix.$table;
1633 }
1634
1635 // --------------------------------------------------------------------
1636
1637 /**
1638 * Track Aliases
1639 *
1640 * Used to track SQL statements written with aliased tables.
1641 *
1642 * @access private
1643 * @param string The table to inspect
1644 * @return string
1645 */
1646 function _track_aliases($table)
1647 {
1648 if (is_array($table))
1649 {
1650 foreach ($table as $t)
1651 {
1652 $this->_track_aliases($t);
1653 }
1654 return;
1655 }
1656
1657 // Does the string contain a comma? If so, we need to separate
1658 // the string into discreet statements
1659 if (strpos($table, ',') !== FALSE)
1660 {
1661 return $this->_track_aliases(explode(',', $table));
1662 }
1663
1664 // if a table alias is used we can recognize it by a space
1665 if (strpos($table, " ") !== FALSE)
1666 {
1667 // if the alias is written with the AS keyword, remove it
1668 $table = preg_replace('/ AS /i', ' ', $table);
1669
1670 // Grab the alias
1671 $table = trim(strrchr($table, " "));
1672
1673 // Store the alias, if it doesn't already exist
1674 if ( ! in_array($table, $this->ar_aliased_tables))
1675 {
1676 $this->ar_aliased_tables[] = $table;
1677 }
1678 }
1679 }
1680
1681 // --------------------------------------------------------------------
1682
1683 /**
1684 * Compile the SELECT statement
1685 *
1686 * Generates a query string based on which functions were used.
1687 * Should not be called directly. The get() function calls it.
1688 *
1689 * @access private
1690 * @return string
1691 */
1692 function _compile_select($select_override = FALSE)
1693 {
1694 // Combine any cached components with the current statements
1695 $this->_merge_cache();
1696
1697 // ----------------------------------------------------------------
1698
1699 // Write the "select" portion of the query
1700
1701 if ($select_override !== FALSE)
1702 {
1703 $sql = $select_override;
1704 }
1705 else
1706 {
1707 $sql = ( ! $this->ar_distinct) ? 'SELECT ' : 'SELECT DISTINCT ';
1708
1709 if (count($this->ar_select) == 0)
1710 {
1711 $sql .= '*';
1712 }
1713 else
1714 {
1715 // Cycle through the "select" portion of the query and prep each column name.
1716 // The reason we protect identifiers here rather then in the select() function
1717 // is because until the user calls the from() function we don't know if there are aliases
1718 foreach ($this->ar_select as $key => $val)
1719 {
1720 $this->ar_select[$key] = $this->_protect_identifiers($val);
1721 }
1722
1723 $sql .= implode(', ', $this->ar_select);
1724 }
1725 }
1726
1727 // ----------------------------------------------------------------
1728
1729 // Write the "FROM" portion of the query
1730
1731 if (count($this->ar_from) > 0)
1732 {
1733 $sql .= "\nFROM ";
1734
1735 $sql .= $this->_from_tables($this->ar_from);
1736 }
1737
1738 // ----------------------------------------------------------------
1739
1740 // Write the "JOIN" portion of the query
1741
1742 if (count($this->ar_join) > 0)
1743 {
1744 $sql .= "\n";
1745
1746 $sql .= implode("\n", $this->ar_join);
1747 }
1748
1749 // ----------------------------------------------------------------
1750
1751 // Write the "WHERE" portion of the query
1752
1753 if (count($this->ar_where) > 0 OR count($this->ar_like) > 0)
1754 {
1755 $sql .= "\n";
1756
1757 $sql .= "WHERE ";
1758 }
1759
1760 $sql .= implode("\n", $this->ar_where);
1761
1762 // ----------------------------------------------------------------
1763
1764 // Write the "LIKE" portion of the query
1765
1766 if (count($this->ar_like) > 0)
1767 {
1768 if (count($this->ar_where) > 0)
1769 {
1770 $sql .= "\nAND ";
1771 }
1772
1773 $sql .= implode("\n", $this->ar_like);
1774 }
1775
1776 // ----------------------------------------------------------------
1777
1778 // Write the "GROUP BY" portion of the query
1779
1780 if (count($this->ar_groupby) > 0)
1781 {
1782 $sql .= "\nGROUP BY ";
1783
1784 $sql .= implode(', ', $this->ar_groupby);
1785 }
1786
1787 // ----------------------------------------------------------------
1788
1789 // Write the "HAVING" portion of the query
1790
1791 if (count($this->ar_having) > 0)
1792 {
1793 $sql .= "\nHAVING ";
1794 $sql .= implode("\n", $this->ar_having);
1795 }
1796
1797 // ----------------------------------------------------------------
1798
1799 // Write the "ORDER BY" portion of the query
1800
1801 if (count($this->ar_orderby) > 0)
1802 {
1803 $sql .= "\nORDER BY ";
1804 $sql .= implode(', ', $this->ar_orderby);
1805
1806 if ($this->ar_order !== FALSE)
1807 {
1808 $sql .= ($this->ar_order == 'desc') ? ' DESC' : ' ASC';
1809 }
1810 }
1811
1812 // ----------------------------------------------------------------
1813
1814 // Write the "LIMIT" portion of the query
1815
1816 if (is_numeric($this->ar_limit))
1817 {
1818 $sql .= "\n";
1819 $sql = $this->_limit($sql, $this->ar_limit, $this->ar_offset);
1820 }
1821
1822 return $sql;
1823 }
1824
1825 // --------------------------------------------------------------------
1826
1827 /**
1828 * Object to Array
1829 *
1830 * Takes an object as input and converts the class variables to array key/vals
1831 *
1832 * @access public
1833 * @param object
1834 * @return array
1835 */
1836 function _object_to_array($object)
1837 {
1838 if ( ! is_object($object))
1839 {
1840 return $object;
1841 }
1842
1843 $array = array();
1844 foreach (get_object_vars($object) as $key => $val)
1845 {
1846 // There are some built in keys we need to ignore for this conversion
Derek Jonescf579552010-03-11 09:13:34 -06001847 if ( ! is_object($val) && ! is_array($val) && $key != '_parent_name')
Derek Allard2067d1a2008-11-13 22:59:24 +00001848 {
1849 $array[$key] = $val;
1850 }
1851 }
Derek Jonesd10e8962010-03-02 17:10:36 -06001852
1853 return $array;
1854 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001855
Derek Jonesd10e8962010-03-02 17:10:36 -06001856 // --------------------------------------------------------------------
1857
1858 /**
1859 * Object to Array
1860 *
1861 * Takes an object as input and converts the class variables to array key/vals
1862 *
1863 * @access public
1864 * @param object
1865 * @return array
1866 */
1867 function _object_to_array_batch($object)
1868 {
1869 if ( ! is_object($object))
1870 {
1871 return $object;
1872 }
1873
1874 $array = array();
1875 $out = get_object_vars($object);
1876 $fields = array_keys($out);
1877
1878 foreach ($fields as $val)
1879 {
1880 // There are some built in keys we need to ignore for this conversion
Derek Jonescf579552010-03-11 09:13:34 -06001881 if ($val != '_parent_name')
Derek Jonesd10e8962010-03-02 17:10:36 -06001882 {
1883
1884 $i = 0;
1885 foreach ($out[$val] as $data)
1886 {
1887 $array[$i][$val] = $data;
1888 $i++;
1889 }
1890 }
1891 }
1892
Derek Allard2067d1a2008-11-13 22:59:24 +00001893 return $array;
1894 }
1895
1896 // --------------------------------------------------------------------
1897
1898 /**
1899 * Start Cache
1900 *
1901 * Starts AR caching
1902 *
1903 * @access public
1904 * @return void
1905 */
1906 function start_cache()
1907 {
1908 $this->ar_caching = TRUE;
1909 }
1910
1911 // --------------------------------------------------------------------
1912
1913 /**
1914 * Stop Cache
1915 *
1916 * Stops AR caching
1917 *
1918 * @access public
1919 * @return void
1920 */
1921 function stop_cache()
1922 {
1923 $this->ar_caching = FALSE;
1924 }
1925
1926 // --------------------------------------------------------------------
1927
1928 /**
1929 * Flush Cache
1930 *
1931 * Empties the AR cache
1932 *
1933 * @access public
1934 * @return void
1935 */
1936 function flush_cache()
1937 {
1938 $this->_reset_run(
1939 array(
1940 'ar_cache_select' => array(),
1941 'ar_cache_from' => array(),
1942 'ar_cache_join' => array(),
1943 'ar_cache_where' => array(),
1944 'ar_cache_like' => array(),
1945 'ar_cache_groupby' => array(),
1946 'ar_cache_having' => array(),
1947 'ar_cache_orderby' => array(),
1948 'ar_cache_set' => array(),
1949 'ar_cache_exists' => array()
1950 )
1951 );
1952 }
1953
1954 // --------------------------------------------------------------------
1955
1956 /**
1957 * Merge Cache
1958 *
1959 * When called, this function merges any cached AR arrays with
1960 * locally called ones.
1961 *
1962 * @access private
1963 * @return void
1964 */
1965 function _merge_cache()
1966 {
1967 if (count($this->ar_cache_exists) == 0)
1968 {
1969 return;
1970 }
1971
1972 foreach ($this->ar_cache_exists as $val)
1973 {
1974 $ar_variable = 'ar_'.$val;
1975 $ar_cache_var = 'ar_cache_'.$val;
1976
1977 if (count($this->$ar_cache_var) == 0)
1978 {
1979 continue;
1980 }
1981
1982 $this->$ar_variable = array_unique(array_merge($this->$ar_cache_var, $this->$ar_variable));
1983 }
1984
1985 // If we are "protecting identifiers" we need to examine the "from"
1986 // portion of the query to determine if there are any aliases
1987 if ($this->_protect_identifiers === TRUE AND count($this->ar_cache_from) > 0)
1988 {
1989 $this->_track_aliases($this->ar_from);
1990 }
1991 }
1992
1993 // --------------------------------------------------------------------
1994
1995 /**
1996 * Resets the active record values. Called by the get() function
1997 *
1998 * @access private
1999 * @param array An array of fields to reset
2000 * @return void
2001 */
2002 function _reset_run($ar_reset_items)
2003 {
2004 foreach ($ar_reset_items as $item => $default_value)
2005 {
2006 if ( ! in_array($item, $this->ar_store_array))
2007 {
2008 $this->$item = $default_value;
2009 }
2010 }
2011 }
2012
2013 // --------------------------------------------------------------------
2014
2015 /**
2016 * Resets the active record values. Called by the get() function
2017 *
2018 * @access private
2019 * @return void
2020 */
2021 function _reset_select()
2022 {
2023 $ar_reset_items = array(
2024 'ar_select' => array(),
2025 'ar_from' => array(),
2026 'ar_join' => array(),
2027 'ar_where' => array(),
2028 'ar_like' => array(),
2029 'ar_groupby' => array(),
2030 'ar_having' => array(),
2031 'ar_orderby' => array(),
2032 'ar_wherein' => array(),
2033 'ar_aliased_tables' => array(),
2034 'ar_distinct' => FALSE,
2035 'ar_limit' => FALSE,
2036 'ar_offset' => FALSE,
2037 'ar_order' => FALSE,
2038 );
2039
2040 $this->_reset_run($ar_reset_items);
2041 }
2042
2043 // --------------------------------------------------------------------
2044
2045 /**
2046 * Resets the active record "write" values.
2047 *
2048 * Called by the insert() update() and delete() functions
2049 *
2050 * @access private
2051 * @return void
2052 */
2053 function _reset_write()
2054 {
2055 $ar_reset_items = array(
2056 'ar_set' => array(),
2057 'ar_from' => array(),
2058 'ar_where' => array(),
2059 'ar_like' => array(),
2060 'ar_orderby' => array(),
2061 'ar_limit' => FALSE,
2062 'ar_order' => FALSE
2063 );
2064
2065 $this->_reset_run($ar_reset_items);
2066 }
2067
2068}
2069
2070/* End of file DB_active_rec.php */
Derek Jonesa3ffbbb2008-05-11 18:18:29 +00002071/* Location: ./system/database/DB_active_rec.php */