blob: b7b568b10573a07d4b3f32e782ac4e9c9d27b607 [file] [log] [blame]
Andrey Andreevc5536aa2012-11-01 17:33:58 +02001<?php
Derek Allard2067d1a2008-11-13 22:59:24 +00002/**
3 * CodeIgniter
4 *
Phil Sturgeon07c1ac82012-03-09 17:03:37 +00005 * An open source application development framework for PHP 5.2.4 or newer
Derek Allard2067d1a2008-11-13 22:59:24 +00006 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05007 * NOTICE OF LICENSE
WanWizard7219c072011-12-28 14:09:05 +01008 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05009 * Licensed under the Open Software License version 3.0
WanWizard7219c072011-12-28 14:09:05 +010010 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -050011 * This source file is subject to the Open Software License (OSL 3.0) that is
12 * bundled with this package in the files license.txt / license.rst. It is
13 * also available through the world wide web at this URL:
14 * http://opensource.org/licenses/OSL-3.0
15 * If you did not receive a copy of the license and are unable to obtain it
16 * through the world wide web, please send an email to
17 * licensing@ellislab.com so we can send you a copy immediately.
18 *
Derek Allard2067d1a2008-11-13 22:59:24 +000019 * @package CodeIgniter
Derek Jonesf4a4bd82011-10-20 12:18:42 -050020 * @author EllisLab Dev Team
Andrey Andreev80500af2013-01-01 08:16:53 +020021 * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
Derek Jonesf4a4bd82011-10-20 12:18:42 -050022 * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
Derek Allard2067d1a2008-11-13 22:59:24 +000023 * @link http://codeigniter.com
24 * @since Version 1.0
25 * @filesource
26 */
Andrey Andreevc5536aa2012-11-01 17:33:58 +020027defined('BASEPATH') OR exit('No direct script access allowed');
Derek Allard2067d1a2008-11-13 22:59:24 +000028
Derek Allard2067d1a2008-11-13 22:59:24 +000029/**
Jamie Rumbelow7efad202012-02-19 12:37:00 +000030 * Query Builder Class
Derek Allard2067d1a2008-11-13 22:59:24 +000031 *
Jamie Rumbelow7efad202012-02-19 12:37:00 +000032 * This is the platform-independent base Query Builder implementation class.
Derek Allard2067d1a2008-11-13 22:59:24 +000033 *
34 * @package CodeIgniter
35 * @subpackage Drivers
36 * @category Database
Derek Jonesf4a4bd82011-10-20 12:18:42 -050037 * @author EllisLab Dev Team
Derek Allard2067d1a2008-11-13 22:59:24 +000038 * @link http://codeigniter.com/user_guide/database/
39 */
Jamie Rumbelowd6ce1e92012-04-26 13:27:35 +010040
41abstract class CI_DB_query_builder extends CI_DB_driver {
Derek Allard2067d1a2008-11-13 22:59:24 +000042
Andrey Andreevae85eb42012-11-02 01:42:31 +020043 /**
44 * Return DELETE SQL flag
45 *
46 * @var bool
47 */
WanWizard7219c072011-12-28 14:09:05 +010048 protected $return_delete_sql = FALSE;
Andrey Andreevae85eb42012-11-02 01:42:31 +020049
50 /**
51 * Reset DELETE data flag
52 *
53 * @var bool
54 */
WanWizard7219c072011-12-28 14:09:05 +010055 protected $reset_delete_data = FALSE;
56
Andrey Andreevae85eb42012-11-02 01:42:31 +020057 /**
58 * QB SELECT data
59 *
60 * @var array
61 */
Jamie Rumbelow7efad202012-02-19 12:37:00 +000062 protected $qb_select = array();
Andrey Andreevae85eb42012-11-02 01:42:31 +020063
64 /**
65 * QB DISTINCT flag
66 *
67 * @var bool
68 */
Jamie Rumbelow7efad202012-02-19 12:37:00 +000069 protected $qb_distinct = FALSE;
Andrey Andreevae85eb42012-11-02 01:42:31 +020070
71 /**
72 * QB FROM data
73 *
74 * @var array
75 */
Jamie Rumbelow7efad202012-02-19 12:37:00 +000076 protected $qb_from = array();
Andrey Andreevae85eb42012-11-02 01:42:31 +020077
78 /**
79 * QB JOIN data
80 *
81 * @var array
82 */
Jamie Rumbelow7efad202012-02-19 12:37:00 +000083 protected $qb_join = array();
Andrey Andreevae85eb42012-11-02 01:42:31 +020084
85 /**
86 * QB WHERE data
87 *
88 * @var array
89 */
Jamie Rumbelow7efad202012-02-19 12:37:00 +000090 protected $qb_where = array();
Andrey Andreevae85eb42012-11-02 01:42:31 +020091
92 /**
93 * QB GROUP BY data
94 *
95 * @var array
96 */
Jamie Rumbelow7efad202012-02-19 12:37:00 +000097 protected $qb_groupby = array();
Andrey Andreevae85eb42012-11-02 01:42:31 +020098
99 /**
100 * QB HAVING data
101 *
102 * @var array
103 */
Jamie Rumbelow7efad202012-02-19 12:37:00 +0000104 protected $qb_having = array();
Andrey Andreevae85eb42012-11-02 01:42:31 +0200105
106 /**
107 * QB keys
108 *
109 * @var array
110 */
Jamie Rumbelow7efad202012-02-19 12:37:00 +0000111 protected $qb_keys = array();
Andrey Andreevae85eb42012-11-02 01:42:31 +0200112
113 /**
114 * QB LIMIT data
115 *
116 * @var int
117 */
Jamie Rumbelow7efad202012-02-19 12:37:00 +0000118 protected $qb_limit = FALSE;
Andrey Andreevae85eb42012-11-02 01:42:31 +0200119
120 /**
121 * QB OFFSET data
122 *
123 * @var int
124 */
Jamie Rumbelow7efad202012-02-19 12:37:00 +0000125 protected $qb_offset = FALSE;
Andrey Andreevae85eb42012-11-02 01:42:31 +0200126
127 /**
128 * QB ORDER BY data
129 *
130 * @var array
131 */
Jamie Rumbelow7efad202012-02-19 12:37:00 +0000132 protected $qb_orderby = array();
Andrey Andreevae85eb42012-11-02 01:42:31 +0200133
134 /**
135 * QB data sets
136 *
137 * @var array
138 */
Jamie Rumbelow7efad202012-02-19 12:37:00 +0000139 protected $qb_set = array();
Andrey Andreevae85eb42012-11-02 01:42:31 +0200140
141 /**
142 * QB aliased tables list
143 *
144 * @var array
145 */
Jamie Rumbelow7efad202012-02-19 12:37:00 +0000146 protected $qb_aliased_tables = array();
Andrey Andreevae85eb42012-11-02 01:42:31 +0200147
148 /**
149 * QB WHERE group started flag
150 *
151 * @var bool
152 */
Jamie Rumbelow7efad202012-02-19 12:37:00 +0000153 protected $qb_where_group_started = FALSE;
Andrey Andreevae85eb42012-11-02 01:42:31 +0200154
155 /**
156 * QB WHERE group count
157 *
158 * @var int
159 */
Jamie Rumbelow7efad202012-02-19 12:37:00 +0000160 protected $qb_where_group_count = 0;
Barry Mienydd671972010-10-04 16:33:58 +0200161
Jamie Rumbelow7efad202012-02-19 12:37:00 +0000162 // Query Builder Caching variables
Andrey Andreevae85eb42012-11-02 01:42:31 +0200163
164 /**
165 * QB Caching flag
166 *
167 * @var bool
168 */
Jamie Rumbelow7efad202012-02-19 12:37:00 +0000169 protected $qb_caching = FALSE;
Andrey Andreevae85eb42012-11-02 01:42:31 +0200170
171 /**
172 * QB Cache exists list
173 *
174 * @var array
175 */
Jamie Rumbelow7efad202012-02-19 12:37:00 +0000176 protected $qb_cache_exists = array();
Andrey Andreevae85eb42012-11-02 01:42:31 +0200177
178 /**
179 * QB Cache SELECT data
180 *
181 * @var array
182 */
Jamie Rumbelow7efad202012-02-19 12:37:00 +0000183 protected $qb_cache_select = array();
Andrey Andreevae85eb42012-11-02 01:42:31 +0200184
185 /**
186 * QB Cache FROM data
187 *
188 * @var array
189 */
Jamie Rumbelow7efad202012-02-19 12:37:00 +0000190 protected $qb_cache_from = array();
Andrey Andreevae85eb42012-11-02 01:42:31 +0200191
192 /**
193 * QB Cache JOIN data
194 *
195 * @var array
196 */
Jamie Rumbelow7efad202012-02-19 12:37:00 +0000197 protected $qb_cache_join = array();
Andrey Andreevae85eb42012-11-02 01:42:31 +0200198
199 /**
200 * QB Cache WHERE data
201 *
202 * @var array
203 */
Jamie Rumbelow7efad202012-02-19 12:37:00 +0000204 protected $qb_cache_where = array();
Andrey Andreevae85eb42012-11-02 01:42:31 +0200205
206 /**
207 * QB Cache GROUP BY data
208 *
209 * @var array
210 */
Jamie Rumbelow7efad202012-02-19 12:37:00 +0000211 protected $qb_cache_groupby = array();
Andrey Andreevae85eb42012-11-02 01:42:31 +0200212
213 /**
214 * QB Cache HAVING data
215 *
216 * @var array
217 */
Jamie Rumbelow7efad202012-02-19 12:37:00 +0000218 protected $qb_cache_having = array();
Andrey Andreevae85eb42012-11-02 01:42:31 +0200219
220 /**
221 * QB Cache ORDER BY data
222 *
223 * @var array
224 */
Jamie Rumbelow7efad202012-02-19 12:37:00 +0000225 protected $qb_cache_orderby = array();
Andrey Andreevae85eb42012-11-02 01:42:31 +0200226
227 /**
228 * QB Cache data sets
229 *
230 * @var array
231 */
Jamie Rumbelow7efad202012-02-19 12:37:00 +0000232 protected $qb_cache_set = array();
WanWizard7219c072011-12-28 14:09:05 +0100233
Andrey Andreevae85eb42012-11-02 01:42:31 +0200234 /**
235 * QB No Escape data
236 *
237 * @var array
238 */
Jamie Rumbelow7efad202012-02-19 12:37:00 +0000239 protected $qb_no_escape = array();
Andrey Andreevae85eb42012-11-02 01:42:31 +0200240
241 /**
242 * QB Cache No Escape data
243 *
244 * @var array
245 */
Jamie Rumbelow7efad202012-02-19 12:37:00 +0000246 protected $qb_cache_no_escape = array();
Derek Allard2067d1a2008-11-13 22:59:24 +0000247
Andrey Andreevae85eb42012-11-02 01:42:31 +0200248 // --------------------------------------------------------------------
249
Derek Allard2067d1a2008-11-13 22:59:24 +0000250 /**
251 * Select
252 *
253 * Generates the SELECT portion of the query
254 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000255 * @param string
Andrey Andreev42870232012-06-12 01:30:20 +0300256 * @param mixed
Andrew Podner4296a652012-12-17 07:51:15 -0500257 * @return CI_DB_query_builder
Derek Allard2067d1a2008-11-13 22:59:24 +0000258 */
Phil Sturgeon9789f322011-07-15 15:14:05 -0600259 public function select($select = '*', $escape = NULL)
Derek Allard2067d1a2008-11-13 22:59:24 +0000260 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000261 if (is_string($select))
262 {
263 $select = explode(',', $select);
264 }
265
Andrey Andreev42870232012-06-12 01:30:20 +0300266 // If the escape value was not set will will base it on the global setting
267 is_bool($escape) OR $escape = $this->_protect_identifiers;
268
Derek Allard2067d1a2008-11-13 22:59:24 +0000269 foreach ($select as $val)
270 {
271 $val = trim($val);
272
Alex Bilbie48a2baf2012-06-02 11:09:54 +0100273 if ($val !== '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000274 {
Jamie Rumbelow7efad202012-02-19 12:37:00 +0000275 $this->qb_select[] = $val;
276 $this->qb_no_escape[] = $escape;
Derek Allard2067d1a2008-11-13 22:59:24 +0000277
Jamie Rumbelow7efad202012-02-19 12:37:00 +0000278 if ($this->qb_caching === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000279 {
Jamie Rumbelow7efad202012-02-19 12:37:00 +0000280 $this->qb_cache_select[] = $val;
281 $this->qb_cache_exists[] = 'select';
282 $this->qb_cache_no_escape[] = $escape;
Derek Allard2067d1a2008-11-13 22:59:24 +0000283 }
284 }
285 }
Andrey Andreev24276a32012-01-08 02:44:38 +0200286
Derek Allard2067d1a2008-11-13 22:59:24 +0000287 return $this;
288 }
289
290 // --------------------------------------------------------------------
291
292 /**
293 * Select Max
294 *
295 * Generates a SELECT MAX(field) portion of a query
296 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000297 * @param string the field
298 * @param string an alias
Andrew Podner4296a652012-12-17 07:51:15 -0500299 * @return CI_DB_query_builder
Derek Allard2067d1a2008-11-13 22:59:24 +0000300 */
Phil Sturgeon9789f322011-07-15 15:14:05 -0600301 public function select_max($select = '', $alias = '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000302 {
303 return $this->_max_min_avg_sum($select, $alias, 'MAX');
304 }
Barry Mienydd671972010-10-04 16:33:58 +0200305
Derek Allard2067d1a2008-11-13 22:59:24 +0000306 // --------------------------------------------------------------------
307
308 /**
309 * Select Min
310 *
311 * Generates a SELECT MIN(field) portion of a query
312 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000313 * @param string the field
314 * @param string an alias
Andrew Podner4296a652012-12-17 07:51:15 -0500315 * @return CI_DB_query_builder
Derek Allard2067d1a2008-11-13 22:59:24 +0000316 */
Phil Sturgeon9789f322011-07-15 15:14:05 -0600317 public function select_min($select = '', $alias = '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000318 {
319 return $this->_max_min_avg_sum($select, $alias, 'MIN');
320 }
321
322 // --------------------------------------------------------------------
323
324 /**
325 * Select Average
326 *
327 * Generates a SELECT AVG(field) portion of a query
328 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000329 * @param string the field
330 * @param string an alias
Andrew Podner4296a652012-12-17 07:51:15 -0500331 * @return CI_DB_query_builder
Derek Allard2067d1a2008-11-13 22:59:24 +0000332 */
Phil Sturgeon9789f322011-07-15 15:14:05 -0600333 public function select_avg($select = '', $alias = '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000334 {
335 return $this->_max_min_avg_sum($select, $alias, 'AVG');
336 }
337
338 // --------------------------------------------------------------------
339
340 /**
341 * Select Sum
342 *
343 * Generates a SELECT SUM(field) portion of a query
344 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000345 * @param string the field
346 * @param string an alias
Andrew Podner4296a652012-12-17 07:51:15 -0500347 * @return CI_DB_query_builder
Derek Allard2067d1a2008-11-13 22:59:24 +0000348 */
Phil Sturgeon9789f322011-07-15 15:14:05 -0600349 public function select_sum($select = '', $alias = '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000350 {
351 return $this->_max_min_avg_sum($select, $alias, 'SUM');
352 }
353
354 // --------------------------------------------------------------------
355
356 /**
Andrey Andreevae85eb42012-11-02 01:42:31 +0200357 * SELECT [MAX|MIN|AVG|SUM]()
Derek Allard2067d1a2008-11-13 22:59:24 +0000358 *
Andrey Andreevae85eb42012-11-02 01:42:31 +0200359 * @used-by select_max()
360 * @used-by select_min()
361 * @used-by select_avg()
362 * @used-by select_sum()
Barry Mienydd671972010-10-04 16:33:58 +0200363 *
Andrey Andreevae85eb42012-11-02 01:42:31 +0200364 * @param string $select Field name
365 * @param string $alias
366 * @param string $type
Andrew Podner4296a652012-12-17 07:51:15 -0500367 * @return CI_DB_query_builder
Derek Allard2067d1a2008-11-13 22:59:24 +0000368 */
Phil Sturgeon9789f322011-07-15 15:14:05 -0600369 protected function _max_min_avg_sum($select = '', $alias = '', $type = 'MAX')
Derek Allard2067d1a2008-11-13 22:59:24 +0000370 {
Alex Bilbie48a2baf2012-06-02 11:09:54 +0100371 if ( ! is_string($select) OR $select === '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000372 {
373 $this->display_error('db_invalid_query');
374 }
Barry Mienydd671972010-10-04 16:33:58 +0200375
Derek Allard2067d1a2008-11-13 22:59:24 +0000376 $type = strtoupper($type);
Barry Mienydd671972010-10-04 16:33:58 +0200377
Derek Allard2067d1a2008-11-13 22:59:24 +0000378 if ( ! in_array($type, array('MAX', 'MIN', 'AVG', 'SUM')))
379 {
380 show_error('Invalid function type: '.$type);
381 }
Barry Mienydd671972010-10-04 16:33:58 +0200382
Alex Bilbie48a2baf2012-06-02 11:09:54 +0100383 if ($alias === '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000384 {
385 $alias = $this->_create_alias_from_table(trim($select));
386 }
Barry Mienydd671972010-10-04 16:33:58 +0200387
Andrey Andreev5b55c152013-08-06 14:14:32 +0300388 $sql = $type.'('.$this->protect_identifiers(trim($select)).') AS '.$this->escape_identifiers(trim($alias));
Andrey Andreev7b5eb732012-05-24 20:52:41 +0300389
Jamie Rumbelow7efad202012-02-19 12:37:00 +0000390 $this->qb_select[] = $sql;
Jamie Rumbelowd6ce1e92012-04-26 13:27:35 +0100391 $this->qb_no_escape[] = NULL;
Barry Mienydd671972010-10-04 16:33:58 +0200392
Jamie Rumbelow7efad202012-02-19 12:37:00 +0000393 if ($this->qb_caching === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000394 {
Jamie Rumbelow7efad202012-02-19 12:37:00 +0000395 $this->qb_cache_select[] = $sql;
396 $this->qb_cache_exists[] = 'select';
Derek Allard2067d1a2008-11-13 22:59:24 +0000397 }
Barry Mienydd671972010-10-04 16:33:58 +0200398
Derek Allard2067d1a2008-11-13 22:59:24 +0000399 return $this;
400 }
401
402 // --------------------------------------------------------------------
403
404 /**
405 * Determines the alias name based on the table
406 *
Andrey Andreevae85eb42012-11-02 01:42:31 +0200407 * @param string $item
Derek Allard2067d1a2008-11-13 22:59:24 +0000408 * @return string
409 */
Phil Sturgeon9789f322011-07-15 15:14:05 -0600410 protected function _create_alias_from_table($item)
Derek Allard2067d1a2008-11-13 22:59:24 +0000411 {
412 if (strpos($item, '.') !== FALSE)
413 {
Andrey Andreevdb0c0622012-02-29 19:02:46 +0200414 $item = explode('.', $item);
415 return end($item);
Derek Allard2067d1a2008-11-13 22:59:24 +0000416 }
Barry Mienydd671972010-10-04 16:33:58 +0200417
Derek Allard2067d1a2008-11-13 22:59:24 +0000418 return $item;
419 }
420
421 // --------------------------------------------------------------------
422
423 /**
424 * DISTINCT
425 *
426 * Sets a flag which tells the query string compiler to add DISTINCT
427 *
Andrey Andreevae85eb42012-11-02 01:42:31 +0200428 * @param bool $val
Andrew Podner4296a652012-12-17 07:51:15 -0500429 * @return CI_DB_query_builder
Derek Allard2067d1a2008-11-13 22:59:24 +0000430 */
Phil Sturgeon9789f322011-07-15 15:14:05 -0600431 public function distinct($val = TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000432 {
Andrey Andreev7b5eb732012-05-24 20:52:41 +0300433 $this->qb_distinct = is_bool($val) ? $val : TRUE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000434 return $this;
435 }
Barry Mienydd671972010-10-04 16:33:58 +0200436
Derek Allard2067d1a2008-11-13 22:59:24 +0000437 // --------------------------------------------------------------------
438
439 /**
440 * From
441 *
442 * Generates the FROM portion of the query
443 *
Andrey Andreevae85eb42012-11-02 01:42:31 +0200444 * @param mixed $from can be a string or array
Andrew Podner4296a652012-12-17 07:51:15 -0500445 * @return CI_DB_query_builder
Derek Allard2067d1a2008-11-13 22:59:24 +0000446 */
Phil Sturgeon9789f322011-07-15 15:14:05 -0600447 public function from($from)
Derek Allard2067d1a2008-11-13 22:59:24 +0000448 {
Andrey Andreev7b5eb732012-05-24 20:52:41 +0300449 foreach ((array) $from as $val)
Derek Allard2067d1a2008-11-13 22:59:24 +0000450 {
451 if (strpos($val, ',') !== FALSE)
452 {
453 foreach (explode(',', $val) as $v)
454 {
455 $v = trim($v);
456 $this->_track_aliases($v);
Barry Mienydd671972010-10-04 16:33:58 +0200457
George Petsagourakis193d4482012-04-28 11:16:18 +0300458 $this->qb_from[] = $v = $this->protect_identifiers($v, TRUE, NULL, FALSE);
Derek Allard2067d1a2008-11-13 22:59:24 +0000459
Jamie Rumbelow7efad202012-02-19 12:37:00 +0000460 if ($this->qb_caching === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000461 {
Jamie Rumbelow7efad202012-02-19 12:37:00 +0000462 $this->qb_cache_from[] = $v;
463 $this->qb_cache_exists[] = 'from';
Barry Mienydd671972010-10-04 16:33:58 +0200464 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000465 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000466 }
467 else
468 {
469 $val = trim($val);
470
Andrey Andreev24276a32012-01-08 02:44:38 +0200471 // Extract any aliases that might exist. We use this information
Jamie Rumbelow0c092992012-03-06 22:05:16 +0000472 // in the protect_identifiers to know whether to add a table prefix
Derek Allard2067d1a2008-11-13 22:59:24 +0000473 $this->_track_aliases($val);
Barry Mienydd671972010-10-04 16:33:58 +0200474
Jamie Rumbelow0c092992012-03-06 22:05:16 +0000475 $this->qb_from[] = $val = $this->protect_identifiers($val, TRUE, NULL, FALSE);
Derek Allard2067d1a2008-11-13 22:59:24 +0000476
Jamie Rumbelow7efad202012-02-19 12:37:00 +0000477 if ($this->qb_caching === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000478 {
Jamie Rumbelow7efad202012-02-19 12:37:00 +0000479 $this->qb_cache_from[] = $val;
480 $this->qb_cache_exists[] = 'from';
Derek Allard2067d1a2008-11-13 22:59:24 +0000481 }
482 }
483 }
484
485 return $this;
486 }
487
488 // --------------------------------------------------------------------
489
490 /**
Andrey Andreevae85eb42012-11-02 01:42:31 +0200491 * JOIN
Derek Allard2067d1a2008-11-13 22:59:24 +0000492 *
493 * Generates the JOIN portion of the query
494 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000495 * @param string
496 * @param string the join condition
497 * @param string the type of join
Alex Bilbief512b732012-06-16 11:15:19 +0100498 * @param string whether not to try to escape identifiers
Andrew Podner4296a652012-12-17 07:51:15 -0500499 * @return CI_DB_query_builder
Derek Allard2067d1a2008-11-13 22:59:24 +0000500 */
Andrey Andreevfe642da2012-06-16 03:47:33 +0300501 public function join($table, $cond, $type = '', $escape = NULL)
Barry Mienydd671972010-10-04 16:33:58 +0200502 {
Alex Bilbie48a2baf2012-06-02 11:09:54 +0100503 if ($type !== '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000504 {
505 $type = strtoupper(trim($type));
506
Andrey Andreev42870232012-06-12 01:30:20 +0300507 if ( ! in_array($type, array('LEFT', 'RIGHT', 'OUTER', 'INNER', 'LEFT OUTER', 'RIGHT OUTER'), TRUE))
Derek Allard2067d1a2008-11-13 22:59:24 +0000508 {
509 $type = '';
510 }
511 else
512 {
513 $type .= ' ';
514 }
515 }
516
Andrey Andreev24276a32012-01-08 02:44:38 +0200517 // Extract any aliases that might exist. We use this information
Jamie Rumbelow0c092992012-03-06 22:05:16 +0000518 // in the protect_identifiers to know whether to add a table prefix
Derek Allard2067d1a2008-11-13 22:59:24 +0000519 $this->_track_aliases($table);
520
Andrey Andreevfe642da2012-06-16 03:47:33 +0300521 is_bool($escape) OR $escape = $this->_protect_identifiers;
522
Andrey Andreev42870232012-06-12 01:30:20 +0300523 // Split multiple conditions
Andrey Andreev49aa45b2012-07-06 16:22:21 +0300524 if ($escape === TRUE && preg_match_all('/\sAND\s|\sOR\s/i', $cond, $m, PREG_OFFSET_CAPTURE))
Andrey Andreev42870232012-06-12 01:30:20 +0300525 {
526 $newcond = '';
527 $m[0][] = array('', strlen($cond));
528
529 for ($i = 0, $c = count($m[0]), $s = 0;
530 $i < $c;
Andrey Andreev49aa45b2012-07-06 16:22:21 +0300531 $s = $m[0][$i][1] + strlen($m[0][$i][0]), $i++)
Andrey Andreev42870232012-06-12 01:30:20 +0300532 {
Andrey Andreev49aa45b2012-07-06 16:22:21 +0300533 $temp = substr($cond, $s, ($m[0][$i][1] - $s));
Andrey Andreev42870232012-06-12 01:30:20 +0300534
Andrey Andreev49aa45b2012-07-06 16:22:21 +0300535 $newcond .= preg_match("/([\[\]\w\.'-]+)(\s*[^\"\[`'\w]+\s*)(.+)/i", $temp, $match)
Andrey Andreev42870232012-06-12 01:30:20 +0300536 ? $this->protect_identifiers($match[1]).$match[2].$this->protect_identifiers($match[3])
537 : $temp;
538
539 $newcond .= $m[0][$i][0];
540 }
541
Andrey Andreev3751f932012-06-17 18:07:48 +0300542 $cond = ' ON '.$newcond;
Andrey Andreev42870232012-06-12 01:30:20 +0300543 }
544 // Split apart the condition and protect the identifiers
Andrey Andreev49aa45b2012-07-06 16:22:21 +0300545 elseif ($escape === TRUE && preg_match("/([\[\]\w\.'-]+)(\s*[^\"\[`'\w]+\s*)(.+)/i", $cond, $match))
Derek Allard2067d1a2008-11-13 22:59:24 +0000546 {
Andrey Andreev3751f932012-06-17 18:07:48 +0300547 $cond = ' ON '.$this->protect_identifiers($match[1]).$match[2].$this->protect_identifiers($match[3]);
548 }
549 elseif ( ! $this->_has_operator($cond))
550 {
551 $cond = ' USING ('.($escape ? $this->escape_identifiers($cond) : $cond).')';
552 }
553 else
554 {
555 $cond = ' ON '.$cond;
Derek Allard2067d1a2008-11-13 22:59:24 +0000556 }
Barry Mienydd671972010-10-04 16:33:58 +0200557
Andrey Andreev42870232012-06-12 01:30:20 +0300558 // Do we want to escape the table name?
559 if ($escape === TRUE)
560 {
561 $table = $this->protect_identifiers($table, TRUE, NULL, FALSE);
562 }
563
Derek Allard2067d1a2008-11-13 22:59:24 +0000564 // Assemble the JOIN statement
Andrey Andreev3751f932012-06-17 18:07:48 +0300565 $this->qb_join[] = $join = $type.'JOIN '.$table.$cond;
Derek Allard2067d1a2008-11-13 22:59:24 +0000566
Jamie Rumbelow7efad202012-02-19 12:37:00 +0000567 if ($this->qb_caching === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000568 {
Jamie Rumbelow7efad202012-02-19 12:37:00 +0000569 $this->qb_cache_join[] = $join;
570 $this->qb_cache_exists[] = 'join';
Derek Allard2067d1a2008-11-13 22:59:24 +0000571 }
572
573 return $this;
574 }
575
576 // --------------------------------------------------------------------
577
578 /**
Andrey Andreevae85eb42012-11-02 01:42:31 +0200579 * WHERE
Derek Allard2067d1a2008-11-13 22:59:24 +0000580 *
Andrey Andreevae85eb42012-11-02 01:42:31 +0200581 * Generates the WHERE portion of the query.
582 * Separates multiple calls with 'AND'.
Derek Allard2067d1a2008-11-13 22:59:24 +0000583 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000584 * @param mixed
585 * @param mixed
Andrey Andreev42870232012-06-12 01:30:20 +0300586 * @param bool
Andrew Podner4296a652012-12-17 07:51:15 -0500587 * @return CI_DB_query_builder
Derek Allard2067d1a2008-11-13 22:59:24 +0000588 */
Andrey Andreev498c1e02012-06-16 03:34:10 +0300589 public function where($key, $value = NULL, $escape = NULL)
Derek Allard2067d1a2008-11-13 22:59:24 +0000590 {
Andrey Andreevd40459d2012-07-18 16:46:39 +0300591 return $this->_wh('qb_where', $key, $value, 'AND ', $escape);
Derek Allard2067d1a2008-11-13 22:59:24 +0000592 }
Barry Mienydd671972010-10-04 16:33:58 +0200593
Derek Allard2067d1a2008-11-13 22:59:24 +0000594 // --------------------------------------------------------------------
595
596 /**
Andrey Andreevae85eb42012-11-02 01:42:31 +0200597 * OR WHERE
Derek Allard2067d1a2008-11-13 22:59:24 +0000598 *
Andrey Andreevae85eb42012-11-02 01:42:31 +0200599 * Generates the WHERE portion of the query.
600 * Separates multiple calls with 'OR'.
Derek Allard2067d1a2008-11-13 22:59:24 +0000601 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000602 * @param mixed
603 * @param mixed
Andrey Andreev42870232012-06-12 01:30:20 +0300604 * @param bool
Andrew Podner4296a652012-12-17 07:51:15 -0500605 * @return CI_DB_query_builder
Derek Allard2067d1a2008-11-13 22:59:24 +0000606 */
Andrey Andreev498c1e02012-06-16 03:34:10 +0300607 public function or_where($key, $value = NULL, $escape = NULL)
Derek Allard2067d1a2008-11-13 22:59:24 +0000608 {
Andrey Andreevd40459d2012-07-18 16:46:39 +0300609 return $this->_wh('qb_where', $key, $value, 'OR ', $escape);
Derek Allard2067d1a2008-11-13 22:59:24 +0000610 }
611
612 // --------------------------------------------------------------------
613
614 /**
Andrey Andreevd40459d2012-07-18 16:46:39 +0300615 * WHERE, HAVING
Derek Allard2067d1a2008-11-13 22:59:24 +0000616 *
Andrey Andreevae85eb42012-11-02 01:42:31 +0200617 * @used-by where()
618 * @used-by or_where()
619 * @used-by having()
620 * @used-by or_having()
Derek Allard2067d1a2008-11-13 22:59:24 +0000621 *
Andrey Andreevae85eb42012-11-02 01:42:31 +0200622 * @param string $qb_key 'qb_where' or 'qb_having'
623 * @param mixed $key
624 * @param mixed $value
625 * @param string $type
626 * @param bool $escape
Andrew Podner4296a652012-12-17 07:51:15 -0500627 * @return CI_DB_query_builder
Derek Allard2067d1a2008-11-13 22:59:24 +0000628 */
Andrey Andreevd40459d2012-07-18 16:46:39 +0300629 protected function _wh($qb_key, $key, $value = NULL, $type = 'AND ', $escape = NULL)
Derek Allard2067d1a2008-11-13 22:59:24 +0000630 {
Andrey Andreevd40459d2012-07-18 16:46:39 +0300631 $qb_cache_key = ($qb_key === 'qb_having') ? 'qb_cache_having' : 'qb_cache_where';
632
Derek Allard2067d1a2008-11-13 22:59:24 +0000633 if ( ! is_array($key))
634 {
635 $key = array($key => $value);
636 }
Barry Mienydd671972010-10-04 16:33:58 +0200637
Derek Allard2067d1a2008-11-13 22:59:24 +0000638 // If the escape value was not set will will base it on the global setting
Andrey Andreeve10fb792012-06-15 12:07:04 +0300639 is_bool($escape) OR $escape = $this->_protect_identifiers;
Derek Allard2067d1a2008-11-13 22:59:24 +0000640
641 foreach ($key as $k => $v)
642 {
Andrey Andreevd40459d2012-07-18 16:46:39 +0300643 $prefix = (count($this->$qb_key) === 0 && count($this->$qb_cache_key) === 0)
Andrey Andreev58803fb2012-06-24 00:45:37 +0300644 ? $this->_group_get_type('')
645 : $this->_group_get_type($type);
Derek Allard2067d1a2008-11-13 22:59:24 +0000646
vlakoff1228fe22013-01-14 01:30:09 +0100647 if ($v !== NULL)
Derek Allard2067d1a2008-11-13 22:59:24 +0000648 {
649 if ($escape === TRUE)
650 {
Andrey Andreev3a5efc22012-11-20 21:18:08 +0200651 $v = ' '.$this->escape($v);
Derek Allard2067d1a2008-11-13 22:59:24 +0000652 }
WanWizard7219c072011-12-28 14:09:05 +0100653
Derek Allard2067d1a2008-11-13 22:59:24 +0000654 if ( ! $this->_has_operator($k))
655 {
Greg Akere156c6e2011-04-20 16:03:04 -0500656 $k .= ' = ';
Derek Allard2067d1a2008-11-13 22:59:24 +0000657 }
658 }
Andrey Andreev3a5efc22012-11-20 21:18:08 +0200659 elseif ( ! $this->_has_operator($k))
660 {
661 // value appears not to have been set, assign the test to IS NULL
662 $k .= ' IS NULL';
663 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000664
Andrey Andreevd40459d2012-07-18 16:46:39 +0300665 $this->{$qb_key}[] = array('condition' => $prefix.$k.$v, 'escape' => $escape);
Jamie Rumbelow7efad202012-02-19 12:37:00 +0000666 if ($this->qb_caching === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000667 {
Andrey Andreevd40459d2012-07-18 16:46:39 +0300668 $this->{$qb_cache_key}[] = array('condition' => $prefix.$k.$v, 'escape' => $escape);
669 $this->qb_cache_exists[] = substr($qb_key, 3);
Derek Allard2067d1a2008-11-13 22:59:24 +0000670 }
Barry Mienydd671972010-10-04 16:33:58 +0200671
Derek Allard2067d1a2008-11-13 22:59:24 +0000672 }
Barry Mienydd671972010-10-04 16:33:58 +0200673
Derek Allard2067d1a2008-11-13 22:59:24 +0000674 return $this;
675 }
676
677 // --------------------------------------------------------------------
678
679 /**
Andrey Andreevae85eb42012-11-02 01:42:31 +0200680 * WHERE IN
Derek Allard2067d1a2008-11-13 22:59:24 +0000681 *
Andrey Andreevae85eb42012-11-02 01:42:31 +0200682 * Generates a WHERE field IN('item', 'item') SQL query,
683 * joined with 'AND' if appropriate.
Derek Allard2067d1a2008-11-13 22:59:24 +0000684 *
Andrey Andreevae85eb42012-11-02 01:42:31 +0200685 * @param string $key The field to search
686 * @param array $values The values searched on
687 * @param bool $escape
Andrew Podner4296a652012-12-17 07:51:15 -0500688 * @return CI_DB_query_builder
Derek Allard2067d1a2008-11-13 22:59:24 +0000689 */
Andrey Andreev498c1e02012-06-16 03:34:10 +0300690 public function where_in($key = NULL, $values = NULL, $escape = NULL)
Derek Allard2067d1a2008-11-13 22:59:24 +0000691 {
Andrey Andreev498c1e02012-06-16 03:34:10 +0300692 return $this->_where_in($key, $values, FALSE, 'AND ', $escape);
Derek Allard2067d1a2008-11-13 22:59:24 +0000693 }
Barry Mienydd671972010-10-04 16:33:58 +0200694
Derek Allard2067d1a2008-11-13 22:59:24 +0000695 // --------------------------------------------------------------------
696
697 /**
Andrey Andreevae85eb42012-11-02 01:42:31 +0200698 * OR WHERE IN
Derek Allard2067d1a2008-11-13 22:59:24 +0000699 *
Andrey Andreevae85eb42012-11-02 01:42:31 +0200700 * Generates a WHERE field IN('item', 'item') SQL query,
701 * joined with 'OR' if appropriate.
Derek Allard2067d1a2008-11-13 22:59:24 +0000702 *
Andrey Andreevae85eb42012-11-02 01:42:31 +0200703 * @param string $key The field to search
704 * @param array $values The values searched on
705 * @param bool $escape
Andrew Podner4296a652012-12-17 07:51:15 -0500706 * @return CI_DB_query_builder
Derek Allard2067d1a2008-11-13 22:59:24 +0000707 */
Andrey Andreev498c1e02012-06-16 03:34:10 +0300708 public function or_where_in($key = NULL, $values = NULL, $escape = NULL)
Derek Allard2067d1a2008-11-13 22:59:24 +0000709 {
Andrey Andreev498c1e02012-06-16 03:34:10 +0300710 return $this->_where_in($key, $values, FALSE, 'OR ', $escape);
Derek Allard2067d1a2008-11-13 22:59:24 +0000711 }
712
713 // --------------------------------------------------------------------
714
715 /**
Andrey Andreevae85eb42012-11-02 01:42:31 +0200716 * WHERE NOT IN
Derek Allard2067d1a2008-11-13 22:59:24 +0000717 *
Andrey Andreevae85eb42012-11-02 01:42:31 +0200718 * Generates a WHERE field NOT IN('item', 'item') SQL query,
719 * joined with 'AND' if appropriate.
Derek Allard2067d1a2008-11-13 22:59:24 +0000720 *
Andrey Andreevae85eb42012-11-02 01:42:31 +0200721 * @param string $key The field to search
722 * @param array $values The values searched on
723 * @param bool $escape
Andrew Podner4296a652012-12-17 07:51:15 -0500724 * @return CI_DB_query_builder
Derek Allard2067d1a2008-11-13 22:59:24 +0000725 */
Andrey Andreev498c1e02012-06-16 03:34:10 +0300726 public function where_not_in($key = NULL, $values = NULL, $escape = NULL)
Derek Allard2067d1a2008-11-13 22:59:24 +0000727 {
Andrey Andreev498c1e02012-06-16 03:34:10 +0300728 return $this->_where_in($key, $values, TRUE, 'AND ', $escape);
Derek Allard2067d1a2008-11-13 22:59:24 +0000729 }
Barry Mienydd671972010-10-04 16:33:58 +0200730
Derek Allard2067d1a2008-11-13 22:59:24 +0000731 // --------------------------------------------------------------------
732
733 /**
Andrey Andreevae85eb42012-11-02 01:42:31 +0200734 * OR WHERE NOT IN
Derek Allard2067d1a2008-11-13 22:59:24 +0000735 *
Andrey Andreevae85eb42012-11-02 01:42:31 +0200736 * Generates a WHERE field NOT IN('item', 'item') SQL query,
737 * joined with 'OR' if appropriate.
Derek Allard2067d1a2008-11-13 22:59:24 +0000738 *
Andrey Andreevae85eb42012-11-02 01:42:31 +0200739 * @param string $key The field to search
740 * @param array $values The values searched on
741 * @param bool $escape
Andrew Podner4296a652012-12-17 07:51:15 -0500742 * @return CI_DB_query_builder
Derek Allard2067d1a2008-11-13 22:59:24 +0000743 */
Andrey Andreev498c1e02012-06-16 03:34:10 +0300744 public function or_where_not_in($key = NULL, $values = NULL, $escape = NULL)
Derek Allard2067d1a2008-11-13 22:59:24 +0000745 {
Andrey Andreev498c1e02012-06-16 03:34:10 +0300746 return $this->_where_in($key, $values, TRUE, 'OR ', $escape);
Derek Allard2067d1a2008-11-13 22:59:24 +0000747 }
748
749 // --------------------------------------------------------------------
750
751 /**
Andrey Andreevae85eb42012-11-02 01:42:31 +0200752 * Internal WHERE IN
Derek Allard2067d1a2008-11-13 22:59:24 +0000753 *
Andrey Andreevae85eb42012-11-02 01:42:31 +0200754 * @used-by where_in()
755 * @used-by or_where_in()
756 * @used-by where_not_in()
757 * @used-by or_where_not_in()
Derek Allard2067d1a2008-11-13 22:59:24 +0000758 *
Andrey Andreevae85eb42012-11-02 01:42:31 +0200759 * @param string $key The field to search
760 * @param array $values The values searched on
761 * @param bool $not If the statement would be IN or NOT IN
762 * @param string $type
763 * @param bool $escape
Andrew Podner4296a652012-12-17 07:51:15 -0500764 * @return CI_DB_query_builder
Derek Allard2067d1a2008-11-13 22:59:24 +0000765 */
Andrey Andreev498c1e02012-06-16 03:34:10 +0300766 protected function _where_in($key = NULL, $values = NULL, $not = FALSE, $type = 'AND ', $escape = NULL)
Derek Allard2067d1a2008-11-13 22:59:24 +0000767 {
768 if ($key === NULL OR $values === NULL)
769 {
Rafael Queiroz6600b692012-06-08 14:34:20 -0300770 return $this;
Derek Allard2067d1a2008-11-13 22:59:24 +0000771 }
Barry Mienydd671972010-10-04 16:33:58 +0200772
Derek Allard2067d1a2008-11-13 22:59:24 +0000773 if ( ! is_array($values))
774 {
775 $values = array($values);
776 }
Barry Mienydd671972010-10-04 16:33:58 +0200777
Andrey Andreev498c1e02012-06-16 03:34:10 +0300778 is_bool($escape) OR $escape = $this->_protect_identifiers;
779
Derek Allard2067d1a2008-11-13 22:59:24 +0000780 $not = ($not) ? ' NOT' : '';
781
Andrey Andreev94611df2012-07-19 12:29:54 +0300782 $where_in = array();
Derek Allard2067d1a2008-11-13 22:59:24 +0000783 foreach ($values as $value)
784 {
Andrey Andreevcc02db92012-10-12 14:30:10 +0300785 $where_in[] = $this->escape($value);
Derek Allard2067d1a2008-11-13 22:59:24 +0000786 }
787
WanWizardbc69f362012-06-22 00:10:11 +0200788 $prefix = (count($this->qb_where) === 0) ? $this->_group_get_type('') : $this->_group_get_type($type);
Andrey Andreev6e704752012-07-18 00:46:33 +0300789 $where_in = array(
Andrey Andreev94611df2012-07-19 12:29:54 +0300790 'condition' => $prefix.$key.$not.' IN('.implode(', ', $where_in).')',
Andrey Andreev6e704752012-07-18 00:46:33 +0300791 'escape' => $escape
792 );
Barry Mienydd671972010-10-04 16:33:58 +0200793
Andrey Andreev6e704752012-07-18 00:46:33 +0300794 $this->qb_where[] = $where_in;
Jamie Rumbelow7efad202012-02-19 12:37:00 +0000795 if ($this->qb_caching === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000796 {
Jamie Rumbelow7efad202012-02-19 12:37:00 +0000797 $this->qb_cache_where[] = $where_in;
798 $this->qb_cache_exists[] = 'where';
Derek Allard2067d1a2008-11-13 22:59:24 +0000799 }
800
Derek Allard2067d1a2008-11-13 22:59:24 +0000801 return $this;
802 }
Barry Mienydd671972010-10-04 16:33:58 +0200803
Derek Allard2067d1a2008-11-13 22:59:24 +0000804 // --------------------------------------------------------------------
805
806 /**
Andrey Andreevae85eb42012-11-02 01:42:31 +0200807 * LIKE
Derek Allard2067d1a2008-11-13 22:59:24 +0000808 *
Andrey Andreevae85eb42012-11-02 01:42:31 +0200809 * Generates a %LIKE% portion of the query.
810 * Separates multiple calls with 'AND'.
Derek Allard2067d1a2008-11-13 22:59:24 +0000811 *
Andrey Andreevae85eb42012-11-02 01:42:31 +0200812 * @param mixed $field
813 * @param string $match
814 * @param string $side
815 * @param bool $escape
Andrew Podner4296a652012-12-17 07:51:15 -0500816 * @return CI_DB_query_builder
Derek Allard2067d1a2008-11-13 22:59:24 +0000817 */
Andrey Andreevb0478652012-07-18 15:34:46 +0300818 public function like($field, $match = '', $side = 'both', $escape = NULL)
Derek Allard2067d1a2008-11-13 22:59:24 +0000819 {
Andrey Andreevb0478652012-07-18 15:34:46 +0300820 return $this->_like($field, $match, 'AND ', $side, '', $escape);
Derek Allard2067d1a2008-11-13 22:59:24 +0000821 }
822
823 // --------------------------------------------------------------------
824
825 /**
Andrey Andreevae85eb42012-11-02 01:42:31 +0200826 * NOT LIKE
Derek Allard2067d1a2008-11-13 22:59:24 +0000827 *
Andrey Andreevae85eb42012-11-02 01:42:31 +0200828 * Generates a NOT LIKE portion of the query.
829 * Separates multiple calls with 'AND'.
Derek Allard2067d1a2008-11-13 22:59:24 +0000830 *
Andrey Andreevae85eb42012-11-02 01:42:31 +0200831 * @param mixed $field
832 * @param string $match
833 * @param string $side
834 * @param bool $escape
Andrew Podner4296a652012-12-17 07:51:15 -0500835 * @return CI_DB_query_builder
Derek Allard2067d1a2008-11-13 22:59:24 +0000836 */
Andrey Andreevb0478652012-07-18 15:34:46 +0300837 public function not_like($field, $match = '', $side = 'both', $escape = NULL)
Derek Allard2067d1a2008-11-13 22:59:24 +0000838 {
Andrey Andreevb0478652012-07-18 15:34:46 +0300839 return $this->_like($field, $match, 'AND ', $side, 'NOT', $escape);
Derek Allard2067d1a2008-11-13 22:59:24 +0000840 }
Barry Mienydd671972010-10-04 16:33:58 +0200841
Derek Allard2067d1a2008-11-13 22:59:24 +0000842 // --------------------------------------------------------------------
843
844 /**
Andrey Andreevae85eb42012-11-02 01:42:31 +0200845 * OR LIKE
Derek Allard2067d1a2008-11-13 22:59:24 +0000846 *
Andrey Andreevae85eb42012-11-02 01:42:31 +0200847 * Generates a %LIKE% portion of the query.
848 * Separates multiple calls with 'OR'.
Derek Allard2067d1a2008-11-13 22:59:24 +0000849 *
Andrey Andreevae85eb42012-11-02 01:42:31 +0200850 * @param mixed $field
851 * @param string $match
852 * @param string $side
853 * @param bool $escape
Andrew Podner4296a652012-12-17 07:51:15 -0500854 * @return CI_DB_query_builder
Derek Allard2067d1a2008-11-13 22:59:24 +0000855 */
Andrey Andreevb0478652012-07-18 15:34:46 +0300856 public function or_like($field, $match = '', $side = 'both', $escape = NULL)
Derek Allard2067d1a2008-11-13 22:59:24 +0000857 {
Andrey Andreevb0478652012-07-18 15:34:46 +0300858 return $this->_like($field, $match, 'OR ', $side, '', $escape);
Derek Allard2067d1a2008-11-13 22:59:24 +0000859 }
860
861 // --------------------------------------------------------------------
862
863 /**
Andrey Andreevae85eb42012-11-02 01:42:31 +0200864 * OR NOT LIKE
Derek Allard2067d1a2008-11-13 22:59:24 +0000865 *
Andrey Andreevae85eb42012-11-02 01:42:31 +0200866 * Generates a NOT LIKE portion of the query.
867 * Separates multiple calls with 'OR'.
Derek Allard2067d1a2008-11-13 22:59:24 +0000868 *
Andrey Andreevae85eb42012-11-02 01:42:31 +0200869 * @param mixed $field
870 * @param string $match
871 * @param string $side
872 * @param bool $escape
Andrew Podner4296a652012-12-17 07:51:15 -0500873 * @return CI_DB_query_builder
Derek Allard2067d1a2008-11-13 22:59:24 +0000874 */
Andrey Andreevb0478652012-07-18 15:34:46 +0300875 public function or_not_like($field, $match = '', $side = 'both', $escape = NULL)
Derek Allard2067d1a2008-11-13 22:59:24 +0000876 {
Andrey Andreevb0478652012-07-18 15:34:46 +0300877 return $this->_like($field, $match, 'OR ', $side, 'NOT', $escape);
Derek Allard2067d1a2008-11-13 22:59:24 +0000878 }
Barry Mienydd671972010-10-04 16:33:58 +0200879
Derek Allard2067d1a2008-11-13 22:59:24 +0000880 // --------------------------------------------------------------------
881
882 /**
Andrey Andreevae85eb42012-11-02 01:42:31 +0200883 * Internal LIKE
Derek Allard2067d1a2008-11-13 22:59:24 +0000884 *
Andrey Andreevae85eb42012-11-02 01:42:31 +0200885 * @used-by like()
886 * @used-by or_like()
887 * @used-by not_like()
888 * @used-by or_not_like()
Derek Allard2067d1a2008-11-13 22:59:24 +0000889 *
Andrey Andreevae85eb42012-11-02 01:42:31 +0200890 * @param mixed $field
891 * @param string $match
892 * @param string $type
893 * @param string $side
894 * @param string $not
895 * @param bool $escape
Andrew Podner4296a652012-12-17 07:51:15 -0500896 * @return CI_DB_query_builder
Derek Allard2067d1a2008-11-13 22:59:24 +0000897 */
Andrey Andreevb0478652012-07-18 15:34:46 +0300898 protected function _like($field, $match = '', $type = 'AND ', $side = 'both', $not = '', $escape = NULL)
Derek Allard2067d1a2008-11-13 22:59:24 +0000899 {
900 if ( ! is_array($field))
901 {
902 $field = array($field => $match);
903 }
Barry Mienydd671972010-10-04 16:33:58 +0200904
Andrey Andreevb0478652012-07-18 15:34:46 +0300905 is_bool($escape) OR $escape = $this->_protect_identifiers;
Andrey Andreevb0478652012-07-18 15:34:46 +0300906
Derek Allard2067d1a2008-11-13 22:59:24 +0000907 foreach ($field as $k => $v)
908 {
Andrey Andreev41738232012-11-30 00:13:17 +0200909 $prefix = (count($this->qb_where) === 0 && count($this->qb_cache_where) === 0)
910 ? $this->_group_get_type('') : $this->_group_get_type($type);
911
Derek Jonese4ed5832009-02-20 21:44:59 +0000912 $v = $this->escape_like_str($v);
Andrey Andreevfc11dcc2012-06-04 16:39:19 +0300913
Andrey Andreev24276a32012-01-08 02:44:38 +0200914 if ($side === 'none')
Kyle Farris81ef70f2011-08-31 11:59:12 -0400915 {
Andrey Andreevb0478652012-07-18 15:34:46 +0300916 $like_statement = "{$prefix} {$k} {$not} LIKE '{$v}'";
Kyle Farris81ef70f2011-08-31 11:59:12 -0400917 }
Andrey Andreev24276a32012-01-08 02:44:38 +0200918 elseif ($side === 'before')
Derek Allard2067d1a2008-11-13 22:59:24 +0000919 {
Andrey Andreevb0478652012-07-18 15:34:46 +0300920 $like_statement = "{$prefix} {$k} {$not} LIKE '%{$v}'";
Derek Allard2067d1a2008-11-13 22:59:24 +0000921 }
Andrey Andreev24276a32012-01-08 02:44:38 +0200922 elseif ($side === 'after')
Derek Allard2067d1a2008-11-13 22:59:24 +0000923 {
Andrey Andreevb0478652012-07-18 15:34:46 +0300924 $like_statement = "{$prefix} {$k} {$not} LIKE '{$v}%'";
Derek Allard2067d1a2008-11-13 22:59:24 +0000925 }
926 else
927 {
Andrey Andreevb0478652012-07-18 15:34:46 +0300928 $like_statement = "{$prefix} {$k} {$not} LIKE '%{$v}%'";
Derek Allard2067d1a2008-11-13 22:59:24 +0000929 }
Derek Jonesd10e8962010-03-02 17:10:36 -0600930
Derek Jonese4ed5832009-02-20 21:44:59 +0000931 // some platforms require an escape sequence definition for LIKE wildcards
Alex Bilbie48a2baf2012-06-02 11:09:54 +0100932 if ($this->_like_escape_str !== '')
Derek Jonese4ed5832009-02-20 21:44:59 +0000933 {
Andrey Andreevb0478652012-07-18 15:34:46 +0300934 $like_statement .= sprintf($this->_like_escape_str, $this->_like_escape_chr);
Derek Jonese4ed5832009-02-20 21:44:59 +0000935 }
Derek Jonesd10e8962010-03-02 17:10:36 -0600936
Andrey Andreevb0478652012-07-18 15:34:46 +0300937 $this->qb_where[] = array('condition' => $like_statement, 'escape' => $escape);
Jamie Rumbelow7efad202012-02-19 12:37:00 +0000938 if ($this->qb_caching === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000939 {
Andrey Andreev55bbd722013-01-28 19:02:13 +0200940 $this->qb_cache_where[] = array('condition' => $like_statement, 'escape' => $escape);
Andrey Andreevededc4a2012-07-18 01:16:15 +0300941 $this->qb_cache_exists[] = 'where';
Derek Allard2067d1a2008-11-13 22:59:24 +0000942 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000943 }
Andrey Andreev24276a32012-01-08 02:44:38 +0200944
Derek Allard2067d1a2008-11-13 22:59:24 +0000945 return $this;
946 }
Barry Mienydd671972010-10-04 16:33:58 +0200947
Derek Allard2067d1a2008-11-13 22:59:24 +0000948 // --------------------------------------------------------------------
949
950 /**
WanWizard7219c072011-12-28 14:09:05 +0100951 * Starts a query group.
952 *
Andrey Andreevae85eb42012-11-02 01:42:31 +0200953 * @param string $not (Internal use only)
954 * @param string $type (Internal use only)
Andrew Podner4296a652012-12-17 07:51:15 -0500955 * @return CI_DB_query_builder
WanWizard7219c072011-12-28 14:09:05 +0100956 */
957 public function group_start($not = '', $type = 'AND ')
958 {
959 $type = $this->_group_get_type($type);
WanWizard7219c072011-12-28 14:09:05 +0100960
Jamie Rumbelow7efad202012-02-19 12:37:00 +0000961 $this->qb_where_group_started = TRUE;
Jamie Rumbelowd6ce1e92012-04-26 13:27:35 +0100962 $prefix = (count($this->qb_where) === 0 && count($this->qb_cache_where) === 0) ? '' : $type;
Andrey Andreev6e704752012-07-18 00:46:33 +0300963 $where = array(
964 'condition' => $prefix.$not.str_repeat(' ', ++$this->qb_where_group_count).' (',
965 'escape' => FALSE
966 );
WanWizard7219c072011-12-28 14:09:05 +0100967
Andrey Andreev6e704752012-07-18 00:46:33 +0300968 $this->qb_where[] = $where;
Jamie Rumbelow7efad202012-02-19 12:37:00 +0000969 if ($this->qb_caching)
WanWizard7219c072011-12-28 14:09:05 +0100970 {
Andrey Andreev6e704752012-07-18 00:46:33 +0300971 $this->qb_cache_where[] = $where;
WanWizard7219c072011-12-28 14:09:05 +0100972 }
973
974 return $this;
975 }
976
977 // --------------------------------------------------------------------
978
979 /**
980 * Starts a query group, but ORs the group
981 *
Andrew Podner4296a652012-12-17 07:51:15 -0500982 * @return CI_DB_query_builder
WanWizard7219c072011-12-28 14:09:05 +0100983 */
984 public function or_group_start()
985 {
986 return $this->group_start('', 'OR ');
987 }
988
989 // --------------------------------------------------------------------
990
991 /**
992 * Starts a query group, but NOTs the group
993 *
Andrew Podner4296a652012-12-17 07:51:15 -0500994 * @return CI_DB_query_builder
WanWizard7219c072011-12-28 14:09:05 +0100995 */
996 public function not_group_start()
997 {
998 return $this->group_start('NOT ', 'AND ');
999 }
1000
1001 // --------------------------------------------------------------------
1002
1003 /**
1004 * Starts a query group, but OR NOTs the group
1005 *
Andrew Podner4296a652012-12-17 07:51:15 -05001006 * @return CI_DB_query_builder
WanWizard7219c072011-12-28 14:09:05 +01001007 */
1008 public function or_not_group_start()
1009 {
1010 return $this->group_start('NOT ', 'OR ');
1011 }
1012
1013 // --------------------------------------------------------------------
1014
1015 /**
1016 * Ends a query group
1017 *
Andrew Podner4296a652012-12-17 07:51:15 -05001018 * @return CI_DB_query_builder
WanWizard7219c072011-12-28 14:09:05 +01001019 */
1020 public function group_end()
1021 {
Jamie Rumbelow7efad202012-02-19 12:37:00 +00001022 $this->qb_where_group_started = FALSE;
Andrey Andreev6e704752012-07-18 00:46:33 +03001023 $where = array(
1024 'condition' => str_repeat(' ', $this->qb_where_group_count--).')',
1025 'escape' => FALSE
1026 );
WanWizard7219c072011-12-28 14:09:05 +01001027
Andrey Andreev6e704752012-07-18 00:46:33 +03001028 $this->qb_where[] = $where;
Jamie Rumbelow7efad202012-02-19 12:37:00 +00001029 if ($this->qb_caching)
WanWizard7219c072011-12-28 14:09:05 +01001030 {
Andrey Andreev6e704752012-07-18 00:46:33 +03001031 $this->qb_cache_where[] = $where;
WanWizard7219c072011-12-28 14:09:05 +01001032 }
1033
WanWizard7219c072011-12-28 14:09:05 +01001034 return $this;
1035 }
1036
1037 // --------------------------------------------------------------------
1038
1039 /**
1040 * Group_get_type
1041 *
Andrey Andreevae85eb42012-11-02 01:42:31 +02001042 * @used-by group_start()
1043 * @used-by _like()
1044 * @used-by _wh()
1045 * @used-by _where_in()
WanWizard7219c072011-12-28 14:09:05 +01001046 *
Andrey Andreevae85eb42012-11-02 01:42:31 +02001047 * @param string $type
WanWizard7219c072011-12-28 14:09:05 +01001048 * @return string
1049 */
1050 protected function _group_get_type($type)
1051 {
Jamie Rumbelow7efad202012-02-19 12:37:00 +00001052 if ($this->qb_where_group_started)
WanWizard7219c072011-12-28 14:09:05 +01001053 {
1054 $type = '';
Jamie Rumbelow7efad202012-02-19 12:37:00 +00001055 $this->qb_where_group_started = FALSE;
WanWizard7219c072011-12-28 14:09:05 +01001056 }
1057
1058 return $type;
1059 }
1060
1061 // --------------------------------------------------------------------
1062
1063 /**
Derek Allard2067d1a2008-11-13 22:59:24 +00001064 * GROUP BY
1065 *
Andrey Andreevae85eb42012-11-02 01:42:31 +02001066 * @param string $by
1067 * @param bool $escape
Andrew Podner4296a652012-12-17 07:51:15 -05001068 * @return CI_DB_query_builder
Derek Allard2067d1a2008-11-13 22:59:24 +00001069 */
Andrey Andreevc9b924c2012-07-19 13:06:02 +03001070 public function group_by($by, $escape = NULL)
Derek Allard2067d1a2008-11-13 22:59:24 +00001071 {
Andrey Andreev96feb582012-07-19 13:12:34 +03001072 is_bool($escape) OR $escape = $this->_protect_identifiers;
1073
Derek Allard2067d1a2008-11-13 22:59:24 +00001074 if (is_string($by))
1075 {
Andrey Andreev96feb582012-07-19 13:12:34 +03001076 $by = ($escape === TRUE)
1077 ? explode(',', $by)
1078 : array($by);
Derek Allard2067d1a2008-11-13 22:59:24 +00001079 }
Barry Mienydd671972010-10-04 16:33:58 +02001080
Derek Allard2067d1a2008-11-13 22:59:24 +00001081 foreach ($by as $val)
1082 {
1083 $val = trim($val);
Barry Mienydd671972010-10-04 16:33:58 +02001084
Alex Bilbie48a2baf2012-06-02 11:09:54 +01001085 if ($val !== '')
Derek Allard2067d1a2008-11-13 22:59:24 +00001086 {
Andrey Andreev96feb582012-07-19 13:12:34 +03001087 $val = array('field' => $val, 'escape' => $escape);
Barry Mienydd671972010-10-04 16:33:58 +02001088
Andrey Andreev96feb582012-07-19 13:12:34 +03001089 $this->qb_groupby[] = $val;
Jamie Rumbelow7efad202012-02-19 12:37:00 +00001090 if ($this->qb_caching === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +00001091 {
Jamie Rumbelow7efad202012-02-19 12:37:00 +00001092 $this->qb_cache_groupby[] = $val;
1093 $this->qb_cache_exists[] = 'groupby';
Derek Allard2067d1a2008-11-13 22:59:24 +00001094 }
1095 }
1096 }
Andrey Andreev24276a32012-01-08 02:44:38 +02001097
Derek Allard2067d1a2008-11-13 22:59:24 +00001098 return $this;
1099 }
1100
1101 // --------------------------------------------------------------------
1102
1103 /**
Andrey Andreevae85eb42012-11-02 01:42:31 +02001104 * HAVING
Derek Allard2067d1a2008-11-13 22:59:24 +00001105 *
Andrey Andreevae85eb42012-11-02 01:42:31 +02001106 * Separates multiple calls with 'AND'.
Derek Allard2067d1a2008-11-13 22:59:24 +00001107 *
Andrey Andreevae85eb42012-11-02 01:42:31 +02001108 * @param string $key
1109 * @param string $value
1110 * @param bool $escape
Derek Allard2067d1a2008-11-13 22:59:24 +00001111 * @return object
1112 */
Andrey Andreev0bcf5902012-10-12 13:03:29 +03001113 public function having($key, $value = NULL, $escape = NULL)
Derek Allard2067d1a2008-11-13 22:59:24 +00001114 {
Andrey Andreevd40459d2012-07-18 16:46:39 +03001115 return $this->_wh('qb_having', $key, $value, 'AND ', $escape);
Derek Allard2067d1a2008-11-13 22:59:24 +00001116 }
Barry Mienydd671972010-10-04 16:33:58 +02001117
Derek Allard2067d1a2008-11-13 22:59:24 +00001118 // --------------------------------------------------------------------
1119
1120 /**
Andrey Andreevae85eb42012-11-02 01:42:31 +02001121 * OR HAVING
Derek Allard2067d1a2008-11-13 22:59:24 +00001122 *
Andrey Andreevae85eb42012-11-02 01:42:31 +02001123 * Separates multiple calls with 'OR'.
Derek Allard2067d1a2008-11-13 22:59:24 +00001124 *
Andrey Andreevae85eb42012-11-02 01:42:31 +02001125 * @param string $key
1126 * @param string $value
1127 * @param bool $escape
Derek Allard2067d1a2008-11-13 22:59:24 +00001128 * @return object
1129 */
Andrey Andreev0bcf5902012-10-12 13:03:29 +03001130 public function or_having($key, $value = NULL, $escape = NULL)
Derek Allard2067d1a2008-11-13 22:59:24 +00001131 {
Andrey Andreevd40459d2012-07-18 16:46:39 +03001132 return $this->_wh('qb_having', $key, $value, 'OR ', $escape);
Derek Allard2067d1a2008-11-13 22:59:24 +00001133 }
Barry Mienydd671972010-10-04 16:33:58 +02001134
Derek Allard2067d1a2008-11-13 22:59:24 +00001135 // --------------------------------------------------------------------
1136
1137 /**
Andrey Andreevae85eb42012-11-02 01:42:31 +02001138 * ORDER BY
Derek Allard2067d1a2008-11-13 22:59:24 +00001139 *
Andrey Andreevae85eb42012-11-02 01:42:31 +02001140 * @param string $orderby
1141 * @param string $direction ASC or DESC
1142 * @param bool $escape
Andrew Podner4296a652012-12-17 07:51:15 -05001143 * @return CI_DB_query_builder
Derek Allard2067d1a2008-11-13 22:59:24 +00001144 */
Andrey Andreevd24160c2012-06-16 03:21:20 +03001145 public function order_by($orderby, $direction = '', $escape = NULL)
Derek Allard2067d1a2008-11-13 22:59:24 +00001146 {
Andrey Andreev98e46cf2012-11-13 03:01:42 +02001147 $direction = strtoupper(trim($direction));
Andrey Andreev2d486232012-07-19 14:46:51 +03001148
Andrey Andreev98e46cf2012-11-13 03:01:42 +02001149 if ($direction === 'RANDOM')
Derek Allard2067d1a2008-11-13 22:59:24 +00001150 {
Andrey Andreev2d486232012-07-19 14:46:51 +03001151 $direction = '';
Andrey Andreev98e46cf2012-11-13 03:01:42 +02001152
1153 // Do we have a seed value?
1154 $orderby = ctype_digit((string) $orderby)
vlakoffe6c4d5b2013-09-08 13:54:57 +02001155 ? sprintf($this->_random_keyword[1], $orderby)
Andrey Andreev98e46cf2012-11-13 03:01:42 +02001156 : $this->_random_keyword[0];
Derek Allard2067d1a2008-11-13 22:59:24 +00001157 }
Andrey Andreev2d486232012-07-19 14:46:51 +03001158 elseif (empty($orderby))
Derek Allard2067d1a2008-11-13 22:59:24 +00001159 {
Andrey Andreev2d486232012-07-19 14:46:51 +03001160 return $this;
1161 }
1162 elseif ($direction !== '')
1163 {
Andrey Andreev98e46cf2012-11-13 03:01:42 +02001164 $direction = in_array($direction, array('ASC', 'DESC'), TRUE) ? ' '.$direction : '';
Derek Allard2067d1a2008-11-13 22:59:24 +00001165 }
Barry Mienydd671972010-10-04 16:33:58 +02001166
Andrey Andreevd24160c2012-06-16 03:21:20 +03001167 is_bool($escape) OR $escape = $this->_protect_identifiers;
Barry Mienydd671972010-10-04 16:33:58 +02001168
Andrey Andreev2d486232012-07-19 14:46:51 +03001169 if ($escape === FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +00001170 {
Andrey Andreev93dd2f22012-10-24 10:09:18 +03001171 $qb_orderby[] = array('field' => $orderby, 'direction' => $direction, 'escape' => FALSE);
Andrey Andreev2d486232012-07-19 14:46:51 +03001172 }
1173 else
1174 {
1175 $qb_orderby = array();
1176 foreach (explode(',', $orderby) as $field)
Derek Allard2067d1a2008-11-13 22:59:24 +00001177 {
Andrey Andreev2d486232012-07-19 14:46:51 +03001178 $qb_orderby[] = ($direction === '' && preg_match('/\s+(ASC|DESC)$/i', rtrim($field), $match, PREG_OFFSET_CAPTURE))
1179 ? array('field' => ltrim(substr($field, 0, $match[0][1])), 'direction' => ' '.$match[1][0], 'escape' => TRUE)
1180 : array('field' => trim($field), 'direction' => $direction, 'escape' => TRUE);
Derek Allard2067d1a2008-11-13 22:59:24 +00001181 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001182 }
Barry Mienydd671972010-10-04 16:33:58 +02001183
Andrey Andreev2d486232012-07-19 14:46:51 +03001184 $this->qb_orderby = array_merge($this->qb_orderby, $qb_orderby);
Jamie Rumbelow7efad202012-02-19 12:37:00 +00001185 if ($this->qb_caching === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +00001186 {
Andrey Andreev2d486232012-07-19 14:46:51 +03001187 $this->qb_cache_orderby = array_merge($this->qb_cache_orderby, $qb_orderby);
Jamie Rumbelow7efad202012-02-19 12:37:00 +00001188 $this->qb_cache_exists[] = 'orderby';
Derek Allard2067d1a2008-11-13 22:59:24 +00001189 }
1190
1191 return $this;
1192 }
Barry Mienydd671972010-10-04 16:33:58 +02001193
Derek Allard2067d1a2008-11-13 22:59:24 +00001194 // --------------------------------------------------------------------
1195
1196 /**
Andrey Andreevae85eb42012-11-02 01:42:31 +02001197 * LIMIT
Derek Allard2067d1a2008-11-13 22:59:24 +00001198 *
Andrey Andreevae85eb42012-11-02 01:42:31 +02001199 * @param int $value LIMIT value
1200 * @param int $offset OFFSET value
Andrew Podner4296a652012-12-17 07:51:15 -05001201 * @return CI_DB_query_builder
Derek Allard2067d1a2008-11-13 22:59:24 +00001202 */
Andrey Andreevc9b924c2012-07-19 13:06:02 +03001203 public function limit($value, $offset = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +00001204 {
vlakoff912f1bc2013-01-15 03:34:12 +01001205 is_null($value) OR $this->qb_limit = (int) $value;
Andrey Andreev777153d2012-06-18 13:30:45 +03001206 empty($offset) OR $this->qb_offset = (int) $offset;
Barry Mienydd671972010-10-04 16:33:58 +02001207
Derek Allard2067d1a2008-11-13 22:59:24 +00001208 return $this;
1209 }
Barry Mienydd671972010-10-04 16:33:58 +02001210
Derek Allard2067d1a2008-11-13 22:59:24 +00001211 // --------------------------------------------------------------------
1212
1213 /**
1214 * Sets the OFFSET value
1215 *
Andrey Andreevae85eb42012-11-02 01:42:31 +02001216 * @param int $offset OFFSET value
Andrew Podner4296a652012-12-17 07:51:15 -05001217 * @return CI_DB_query_builder
Derek Allard2067d1a2008-11-13 22:59:24 +00001218 */
Phil Sturgeon9789f322011-07-15 15:14:05 -06001219 public function offset($offset)
Derek Allard2067d1a2008-11-13 22:59:24 +00001220 {
Andrey Andreev777153d2012-06-18 13:30:45 +03001221 empty($offset) OR $this->qb_offset = (int) $offset;
Derek Allard2067d1a2008-11-13 22:59:24 +00001222 return $this;
1223 }
Barry Mienydd671972010-10-04 16:33:58 +02001224
Derek Allard2067d1a2008-11-13 22:59:24 +00001225 // --------------------------------------------------------------------
1226
1227 /**
Andrey Andreevae85eb42012-11-02 01:42:31 +02001228 * LIMIT string
Andrey Andreev2c35b642012-06-24 03:05:26 +03001229 *
Andrey Andreevae85eb42012-11-02 01:42:31 +02001230 * Generates a platform-specific LIMIT clause.
Andrey Andreev2c35b642012-06-24 03:05:26 +03001231 *
Andrey Andreevae85eb42012-11-02 01:42:31 +02001232 * @param string $sql SQL Query
Andrey Andreev2c35b642012-06-24 03:05:26 +03001233 * @return string
1234 */
Andrey Andreevc9b924c2012-07-19 13:06:02 +03001235 protected function _limit($sql)
Andrey Andreev2c35b642012-06-24 03:05:26 +03001236 {
Andrey Andreevc9b924c2012-07-19 13:06:02 +03001237 return $sql.' LIMIT '.($this->qb_offset ? $this->qb_offset.', ' : '').$this->qb_limit;
Andrey Andreev2c35b642012-06-24 03:05:26 +03001238 }
1239
1240 // --------------------------------------------------------------------
1241
1242 /**
Andrey Andreevfe642da2012-06-16 03:47:33 +03001243 * The "set" function.
1244 *
1245 * Allows key/value pairs to be set for inserting or updating
Derek Allard2067d1a2008-11-13 22:59:24 +00001246 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001247 * @param mixed
1248 * @param string
Andrey Andreeva8bb4be2012-03-26 15:54:23 +03001249 * @param bool
Andrew Podner4296a652012-12-17 07:51:15 -05001250 * @return CI_DB_query_builder
Derek Allard2067d1a2008-11-13 22:59:24 +00001251 */
Andrey Andreevfe642da2012-06-16 03:47:33 +03001252 public function set($key, $value = '', $escape = NULL)
Derek Allard2067d1a2008-11-13 22:59:24 +00001253 {
1254 $key = $this->_object_to_array($key);
Barry Mienydd671972010-10-04 16:33:58 +02001255
Derek Allard2067d1a2008-11-13 22:59:24 +00001256 if ( ! is_array($key))
1257 {
1258 $key = array($key => $value);
Barry Mienydd671972010-10-04 16:33:58 +02001259 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001260
Andrey Andreevfe642da2012-06-16 03:47:33 +03001261 is_bool($escape) OR $escape = $this->_protect_identifiers;
1262
Derek Allard2067d1a2008-11-13 22:59:24 +00001263 foreach ($key as $k => $v)
1264 {
Andrey Andreevfe642da2012-06-16 03:47:33 +03001265 $this->qb_set[$this->protect_identifiers($k, FALSE, $escape)] = ($escape)
1266 ? $this->escape($v) : $v;
Derek Allard2067d1a2008-11-13 22:59:24 +00001267 }
Barry Mienydd671972010-10-04 16:33:58 +02001268
Derek Allard2067d1a2008-11-13 22:59:24 +00001269 return $this;
1270 }
WanWizard7219c072011-12-28 14:09:05 +01001271
Kyle Farris0c147b32011-08-26 02:29:31 -04001272 // --------------------------------------------------------------------
1273
1274 /**
1275 * Get SELECT query string
1276 *
1277 * Compiles a SELECT query string and returns the sql.
1278 *
Kyle Farris0c147b32011-08-26 02:29:31 -04001279 * @param string the table name to select from (optional)
Jamie Rumbelowd6ce1e92012-04-26 13:27:35 +01001280 * @param bool TRUE: resets QB values; FALSE: leave QB vaules alone
Kyle Farris0c147b32011-08-26 02:29:31 -04001281 * @return string
1282 */
WanWizard7219c072011-12-28 14:09:05 +01001283 public function get_compiled_select($table = '', $reset = TRUE)
Kyle Farris0c147b32011-08-26 02:29:31 -04001284 {
Alex Bilbie48a2baf2012-06-02 11:09:54 +01001285 if ($table !== '')
kylefarris0a3176b2011-08-26 02:37:52 -04001286 {
Kyle Farris0c147b32011-08-26 02:29:31 -04001287 $this->_track_aliases($table);
1288 $this->from($table);
1289 }
WanWizard7219c072011-12-28 14:09:05 +01001290
Andrey Andreev650b4c02012-06-11 12:07:15 +03001291 $select = $this->_compile_select();
WanWizard7219c072011-12-28 14:09:05 +01001292
Kyle Farris0c147b32011-08-26 02:29:31 -04001293 if ($reset === TRUE)
1294 {
1295 $this->_reset_select();
1296 }
WanWizard7219c072011-12-28 14:09:05 +01001297
Kyle Farris0c147b32011-08-26 02:29:31 -04001298 return $select;
1299 }
WanWizard7219c072011-12-28 14:09:05 +01001300
Derek Allard2067d1a2008-11-13 22:59:24 +00001301 // --------------------------------------------------------------------
1302
1303 /**
1304 * Get
1305 *
1306 * Compiles the select statement based on the other functions called
1307 * and runs the query
1308 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001309 * @param string the table
1310 * @param string the limit clause
1311 * @param string the offset clause
1312 * @return object
1313 */
Andrey Andreev650b4c02012-06-11 12:07:15 +03001314 public function get($table = '', $limit = NULL, $offset = NULL)
Derek Allard2067d1a2008-11-13 22:59:24 +00001315 {
Alex Bilbie48a2baf2012-06-02 11:09:54 +01001316 if ($table !== '')
Derek Allard2067d1a2008-11-13 22:59:24 +00001317 {
1318 $this->_track_aliases($table);
1319 $this->from($table);
1320 }
Barry Mienydd671972010-10-04 16:33:58 +02001321
Andrey Andreev650b4c02012-06-11 12:07:15 +03001322 if ( ! empty($limit))
Derek Allard2067d1a2008-11-13 22:59:24 +00001323 {
1324 $this->limit($limit, $offset);
1325 }
Barry Mienydd671972010-10-04 16:33:58 +02001326
Andrey Andreev24276a32012-01-08 02:44:38 +02001327 $result = $this->query($this->_compile_select());
Derek Allard2067d1a2008-11-13 22:59:24 +00001328 $this->_reset_select();
1329 return $result;
1330 }
1331
Andrey Andreev7b5eb732012-05-24 20:52:41 +03001332 // --------------------------------------------------------------------
1333
Derek Allard2067d1a2008-11-13 22:59:24 +00001334 /**
1335 * "Count All Results" query
1336 *
Barry Mienydd671972010-10-04 16:33:58 +02001337 * Generates a platform-specific query string that counts all records
Jamie Rumbelow7efad202012-02-19 12:37:00 +00001338 * returned by an Query Builder query.
Derek Allard2067d1a2008-11-13 22:59:24 +00001339 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001340 * @param string
1341 * @return string
1342 */
Phil Sturgeon9789f322011-07-15 15:14:05 -06001343 public function count_all_results($table = '')
Derek Allard2067d1a2008-11-13 22:59:24 +00001344 {
Alex Bilbie48a2baf2012-06-02 11:09:54 +01001345 if ($table !== '')
Derek Allard2067d1a2008-11-13 22:59:24 +00001346 {
1347 $this->_track_aliases($table);
1348 $this->from($table);
1349 }
Barry Mienydd671972010-10-04 16:33:58 +02001350
Andrey Andreevb05f5062012-10-26 12:01:02 +03001351 $result = ($this->qb_distinct === TRUE)
1352 ? $this->query($this->_count_string.$this->protect_identifiers('numrows')."\nFROM (\n".$this->_compile_select()."\n) CI_count_all_results")
1353 : $this->query($this->_compile_select($this->_count_string.$this->protect_identifiers('numrows')));
Derek Allard2067d1a2008-11-13 22:59:24 +00001354 $this->_reset_select();
Barry Mienydd671972010-10-04 16:33:58 +02001355
Purwandi1d160e72012-01-09 16:33:28 +07001356 if ($result->num_rows() === 0)
Derek Allard2067d1a2008-11-13 22:59:24 +00001357 {
Phil Sturgeonaf6f3442011-03-22 19:12:23 +00001358 return 0;
Derek Allard2067d1a2008-11-13 22:59:24 +00001359 }
1360
Purwandi1d160e72012-01-09 16:33:28 +07001361 $row = $result->row();
Phil Sturgeonaf6f3442011-03-22 19:12:23 +00001362 return (int) $row->numrows;
Derek Allard2067d1a2008-11-13 22:59:24 +00001363 }
Andrey Andreev7b5eb732012-05-24 20:52:41 +03001364
Derek Allard2067d1a2008-11-13 22:59:24 +00001365 // --------------------------------------------------------------------
1366
1367 /**
1368 * Get_Where
1369 *
1370 * Allows the where clause, limit and offset to be added directly
1371 *
Andrey Andreevae85eb42012-11-02 01:42:31 +02001372 * @param string $table
1373 * @param string $where
1374 * @param int $limit
1375 * @param int $offset
Derek Allard2067d1a2008-11-13 22:59:24 +00001376 * @return object
1377 */
Andrey Andreeveb22d542012-06-26 23:16:35 +03001378 public function get_where($table = '', $where = NULL, $limit = NULL, $offset = NULL)
Derek Allard2067d1a2008-11-13 22:59:24 +00001379 {
Alex Bilbie48a2baf2012-06-02 11:09:54 +01001380 if ($table !== '')
Derek Allard2067d1a2008-11-13 22:59:24 +00001381 {
1382 $this->from($table);
1383 }
1384
vlakoff1228fe22013-01-14 01:30:09 +01001385 if ($where !== NULL)
Derek Allard2067d1a2008-11-13 22:59:24 +00001386 {
1387 $this->where($where);
1388 }
Barry Mienydd671972010-10-04 16:33:58 +02001389
Andrey Andreev650b4c02012-06-11 12:07:15 +03001390 if ( ! empty($limit))
Derek Allard2067d1a2008-11-13 22:59:24 +00001391 {
1392 $this->limit($limit, $offset);
1393 }
Barry Mienydd671972010-10-04 16:33:58 +02001394
Andrey Andreev24276a32012-01-08 02:44:38 +02001395 $result = $this->query($this->_compile_select());
Derek Allard2067d1a2008-11-13 22:59:24 +00001396 $this->_reset_select();
1397 return $result;
1398 }
1399
1400 // --------------------------------------------------------------------
1401
1402 /**
Derek Jonesd10e8962010-03-02 17:10:36 -06001403 * Insert_Batch
1404 *
1405 * Compiles batch insert strings and runs the queries
1406 *
Andrey Andreevae85eb42012-11-02 01:42:31 +02001407 * @param string $table Table to insert into
1408 * @param array $set An associative array of insert values
Andrey Andreevbdd9c112012-11-06 12:07:16 +02001409 * @param bool $escape Whether to escape values and identifiers
Andrey Andreevae85eb42012-11-02 01:42:31 +02001410 * @return int Number of rows inserted or FALSE on failure
Derek Jonesd10e8962010-03-02 17:10:36 -06001411 */
Andrey Andreevbdd9c112012-11-06 12:07:16 +02001412 public function insert_batch($table = '', $set = NULL, $escape = NULL)
Barry Mienydd671972010-10-04 16:33:58 +02001413 {
vlakoff1228fe22013-01-14 01:30:09 +01001414 if ($set !== NULL)
Derek Jonesd10e8962010-03-02 17:10:36 -06001415 {
Andrey Andreevbdd9c112012-11-06 12:07:16 +02001416 $this->set_insert_batch($set, '', $escape);
Derek Jonesd10e8962010-03-02 17:10:36 -06001417 }
Barry Mienydd671972010-10-04 16:33:58 +02001418
Jamie Rumbelow7efad202012-02-19 12:37:00 +00001419 if (count($this->qb_set) === 0)
Derek Jonesd10e8962010-03-02 17:10:36 -06001420 {
Andrey Andreev9f808b02012-10-24 17:38:48 +03001421 // No valid data array. Folds in cases where keys and values did not match up
1422 return ($this->db_debug) ? $this->display_error('db_must_use_set') : FALSE;
Derek Jonesd10e8962010-03-02 17:10:36 -06001423 }
1424
Alex Bilbie48a2baf2012-06-02 11:09:54 +01001425 if ($table === '')
Derek Jonesd10e8962010-03-02 17:10:36 -06001426 {
Jamie Rumbelow7efad202012-02-19 12:37:00 +00001427 if ( ! isset($this->qb_from[0]))
Derek Jonesd10e8962010-03-02 17:10:36 -06001428 {
Andrey Andreev24276a32012-01-08 02:44:38 +02001429 return ($this->db_debug) ? $this->display_error('db_must_set_table') : FALSE;
Derek Jonesd10e8962010-03-02 17:10:36 -06001430 }
Barry Mienydd671972010-10-04 16:33:58 +02001431
Jamie Rumbelow7efad202012-02-19 12:37:00 +00001432 $table = $this->qb_from[0];
Derek Jonesd10e8962010-03-02 17:10:36 -06001433 }
1434
1435 // Batch this baby
Andrey Andreev9f808b02012-10-24 17:38:48 +03001436 $affected_rows = 0;
Jamie Rumbelow7efad202012-02-19 12:37:00 +00001437 for ($i = 0, $total = count($this->qb_set); $i < $total; $i += 100)
Derek Jonesd10e8962010-03-02 17:10:36 -06001438 {
Andrey Andreevbdd9c112012-11-06 12:07:16 +02001439 $this->query($this->_insert_batch($this->protect_identifiers($table, TRUE, $escape, FALSE), $this->qb_keys, array_slice($this->qb_set, $i, 100)));
Andrey Andreev9f808b02012-10-24 17:38:48 +03001440 $affected_rows += $this->affected_rows();
Derek Jonesd10e8962010-03-02 17:10:36 -06001441 }
Barry Mienydd671972010-10-04 16:33:58 +02001442
Derek Jonesd10e8962010-03-02 17:10:36 -06001443 $this->_reset_write();
Andrey Andreev9f808b02012-10-24 17:38:48 +03001444 return $affected_rows;
Derek Jonesd10e8962010-03-02 17:10:36 -06001445 }
1446
1447 // --------------------------------------------------------------------
1448
1449 /**
Andrey Andreev083e3c82012-11-06 12:48:32 +02001450 * Insert batch statement
Andrey Andreev97f36972012-04-05 12:44:36 +03001451 *
1452 * Generates a platform-specific insert string from the supplied data.
1453 *
Andrey Andreev083e3c82012-11-06 12:48:32 +02001454 * @param string $table Table name
1455 * @param array $keys INSERT keys
1456 * @param array $values INSERT values
Andrey Andreeva3bca8f2012-04-05 15:17:25 +03001457 * @return string
Andrey Andreev97f36972012-04-05 12:44:36 +03001458 */
1459 protected function _insert_batch($table, $keys, $values)
1460 {
Andrey Andreev65d537c2012-04-05 14:11:41 +03001461 return 'INSERT INTO '.$table.' ('.implode(', ', $keys).') VALUES '.implode(', ', $values);
Andrey Andreev97f36972012-04-05 12:44:36 +03001462 }
1463
1464 // --------------------------------------------------------------------
1465
1466 /**
Derek Jones37f4b9c2011-07-01 17:56:50 -05001467 * The "set_insert_batch" function. Allows key/value pairs to be set for batch inserts
Derek Jonesd10e8962010-03-02 17:10:36 -06001468 *
Derek Jonesd10e8962010-03-02 17:10:36 -06001469 * @param mixed
1470 * @param string
Andrey Andreeva8bb4be2012-03-26 15:54:23 +03001471 * @param bool
Andrew Podner4296a652012-12-17 07:51:15 -05001472 * @return CI_DB_query_builder
Derek Jonesd10e8962010-03-02 17:10:36 -06001473 */
Andrey Andreevfe642da2012-06-16 03:47:33 +03001474 public function set_insert_batch($key, $value = '', $escape = NULL)
Derek Jonesd10e8962010-03-02 17:10:36 -06001475 {
1476 $key = $this->_object_to_array_batch($key);
Barry Mienydd671972010-10-04 16:33:58 +02001477
Derek Jonesd10e8962010-03-02 17:10:36 -06001478 if ( ! is_array($key))
1479 {
1480 $key = array($key => $value);
Barry Mienydd671972010-10-04 16:33:58 +02001481 }
Derek Jonesd10e8962010-03-02 17:10:36 -06001482
Andrey Andreevfe642da2012-06-16 03:47:33 +03001483 is_bool($escape) OR $escape = $this->_protect_identifiers;
1484
Iban Eguia3c0a4522012-04-15 13:30:44 +02001485 $keys = array_keys($this->_object_to_array(current($key)));
Derek Jonesd10e8962010-03-02 17:10:36 -06001486 sort($keys);
1487
1488 foreach ($key as $row)
1489 {
Iban Eguia3c0a4522012-04-15 13:30:44 +02001490 $row = $this->_object_to_array($row);
Barry Mienydd671972010-10-04 16:33:58 +02001491 if (count(array_diff($keys, array_keys($row))) > 0 OR count(array_diff(array_keys($row), $keys)) > 0)
1492 {
1493 // batch function above returns an error on an empty array
Jamie Rumbelow7efad202012-02-19 12:37:00 +00001494 $this->qb_set[] = array();
Barry Mienydd671972010-10-04 16:33:58 +02001495 return;
1496 }
Phil Sturgeond0ac1a22011-02-15 22:54:08 +00001497
Barry Mienydd671972010-10-04 16:33:58 +02001498 ksort($row); // puts $row in the same order as our keys
1499
Andrey Andreev650b4c02012-06-11 12:07:15 +03001500 if ($escape !== FALSE)
Derek Jonesd10e8962010-03-02 17:10:36 -06001501 {
1502 $clean = array();
Pascal Krietec3a4a8d2011-02-14 13:40:08 -05001503 foreach ($row as $value)
Derek Jonesd10e8962010-03-02 17:10:36 -06001504 {
Barry Mienydd671972010-10-04 16:33:58 +02001505 $clean[] = $this->escape($value);
Derek Jonesd10e8962010-03-02 17:10:36 -06001506 }
1507
Andrey Andreev650b4c02012-06-11 12:07:15 +03001508 $row = $clean;
Barry Mienydd671972010-10-04 16:33:58 +02001509 }
Andrey Andreev650b4c02012-06-11 12:07:15 +03001510
Andrey Andreev838a9d62012-12-03 14:37:47 +02001511 $this->qb_set[] = '('.implode(',', $row).')';
Derek Jonesd10e8962010-03-02 17:10:36 -06001512 }
1513
1514 foreach ($keys as $k)
1515 {
Andrey Andreevfe642da2012-06-16 03:47:33 +03001516 $this->qb_keys[] = $this->protect_identifiers($k, FALSE, $escape);
Derek Jonesd10e8962010-03-02 17:10:36 -06001517 }
Barry Mienydd671972010-10-04 16:33:58 +02001518
Derek Jonesd10e8962010-03-02 17:10:36 -06001519 return $this;
1520 }
WanWizard7219c072011-12-28 14:09:05 +01001521
Kyle Farris0c147b32011-08-26 02:29:31 -04001522 // --------------------------------------------------------------------
1523
1524 /**
1525 * Get INSERT query string
1526 *
1527 * Compiles an insert query and returns the sql
1528 *
Kyle Farris0c147b32011-08-26 02:29:31 -04001529 * @param string the table to insert into
Jamie Rumbelowd6ce1e92012-04-26 13:27:35 +01001530 * @param bool TRUE: reset QB values; FALSE: leave QB values alone
Kyle Farris0c147b32011-08-26 02:29:31 -04001531 * @return string
1532 */
1533 public function get_compiled_insert($table = '', $reset = TRUE)
WanWizard7219c072011-12-28 14:09:05 +01001534 {
Kyle Farris0c147b32011-08-26 02:29:31 -04001535 if ($this->_validate_insert($table) === FALSE)
1536 {
1537 return FALSE;
1538 }
WanWizard7219c072011-12-28 14:09:05 +01001539
Kyle Farris76116012011-08-31 11:17:48 -04001540 $sql = $this->_insert(
Jamie Rumbelow0c092992012-03-06 22:05:16 +00001541 $this->protect_identifiers(
Jamie Rumbelow7efad202012-02-19 12:37:00 +00001542 $this->qb_from[0], TRUE, NULL, FALSE
Kyle Farris76116012011-08-31 11:17:48 -04001543 ),
Jamie Rumbelow7efad202012-02-19 12:37:00 +00001544 array_keys($this->qb_set),
1545 array_values($this->qb_set)
Kyle Farris76116012011-08-31 11:17:48 -04001546 );
WanWizard7219c072011-12-28 14:09:05 +01001547
Kyle Farris0c147b32011-08-26 02:29:31 -04001548 if ($reset === TRUE)
1549 {
1550 $this->_reset_write();
1551 }
WanWizard7219c072011-12-28 14:09:05 +01001552
Kyle Farris0c147b32011-08-26 02:29:31 -04001553 return $sql;
1554 }
Derek Jonesd10e8962010-03-02 17:10:36 -06001555
Derek Allard2067d1a2008-11-13 22:59:24 +00001556 // --------------------------------------------------------------------
1557
1558 /**
1559 * Insert
1560 *
1561 * Compiles an insert string and runs the query
1562 *
Phil Sturgeon9789f322011-07-15 15:14:05 -06001563 * @param string the table to insert data into
Derek Allard2067d1a2008-11-13 22:59:24 +00001564 * @param array an associative array of insert values
Andrey Andreevbdd9c112012-11-06 12:07:16 +02001565 * @param bool $escape Whether to escape values and identifiers
Derek Allard2067d1a2008-11-13 22:59:24 +00001566 * @return object
1567 */
Andrey Andreevbdd9c112012-11-06 12:07:16 +02001568 public function insert($table = '', $set = NULL, $escape = NULL)
Barry Mienydd671972010-10-04 16:33:58 +02001569 {
vlakoff1228fe22013-01-14 01:30:09 +01001570 if ($set !== NULL)
Derek Allard2067d1a2008-11-13 22:59:24 +00001571 {
Andrey Andreevbdd9c112012-11-06 12:07:16 +02001572 $this->set($set, '', $escape);
Derek Allard2067d1a2008-11-13 22:59:24 +00001573 }
WanWizard7219c072011-12-28 14:09:05 +01001574
Kyle Farris0c147b32011-08-26 02:29:31 -04001575 if ($this->_validate_insert($table) === FALSE)
1576 {
1577 return FALSE;
1578 }
WanWizard7219c072011-12-28 14:09:05 +01001579
Kyle Farris76116012011-08-31 11:17:48 -04001580 $sql = $this->_insert(
Jamie Rumbelow0c092992012-03-06 22:05:16 +00001581 $this->protect_identifiers(
Andrey Andreevbdd9c112012-11-06 12:07:16 +02001582 $this->qb_from[0], TRUE, $escape, FALSE
WanWizard7219c072011-12-28 14:09:05 +01001583 ),
Jamie Rumbelow7efad202012-02-19 12:37:00 +00001584 array_keys($this->qb_set),
1585 array_values($this->qb_set)
Kyle Farris76116012011-08-31 11:17:48 -04001586 );
Barry Mienydd671972010-10-04 16:33:58 +02001587
Kyle Farris0c147b32011-08-26 02:29:31 -04001588 $this->_reset_write();
1589 return $this->query($sql);
1590 }
WanWizard7219c072011-12-28 14:09:05 +01001591
Kyle Farris0c147b32011-08-26 02:29:31 -04001592 // --------------------------------------------------------------------
1593
1594 /**
1595 * Validate Insert
1596 *
1597 * This method is used by both insert() and get_compiled_insert() to
1598 * validate that the there data is actually being set and that table
1599 * has been chosen to be inserted into.
1600 *
Kyle Farris0c147b32011-08-26 02:29:31 -04001601 * @param string the table to insert data into
1602 * @return string
1603 */
WanWizard7219c072011-12-28 14:09:05 +01001604 protected function _validate_insert($table = '')
Kyle Farris0c147b32011-08-26 02:29:31 -04001605 {
Jamie Rumbelow7efad202012-02-19 12:37:00 +00001606 if (count($this->qb_set) === 0)
Derek Allard2067d1a2008-11-13 22:59:24 +00001607 {
Andrey Andreev24276a32012-01-08 02:44:38 +02001608 return ($this->db_debug) ? $this->display_error('db_must_use_set') : FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +00001609 }
1610
Alex Bilbie48a2baf2012-06-02 11:09:54 +01001611 if ($table !== '')
Kyle Farris0c147b32011-08-26 02:29:31 -04001612 {
Jamie Rumbelow7efad202012-02-19 12:37:00 +00001613 $this->qb_from[0] = $table;
Kyle Farris0c147b32011-08-26 02:29:31 -04001614 }
Andrey Andreev7b5eb732012-05-24 20:52:41 +03001615 elseif ( ! isset($this->qb_from[0]))
1616 {
1617 return ($this->db_debug) ? $this->display_error('db_must_set_table') : FALSE;
1618 }
WanWizard7219c072011-12-28 14:09:05 +01001619
Kyle Farris0c147b32011-08-26 02:29:31 -04001620 return TRUE;
Derek Allard2067d1a2008-11-13 22:59:24 +00001621 }
Barry Mienydd671972010-10-04 16:33:58 +02001622
Phil Sturgeon9789f322011-07-15 15:14:05 -06001623 // --------------------------------------------------------------------
1624
1625 /**
1626 * Replace
1627 *
1628 * Compiles an replace into string and runs the query
1629 *
1630 * @param string the table to replace data into
1631 * @param array an associative array of insert values
1632 * @return object
1633 */
1634 public function replace($table = '', $set = NULL)
Derek Jonesd10e8962010-03-02 17:10:36 -06001635 {
vlakoff1228fe22013-01-14 01:30:09 +01001636 if ($set !== NULL)
Derek Jonesd10e8962010-03-02 17:10:36 -06001637 {
1638 $this->set($set);
1639 }
Barry Mienydd671972010-10-04 16:33:58 +02001640
Jamie Rumbelow7efad202012-02-19 12:37:00 +00001641 if (count($this->qb_set) === 0)
Derek Jonesd10e8962010-03-02 17:10:36 -06001642 {
Andrey Andreev24276a32012-01-08 02:44:38 +02001643 return ($this->db_debug) ? $this->display_error('db_must_use_set') : FALSE;
Derek Jonesd10e8962010-03-02 17:10:36 -06001644 }
1645
Alex Bilbie48a2baf2012-06-02 11:09:54 +01001646 if ($table === '')
Derek Jonesd10e8962010-03-02 17:10:36 -06001647 {
Jamie Rumbelow7efad202012-02-19 12:37:00 +00001648 if ( ! isset($this->qb_from[0]))
Derek Jonesd10e8962010-03-02 17:10:36 -06001649 {
Andrey Andreev24276a32012-01-08 02:44:38 +02001650 return ($this->db_debug) ? $this->display_error('db_must_set_table') : FALSE;
Derek Jonesd10e8962010-03-02 17:10:36 -06001651 }
Barry Mienydd671972010-10-04 16:33:58 +02001652
Jamie Rumbelow7efad202012-02-19 12:37:00 +00001653 $table = $this->qb_from[0];
Derek Jonesd10e8962010-03-02 17:10:36 -06001654 }
1655
Jamie Rumbelow0c092992012-03-06 22:05:16 +00001656 $sql = $this->_replace($this->protect_identifiers($table, TRUE, NULL, FALSE), array_keys($this->qb_set), array_values($this->qb_set));
Jamie Rumbelow3b1355c2012-03-06 21:27:46 +00001657
Derek Jonesd10e8962010-03-02 17:10:36 -06001658 $this->_reset_write();
Barry Mienydd671972010-10-04 16:33:58 +02001659 return $this->query($sql);
Derek Jonesd10e8962010-03-02 17:10:36 -06001660 }
WanWizard7219c072011-12-28 14:09:05 +01001661
Kyle Farris0c147b32011-08-26 02:29:31 -04001662 // --------------------------------------------------------------------
Derek Jonesd10e8962010-03-02 17:10:36 -06001663
Kyle Farris0c147b32011-08-26 02:29:31 -04001664 /**
Andrey Andreeva3bca8f2012-04-05 15:17:25 +03001665 * Replace statement
1666 *
1667 * Generates a platform-specific replace string from the supplied data
1668 *
1669 * @param string the table name
1670 * @param array the insert keys
1671 * @param array the insert values
1672 * @return string
1673 */
1674 protected function _replace($table, $keys, $values)
1675 {
1676 return 'REPLACE INTO '.$table.' ('.implode(', ', $keys).') VALUES ('.implode(', ', $values).')';
1677 }
1678
1679 // --------------------------------------------------------------------
1680
1681 /**
Andrey Andreev7eaa14f2012-10-09 11:34:01 +03001682 * FROM tables
Andrey Andreevc78e56a2012-06-08 02:12:07 +03001683 *
Andrey Andreev7eaa14f2012-10-09 11:34:01 +03001684 * Groups tables in FROM clauses if needed, so there is no confusion
1685 * about operator precedence.
Andrey Andreevc78e56a2012-06-08 02:12:07 +03001686 *
Andrey Andreev7eaa14f2012-10-09 11:34:01 +03001687 * Note: This is only used (and overriden) by MySQL and CUBRID.
1688 *
1689 * @return string
Andrey Andreevc78e56a2012-06-08 02:12:07 +03001690 */
Andrey Andreev7eaa14f2012-10-09 11:34:01 +03001691 protected function _from_tables()
Andrey Andreevc78e56a2012-06-08 02:12:07 +03001692 {
Andrey Andreev7eaa14f2012-10-09 11:34:01 +03001693 return implode(', ', $this->qb_from);
Andrey Andreevc78e56a2012-06-08 02:12:07 +03001694 }
1695
1696 // --------------------------------------------------------------------
1697
1698 /**
Kyle Farris0c147b32011-08-26 02:29:31 -04001699 * Get UPDATE query string
1700 *
1701 * Compiles an update query and returns the sql
1702 *
Kyle Farris0c147b32011-08-26 02:29:31 -04001703 * @param string the table to update
Jamie Rumbelowd6ce1e92012-04-26 13:27:35 +01001704 * @param bool TRUE: reset QB values; FALSE: leave QB values alone
Kyle Farris0c147b32011-08-26 02:29:31 -04001705 * @return string
1706 */
1707 public function get_compiled_update($table = '', $reset = TRUE)
1708 {
1709 // Combine any cached components with the current statements
1710 $this->_merge_cache();
WanWizard7219c072011-12-28 14:09:05 +01001711
Kyle Farris0c147b32011-08-26 02:29:31 -04001712 if ($this->_validate_update($table) === FALSE)
1713 {
1714 return FALSE;
1715 }
WanWizard7219c072011-12-28 14:09:05 +01001716
Andrey Andreevb0478652012-07-18 15:34:46 +03001717 $sql = $this->_update($this->protect_identifiers($this->qb_from[0], TRUE, NULL, FALSE), $this->qb_set);
WanWizard7219c072011-12-28 14:09:05 +01001718
Kyle Farris0c147b32011-08-26 02:29:31 -04001719 if ($reset === TRUE)
1720 {
1721 $this->_reset_write();
1722 }
WanWizard7219c072011-12-28 14:09:05 +01001723
Kyle Farris0c147b32011-08-26 02:29:31 -04001724 return $sql;
1725 }
WanWizard7219c072011-12-28 14:09:05 +01001726
Derek Allard2067d1a2008-11-13 22:59:24 +00001727 // --------------------------------------------------------------------
1728
1729 /**
Andrey Andreevae85eb42012-11-02 01:42:31 +02001730 * UPDATE
Derek Allard2067d1a2008-11-13 22:59:24 +00001731 *
Andrey Andreevae85eb42012-11-02 01:42:31 +02001732 * Compiles an update string and runs the query.
Derek Allard2067d1a2008-11-13 22:59:24 +00001733 *
Andrey Andreevae85eb42012-11-02 01:42:31 +02001734 * @param string $table
1735 * @param array $set An associative array of update values
1736 * @param mixed $where
1737 * @param int $limit
Derek Allard2067d1a2008-11-13 22:59:24 +00001738 * @return object
1739 */
Phil Sturgeon9789f322011-07-15 15:14:05 -06001740 public function update($table = '', $set = NULL, $where = NULL, $limit = NULL)
Derek Allard2067d1a2008-11-13 22:59:24 +00001741 {
1742 // Combine any cached components with the current statements
1743 $this->_merge_cache();
1744
vlakoff1228fe22013-01-14 01:30:09 +01001745 if ($set !== NULL)
Derek Allard2067d1a2008-11-13 22:59:24 +00001746 {
1747 $this->set($set);
1748 }
Barry Mienydd671972010-10-04 16:33:58 +02001749
Kyle Farris0c147b32011-08-26 02:29:31 -04001750 if ($this->_validate_update($table) === FALSE)
1751 {
1752 return FALSE;
1753 }
1754
Alex Bilbie48a2baf2012-06-02 11:09:54 +01001755 if ($where !== NULL)
Kyle Farris0c147b32011-08-26 02:29:31 -04001756 {
1757 $this->where($where);
1758 }
1759
Andrey Andreev650b4c02012-06-11 12:07:15 +03001760 if ( ! empty($limit))
Kyle Farris0c147b32011-08-26 02:29:31 -04001761 {
1762 $this->limit($limit);
1763 }
1764
Andrey Andreevb0478652012-07-18 15:34:46 +03001765 $sql = $this->_update($this->protect_identifiers($this->qb_from[0], TRUE, NULL, FALSE), $this->qb_set);
Kyle Farris0c147b32011-08-26 02:29:31 -04001766 $this->_reset_write();
1767 return $this->query($sql);
1768 }
WanWizard7219c072011-12-28 14:09:05 +01001769
Kyle Farris0c147b32011-08-26 02:29:31 -04001770 // --------------------------------------------------------------------
1771
1772 /**
1773 * Validate Update
1774 *
1775 * This method is used by both update() and get_compiled_update() to
1776 * validate that data is actually being set and that a table has been
1777 * chosen to be update.
1778 *
Kyle Farris0c147b32011-08-26 02:29:31 -04001779 * @param string the table to update data on
Andrey Andreev24276a32012-01-08 02:44:38 +02001780 * @return bool
Kyle Farris0c147b32011-08-26 02:29:31 -04001781 */
1782 protected function _validate_update($table = '')
1783 {
Alex Bilbie48a2baf2012-06-02 11:09:54 +01001784 if (count($this->qb_set) === 0)
Derek Allard2067d1a2008-11-13 22:59:24 +00001785 {
Andrey Andreev24276a32012-01-08 02:44:38 +02001786 return ($this->db_debug) ? $this->display_error('db_must_use_set') : FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +00001787 }
1788
Alex Bilbie48a2baf2012-06-02 11:09:54 +01001789 if ($table !== '')
Derek Allard2067d1a2008-11-13 22:59:24 +00001790 {
Jamie Rumbelow7efad202012-02-19 12:37:00 +00001791 $this->qb_from[0] = $table;
Derek Allard2067d1a2008-11-13 22:59:24 +00001792 }
Andrey Andreev7b5eb732012-05-24 20:52:41 +03001793 elseif ( ! isset($this->qb_from[0]))
1794 {
1795 return ($this->db_debug) ? $this->display_error('db_must_set_table') : FALSE;
1796 }
Andrey Andreev24276a32012-01-08 02:44:38 +02001797
1798 return TRUE;
Derek Allard2067d1a2008-11-13 22:59:24 +00001799 }
WanWizard7219c072011-12-28 14:09:05 +01001800
Derek Jonesd10e8962010-03-02 17:10:36 -06001801 // --------------------------------------------------------------------
1802
1803 /**
1804 * Update_Batch
1805 *
1806 * Compiles an update string and runs the query
1807 *
Derek Jonesd10e8962010-03-02 17:10:36 -06001808 * @param string the table to retrieve the results from
1809 * @param array an associative array of update values
1810 * @param string the where key
Andrey Andreev9f808b02012-10-24 17:38:48 +03001811 * @return int number of rows affected or FALSE on failure
Derek Jonesd10e8962010-03-02 17:10:36 -06001812 */
Phil Sturgeon9789f322011-07-15 15:14:05 -06001813 public function update_batch($table = '', $set = NULL, $index = NULL)
Derek Jonesd10e8962010-03-02 17:10:36 -06001814 {
1815 // Combine any cached components with the current statements
1816 $this->_merge_cache();
Barry Mienydd671972010-10-04 16:33:58 +02001817
vlakoff1228fe22013-01-14 01:30:09 +01001818 if ($index === NULL)
Derek Jonesd10e8962010-03-02 17:10:36 -06001819 {
Andrey Andreev24276a32012-01-08 02:44:38 +02001820 return ($this->db_debug) ? $this->display_error('db_must_use_index') : FALSE;
Derek Jonesd10e8962010-03-02 17:10:36 -06001821 }
1822
vlakoff1228fe22013-01-14 01:30:09 +01001823 if ($set !== NULL)
Derek Jonesd10e8962010-03-02 17:10:36 -06001824 {
1825 $this->set_update_batch($set, $index);
1826 }
1827
Jamie Rumbelow7efad202012-02-19 12:37:00 +00001828 if (count($this->qb_set) === 0)
Derek Jonesd10e8962010-03-02 17:10:36 -06001829 {
Andrey Andreev24276a32012-01-08 02:44:38 +02001830 return ($this->db_debug) ? $this->display_error('db_must_use_set') : FALSE;
Derek Jonesd10e8962010-03-02 17:10:36 -06001831 }
1832
Alex Bilbie48a2baf2012-06-02 11:09:54 +01001833 if ($table === '')
Derek Jonesd10e8962010-03-02 17:10:36 -06001834 {
Jamie Rumbelow7efad202012-02-19 12:37:00 +00001835 if ( ! isset($this->qb_from[0]))
Derek Jonesd10e8962010-03-02 17:10:36 -06001836 {
Andrey Andreev24276a32012-01-08 02:44:38 +02001837 return ($this->db_debug) ? $this->display_error('db_must_set_table') : FALSE;
Derek Jonesd10e8962010-03-02 17:10:36 -06001838 }
Barry Mienydd671972010-10-04 16:33:58 +02001839
Jamie Rumbelow7efad202012-02-19 12:37:00 +00001840 $table = $this->qb_from[0];
Derek Jonesd10e8962010-03-02 17:10:36 -06001841 }
Barry Mienydd671972010-10-04 16:33:58 +02001842
Derek Jonesd10e8962010-03-02 17:10:36 -06001843 // Batch this baby
Andrey Andreev9f808b02012-10-24 17:38:48 +03001844 $affected_rows = 0;
Jamie Rumbelow7efad202012-02-19 12:37:00 +00001845 for ($i = 0, $total = count($this->qb_set); $i < $total; $i += 100)
Derek Jonesd10e8962010-03-02 17:10:36 -06001846 {
Andrey Andreevb0478652012-07-18 15:34:46 +03001847 $this->query($this->_update_batch($this->protect_identifiers($table, TRUE, NULL, FALSE), array_slice($this->qb_set, $i, 100), $this->protect_identifiers($index)));
Andrey Andreev9f808b02012-10-24 17:38:48 +03001848 $affected_rows += $this->affected_rows();
Andrey Andreev79f888b2013-08-06 13:59:23 +03001849 $this->qb_where = array();
Derek Jonesd10e8962010-03-02 17:10:36 -06001850 }
Barry Mienydd671972010-10-04 16:33:58 +02001851
Derek Jonesd10e8962010-03-02 17:10:36 -06001852 $this->_reset_write();
Andrey Andreev9f808b02012-10-24 17:38:48 +03001853 return $affected_rows;
Derek Jonesd10e8962010-03-02 17:10:36 -06001854 }
1855
1856 // --------------------------------------------------------------------
1857
1858 /**
Andrey Andreev219565d2013-03-12 20:00:08 +02001859 * Update_Batch statement
1860 *
1861 * Generates a platform-specific batch update string from the supplied data
1862 *
1863 * @param string $table Table name
1864 * @param array $values Update data
1865 * @param string $index WHERE key
1866 * @return string
1867 */
1868 protected function _update_batch($table, $values, $index)
1869 {
1870 $ids = array();
1871 foreach ($values as $key => $val)
1872 {
1873 $ids[] = $val[$index];
1874
1875 foreach (array_keys($val) as $field)
1876 {
1877 if ($field !== $index)
1878 {
1879 $final[$field][] = 'WHEN '.$index.' = '.$val[$index].' THEN '.$val[$field];
1880 }
1881 }
1882 }
1883
1884 $cases = '';
1885 foreach ($final as $k => $v)
1886 {
1887 $cases .= $k." = CASE \n"
1888 .implode("\n", $v)."\n"
1889 .'ELSE '.$k.' END, ';
1890 }
1891
1892 $this->where($index.' IN('.implode(',', $ids).')', NULL, FALSE);
1893
1894 return 'UPDATE '.$table.' SET '.substr($cases, 0, -2).$this->_compile_wh('qb_where');
1895 }
1896
1897 // --------------------------------------------------------------------
1898
1899 /**
Derek Jones37f4b9c2011-07-01 17:56:50 -05001900 * The "set_update_batch" function. Allows key/value pairs to be set for batch updating
Derek Jonesd10e8962010-03-02 17:10:36 -06001901 *
Derek Jonesd10e8962010-03-02 17:10:36 -06001902 * @param array
1903 * @param string
Andrey Andreeva8bb4be2012-03-26 15:54:23 +03001904 * @param bool
Andrew Podner4296a652012-12-17 07:51:15 -05001905 * @return CI_DB_query_builder
Derek Jonesd10e8962010-03-02 17:10:36 -06001906 */
Andrey Andreevfe642da2012-06-16 03:47:33 +03001907 public function set_update_batch($key, $index = '', $escape = NULL)
Derek Jonesd10e8962010-03-02 17:10:36 -06001908 {
1909 $key = $this->_object_to_array_batch($key);
Barry Mienydd671972010-10-04 16:33:58 +02001910
Derek Jonesd10e8962010-03-02 17:10:36 -06001911 if ( ! is_array($key))
1912 {
1913 // @todo error
Barry Mienydd671972010-10-04 16:33:58 +02001914 }
Derek Jonesd10e8962010-03-02 17:10:36 -06001915
Andrey Andreevfe642da2012-06-16 03:47:33 +03001916 is_bool($escape) OR $escape = $this->_protect_identifiers;
1917
Derek Jonesd10e8962010-03-02 17:10:36 -06001918 foreach ($key as $k => $v)
1919 {
1920 $index_set = FALSE;
1921 $clean = array();
Pascal Krietec3a4a8d2011-02-14 13:40:08 -05001922 foreach ($v as $k2 => $v2)
Derek Jonesd10e8962010-03-02 17:10:36 -06001923 {
Alex Bilbie48a2baf2012-06-02 11:09:54 +01001924 if ($k2 === $index)
Derek Jonesd10e8962010-03-02 17:10:36 -06001925 {
1926 $index_set = TRUE;
1927 }
Derek Jonesd10e8962010-03-02 17:10:36 -06001928
Andrey Andreevfe642da2012-06-16 03:47:33 +03001929 $clean[$this->protect_identifiers($k2, FALSE, $escape)] = ($escape === FALSE) ? $v2 : $this->escape($v2);
Derek Jonesd10e8962010-03-02 17:10:36 -06001930 }
1931
Andrey Andreev7b5eb732012-05-24 20:52:41 +03001932 if ($index_set === FALSE)
Derek Jonesd10e8962010-03-02 17:10:36 -06001933 {
1934 return $this->display_error('db_batch_missing_index');
1935 }
1936
Jamie Rumbelow7efad202012-02-19 12:37:00 +00001937 $this->qb_set[] = $clean;
Derek Jonesd10e8962010-03-02 17:10:36 -06001938 }
Barry Mienydd671972010-10-04 16:33:58 +02001939
Derek Jonesd10e8962010-03-02 17:10:36 -06001940 return $this;
1941 }
1942
Derek Allard2067d1a2008-11-13 22:59:24 +00001943 // --------------------------------------------------------------------
1944
1945 /**
1946 * Empty Table
1947 *
1948 * Compiles a delete string and runs "DELETE FROM table"
1949 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001950 * @param string the table to empty
1951 * @return object
1952 */
Phil Sturgeon9789f322011-07-15 15:14:05 -06001953 public function empty_table($table = '')
Derek Allard2067d1a2008-11-13 22:59:24 +00001954 {
Alex Bilbie48a2baf2012-06-02 11:09:54 +01001955 if ($table === '')
Derek Allard2067d1a2008-11-13 22:59:24 +00001956 {
Jamie Rumbelow7efad202012-02-19 12:37:00 +00001957 if ( ! isset($this->qb_from[0]))
Derek Allard2067d1a2008-11-13 22:59:24 +00001958 {
Andrey Andreev24276a32012-01-08 02:44:38 +02001959 return ($this->db_debug) ? $this->display_error('db_must_set_table') : FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +00001960 }
1961
Jamie Rumbelow7efad202012-02-19 12:37:00 +00001962 $table = $this->qb_from[0];
Derek Allard2067d1a2008-11-13 22:59:24 +00001963 }
1964 else
1965 {
Andrey Andreev032e7ea2012-03-06 19:48:35 +02001966 $table = $this->protect_identifiers($table, TRUE, NULL, FALSE);
Derek Allard2067d1a2008-11-13 22:59:24 +00001967 }
1968
1969 $sql = $this->_delete($table);
Derek Allard2067d1a2008-11-13 22:59:24 +00001970 $this->_reset_write();
Derek Allard2067d1a2008-11-13 22:59:24 +00001971 return $this->query($sql);
1972 }
1973
1974 // --------------------------------------------------------------------
1975
1976 /**
1977 * Truncate
1978 *
1979 * Compiles a truncate string and runs the query
1980 * If the database does not support the truncate() command
1981 * This function maps to "DELETE FROM table"
1982 *
Derek Allard2067d1a2008-11-13 22:59:24 +00001983 * @param string the table to truncate
1984 * @return object
1985 */
Phil Sturgeon9789f322011-07-15 15:14:05 -06001986 public function truncate($table = '')
Derek Allard2067d1a2008-11-13 22:59:24 +00001987 {
Alex Bilbie48a2baf2012-06-02 11:09:54 +01001988 if ($table === '')
Derek Allard2067d1a2008-11-13 22:59:24 +00001989 {
Jamie Rumbelow7efad202012-02-19 12:37:00 +00001990 if ( ! isset($this->qb_from[0]))
Derek Allard2067d1a2008-11-13 22:59:24 +00001991 {
Andrey Andreev24276a32012-01-08 02:44:38 +02001992 return ($this->db_debug) ? $this->display_error('db_must_set_table') : FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +00001993 }
1994
Jamie Rumbelow7efad202012-02-19 12:37:00 +00001995 $table = $this->qb_from[0];
Derek Allard2067d1a2008-11-13 22:59:24 +00001996 }
1997 else
1998 {
Andrey Andreev032e7ea2012-03-06 19:48:35 +02001999 $table = $this->protect_identifiers($table, TRUE, NULL, FALSE);
Derek Allard2067d1a2008-11-13 22:59:24 +00002000 }
2001
2002 $sql = $this->_truncate($table);
Derek Allard2067d1a2008-11-13 22:59:24 +00002003 $this->_reset_write();
Derek Allard2067d1a2008-11-13 22:59:24 +00002004 return $this->query($sql);
2005 }
WanWizard7219c072011-12-28 14:09:05 +01002006
Kyle Farris0c147b32011-08-26 02:29:31 -04002007 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +02002008
Kyle Farris0c147b32011-08-26 02:29:31 -04002009 /**
Andrey Andreeva6fe36e2012-04-05 16:00:32 +03002010 * Truncate statement
2011 *
2012 * Generates a platform-specific truncate string from the supplied data
2013 *
2014 * If the database does not support the truncate() command,
2015 * then this method maps to 'DELETE FROM table'
2016 *
2017 * @param string the table name
2018 * @return string
2019 */
2020 protected function _truncate($table)
2021 {
2022 return 'TRUNCATE '.$table;
2023 }
2024
2025 // --------------------------------------------------------------------
2026
2027 /**
Kyle Farris0c147b32011-08-26 02:29:31 -04002028 * Get DELETE query string
2029 *
2030 * Compiles a delete query string and returns the sql
2031 *
Kyle Farris0c147b32011-08-26 02:29:31 -04002032 * @param string the table to delete from
Jamie Rumbelowd6ce1e92012-04-26 13:27:35 +01002033 * @param bool TRUE: reset QB values; FALSE: leave QB values alone
Kyle Farris0c147b32011-08-26 02:29:31 -04002034 * @return string
2035 */
2036 public function get_compiled_delete($table = '', $reset = TRUE)
2037 {
2038 $this->return_delete_sql = TRUE;
2039 $sql = $this->delete($table, '', NULL, $reset);
2040 $this->return_delete_sql = FALSE;
2041 return $sql;
2042 }
WanWizard7219c072011-12-28 14:09:05 +01002043
Derek Allard2067d1a2008-11-13 22:59:24 +00002044 // --------------------------------------------------------------------
2045
2046 /**
2047 * Delete
2048 *
2049 * Compiles a delete string and runs the query
2050 *
Derek Allard2067d1a2008-11-13 22:59:24 +00002051 * @param mixed the table(s) to delete from. String or array
2052 * @param mixed the where clause
2053 * @param mixed the limit clause
Andrey Andreeva8bb4be2012-03-26 15:54:23 +03002054 * @param bool
Andrey Andreev0bcf5902012-10-12 13:03:29 +03002055 * @return mixed
Derek Allard2067d1a2008-11-13 22:59:24 +00002056 */
Phil Sturgeon9789f322011-07-15 15:14:05 -06002057 public function delete($table = '', $where = '', $limit = NULL, $reset_data = TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +00002058 {
2059 // Combine any cached components with the current statements
2060 $this->_merge_cache();
2061
Alex Bilbie48a2baf2012-06-02 11:09:54 +01002062 if ($table === '')
Derek Allard2067d1a2008-11-13 22:59:24 +00002063 {
Jamie Rumbelow7efad202012-02-19 12:37:00 +00002064 if ( ! isset($this->qb_from[0]))
Derek Allard2067d1a2008-11-13 22:59:24 +00002065 {
Andrey Andreev24276a32012-01-08 02:44:38 +02002066 return ($this->db_debug) ? $this->display_error('db_must_set_table') : FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +00002067 }
2068
Jamie Rumbelow7efad202012-02-19 12:37:00 +00002069 $table = $this->qb_from[0];
Derek Allard2067d1a2008-11-13 22:59:24 +00002070 }
2071 elseif (is_array($table))
2072 {
Pascal Krietec3a4a8d2011-02-14 13:40:08 -05002073 foreach ($table as $single_table)
Derek Allard2067d1a2008-11-13 22:59:24 +00002074 {
Andrey Andreev13f50542012-10-12 12:31:02 +03002075 $this->delete($single_table, $where, $limit, $reset_data);
Derek Allard2067d1a2008-11-13 22:59:24 +00002076 }
Derek Allard2067d1a2008-11-13 22:59:24 +00002077 return;
2078 }
2079 else
2080 {
Andrey Andreev032e7ea2012-03-06 19:48:35 +02002081 $table = $this->protect_identifiers($table, TRUE, NULL, FALSE);
Derek Allard2067d1a2008-11-13 22:59:24 +00002082 }
2083
Alex Bilbie48a2baf2012-06-02 11:09:54 +01002084 if ($where !== '')
Derek Allard2067d1a2008-11-13 22:59:24 +00002085 {
2086 $this->where($where);
2087 }
2088
Andrey Andreev650b4c02012-06-11 12:07:15 +03002089 if ( ! empty($limit))
Derek Allard2067d1a2008-11-13 22:59:24 +00002090 {
2091 $this->limit($limit);
2092 }
2093
Andrey Andreev94611df2012-07-19 12:29:54 +03002094 if (count($this->qb_where) === 0)
Derek Allard2067d1a2008-11-13 22:59:24 +00002095 {
Andrey Andreev24276a32012-01-08 02:44:38 +02002096 return ($this->db_debug) ? $this->display_error('db_del_must_use_where') : FALSE;
Barry Mienydd671972010-10-04 16:33:58 +02002097 }
Derek Allard2067d1a2008-11-13 22:59:24 +00002098
Andrey Andreevb0478652012-07-18 15:34:46 +03002099 $sql = $this->_delete($table);
Derek Allard2067d1a2008-11-13 22:59:24 +00002100 if ($reset_data)
2101 {
2102 $this->_reset_write();
2103 }
WanWizard7219c072011-12-28 14:09:05 +01002104
Andrey Andreev24276a32012-01-08 02:44:38 +02002105 return ($this->return_delete_sql === TRUE) ? $sql : $this->query($sql);
Derek Allard2067d1a2008-11-13 22:59:24 +00002106 }
WanWizard7219c072011-12-28 14:09:05 +01002107
Derek Allard2067d1a2008-11-13 22:59:24 +00002108 // --------------------------------------------------------------------
2109
2110 /**
Andrey Andreevc01d3162012-04-09 12:55:11 +03002111 * Delete statement
2112 *
2113 * Generates a platform-specific delete string from the supplied data
2114 *
2115 * @param string the table name
Andrey Andreevc01d3162012-04-09 12:55:11 +03002116 * @return string
2117 */
Andrey Andreevb0478652012-07-18 15:34:46 +03002118 protected function _delete($table)
Andrey Andreevc01d3162012-04-09 12:55:11 +03002119 {
Andrey Andreevd40459d2012-07-18 16:46:39 +03002120 return 'DELETE FROM '.$table.$this->_compile_wh('qb_where')
Andrey Andreevc9b924c2012-07-19 13:06:02 +03002121 .($this->qb_limit ? ' LIMIT '.$this->qb_limit : '');
Andrey Andreevc01d3162012-04-09 12:55:11 +03002122 }
2123
2124 // --------------------------------------------------------------------
2125
2126 /**
Derek Allard2067d1a2008-11-13 22:59:24 +00002127 * DB Prefix
2128 *
2129 * Prepends a database prefix if one exists in configuration
2130 *
Derek Allard2067d1a2008-11-13 22:59:24 +00002131 * @param string the table
2132 * @return string
2133 */
Phil Sturgeon9789f322011-07-15 15:14:05 -06002134 public function dbprefix($table = '')
Derek Allard2067d1a2008-11-13 22:59:24 +00002135 {
Alex Bilbie48a2baf2012-06-02 11:09:54 +01002136 if ($table === '')
Derek Allard2067d1a2008-11-13 22:59:24 +00002137 {
2138 $this->display_error('db_table_name_required');
2139 }
2140
2141 return $this->dbprefix.$table;
2142 }
2143
2144 // --------------------------------------------------------------------
2145
2146 /**
Phil Sturgeon8a022472011-07-15 15:25:15 -06002147 * Set DB Prefix
2148 *
2149 * Set's the DB Prefix to something new without needing to reconnect
2150 *
2151 * @param string the prefix
2152 * @return string
2153 */
2154 public function set_dbprefix($prefix = '')
2155 {
2156 return $this->dbprefix = $prefix;
2157 }
2158
2159 // --------------------------------------------------------------------
2160
2161 /**
Derek Allard2067d1a2008-11-13 22:59:24 +00002162 * Track Aliases
2163 *
2164 * Used to track SQL statements written with aliased tables.
2165 *
Derek Allard2067d1a2008-11-13 22:59:24 +00002166 * @param string The table to inspect
2167 * @return string
Barry Mienydd671972010-10-04 16:33:58 +02002168 */
Phil Sturgeon9789f322011-07-15 15:14:05 -06002169 protected function _track_aliases($table)
Derek Allard2067d1a2008-11-13 22:59:24 +00002170 {
2171 if (is_array($table))
2172 {
2173 foreach ($table as $t)
2174 {
2175 $this->_track_aliases($t);
2176 }
2177 return;
2178 }
Barry Mienydd671972010-10-04 16:33:58 +02002179
Derek Jones37f4b9c2011-07-01 17:56:50 -05002180 // Does the string contain a comma? If so, we need to separate
Derek Allard2067d1a2008-11-13 22:59:24 +00002181 // the string into discreet statements
2182 if (strpos($table, ',') !== FALSE)
2183 {
2184 return $this->_track_aliases(explode(',', $table));
2185 }
Barry Mienydd671972010-10-04 16:33:58 +02002186
Derek Allard2067d1a2008-11-13 22:59:24 +00002187 // if a table alias is used we can recognize it by a space
Andrey Andreev24276a32012-01-08 02:44:38 +02002188 if (strpos($table, ' ') !== FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +00002189 {
2190 // if the alias is written with the AS keyword, remove it
Andrey Andreev5a257182012-06-10 06:18:14 +03002191 $table = preg_replace('/\s+AS\s+/i', ' ', $table);
Barry Mienydd671972010-10-04 16:33:58 +02002192
Derek Allard2067d1a2008-11-13 22:59:24 +00002193 // Grab the alias
Andrey Andreev24276a32012-01-08 02:44:38 +02002194 $table = trim(strrchr($table, ' '));
Barry Mienydd671972010-10-04 16:33:58 +02002195
Derek Allard2067d1a2008-11-13 22:59:24 +00002196 // Store the alias, if it doesn't already exist
Jamie Rumbelow7efad202012-02-19 12:37:00 +00002197 if ( ! in_array($table, $this->qb_aliased_tables))
Derek Allard2067d1a2008-11-13 22:59:24 +00002198 {
Jamie Rumbelow7efad202012-02-19 12:37:00 +00002199 $this->qb_aliased_tables[] = $table;
Derek Allard2067d1a2008-11-13 22:59:24 +00002200 }
2201 }
2202 }
WanWizard7219c072011-12-28 14:09:05 +01002203
Derek Allard2067d1a2008-11-13 22:59:24 +00002204 // --------------------------------------------------------------------
2205
2206 /**
2207 * Compile the SELECT statement
2208 *
2209 * Generates a query string based on which functions were used.
Andrey Andreev5fd3ae82012-10-24 14:55:35 +03002210 * Should not be called directly.
Derek Allard2067d1a2008-11-13 22:59:24 +00002211 *
Andrey Andreevae85eb42012-11-02 01:42:31 +02002212 * @param bool $select_override
Derek Allard2067d1a2008-11-13 22:59:24 +00002213 * @return string
2214 */
Phil Sturgeon9789f322011-07-15 15:14:05 -06002215 protected function _compile_select($select_override = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +00002216 {
2217 // Combine any cached components with the current statements
2218 $this->_merge_cache();
2219
Derek Allard2067d1a2008-11-13 22:59:24 +00002220 // Write the "select" portion of the query
Derek Allard2067d1a2008-11-13 22:59:24 +00002221 if ($select_override !== FALSE)
2222 {
2223 $sql = $select_override;
2224 }
2225 else
2226 {
Jamie Rumbelow7efad202012-02-19 12:37:00 +00002227 $sql = ( ! $this->qb_distinct) ? 'SELECT ' : 'SELECT DISTINCT ';
Barry Mienydd671972010-10-04 16:33:58 +02002228
Jamie Rumbelow7efad202012-02-19 12:37:00 +00002229 if (count($this->qb_select) === 0)
Derek Allard2067d1a2008-11-13 22:59:24 +00002230 {
Barry Mienydd671972010-10-04 16:33:58 +02002231 $sql .= '*';
Derek Allard2067d1a2008-11-13 22:59:24 +00002232 }
2233 else
Barry Mienydd671972010-10-04 16:33:58 +02002234 {
Derek Allard2067d1a2008-11-13 22:59:24 +00002235 // Cycle through the "select" portion of the query and prep each column name.
2236 // The reason we protect identifiers here rather then in the select() function
2237 // is because until the user calls the from() function we don't know if there are aliases
Jamie Rumbelow7efad202012-02-19 12:37:00 +00002238 foreach ($this->qb_select as $key => $val)
Derek Allard2067d1a2008-11-13 22:59:24 +00002239 {
Jamie Rumbelow7efad202012-02-19 12:37:00 +00002240 $no_escape = isset($this->qb_no_escape[$key]) ? $this->qb_no_escape[$key] : NULL;
Jamie Rumbelow0c092992012-03-06 22:05:16 +00002241 $this->qb_select[$key] = $this->protect_identifiers($val, FALSE, $no_escape);
Derek Allard2067d1a2008-11-13 22:59:24 +00002242 }
Barry Mienydd671972010-10-04 16:33:58 +02002243
Jamie Rumbelow7efad202012-02-19 12:37:00 +00002244 $sql .= implode(', ', $this->qb_select);
Derek Allard2067d1a2008-11-13 22:59:24 +00002245 }
2246 }
2247
Derek Allard2067d1a2008-11-13 22:59:24 +00002248 // Write the "FROM" portion of the query
Jamie Rumbelow7efad202012-02-19 12:37:00 +00002249 if (count($this->qb_from) > 0)
Derek Allard2067d1a2008-11-13 22:59:24 +00002250 {
Andrey Andreeve78f8152012-10-09 11:38:38 +03002251 $sql .= "\nFROM ".$this->_from_tables();
Derek Allard2067d1a2008-11-13 22:59:24 +00002252 }
2253
Derek Allard2067d1a2008-11-13 22:59:24 +00002254 // Write the "JOIN" portion of the query
Jamie Rumbelow7efad202012-02-19 12:37:00 +00002255 if (count($this->qb_join) > 0)
Derek Allard2067d1a2008-11-13 22:59:24 +00002256 {
Jamie Rumbelow7efad202012-02-19 12:37:00 +00002257 $sql .= "\n".implode("\n", $this->qb_join);
Derek Allard2067d1a2008-11-13 22:59:24 +00002258 }
2259
Andrey Andreev2d486232012-07-19 14:46:51 +03002260 $sql .= $this->_compile_wh('qb_where')
2261 .$this->_compile_group_by()
2262 .$this->_compile_wh('qb_having')
2263 .$this->_compile_order_by(); // ORDER BY
Andrey Andreevb0478652012-07-18 15:34:46 +03002264
Andrey Andreevd40459d2012-07-18 16:46:39 +03002265 // LIMIT
Andrey Andreevc9b924c2012-07-19 13:06:02 +03002266 if ($this->qb_limit)
Derek Allard2067d1a2008-11-13 22:59:24 +00002267 {
Andrey Andreevc9b924c2012-07-19 13:06:02 +03002268 return $this->_limit($sql."\n");
Derek Allard2067d1a2008-11-13 22:59:24 +00002269 }
2270
2271 return $sql;
2272 }
2273
2274 // --------------------------------------------------------------------
2275
2276 /**
Andrey Andreevd40459d2012-07-18 16:46:39 +03002277 * Compile WHERE, HAVING statements
Andrey Andreev6e704752012-07-18 00:46:33 +03002278 *
Andrey Andreevd40459d2012-07-18 16:46:39 +03002279 * Escapes identifiers in WHERE and HAVING statements at execution time.
2280 *
Andrey Andreevb0478652012-07-18 15:34:46 +03002281 * Required so that aliases are tracked properly, regardless of wether
Andrey Andreevd40459d2012-07-18 16:46:39 +03002282 * where(), or_where(), having(), or_having are called prior to from(),
2283 * join() and dbprefix is added only if needed.
Andrey Andreev6e704752012-07-18 00:46:33 +03002284 *
Andrey Andreevae85eb42012-11-02 01:42:31 +02002285 * @param string $qb_key 'qb_where' or 'qb_having'
Andrey Andreevd40459d2012-07-18 16:46:39 +03002286 * @return string SQL statement
Andrey Andreev6e704752012-07-18 00:46:33 +03002287 */
Andrey Andreevd40459d2012-07-18 16:46:39 +03002288 protected function _compile_wh($qb_key)
Andrey Andreev6e704752012-07-18 00:46:33 +03002289 {
Andrey Andreevd40459d2012-07-18 16:46:39 +03002290 if (count($this->$qb_key) > 0)
Andrey Andreev6e704752012-07-18 00:46:33 +03002291 {
Andrey Andreevd40459d2012-07-18 16:46:39 +03002292 for ($i = 0, $c = count($this->$qb_key); $i < $c; $i++)
Andrey Andreev6e704752012-07-18 00:46:33 +03002293 {
Andrey Andreevd40459d2012-07-18 16:46:39 +03002294 if ($this->{$qb_key}[$i]['escape'] === FALSE)
Andrey Andreev6e704752012-07-18 00:46:33 +03002295 {
Andrey Andreevd40459d2012-07-18 16:46:39 +03002296 $this->{$qb_key}[$i] = $this->{$qb_key}[$i]['condition'];
Andrey Andreev6e704752012-07-18 00:46:33 +03002297 continue;
2298 }
2299
Andrey Andreevf2ec8b82012-10-12 14:01:13 +03002300 // Split multiple conditions
2301 $conditions = preg_split(
2302 '/(\s*AND\s+|\s*OR\s+)/i',
2303 $this->{$qb_key}[$i]['condition'],
2304 -1,
2305 PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY
2306 );
2307
2308 for ($ci = 0, $cc = count($conditions); $ci < $cc; $ci++)
Andrey Andreev6e704752012-07-18 00:46:33 +03002309 {
Andrey Andreevf2ec8b82012-10-12 14:01:13 +03002310 if (($op = $this->_get_operator($conditions[$ci])) === FALSE
Andrey Andreeve4742582012-10-25 13:25:13 +03002311 OR ! preg_match('/^(\(?)(.*)('.preg_quote($op, '/').')\s*(.*(?<!\)))?(\)?)$/i', $conditions[$ci], $matches))
Andrey Andreevf2ec8b82012-10-12 14:01:13 +03002312 {
2313 continue;
2314 }
2315
2316 // $matches = array(
2317 // 0 => '(test <= foo)', /* the whole thing */
2318 // 1 => '(', /* optional */
2319 // 2 => 'test', /* the field name */
2320 // 3 => ' <= ', /* $op */
2321 // 4 => 'foo', /* optional, if $op is e.g. 'IS NULL' */
2322 // 5 => ')' /* optional */
2323 // );
Andrey Andreev082aa402012-10-22 19:41:55 +03002324
2325 if ( ! empty($matches[4]))
2326 {
2327 $this->_is_literal($matches[4]) OR $matches[4] = $this->protect_identifiers(trim($matches[4]));
2328 $matches[4] = ' '.$matches[4];
2329 }
2330
Andrey Andreevf2ec8b82012-10-12 14:01:13 +03002331 $conditions[$ci] = $matches[1].$this->protect_identifiers(trim($matches[2]))
2332 .' '.trim($matches[3]).$matches[4].$matches[5];
Andrey Andreev6e704752012-07-18 00:46:33 +03002333 }
2334
Andrey Andreevf2ec8b82012-10-12 14:01:13 +03002335 $this->{$qb_key}[$i] = implode('', $conditions);
Andrey Andreev6e704752012-07-18 00:46:33 +03002336 }
2337
Andrey Andreev9d3aa1b2012-10-12 12:14:09 +03002338 return ($qb_key === 'qb_having' ? "\nHAVING " : "\nWHERE ")
2339 .implode("\n", $this->$qb_key);
Andrey Andreev6e704752012-07-18 00:46:33 +03002340 }
2341
Andrey Andreevb0478652012-07-18 15:34:46 +03002342 return '';
Andrey Andreev6e704752012-07-18 00:46:33 +03002343 }
2344
2345 // --------------------------------------------------------------------
2346
2347 /**
Andrey Andreevc9b924c2012-07-19 13:06:02 +03002348 * Compile GROUP BY
2349 *
2350 * Escapes identifiers in GROUP BY statements at execution time.
2351 *
2352 * Required so that aliases are tracked properly, regardless of wether
2353 * group_by() is called prior to from(), join() and dbprefix is added
2354 * only if needed.
2355 *
2356 * @return string SQL statement
2357 */
2358 protected function _compile_group_by()
2359 {
2360 if (count($this->qb_groupby) > 0)
2361 {
Andrey Andreev96feb582012-07-19 13:12:34 +03002362 for ($i = 0, $c = count($this->qb_groupby); $i < $c; $i++)
2363 {
Andrey Andreev082aa402012-10-22 19:41:55 +03002364 $this->qb_groupby[$i] = ($this->qb_groupby[$i]['escape'] === FALSE OR $this->_is_literal($this->qb_groupby[$i]['field']))
Andrey Andreev96feb582012-07-19 13:12:34 +03002365 ? $this->qb_groupby[$i]['field']
Andrey Andreev13f50542012-10-12 12:31:02 +03002366 : $this->protect_identifiers($this->qb_groupby[$i]['field']);
Andrey Andreev96feb582012-07-19 13:12:34 +03002367 }
2368
Andrey Andreev0bcf5902012-10-12 13:03:29 +03002369 return "\nGROUP BY ".implode(', ', $this->qb_groupby);
Andrey Andreevc9b924c2012-07-19 13:06:02 +03002370 }
2371
2372 return '';
2373 }
2374
2375 // --------------------------------------------------------------------
2376
2377 /**
Andrey Andreev2d486232012-07-19 14:46:51 +03002378 * Compile ORDER BY
2379 *
2380 * Escapes identifiers in ORDER BY statements at execution time.
2381 *
2382 * Required so that aliases are tracked properly, regardless of wether
2383 * order_by() is called prior to from(), join() and dbprefix is added
2384 * only if needed.
2385 *
2386 * @return string SQL statement
2387 */
2388 protected function _compile_order_by()
2389 {
Andrey Andreeva53ea842012-10-23 12:44:09 +03002390 if (is_array($this->qb_orderby) && count($this->qb_orderby) > 0)
Andrey Andreev2d486232012-07-19 14:46:51 +03002391 {
Andrey Andreev2d486232012-07-19 14:46:51 +03002392 for ($i = 0, $c = count($this->qb_orderby); $i < $c; $i++)
2393 {
Andrey Andreev082aa402012-10-22 19:41:55 +03002394 if ($this->qb_orderby[$i]['escape'] !== FALSE && ! $this->_is_literal($this->qb_orderby[$i]['field']))
Andrey Andreev2d486232012-07-19 14:46:51 +03002395 {
Andrey Andreevfc043b32012-10-12 14:46:14 +03002396 $this->qb_orderby[$i]['field'] = $this->protect_identifiers($this->qb_orderby[$i]['field']);
Andrey Andreev2d486232012-07-19 14:46:51 +03002397 }
2398
2399 $this->qb_orderby[$i] = $this->qb_orderby[$i]['field'].$this->qb_orderby[$i]['direction'];
2400 }
2401
Andrey Andreeva53ea842012-10-23 12:44:09 +03002402 return $this->qb_orderby = "\nORDER BY ".implode(', ', $this->qb_orderby);
2403 }
2404 elseif (is_string($this->qb_orderby))
2405 {
2406 return $this->qb_orderby;
Andrey Andreev2d486232012-07-19 14:46:51 +03002407 }
2408
2409 return '';
2410 }
2411
2412 // --------------------------------------------------------------------
2413
2414 /**
Derek Allard2067d1a2008-11-13 22:59:24 +00002415 * Object to Array
2416 *
2417 * Takes an object as input and converts the class variables to array key/vals
2418 *
Derek Allard2067d1a2008-11-13 22:59:24 +00002419 * @param object
2420 * @return array
2421 */
Andrey Andreev7b5eb732012-05-24 20:52:41 +03002422 protected function _object_to_array($object)
Derek Allard2067d1a2008-11-13 22:59:24 +00002423 {
2424 if ( ! is_object($object))
2425 {
2426 return $object;
2427 }
Barry Mienydd671972010-10-04 16:33:58 +02002428
Derek Allard2067d1a2008-11-13 22:59:24 +00002429 $array = array();
2430 foreach (get_object_vars($object) as $key => $val)
2431 {
2432 // There are some built in keys we need to ignore for this conversion
Alex Bilbie48a2baf2012-06-02 11:09:54 +01002433 if ( ! is_object($val) && ! is_array($val) && $key !== '_parent_name')
Derek Allard2067d1a2008-11-13 22:59:24 +00002434 {
2435 $array[$key] = $val;
2436 }
2437 }
Derek Jonesd10e8962010-03-02 17:10:36 -06002438
2439 return $array;
2440 }
Barry Mienydd671972010-10-04 16:33:58 +02002441
Derek Jonesd10e8962010-03-02 17:10:36 -06002442 // --------------------------------------------------------------------
2443
2444 /**
2445 * Object to Array
2446 *
2447 * Takes an object as input and converts the class variables to array key/vals
2448 *
Derek Jonesd10e8962010-03-02 17:10:36 -06002449 * @param object
2450 * @return array
2451 */
Andrey Andreev7b5eb732012-05-24 20:52:41 +03002452 protected function _object_to_array_batch($object)
Derek Jonesd10e8962010-03-02 17:10:36 -06002453 {
2454 if ( ! is_object($object))
2455 {
2456 return $object;
2457 }
Barry Mienydd671972010-10-04 16:33:58 +02002458
Derek Jonesd10e8962010-03-02 17:10:36 -06002459 $array = array();
2460 $out = get_object_vars($object);
2461 $fields = array_keys($out);
2462
2463 foreach ($fields as $val)
2464 {
2465 // There are some built in keys we need to ignore for this conversion
Andrey Andreev24276a32012-01-08 02:44:38 +02002466 if ($val !== '_parent_name')
Derek Jonesd10e8962010-03-02 17:10:36 -06002467 {
Derek Jonesd10e8962010-03-02 17:10:36 -06002468 $i = 0;
2469 foreach ($out[$val] as $data)
2470 {
Andrey Andreev24276a32012-01-08 02:44:38 +02002471 $array[$i++][$val] = $data;
Derek Jonesd10e8962010-03-02 17:10:36 -06002472 }
2473 }
2474 }
2475
Derek Allard2067d1a2008-11-13 22:59:24 +00002476 return $array;
2477 }
Barry Mienydd671972010-10-04 16:33:58 +02002478
Derek Allard2067d1a2008-11-13 22:59:24 +00002479 // --------------------------------------------------------------------
2480
2481 /**
2482 * Start Cache
2483 *
Jamie Rumbelow17c1bed2012-03-06 21:30:38 +00002484 * Starts QB caching
Derek Allard2067d1a2008-11-13 22:59:24 +00002485 *
Derek Allard2067d1a2008-11-13 22:59:24 +00002486 * @return void
Barry Mienydd671972010-10-04 16:33:58 +02002487 */
Phil Sturgeon9789f322011-07-15 15:14:05 -06002488 public function start_cache()
Derek Allard2067d1a2008-11-13 22:59:24 +00002489 {
Jamie Rumbelow7efad202012-02-19 12:37:00 +00002490 $this->qb_caching = TRUE;
Derek Allard2067d1a2008-11-13 22:59:24 +00002491 }
2492
2493 // --------------------------------------------------------------------
2494
2495 /**
2496 * Stop Cache
2497 *
Jamie Rumbelow17c1bed2012-03-06 21:30:38 +00002498 * Stops QB caching
Derek Allard2067d1a2008-11-13 22:59:24 +00002499 *
Derek Allard2067d1a2008-11-13 22:59:24 +00002500 * @return void
Barry Mienydd671972010-10-04 16:33:58 +02002501 */
Phil Sturgeon9789f322011-07-15 15:14:05 -06002502 public function stop_cache()
Derek Allard2067d1a2008-11-13 22:59:24 +00002503 {
Jamie Rumbelow7efad202012-02-19 12:37:00 +00002504 $this->qb_caching = FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +00002505 }
2506
2507 // --------------------------------------------------------------------
2508
2509 /**
2510 * Flush Cache
2511 *
Jamie Rumbelow17c1bed2012-03-06 21:30:38 +00002512 * Empties the QB cache
Derek Allard2067d1a2008-11-13 22:59:24 +00002513 *
Derek Allard2067d1a2008-11-13 22:59:24 +00002514 * @return void
Barry Mienydd671972010-10-04 16:33:58 +02002515 */
Phil Sturgeon9789f322011-07-15 15:14:05 -06002516 public function flush_cache()
Barry Mienydd671972010-10-04 16:33:58 +02002517 {
Phil Sturgeon9789f322011-07-15 15:14:05 -06002518 $this->_reset_run(array(
Jamie Rumbelow17c1bed2012-03-06 21:30:38 +00002519 'qb_cache_select' => array(),
2520 'qb_cache_from' => array(),
2521 'qb_cache_join' => array(),
2522 'qb_cache_where' => array(),
Jamie Rumbelow17c1bed2012-03-06 21:30:38 +00002523 'qb_cache_groupby' => array(),
2524 'qb_cache_having' => array(),
2525 'qb_cache_orderby' => array(),
2526 'qb_cache_set' => array(),
2527 'qb_cache_exists' => array(),
2528 'qb_cache_no_escape' => array()
Phil Sturgeon9789f322011-07-15 15:14:05 -06002529 ));
Derek Allard2067d1a2008-11-13 22:59:24 +00002530 }
2531
2532 // --------------------------------------------------------------------
2533
2534 /**
2535 * Merge Cache
2536 *
Jamie Rumbelow17c1bed2012-03-06 21:30:38 +00002537 * When called, this function merges any cached QB arrays with
Derek Allard2067d1a2008-11-13 22:59:24 +00002538 * locally called ones.
2539 *
Derek Allard2067d1a2008-11-13 22:59:24 +00002540 * @return void
2541 */
Phil Sturgeon9789f322011-07-15 15:14:05 -06002542 protected function _merge_cache()
Derek Allard2067d1a2008-11-13 22:59:24 +00002543 {
Jamie Rumbelow7efad202012-02-19 12:37:00 +00002544 if (count($this->qb_cache_exists) === 0)
Derek Allard2067d1a2008-11-13 22:59:24 +00002545 {
2546 return;
2547 }
2548
Jamie Rumbelow7efad202012-02-19 12:37:00 +00002549 foreach ($this->qb_cache_exists as $val)
Derek Allard2067d1a2008-11-13 22:59:24 +00002550 {
Jamie Rumbelowae123e02012-02-21 16:39:56 +00002551 $qb_variable = 'qb_'.$val;
2552 $qb_cache_var = 'qb_cache_'.$val;
Derek Allard2067d1a2008-11-13 22:59:24 +00002553
Jamie Rumbelow7efad202012-02-19 12:37:00 +00002554 if (count($this->$qb_cache_var) === 0)
Derek Allard2067d1a2008-11-13 22:59:24 +00002555 {
2556 continue;
2557 }
Andrey Andreeveae17d12012-11-17 23:55:18 +02002558 $this->$qb_variable = array_merge($this->$qb_variable, array_diff($this->$qb_cache_var, $this->$qb_variable));
Derek Allard2067d1a2008-11-13 22:59:24 +00002559 }
2560
2561 // If we are "protecting identifiers" we need to examine the "from"
2562 // portion of the query to determine if there are any aliases
Jamie Rumbelowd6ce1e92012-04-26 13:27:35 +01002563 if ($this->_protect_identifiers === TRUE && count($this->qb_cache_from) > 0)
Derek Allard2067d1a2008-11-13 22:59:24 +00002564 {
Jamie Rumbelow7efad202012-02-19 12:37:00 +00002565 $this->_track_aliases($this->qb_from);
Derek Allard2067d1a2008-11-13 22:59:24 +00002566 }
Greg Aker2e1837a2011-05-06 12:17:04 -05002567
Andrey Andreeveae17d12012-11-17 23:55:18 +02002568 $this->qb_no_escape = array_merge($this->qb_no_escape, array_diff($this->qb_cache_no_escape, $this->qb_no_escape));
Derek Allard2067d1a2008-11-13 22:59:24 +00002569 }
WanWizard7219c072011-12-28 14:09:05 +01002570
Kyle Farris0c147b32011-08-26 02:29:31 -04002571 // --------------------------------------------------------------------
2572
2573 /**
Andrey Andreev082aa402012-10-22 19:41:55 +03002574 * Is literal
2575 *
2576 * Determines if a string represents a literal value or a field name
2577 *
Andrey Andreev02e4cd72012-11-13 11:50:47 +02002578 * @param string $str
Andrey Andreev082aa402012-10-22 19:41:55 +03002579 * @return bool
2580 */
2581 protected function _is_literal($str)
2582 {
2583 $str = trim($str);
2584
Andrey Andreev3a5efc22012-11-20 21:18:08 +02002585 if (empty($str) OR ctype_digit($str) OR (string) (float) $str === $str OR in_array(strtoupper($str), array('TRUE', 'FALSE'), TRUE))
Andrey Andreev082aa402012-10-22 19:41:55 +03002586 {
2587 return TRUE;
2588 }
2589
2590 static $_str;
2591
2592 if (empty($_str))
2593 {
2594 $_str = ($this->_escape_char !== '"')
2595 ? array('"', "'") : array("'");
2596 }
2597
Andrey Andreev3a5efc22012-11-20 21:18:08 +02002598 return in_array($str[0], $_str, TRUE);
Andrey Andreev082aa402012-10-22 19:41:55 +03002599 }
2600
2601 // --------------------------------------------------------------------
2602
2603 /**
Jamie Rumbelow7efad202012-02-19 12:37:00 +00002604 * Reset Query Builder values.
WanWizard7219c072011-12-28 14:09:05 +01002605 *
Jamie Rumbelow17c1bed2012-03-06 21:30:38 +00002606 * Publicly-visible method to reset the QB values.
Kyle Farris0c147b32011-08-26 02:29:31 -04002607 *
Kyle Farris0c147b32011-08-26 02:29:31 -04002608 * @return void
2609 */
2610 public function reset_query()
2611 {
2612 $this->_reset_select();
2613 $this->_reset_write();
2614 }
Derek Allard2067d1a2008-11-13 22:59:24 +00002615
2616 // --------------------------------------------------------------------
2617
2618 /**
Jamie Rumbelow7efad202012-02-19 12:37:00 +00002619 * Resets the query builder values. Called by the get() function
Derek Allard2067d1a2008-11-13 22:59:24 +00002620 *
Derek Allard2067d1a2008-11-13 22:59:24 +00002621 * @param array An array of fields to reset
2622 * @return void
2623 */
Jamie Rumbelow7efad202012-02-19 12:37:00 +00002624 protected function _reset_run($qb_reset_items)
Derek Allard2067d1a2008-11-13 22:59:24 +00002625 {
Jamie Rumbelow7efad202012-02-19 12:37:00 +00002626 foreach ($qb_reset_items as $item => $default_value)
Derek Allard2067d1a2008-11-13 22:59:24 +00002627 {
Andrey Andreevae85eb42012-11-02 01:42:31 +02002628 $this->$item = $default_value;
Derek Allard2067d1a2008-11-13 22:59:24 +00002629 }
2630 }
2631
2632 // --------------------------------------------------------------------
2633
2634 /**
Jamie Rumbelow7efad202012-02-19 12:37:00 +00002635 * Resets the query builder values. Called by the get() function
Derek Allard2067d1a2008-11-13 22:59:24 +00002636 *
Derek Allard2067d1a2008-11-13 22:59:24 +00002637 * @return void
2638 */
Phil Sturgeon9789f322011-07-15 15:14:05 -06002639 protected function _reset_select()
Derek Allard2067d1a2008-11-13 22:59:24 +00002640 {
Andrey Andreev24276a32012-01-08 02:44:38 +02002641 $this->_reset_run(array(
Jamie Rumbelowae123e02012-02-21 16:39:56 +00002642 'qb_select' => array(),
2643 'qb_from' => array(),
2644 'qb_join' => array(),
2645 'qb_where' => array(),
Jamie Rumbelowae123e02012-02-21 16:39:56 +00002646 'qb_groupby' => array(),
2647 'qb_having' => array(),
2648 'qb_orderby' => array(),
Jamie Rumbelowae123e02012-02-21 16:39:56 +00002649 'qb_aliased_tables' => array(),
2650 'qb_no_escape' => array(),
2651 'qb_distinct' => FALSE,
2652 'qb_limit' => FALSE,
Andrey Andreev650b4c02012-06-11 12:07:15 +03002653 'qb_offset' => FALSE
Andrey Andreev24276a32012-01-08 02:44:38 +02002654 )
2655 );
Derek Allard2067d1a2008-11-13 22:59:24 +00002656 }
Barry Mienydd671972010-10-04 16:33:58 +02002657
Derek Allard2067d1a2008-11-13 22:59:24 +00002658 // --------------------------------------------------------------------
2659
2660 /**
Jamie Rumbelow7efad202012-02-19 12:37:00 +00002661 * Resets the query builder "write" values.
Derek Allard2067d1a2008-11-13 22:59:24 +00002662 *
Robin Sowell43753fd2010-09-16 12:52:07 -04002663 * Called by the insert() update() insert_batch() update_batch() and delete() functions
Derek Allard2067d1a2008-11-13 22:59:24 +00002664 *
Derek Allard2067d1a2008-11-13 22:59:24 +00002665 * @return void
2666 */
Phil Sturgeon9789f322011-07-15 15:14:05 -06002667 protected function _reset_write()
Barry Mienydd671972010-10-04 16:33:58 +02002668 {
Andrey Andreev24276a32012-01-08 02:44:38 +02002669 $this->_reset_run(array(
Jamie Rumbelowd6ce1e92012-04-26 13:27:35 +01002670 'qb_set' => array(),
2671 'qb_from' => array(),
Andrey Andreev3e014372013-02-21 15:59:34 +02002672 'qb_join' => array(),
Jamie Rumbelowd6ce1e92012-04-26 13:27:35 +01002673 'qb_where' => array(),
Jamie Rumbelowd6ce1e92012-04-26 13:27:35 +01002674 'qb_orderby' => array(),
2675 'qb_keys' => array(),
Andrey Andreev650b4c02012-06-11 12:07:15 +03002676 'qb_limit' => FALSE
Timothy Warren215890b2012-03-20 09:38:16 -04002677 )
2678 );
Derek Allard2067d1a2008-11-13 22:59:24 +00002679 }
Andrey Andreev24276a32012-01-08 02:44:38 +02002680
Derek Allard2067d1a2008-11-13 22:59:24 +00002681}
2682
Jamie Rumbelow7efad202012-02-19 12:37:00 +00002683/* End of file DB_query_builder.php */
Andrey Andreev58803fb2012-06-24 00:45:37 +03002684/* Location: ./system/database/DB_query_builder.php */