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