Source for file Select.php

Documentation is available at Select.php


1 <?php
2 /**
3 * $Id: Select.php,v 1.1.1.1 2004/02/14 01:43:22 luckec Exp $
4 *
5 * Subclass of tgcSqlBuilder that helps to create SELECT sql-statements.
6 *
7 * @package tgcSqlBuilder
8 * @author Carsten Lucke <luckec@tool-garage.de>
9 * @copyright Carsten Lucke <http://www.tool-garage.de>
10 */
11
12
13
14 /**
15 * Removing a SELECT value failed
16 *
17 * @access public
18 */
19 define('SQLBUILDER_ERROR_SELECT_REMOVE', 101);
20
21 /**
22 * Invalid ORDER BY direction
23 *
24 * @access public
25 */
26 define('SQLBUILDER_ERROR_INVALID_ORDER_BY_DIRECTION', 102);
27
28
29
30 /**
31 * Subclass of tgcSqlBuilder that helps to create SELECT sql-statements.
32 *
33 * @package tgcSqlBuilder
34 * @access public
35 * @version 1.0.0
36 * @author Carsten Lucke <luckec@tool-garage.de>
37 */
38 class tgcSqlBuilder_Select extends tgcSqlBuilder
39 {
40
41 /**
42 * Keeps the ORDER BY information.
43 *
44 * The array's structure looks like that:
45 * <pre>
46 * array(
47 * array(
48 * 'table' => $tableName,
49 * 'column' => $columnName,
50 * 'direction' => $direction
51 * ),
52 * array( ... ),
53 * ...
54 * )
55 * </pre>
56 *
57 * @access private
58 * @var array ORDER BY information
59 *
60 *
61 */
62 var $_orderBy = array();
63
64 /**
65 * Keeps the WHERE information.
66 *
67 * Structure:
68 * <pre>
69 * array(
70 * 'OR' => array(
71 * array(
72 * 'table' => $tableName,
73 * 'column' => $columnName,
74 * 'value' => $value,
75 * 'compOp' => $comparisonOperator,
76 * },
77 * ...
78 * ),
79 * 'AND' => array(
80 * array(
81 * 'table' => $tableName,
82 * 'column' => $columnName,
83 * 'value' => $value,
84 * 'compOp' => $comparisonOperator,
85 * },
86 * ...
87 * )
88 * </pre>
89 *
90 * @access private
91 * @var array WHERE information
92 */
93 var $_where = array(
94 SQLBUILDER_LOGICAL_AND => array(),
95 SQLBUILDER_LOGICAL_OR => array()
96 );
97
98 /**
99 * Keeps the raw WHERE information.
100 *
101 * Structure:
102 * <pre>
103 * array(
104 * 'OR' => array(
105 * $statement1,
106 * $statement2,
107 * ...
108 * ),
109 * 'AND' => array(
110 * $statement1,
111 * $statement2,
112 * ...
113 * )
114 * </pre>
115 *
116 * @access private
117 * @var array WHERE information
118 */
119 var $_rawWhere = array(
120 SQLBUILDER_LOGICAL_AND => array(),
121 SQLBUILDER_LOGICAL_OR => array()
122 );
123
124 /**
125 * Keeps the HAVING information.
126 *
127 * Structure:
128 * <pre>
129 * array(
130 * 'OR' => array(
131 * array(
132 * 'table' => $tableName,
133 * 'column' => $columnName,
134 * 'value' => $value,
135 * 'compOp' => $comparisonOperator,
136 * },
137 * ...
138 * ),
139 * 'AND' => array(
140 * array(
141 * 'table' => $tableName,
142 * 'column' => $columnName,
143 * 'value' => $value,
144 * 'compOp' => $comparisonOperator,
145 * },
146 * ...
147 * )
148 * </pre>
149 *
150 * @access private
151 * @var array HAVING information
152 */
153 var $_having = array(
154 SQLBUILDER_LOGICAL_AND => array(),
155 SQLBUILDER_LOGICAL_OR => array()
156 );
157
158 /**
159 * Keeps the raw HAVING information.
160 *
161 * Structure:
162 * <pre>
163 * array(
164 * 'OR' => array(
165 * $statement1,
166 * $statement2,
167 * ...
168 * ),
169 * 'AND' => array(
170 * $statement1,
171 * $statement2,
172 * ...
173 * )
174 * </pre>
175 *
176 * @access private
177 * @var array HAVING information
178 */
179 var $_rawHaving = array(
180 SQLBUILDER_LOGICAL_AND => array(),
181 SQLBUILDER_LOGICAL_OR => array()
182 );
183
184 /**
185 * DISTINCT option
186 *
187 * @access private
188 * @var boolean DISTINCT or not
189 */
190 var $_distinct = false;
191
192 /**
193 * Keeps the normal SELECT information.
194 *
195 * Structure:
196 * <pre>
197 * array(
198 * array(
199 * 'table' => $tableName,
200 * 'column' => $column,
201 * 'alias' => $alias
202 * ),
203 * array( ... )
204 * )
205 * </pre>
206 *
207 * @access private
208 * @var array SELECT information
209 */
210 var $_select = array();
211
212
213 /**
214 * Keeps raw SELECT information. Good to use mysql-functions (CONCAT, MAX, ...).
215 *
216 * Structure:
217 * <pre>
218 * array(
219 * array
220 * (
221 * 'statement' => $statement,
222 * 'alias' => $alias
223 * ),
224 * array
225 * (
226 * 'statement' => ...,
227 * 'alias' => ...
228 * ),
229 * ...
230 * )
231 * </pre>
232 *
233 * @access private
234 * @var array raw SELECT information
235 */
236 var $_rawSelect = array();
237
238 /**
239 * Tablename on which a sql-statement concerns.
240 *
241 * It's a numeric array, that contains the tablenames, that shall be used in an sql-statement.
242 *
243 * @access private
244 * @var array tablename
245 */
246 var $_tables = array();
247
248 /**
249 * GROUP BY information.
250 *
251 * The array's structure:
252 * <pre>
253 * array(
254 * array(
255 * 'table' => $tableName,
256 * 'column' => $columnName,
257 * 'direction' => $direction,
258 * 'alias' => $alias,
259 * 'int' => $int
260 * ),
261 * array( ... ),
262 * ...
263 * )
264 * </pre>
265 *
266 * @access private
267 * @var array ORDER BY information
268 *
269 *
270 */
271 var $_groupBy = array();
272
273 /**
274 * LIMIT information
275 *
276 * @access private
277 * @var array LIMIT information
278 */
279 var $_limit = array (
280 'offset' => null,
281 'rows' => null
282 );
283
284
285
286 /**
287 * Constructor
288 *
289 * @access public
290 * @param object $dbc PEAR::DB connection object
291 */
292 function tgcSqlBuilder_Select(&$dbc)
293 {
294 parent::tgcSqlBuilder($dbc);
295 }
296
297 /**
298 * Generate the sql-statement.
299 *
300 * This method generates a query based on the object-information and returns it as a string.
301 *
302 * <code>
303 * $sql = new tgcSqlBuilder_Select($dbc);
304 * $query = $sql->generateQuery();
305 * </code>
306 *
307 * @access public
308 * @return string sql-statement
309 */
310 function generateQuery()
311 {
312 // check if at least one table has been specified
313 if (! count($this->_tables))
314 {
315 return PEAR::raiseError (
316 'You have to specifiy at least one tablename',
317 SQLBUILDER_ERROR_NO_TABLE_FOUND
318 );
319 }
320
321 $query = $this->_distinct ? 'SELECT DISTINCT' : 'SELECT';
322
323 if (count($this->_select) || count($this->_rawSelect)) {
324 $query .= ' ' . $this->_generateSelectInformation($this->_select, $this->_rawSelect);
325 } else {
326 $query .= ' *';
327 }
328
329 $query .= ' FROM ' . $this->_generateTableInformation($this->_tables);
330
331 if (count($this->_where[SQLBUILDER_LOGICAL_AND])
332 || count($this->_where[SQLBUILDER_LOGICAL_OR])
333 || count($this->_rawWhere[SQLBUILDER_LOGICAL_AND])
334 || count($this->_rawWhere[SQLBUILDER_LOGICAL_OR])) {
335 $query .= ' WHERE ' . $this->_generateWhereInformation($this->_where, $this->_rawWhere);
336 }
337
338 if (count($this->_groupBy)) {
339 $query .= ' GROUPY BY ' . $this->_generateGroupByInformation($this->_groupBy);
340 }
341
342 if (count($this->_having[SQLBUILDER_LOGICAL_AND])
343 || count($this->_having[SQLBUILDER_LOGICAL_OR])
344 || count($this->_rawHaving[SQLBUILDER_LOGICAL_AND])
345 || count($this->_rawHaving[SQLBUILDER_LOGICAL_OR])) {
346 $query .= ' HAVING ' . $this->_generateHavingInformation($this->_having, $this->_rawHaving);
347 }
348
349 if (count($this->_orderBy)) {
350 $query .= ' ORDER BY ' . $this->_generateOrderByInformation($this->_orderBy);
351 }
352
353 if (! (is_null($this->_limit['offset']) && is_null($this->_limit['rows']))) {
354 $query .= ' LIMIT ' . $this->_generateLimitInformation($this->_limit);
355 }
356
357 $this->reset();
358 return $query;
359 }
360
361 /**
362 * Reset the object's whole information.
363 *
364 * @access public
365 */
366 function reset()
367 {
368 $this->removeTable();
369 $this->removeSelect();
370 $this->removeRawSelect();
371 $this->removeTable();
372 $this->removeWhere();
373 $this->removeRawWhere();
374 $this->removeGroupBy();
375 $this->removeHaving();
376 $this->removeRawHaving();
377 $this->removeOrderBy();
378 $this->unsetLimit();
379 }
380
381 /**
382 * Enable the distinct setting.
383 *
384 * @access public
385 */
386 function enableDistinct()
387 {
388 $this->_distinct = true;
389 }
390
391 /**
392 * Enable the distinct setting.
393 *
394 * @access public
395 */
396 function disableDistinct()
397 {
398 $this->_distinct = false;
399 }
400
401 /**
402 * Add a SELECT statement. Optionally you can specify an alias for the column.
403 *
404 * <code>
405 * $sql = new tgcSqlBuilder_Select($dbc)
406 * // this will add the following statement: SELECT users.username AS name ...
407 * $sql->addSelect('users', 'username', 'name');
408 * </code>
409 *
410 * If you call $sql->generateQuery() before you add a select statement, a SELECT * FROM ... will be performed.
411 *
412 * @access public
413 * @param string $table tablename
414 * @param string $column columnname
415 * @param string $alias aliasname for the column
416 * @see addRawSelect(), removeSelect()
417 */
418 function addSelect($table, $column, $alias = null)
419 {
420 $statement = array
421 (
422 'table' => $table,
423 'column' => $column,
424 'alias' => $alias
425 );
426 array_push($this->_select, $statement);
427 }
428
429 /**
430 * Remove a SELECT statement.
431 *
432 * If call the method without parameters, all SELECT statements that have been stored so far will be removed.
433 * If you call the method with one or two parameters, then the specified SELECT statement will be removed.
434 *
435 * <code>
436 * $sql = new tgcSqlBuilder_Select($dbc);
437 * $sql->addSelect('users', 'userId');
438 * $sql->addSelect('users', 'username', 'name');
439 * $sql->addSelect('users', 'email', 'mail');
440 *
441 * // remove a specific SELECT statement by alias
442 * $sql->removeSelect('name');
443 *
444 * // remove a specific SELECT statement
445 * $sql->removeSelect('users', 'userId');
446 *
447 * // remove all SELECT statements
448 * $sql->removeSelect();
449 * </code>
450 *
451 * @access public
452 * @param string $table tablename
453 * @param string $column columnname
454 * @return mixed true on success, else PEAR_Error object
455 */
456 function removeSelect($table = null, $column = null)
457 {
458 // delete all selects
459 if (is_null($table) && is_null($column)) {
460 $this->_select = array();
461 return true;
462 }
463
464 // delete depending on alias
465 if (! is_null($table) && is_null($column)) {
466 $alias = $table;
467 $newSelect = array();
468 foreach ($this->_select as $selectData) {
469 if ($selectData['alias'] != $alias) {
470 array_push($newSelect, $selectData);
471 }
472 }
473 $this->_select = $newSelect;
474 return true;
475 }
476
477 // delete depending on $table and $column
478 if (! is_null($table) && ! is_null($column)) {
479 $newSelect = array();
480 foreach ($this->_select as $selectData) {
481 if (! ($selectData['table'] == $table && $selectData['column'] == $column)) {
482 array_push($newSelect, $selectData);
483 }
484 }
485 $this->_select = $newSelect;
486 return true;
487 }
488
489 return PEAR::raiseError(
490 'Removing SELECT statement failed',
491 SQLBUILDER_ERROR_SELECT_REMOVE
492 );
493 }
494
495 /**
496 * Add a SELECT statement. Optionally you can specify an alias for the column.
497 *
498 * <code>
499 * $sql = new tgcSqlBuilder_Select($dbc)
500 * // this will add the following statement:
501 * // SELECT MAX(users.userId) AS maxId, AVG(users.money) FROM ...
502 * $sql->addRawSelect('MAX(users.userId)', 'maxId');
503 * $sql->addRawSelect('AVG(users.money)');
504 * </code>
505 *
506 * If you call $sql->generateQuery() before you add a (raw) SELECT statement, a SELECT * FROM ... will be performed.
507 *
508 * @access public
509 * @param string $statement raw SELECT statement
510 * @param string $alias alias
511 * @see addSelect(), removeRawSelect()
512 */
513 function addRawSelect($statement, $alias = null)
514 {
515 $rawSelect = array();
516 $rawSelect['statement'] = $statement;
517 if (! is_null($alias)) {
518 $rawSelect['alias'] = $alias;
519 }
520
521 array_push($this->_rawSelect, $rawSelect);
522 }
523
524 /**
525 * Remove a raw SELECT statement.
526 *
527 * If call the method without parameters, all raw SELECT statements that have been stored so far will be removed.
528 * If you call the method with parameter, then the specified SELECT statement will be removed.
529 *
530 * <code>
531 * $sql = new tgcSqlBuilder_Select($dbc);
532 * $sql->addRawSelect('MAX(users.userId)', 'maxId');
533 * $sql->addRawSelect('AVG(users.money)');
534 *
535 * // remove a specific raw SELECT statement by alias
536 * $sql->removeRawSelect('maxId');
537 *
538 * // remove all raw SELECT statements
539 * $sql->removeRawSelect();
540 * </code>
541 *
542 * @access public
543 * @param string $alias alias
544 */
545 function removeRawSelect($alias = null)
546 {
547 // delete specific raw SELECT
548 if (! is_null($alias)) {
549 $newRawSelect = array();
550 foreach ($this->_rawSelect as $rawSelectData) {
551 if (isset($rawSelectData['alias']) && $rawSelectData['alias'] != $alias) {
552 array_push($newRawSelect, $rawSelectData);
553 } elseif (! isset($rawSelectData['alias'])) {
554 array_push($newRawSelect, $rawSelectData);
555 }
556 }
557 $this->_rawSelect = $newRawSelect;
558 return;
559 }
560
561 // delete all raw SELECT statements
562 $this->_rawSelect = array();
563 }
564
565 /**
566 * Add a WHERE statement.
567 *
568 * Possible comparison operators are:
569 * SQLBUILDER_COMP_EQUAL, SQLBUILDER_COMP_NOT_EQUAL, SQLBUILDER_COMP_LESSER_THAN, SQLBUILDER_COMP_LESSER_EQUAL,
570 * SQLBUILDER_COMP_GREATER_EQUAL, SQLBUILDER_COMP_GREATER_THAN, SQLBUILDER_COMP_STARTSWITH, SQLBUILDER_COMP_CONTAINS,
571 * SQLBUILDER_COMP_ENDSWITH, SQLBUILDER_COMP_BETWEEN
572 *
573 * If none is specified then SQLBUILDER_COMP_EQUAL will be used.
574 *
575 * Possible logical expressions are:
576 * SQLBUILDER_LOGICAL_AND, SQLBUILDER_LOGICAL_OR
577 *
578 * If none is specified, then SQLBUILDER_LOGICAL_AND will be used.
579 *
580 * When you are using SQLBUILDER_COMP_BETWEEN, then specify $values as a numerical array with two values
581 * in correct order.
582 *
583 * @access public
584 * @param string $table tablename
585 * @param string $column columnname
586 * @param mixed $value value(s)
587 * @param string $compOp comparison operator
588 * @param string $logic logical linkup
589 */
590 function addWhere($table, $column, $value, $compOp = null, $logic = null)
591 {
592 $this->_addWhereHaving($this->_where, $table, $column, $value, $compOp, $logic);
593 }
594
595 /**
596 * Remove a WHERE statement.
597 *
598 * If you don't specify any parameter, then all WHERE information will be removed.
599 * If you specify a tablename and a columnname, then this specific ORDER BY setting will be removed.
600 *
601 * @access public
602 * @param string $table tablename
603 * @param string $column columnname
604 * @param string $logic logical operation (possible values: SQLBUILDER_LOGICAL_AND, SQLBUILDER_LOGICAL_OR)
605 * @return mixed true on success or PEAR_Error (possible error(s): SQLBUILDER_ERROR_INVALID_PARAM_COMBO)
606 */
607 function removeWhere($table = null, $column = null, $logic = null)
608 {
609 return $this->_removeWhereHaving($this->_where, $table, $column, $logic);
610 }
611
612 /**
613 * Add a raw WHERE statement.
614 *
615 * You can add a raw WHERE statement and define a logical operator. As default this is the logical AND.
616 *
617 * @access public
618 * @param string $statement raw WHERE statement
619 * @param string $logic SQLBUILDER_LOGICAL_AND or SQLBUILDER_LOGICAL_OR
620 */
621 function addRawWhere($statement, $logic = SQLBUILDER_LOGICAL_AND)
622 {
623 $this->_addRawWhereHaving($this->_rawWhere, $statement, $logic);
624 }
625
626 /**
627 * Remove the raw WHERE statements, that have been stored so far.
628 *
629 * @access public
630 * @param string $logic SQLBUILDER_LOGICAL_AND or SQLBUILDER_LOGICAL_OR
631 * @return mixed true on success, else PEAR_Error
632 */
633 function removeRawWhere($logic = null)
634 {
635 return $this->_removeRawWhereHaving($this->_rawWhere, $logic);
636 }
637
638 /**
639 * Add a GROUP BY statement.
640 *
641 * How to call the method:
642 * <code>
643 * $sql = new tgcSqlBuilder_Select($dbc);
644 *
645 * // add a GROUP BY for a tablename and a column, ASC
646 * // as ASC is the default direction it doesn't have to be specified
647 * $sql->addGroupBy('users', 'groupName');
648 *
649 * // group by alias 'grpName', direction DESC
650 * $sql->addGroupBy('grpName', null, SQLBUILDER_ORDER_DESC);
651 *
652 * // group by column no. 2, direction ASC
653 * $sql->addGroupBy(2);
654 * </code>
655 *
656 * The statements will be found in that order in the query, in which they have been added.
657 *
658 * @access public
659 * @param string $table tablename
660 * @param string $column columnname
661 * @param string $direction SQLBUILDER_ORDER_ASC or SQLBUILDER_ORDER_DESC
662 * @return mixed true on success, else PEAR_Error
663 */
664 function addGroupBy($table, $column = null, $direction = SQLBUILDER_ORDER_ASC)
665 {
666 // check $direction
667 if (! ($direction == SQLBUILDER_ORDER_ASC || $direction == SQLBUILDER_ORDER_DESC)) {
668 return PEAR::raiseError (
669 'Invalid ORDER BY direction',
670 SQLBUILDER_ERROR_INVALID_ORDER_BY_DIRECTION
671 );
672 }
673
674 // normal method-call
675 if (! is_null($column)) {
676 $groupBy = array
677 (
678 'table' => $table,
679 'column' => $column,
680 'direction' => $direction
681 );
682 array_push($this->_groupBy, $groupBy);
683 return true;
684 }
685
686 // alias or col-number
687 if (is_int($table)) {
688 $groupBy = array
689 (
690 'int' => $table,
691 'direction' => $direction
692 );
693 array_push($this->_groupBy, $groupBy);
694 return true;
695 } elseif (is_string($table)) {
696 $groupBy = array
697 (
698 'alias' => $table,
699 'direction' => $direction
700 );
701 array_push($this->_groupBy, $groupBy);
702 return true;
703 }
704 }
705
706 /**
707 * Remove a GROUP BY statement.
708 *
709 * @access public
710 * @param string $table tablename
711 * @param string $column columnname
712 * @return mixed true on success, else PEAR_Error
713 */
714 function removeGroupBy($table = null, $column = null)
715 {
716 // remove all
717 if (is_null($table) && is_null($column)) {
718 $this->_groupBy = array();
719 return true;
720 }
721
722 // remove depending on table- and columnname
723 if (! is_null($table) && ! is_null($column)) {
724 $newGroupBy = array();
725 foreach ($this->_groupBy as $groupBy) {
726 if (isset($groupBy['table']) && isset($groupBy['column'])) {
727 if (! ($groupBy['table'] == $table && $groupBy['column'] == $column)) {
728 array_push($newGroupBy, $groupBy);
729 }
730 } else {
731 array_push($newGroupBy, $groupBy);
732 }
733 }
734 return true;
735 }
736
737 // delete depending on alias or col-number
738 if (! is_null($table) && is_null($column)) {
739 $newGroupBy = array();
740
741 // col-number
742 if (is_int($table)) {
743 foreach ($this->_groupBy as $groupBy) {
744 if (isset($groupBy['int'])) {
745 if ($groupBy['int'] != $table) {
746 array_push($newGroupBy, $groupBy);
747 }
748 } else {
749 array_push($newGroupBy, $groupBy);
750 }
751 }
752 return true;
753 }
754
755 // alias
756 if (is_string($table)) {
757 foreach ($this->_groupBy as $groupBy) {
758 if (isset($groupBy['alias'])) {
759 if ($groupBy['alias'] != $table) {
760 array_push($newGroupBy, $groupBy);
761 }
762 } else {
763 array_push($newGroupBy, $groupBy);
764 }
765 }
766 return true;
767 }
768
769 return PEAR::raiseError (
770 'Invalid parameter-datatype',
771 SQLBUILDER_ERROR_INVALID_PARAMETER
772 );
773 }
774
775 return PEAR::raiseError (
776 'The combination of parameters is invalid',
777 SQLBUILDER_ERROR_INVALID_PARAM_COMBO
778 );
779 }
780
781 /**
782 * Add an ORDER BY setting.
783 *
784 * The parameter $direction can be either SQLBUILDER_ORDER_ASC or SQLBUILDER_ORDER_DESC.
785 * If none is specified, then SQLBUILDER_ORDER_ASC will be used.
786 *
787 * You can also leave $column null, if you want to order by an alias.
788 * <code>
789 * $sql = new tgcSqlBuilder_Delete($dbc);
790 *
791 * // ... ORDER BY alias1 ASC ...
792 * $sql->addOrderBy('alias1');
793 *
794 * // ... ORDER BY alias2 DESC ...
795 * $sql->addOrderBy('alias2', null, SQLBUILDER_ORDER_DESC);
796 * </code>
797 *
798 * If a setting for this table/column exists, it will be overwritten.
799 *
800 * @access public
801 * @param string $table tablename
802 * @param string $column columnname
803 * @param string $direction oder direction
804 */
805 function addOrderBy($table, $column = null, $direction = null)
806 {
807 $direction = is_null($direction) ? SQLBUILDER_ORDER_ASC : $direction;
808
809 if (! is_null($column)) {
810 $orderBy = array(
811 'table' => $table,
812 'column' => $column,
813 'direction' => $direction
814 );
815 } else {
816 $orderBy = array(
817 'table' => $table,
818 'column' => null,
819 'direction' => $direction
820 );
821 }
822
823 $exists = false;
824 foreach ($this->_orderBy as $index => $orderByData) {
825 if ($orderByData['table'] == $table && $orderByData['column'] == $column) {
826 $exists = true;
827 break;
828 }
829 }
830 if ($exists) {
831 $this->_orderBy[$index] = $orderBy;
832 return;
833 }
834
835 array_push($this->_orderBy, $orderBy);
836 }
837
838 /**
839 * Remove an ORDER BY setting.
840 *
841 * If you don't specify any parameter, then all ORDER BY information will be removed.
842 * If you specify a tablename and a columnname, then this specific ORDER BY setting will be removed.
843 *
844 * @access public
845 * @param string $table tablename
846 * @param string $column columnname
847 * @return mixed true on success or PEAR_Error (possible error(s): SQLBUILDER_ERROR_INVALID_PARAM_COMBO)
848 */
849 function removeOrderBy($table = null, $column = null)
850 {
851 // delete all
852 if (is_null($table) && is_null($column)) {
853 $this->_orderBy = array();
854 return true;
855 }
856
857 // delete table.column
858 if (! is_null($table) && ! is_null($column)) {
859 $newOrderBy = array();
860 foreach ($this->_orderBy as $orderByData) {
861 if (! ($orderByData['table'] == $table && $orderByData['column'] == $column)) {
862 array_push($newOrderBy, $orderByData);
863 }
864 }
865 $this->_orderBy = $newOrderBy;
866 return true;
867 }
868
869 // delete alias
870 if (! is_null($table) && is_null($column)) {
871 $newOrderBy = array();
872 foreach ($this->_orderBy as $orderByData) {
873 if (! ($orderByData['table'] == $table && $orderByData['column'] == null)) {
874 array_push($newOrderBy, $orderByData);
875 }
876 }
877 $this->_orderBy = $newOrderBy;
878 return true;
879 }
880
881 return PEAR::raiseError (
882 'The combination of parameters is invalid',
883 SQLBUILDER_ERROR_INVALID_PARAM_COMBO,
884 null,
885 null,
886 'You have to call the method with none or two parameters'
887 );
888 }
889
890 /**
891 * Set a LIMIT for the query.
892 *
893 * Example:
894 * <code>
895 * $sql = new tgcSqlBuilder_Select($dbc);
896 *
897 * // set a limit of 15 rows starting from offset 30
898 * $sql->setLimit(30, 15);
899 *
900 * // set a limit of 20 rows (starting from offset 0)
901 * $sql->setLimit(20);
902 * </code>
903 *
904 * @access public
905 * @param int $offset offset
906 * @param int $rows number of rows
907 */
908 function setLimit($offset, $rows = null)
909 {
910 if (is_null($rows)) {
911 $this->_limit['offset'] = null;
912 $this->_limit['rows'] = $offset;
913 return;
914 }
915
916 $this->_limit['offset'] = $offset;
917 $this->_limit['rows'] = $rows;
918 }
919
920 /**
921 * Unset the current LIMIT information.
922 *
923 * @access public
924 */
925 function unsetLimit()
926 {
927 $this->_limit['offset'] = null;
928 $this->_limit['rows'] = null;
929 }
930
931 /**
932 * Add a WHERE statement.
933 *
934 * Possible comparison operators are:
935 * SQLBUILDER_COMP_EQUAL, SQLBUILDER_COMP_NOT_EQUAL, SQLBUILDER_COMP_LESSER_THAN, SQLBUILDER_COMP_LESSER_EQUAL,
936 * SQLBUILDER_COMP_GREATER_EQUAL, SQLBUILDER_COMP_GREATER_THAN, SQLBUILDER_COMP_STARTSWITH, SQLBUILDER_COMP_CONTAINS,
937 * SQLBUILDER_COMP_ENDSWITH, SQLBUILDER_COMP_BETWEEN
938 *
939 * If none is specified then SQLBUILDER_COMP_EQUAL will be used.
940 *
941 * Possible logical expressions are:
942 * SQLBUILDER_LOGICAL_AND, SQLBUILDER_LOGICAL_OR
943 *
944 * If none is specified, then SQLBUILDER_LOGICAL_AND will be used.
945 *
946 * When you are using SQLBUILDER_COMP_BETWEEN, then specify $values as a numerical array with two values
947 * in correct order.
948 *
949 * @access public
950 * @param string $table tablename
951 * @param string $column columnname
952 * @param mixed $value value(s)
953 * @param string $compOp comparison operator
954 * @param string $logic logical linkup
955 */
956 function addHaving($table, $column, $value, $compOp = null, $logic = null)
957 {
958 $this->_addWhereHaving($this->_having, $table, $column, $value, $compOp, $logic);
959 }
960
961 /**
962 * Remove a WHERE statement.
963 *
964 * If you don't specify any parameter, then all WHERE information will be removed.
965 * If you specify a tablename and a columnname, then this specific ORDER BY setting will be removed.
966 *
967 * @access public
968 * @param string $table tablename
969 * @param string $column columnname
970 * @param string $logic logical operation (possible values: SQLBUILDER_LOGICAL_AND, SQLBUILDER_LOGICAL_OR)
971 * @return mixed true on success or PEAR_Error (possible error(s): SQLBUILDER_ERROR_INVALID_PARAM_COMBO)
972 */
973 function removeHaving($table = null, $column = null, $logic = null)
974 {
975 return $this->_removeWhereHaving($this->_having, $table, $column, $logic);
976 }
977
978 /**
979 * Add a raw HAVING statement.
980 *
981 * You can add a raw HAVING statement and define a logical operator. As default this is the logical AND.
982 *
983 * @access public
984 * @param string $statement raw HAVING statement
985 * @param string $logic SQLBUILDER_LOGICAL_AND or SQLBUILDER_LOGICAL_OR
986 */
987 function addRawHaving($statement, $logic = SQLBUILDER_LOGICAL_AND)
988 {
989 $this->_addRawWhereHaving($this->_rawHaving, $statement, $logic);
990 }
991
992 /**
993 * Remove the raw WHERE statements, that have been stored so far.
994 *
995 * @access public
996 * @param string $logic SQLBUILDER_LOGICAL_AND or SQLBUILDER_LOGICAL_OR
997 * @return mixed true on success, else PEAR_Error
998 */
999 function removeRawHaving($logic = null)
1000 {
1001 return $this->_removeRawWhereHaving($this->_rawHaving, $logic);
1002 }
1003
1004
1005
1006 /**
1007 * Generates a string based on the objects tables.
1008 *
1009 * @access private
1010 * @param mixed $att TABLE/FROM attribute
1011 */
1012 function _generateTableInformation(&$att)
1013 {
1014 $statement = array();
1015
1016 foreach ($att as $tableName => $alias) {
1017 if (! is_null($alias)) {
1018 array_push($statement, sprintf("%s as %s", $tableName, $alias));
1019 } else {
1020 array_push($statement, $tableName);
1021 }
1022 }
1023
1024 return implode(', ', $statement);
1025 }
1026
1027 /**
1028 * Generates a string based on the objects LIMIT information.
1029 *
1030 * @access private
1031 * @param mixed $att LIMIT attribute
1032 */
1033 function _generateLimitInformation(&$att)
1034 {
1035 if (! is_null($att['offset'])) {
1036 return sprintf("%d, %d", $att['offset'], $att['rows']);
1037 }
1038
1039 return sprintf("%d", $att['rows']);
1040 }
1041
1042 /**
1043 * Generates a string based on the object's SELECT information.
1044 *
1045 * @access private
1046 * @param mixed $select SELECT attribute
1047 * @param mixed $rawSelect raw SELECT attribute
1048 */
1049 function _generateSelectInformation(&$select, &$rawSelect)
1050 {
1051 $statement = array();
1052
1053 foreach ($select as $selectData) {
1054 if (! is_null($selectData['alias'])) {
1055 array_push($statement, sprintf("%s.%s as %s", $selectData['table'],
1056 $selectData['column'],
1057 $selectData['alias']) );
1058 } else {
1059 array_push($statement, sprintf("%s.%s", $selectData['table'], $selectData['column']) );
1060 }
1061 }
1062
1063 foreach ($rawSelect as $selectData) {
1064 if (isset($selectData['alias']) && ! is_null($selectData['alias'])) {
1065 array_push($statement, sprintf("%s as %s", $selectData['statement'],
1066 $selectData['alias']) );
1067 } else {
1068 array_push($statement, $selectData['statement']);
1069 }
1070 }
1071
1072
1073
1074 return implode(', ', $statement);
1075 }
1076
1077 /**
1078 * Generate a string for the final query based on the GROUP BY information.
1079 *
1080 * @access private
1081 * @param mixed $att GROUP BY attribute
1082 *
1083 *
1084 *
1085 *
1086 * <pre>
1087 * array(
1088 * array(
1089 * 'table' => $tableName,
1090 * 'column' => $columnName,
1091 * 'direction' => $direction,
1092 * 'alias' => $alias,
1093 * 'int' => $int
1094 * ),
1095 * array( ... ),
1096 * ...
1097 * )
1098 * </pre>
1099 */
1100 function _generateGroupByInformation(&$att)
1101 {
1102 $statement = array();
1103
1104 foreach ($att as $groupBy) {
1105 // by table and column
1106 if (isset($groupBy['table']) && isset($groupBy['column'])) {
1107 array_push($statement, sprintf("%s.%s %s", $groupBy['table'], $groupBy['column'], $groupBy['direction']) );
1108 }
1109 // by alias
1110 elseif (isset($groupBy['alias'])) {
1111 array_push($statement, sprintf("%s %s", $groupBy['alias'], $groupBy['direction']));
1112 }
1113 // by col-number
1114 elseif (isset($groupBy['int'])) {
1115 array_push($statement, sprintf("%s %s", $groupBy['int'], $groupBy['direction']));
1116 }
1117 }
1118
1119 return implode(', ', $statement);
1120 }
1121
1122 /**
1123 * Generates a string based on the object's HAVING information.
1124 *
1125 * Must only be called from objects that contain a HAVING attribute.
1126 *
1127 * @access private
1128 * @param array $having HAVING attribute
1129 * @param array $rawHaving raw HAVING attribute
1130 * @uses _generateWhereInformation()
1131 */
1132 function _generateHavingInformation(&$having, &$rawHaving)
1133 {
1134 return $this->_generateWhereInformation($having, $rawHaving);
1135 }
1136
1137 }
1138 ?>

Documentation generated on Fri, 19 Nov 2004 23:54:05 +0100 by phpDocumentor 1.2.3