# Coverage for Doctrine_Expression_Driver

Back to coverage report

1 | <?php
2 | /*
3 | * $Id$
4 | *
5 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
6 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
7 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
8 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
9 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
10 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
11 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
12 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
13 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
14 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
15 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16 | *
17 | * This software consists of voluntary contributions made by many individuals
18 | * and is licensed under the LGPL. For more information, see
19 | * <http://www.phpdoctrine.org>.
20 | */
21 | Doctrine::autoload('Doctrine_Connection_Module');
22 | /**
23 | * Doctrine_Expression_Driver
24 | *
25 | * @package Doctrine
26 | * @subpackage Expression
27 | * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
28 | * @link www.phpdoctrine.org
29 | * @since 1.0
30 | * @version $Revision$
31 | * @author Konsta Vesterinen <kvesteri@cc.hut.fi>
32 | */
33 | class Doctrine_Expression_Driver extends Doctrine_Connection_Module
34 | {
35 | public function getIdentifier($column)
36 | {
37 | return $column;
38 | }
39 | public function getIdentifiers($columns)
40 | {
41 | return $columns;
42 | }
43 |
44 | /**
45 | * regexp
46 | * returns the regular expression operator
47 | *
48 | * @return string
49 | */
50 | public function regexp()
51 | {
52 | throw new Doctrine_Expression_Exception('Regular expression operator is not supported by this database driver.');
53 | }
54 |
55 | /**
56 | * Returns the average value of a column
57 | *
58 | * @param string $column the column to use
59 | * @return string generated sql including an AVG aggregate function
60 | */
61 | public function avg($column)
62 | {
63 | $column = $this->getIdentifier($column);
64 | return 'AVG(' . $column . ')';
65 | }
66 |
67 | /**
68 | * Returns the number of rows (without a NULL value) of a column
69 | *
70 | * If a '*' is used instead of a column the number of selected rows
71 | * is returned.
72 | *
73 | * @param string|integer $column the column to use
74 | * @return string generated sql including a COUNT aggregate function
75 | */
76 | public function count($column)
77 | {
78 | $column = $this->getIdentifier($column);
79 | return 'COUNT(' . $column . ')';
80 | }
81 |
82 | /**
83 | * Returns the highest value of a column
84 | *
85 | * @param string $column the column to use
86 | * @return string generated sql including a MAX aggregate function
87 | */
88 | public function max($column)
89 | {
90 | $column = $this->getIdentifier($column);
91 | return 'MAX(' . $column . ')';
92 | }
93 |
94 | /**
95 | * Returns the lowest value of a column
96 | *
97 | * @param string $column the column to use
98 | * @return string
99 | */
100 | public function min($column)
101 | {
102 | $column = $this->getIdentifier($column);
103 | return 'MIN(' . $column . ')';
104 | }
105 |
106 | /**
107 | * Returns the total sum of a column
108 | *
109 | * @param string $column the column to use
110 | * @return string
111 | */
112 | public function sum($column)
113 | {
114 | $column = $this->getIdentifier($column);
115 | return 'SUM(' . $column . ')';
116 | }
117 |
118 | // scalar functions
119 |
120 | /**
121 | * Returns the md5 sum of a field.
122 | *
123 | * Note: Not SQL92, but common functionality
124 | *
125 | * @return string
126 | */
127 | public function md5($column)
128 | {
129 | $column = $this->getIdentifier($column);
130 | return 'MD5(' . $column . ')';
131 | }
132 |
133 | /**
134 | * Returns the length of a text field.
135 | *
136 | * @param string $expression1
137 | * @param string $expression2
138 | * @return string
139 | */
140 | public function length($column)
141 | {
142 | $column = $this->getIdentifier($column);
143 | return 'LENGTH(' . $column . ')';
144 | }
145 |
146 | /**
147 | * Rounds a numeric field to the number of decimals specified.
148 | *
149 | * @param string $expression1
150 | * @param string $expression2
151 | * @return string
152 | */
153 | public function round($column, $decimals = 0)
154 | {
155 | $column = $this->getIdentifier($column);
156 |
157 | return 'ROUND(' . $column . ', ' . $decimals . ')';
158 | }
159 |
160 | /**
161 | * Returns the remainder of the division operation
162 | * $expression1 / $expression2.
163 | *
164 | * @param string $expression1
165 | * @param string $expression2
166 | * @return string
167 | */
168 | public function mod($expression1, $expression2)
169 | {
170 | $expression1 = $this->getIdentifier($expression1);
171 | $expression2 = $this->getIdentifier($expression2);
172 | return 'MOD(' . $expression1 . ', ' . $expression2 . ')';
173 | }
174 |
175 | /**
176 | * trim
177 | * returns the string $str with leading and proceeding space characters removed
178 | *
179 | * @param string $str literal string or column name
180 | * @return string
181 | */
182 | public function trim($str)
183 | {
184 | return 'TRIM(' . $str . ')';
185 | }
186 |
187 | /**
188 | * rtrim
189 | * returns the string $str with proceeding space characters removed
190 | *
191 | * @param string $str literal string or column name
192 | * @return string
193 | */
194 | public function rtrim($str)
195 | {
196 | return 'RTRIM(' . $str . ')';
197 | }
198 |
199 | /**
200 | * ltrim
201 | * returns the string $str with leading space characters removed
202 | *
203 | * @param string $str literal string or column name
204 | * @return string
205 | */
206 | public function ltrim($str)
207 | {
208 | return 'LTRIM(' . $str . ')';
209 | }
210 |
211 | /**
212 | * upper
213 | * Returns the string $str with all characters changed to
214 | * uppercase according to the current character set mapping.
215 | *
216 | * @param string $str literal string or column name
217 | * @return string
218 | */
219 | public function upper($str)
220 | {
221 | return 'UPPER(' . $str . ')';
222 | }
223 |
224 | /**
225 | * lower
226 | * Returns the string $str with all characters changed to
227 | * lowercase according to the current character set mapping.
228 | *
229 | * @param string $str literal string or column name
230 | * @return string
231 | */
232 | public function lower($str)
233 | {
234 | return 'LOWER(' . $str . ')';
235 | }
236 |
237 | /**
238 | * locate
239 | * returns the position of the first occurrence of substring $substr in string $str
240 | *
241 | * @param string $substr literal string to find
242 | * @param string $str literal string
243 | * @return integer
244 | */
245 | public function locate($str, $substr)
246 | {
247 | return 'LOCATE(' . $str . ', ' . $substr . ')';
248 | }
249 |
250 | /**
251 | * Returns the current system date.
252 | *
253 | * @return string
254 | */
255 | public function now()
256 | {
257 | return 'NOW()';
258 | }
259 |
260 | /**
261 | * soundex
262 | * Returns a string to call a function to compute the
263 | * soundex encoding of a string
264 | *
265 | * The string "?000" is returned if the argument is NULL.
266 | *
267 | * @param string $value
268 | * @return string SQL soundex function with given parameter
269 | */
270 | public function soundex($value)
271 | {
272 | throw new Doctrine_Expression_Exception('SQL soundex function not supported by this driver.');
273 | }
274 |
275 | /**
276 | * return string to call a function to get a substring inside an SQL statement
277 | *
278 | * Note: Not SQL92, but common functionality.
279 | *
280 | * SQLite only supports the 2 parameter variant of this function
281 | *
282 | * @param string $value an sql string literal or column name/alias
283 | * @param integer $position where to start the substring portion
284 | * @param integer $length the substring portion length
285 | * @return string SQL substring function with given parameters
286 | */
287 | public function substring($value, $from, $len = null)
288 | {
289 | $value = $this->getIdentifier($value);
290 | if ($len === null)
291 | return 'SUBSTRING(' . $value . ' FROM ' . $from . ')';
292 | else {
293 | $len = $this->getIdentifier($len);
294 | return 'SUBSTRING(' . $value . ' FROM ' . $from . ' FOR ' . $len . ')';
295 | }
296 | }
297 |
298 | /**
299 | * Returns a series of strings concatinated
300 | *
301 | * concat() accepts an arbitrary number of parameters. Each parameter
302 | * must contain an expression or an array with expressions.
303 | *
304 | * @param string|array(string) strings that will be concatinated.
305 | */
306 | public function concat()
307 | {
308 | $args = func_get_args();
309 |
310 | return 'CONCAT(' . join(', ', (array) $args) . ')';
311 | }
312 |
313 | /**
314 | * Returns the SQL for a logical not.
315 | *
316 | * Example:
317 | * <code>
318 | * $q = new Doctrine_Query();
319 | * $e = $q->expr;
320 | * $q->select('*')->from('table')
321 | * ->where($e->eq('id', $e->not('null'));
322 | * </code>
323 | *
324 | * @return string a logical expression
325 | */
326 | public function not($expression)
327 | {
328 | $expression = $this->getIdentifier($expression);
329 | return 'NOT(' . $expression . ')';
330 | }
331 |
332 | /**
333 | * Returns the SQL to perform the same mathematical operation over an array
334 | * of values or expressions.
335 | *
336 | * basicMath() accepts an arbitrary number of parameters. Each parameter
337 | * must contain a value or an expression or an array with values or
338 | * expressions.
339 | *
340 | * @param string $type the type of operation, can be '+', '-', '*' or '/'.
341 | * @param string|array(string)
342 | * @return string an expression
343 | */
344 | private function basicMath($type, array $args)
345 | {
346 | $elements = $this->getIdentifiers($args);
347 | if (count($elements) < 1) {
348 | return '';
349 | }
350 | if (count($elements) == 1) {
351 | return $elements[0];
352 | } else {
353 | return '(' . implode(' ' . $type . ' ', $elements) . ')';
354 | }
355 | }
356 |
357 | /**
358 | * Returns the SQL to add values or expressions together.
359 | *
360 | * add() accepts an arbitrary number of parameters. Each parameter
361 | * must contain a value or an expression or an array with values or
362 | * expressions.
363 | *
364 | * Example:
365 | * <code>
366 | * $q = new Doctrine_Query();
367 | * $e = $q->expr;
368 | *
369 | * $q->select('u.*')
370 | * ->from('User u')
371 | * ->where($e->eq($e->add('id', 2), 12));
372 | * </code>
373 | *
374 | * @param string|array(string)
375 | * @return string an expression
376 | */
377 | public function add(array $args)
378 | {
379 | return $this->basicMath('+', $args);
380 | }
381 |
382 | /**
383 | * Returns the SQL to subtract values or expressions from eachother.
384 | *
385 | * subtract() accepts an arbitrary number of parameters. Each parameter
386 | * must contain a value or an expression or an array with values or
387 | * expressions.
388 | *
389 | * Example:
390 | * <code>
391 | * $q = new Doctrine_Query();
392 | * $e = $q->expr;
393 | *
394 | * $q->select('u.*')
395 | * ->from('User u')
396 | * ->where($e->eq($e->sub('id', 2), 12));
397 | * </code>
398 | *
399 | * @param string|array(string)
400 | * @return string an expression
401 | */
402 | public function sub(array $args)
403 | {
404 | return $this->basicMath('-', $args );
405 | }
406 |
407 | /**
408 | * Returns the SQL to multiply values or expressions by eachother.
409 | *
410 | * multiply() accepts an arbitrary number of parameters. Each parameter
411 | * must contain a value or an expression or an array with values or
412 | * expressions.
413 | *
414 | * Example:
415 | * <code>
416 | * $q = new Doctrine_Query();
417 | * $e = $q->expr;
418 | *
419 | * $q->select('u.*')
420 | * ->from('User u')
421 | * ->where($e->eq($e->mul('id', 2), 12));
422 | * </code>
423 | *
424 | * @param string|array(string)
425 | * @return string an expression
426 | */
427 | public function mul(array $args)
428 | {
429 | return $this->basicMath('*', $args);
430 | }
431 |
432 | /**
433 | * Returns the SQL to divide values or expressions by eachother.
434 | *
435 | * divide() accepts an arbitrary number of parameters. Each parameter
436 | * must contain a value or an expression or an array with values or
437 | * expressions.
438 | *
439 | * Example:
440 | * <code>
441 | * $q = new Doctrine_Query();
442 | * $e = $q->expr;
443 | *
444 | * $q->select('u.*')
445 | * ->from('User u')
446 | * ->where($e->eq($e->div('id', 2), 12));
447 | * </code>
448 | *
449 | * @param string|array(string)
450 | * @return string an expression
451 | */
452 | public function div(array $args)
453 | {
454 | return $this->basicMath('/', $args);
455 | }
456 |
457 | /**
458 | * Returns the SQL to check if two values are equal.
459 | *
460 | * Example:
461 | * <code>
462 | * $q = new Doctrine_Query();
463 | * $q->select('u.*')
464 | * ->from('User u')
465 | * ->where($q->expr->eq('id', 1));
466 | * </code>
467 | *
468 | * @param string $value1 logical expression to compare
469 | * @param string $value2 logical expression to compare with
470 | * @return string logical expression
471 | */
472 | public function eq($value1, $value2)
473 | {
474 | $value1 = $this->getIdentifier($value1);
475 | $value2 = $this->getIdentifier($value2);
476 | return $value1 . ' = ' . $value2;
477 | }
478 |
479 | /**
480 | * Returns the SQL to check if two values are unequal.
481 | *
482 | * Example:
483 | * <code>
484 | * $q = new Doctrine_Query();
485 | * $q->select('u.*')
486 | * ->from('User u')
487 | * ->where($q->expr->neq('id', 1));
488 | * </code>
489 | *
490 | * @param string $value1 logical expression to compare
491 | * @param string $value2 logical expression to compare with
492 | * @return string logical expression
493 | */
494 | public function neq($value1, $value2)
495 | {
496 | $value1 = $this->getIdentifier($value1);
497 | $value2 = $this->getIdentifier($value2);
498 | return $value1 . ' <> ' . $value2;
499 | }
500 |
501 | /**
502 | * Returns the SQL to check if one value is greater than another value.
503 | *
504 | * Example:
505 | * <code>
506 | * $q = new Doctrine_Query();
507 | * $q->select('u.*')
508 | * ->from('User u')
509 | * ->where($q->expr->gt('id', 1));
510 | * </code>
511 | *
512 | * @param string $value1 logical expression to compare
513 | * @param string $value2 logical expression to compare with
514 | * @return string logical expression
515 | */
516 | public function gt($value1, $value2)
517 | {
518 | $value1 = $this->getIdentifier($value1);
519 | $value2 = $this->getIdentifier($value2);
520 | return $value1 . ' > ' . $value2;
521 | }
522 |
523 | /**
524 | * Returns the SQL to check if one value is greater than or equal to
525 | * another value.
526 | *
527 | * Example:
528 | * <code>
529 | * $q = new Doctrine_Query();
530 | * $q->select('u.*')
531 | * ->from('User u')
532 | * ->where($q->expr->gte('id', 1));
533 | * </code>
534 | *
535 | * @param string $value1 logical expression to compare
536 | * @param string $value2 logical expression to compare with
537 | * @return string logical expression
538 | */
539 | public function gte($value1, $value2)
540 | {
541 | $value1 = $this->getIdentifier($value1);
542 | $value2 = $this->getIdentifier($value2);
543 | return $value1 . ' >= ' . $value2;
544 | }
545 |
546 | /**
547 | * Returns the SQL to check if one value is less than another value.
548 | *
549 | * Example:
550 | * <code>
551 | * $q = new Doctrine_Query();
552 | * $q->select('u.*')
553 | * ->from('User u')
554 | * ->where($q->expr->lt('id', 1));
555 | * </code>
556 | *
557 | * @param string $value1 logical expression to compare
558 | * @param string $value2 logical expression to compare with
559 | * @return string logical expression
560 | */
561 | public function lt($value1, $value2)
562 | {
563 | $value1 = $this->getIdentifier($value1);
564 | $value2 = $this->getIdentifier($value2);
565 | return $value1 . ' < ' . $value2;
566 | }
567 |
568 | /**
569 | * Returns the SQL to check if one value is less than or equal to
570 | * another value.
571 | *
572 | * Example:
573 | * <code>
574 | * $q = new Doctrine_Query();
575 | * $q->select('u.*')
576 | * ->from('User u')
577 | * ->where($q->expr->lte('id', 1));
578 | * </code>
579 | *
580 | * @param string $value1 logical expression to compare
581 | * @param string $value2 logical expression to compare with
582 | * @return string logical expression
583 | */
584 | public function lte($value1, $value2)
585 | {
586 | $value1 = $this->getIdentifier($value1);
587 | $value2 = $this->getIdentifier($value2);
588 | return $value1 . ' <= ' . $value2;
589 | }
590 |
591 | /**
592 | * Returns the SQL to check if a value is one in a set of
593 | * given values..
594 | *
595 | * in() accepts an arbitrary number of parameters. The first parameter
596 | * must always specify the value that should be matched against. Successive
597 | * must contain a logical expression or an array with logical expressions.
598 | * These expressions will be matched against the first parameter.
599 | *
600 | * Example:
601 | * <code>
602 | * $q = new Doctrine_Query();
603 | * $q->select('u.*')
604 | * ->from('User u')
605 | * ->where($q->expr->in( 'id', array(1,2,3)));
606 | * </code>
607 | *
608 | * @param string $column the value that should be matched against
609 | * @param string|array(string) values that will be matched against $column
610 | * @return string logical expression
611 | */
612 | public function in($column, $values)
613 | {
614 | if ( ! is_array($values)) {
615 | $values = array($values);
616 | }
617 | $values = $this->getIdentifiers($values);
618 | $column = $this->getIdentifier($column);
619 |
620 | if (count($values) == 0) {
621 | throw new Doctrine_Expression_Exception('Values array for IN operator should not be empty.');
622 | }
623 | return $column . ' IN (' . implode(', ', $values) . ')';
624 | }
625 |
626 | /**
627 | * Returns SQL that checks if a expression is null.
628 | *
629 | * Example:
630 | * <code>
631 | * $q = new Doctrine_Query();
632 | * $q->select('u.*')
633 | * ->from('User u')
634 | * ->where($q->expr->isNull('id'));
635 | * </code>
636 | *
637 | * @param string $expression the expression that should be compared to null
638 | * @return string logical expression
639 | */
640 | public function isNull($expression)
641 | {
642 | $expression = $this->getIdentifier($expression);
643 | return $expression . ' IS NULL';
644 | }
645 |
646 | /**
647 | * Returns SQL that checks if a expression is not null.
648 | *
649 | * Example:
650 | * <code>
651 | * $q = new Doctrine_Query();
652 | * $q->select('u.*')
653 | * ->from('User u')
654 | * ->where($q->expr->isNotNull('id'));
655 | * </code>
656 | *
657 | * @param string $expression the expression that should be compared to null
658 | * @return string logical expression
659 | */
660 | public function isNotNull($expression)
661 | {
662 | $expression = $this->getIdentifier($expression);
663 | return $expression . ' IS NOT NULL';
664 | }
665 |
666 | /**
667 | * Returns SQL that checks if an expression evaluates to a value between
668 | * two values.
669 | *
670 | * The parameter $expression is checked if it is between $value1 and $value2.
671 | *
672 | * Note: There is a slight difference in the way BETWEEN works on some databases.
673 | * http://www.w3schools.com/sql/sql_between.asp. If you want complete database
674 | * independence you should avoid using between().
675 | *
676 | * Example:
677 | * <code>
678 | * $q = new Doctrine_Query();
679 | * $q->select('u.*')
680 | * ->from('User u')
681 | * ->where($q->expr->between('id', 1, 5));
682 | * </code>
683 | *
684 | * @param string $expression the value to compare to
685 | * @param string $value1 the lower value to compare with
686 | * @param string $value2 the higher value to compare with
687 | * @return string logical expression
688 | */
689 | public function between($expression, $value1, $value2)
690 | {
691 | $expression = $this->getIdentifier($expression);
692 | $value1 = $this->getIdentifier($value1);
693 | $value2 = $this->getIdentifier($value2);
694 | return $expression . ' BETWEEN ' .$value1 . ' AND ' . $value2;
695 | }
696 |
697 | /**
698 | * Returns global unique identifier
699 | *
700 | * @return string to get global unique identifier
701 | */
702 | public function guid()
703 | {
704 | throw new Doctrine_Expression_Exception('method not implemented');
705 | }
706 |
707 | /**
708 | * returns arcus cosine SQL string
709 | *
710 | * @return string
711 | */
712 | public function acos($value)
713 | {
714 | return 'ACOS(' . $value . ')';
715 | }
716 |
717 | /**
718 | * __call
719 | *
720 | * for all native RDBMS functions the function name itself is returned
721 | */
722 | public function __call($m, $a)
723 | {
724 | if ($this->conn->getAttribute(Doctrine::ATTR_PORTABILITY) & Doctrine::PORTABILITY_EXPR) {
725 | throw new Doctrine_Expression_Exception('Unknown expression ' . $m);
726 | }
727 | return $m . '(' . implode(', ', $a) . ')';
728 | }
729 | }