/lenasys/trunk

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/lenasys/trunk

« back to all changes in this revision

Viewing changes to codeigniter/system/database/DB_active_rec.php

  • Committer: Gustav Hatvigsson
  • Date: 2013-04-11 09:20:09 UTC
  • mfrom: (19.1.5 lenasys)
  • Revision ID: gustav.hartvigsson@gmail.com-20130411092009-ylcqzqwcmjdglb17
merged in implemetaion group one's team bransh, it contains code-ignighter
and the new admin-panel.
20130411

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 */
 
 
b'\\ No newline at end of file'