/lenasys/trunk

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