SQLFunction.class.php

Go to the documentation of this file.
00001 <?php
00002 /****************************************************************************
00003  *   Copyright (C) 2005-2008 by Anton E. Lebedevich, Konstantin V. Arkhipov *
00004  *                                                                          *
00005  *   This program is free software; you can redistribute it and/or modify   *
00006  *   it under the terms of the GNU Lesser General Public License as         *
00007  *   published by the Free Software Foundation; either version 3 of the     *
00008  *   License, or (at your option) any later version.                        *
00009  *                                                                          *
00010  ****************************************************************************/
00011 
00017     final class SQLFunction extends Castable implements MappableObject, Aliased
00018     {
00019         const AGGREGATE_ALL         = 1;
00020         const AGGREGATE_DISTINCT    = 2;
00021         
00022         private $name       = null;
00023         private $alias      = null;
00024         private $aggregate  = null;
00025         
00026         private $args   = array();
00027         
00031         public static function create($name /* , ... */)
00032         {
00033             if (func_num_args() > 1) {
00034                 $args = func_get_args();
00035                 array_shift($args);
00036                 return new SQLFunction($name, $args);
00037             } else
00038                 return new SQLFunction($name);
00039         }
00040         
00041         public function __construct($name /* , ... */)
00042         {
00043             $this->name = $name;
00044             
00045             if (func_num_args() > 1) {
00046                 $args = func_get_args();
00047                 
00048                 if (is_array($args[1]))
00049                     $this->args = $args[1];
00050                 else {
00051                     array_shift($args);
00052                     $this->args = $args;
00053                 }
00054             }
00055         }
00056         
00057         public function getAlias()
00058         {
00059             return $this->alias;
00060         }
00061         
00062         public function getName()
00063         {
00064             return $this->name;
00065         }
00066         
00070         public function setAlias($alias)
00071         {
00072             $this->alias = $alias;
00073             
00074             return $this;
00075         }
00076         
00080         public function setAggregateAll()
00081         {
00082             $this->aggregate = self::AGGREGATE_ALL;
00083             
00084             return $this;
00085         }
00086         
00090         public function setAggregateDistinct()
00091         {
00092             $this->aggregate = self::AGGREGATE_DISTINCT;
00093             
00094             return $this;
00095         }
00096         
00100         public function toMapped(ProtoDAO $dao, JoinCapableQuery $query)
00101         {
00102             $mapped = array();
00103             
00104             $mapped[] = $this->name;
00105             
00106             foreach ($this->args as $arg) {
00107                 if ($arg instanceof MappableObject)
00108                     $mapped[] = $arg->toMapped($dao, $query);
00109                 else
00110                     $mapped[] = $dao->guessAtom($arg, $query);
00111             }
00112             
00113             $sqlFunction = call_user_func_array(array('self', 'create'), $mapped);
00114             
00115             $sqlFunction->aggregate = $this->aggregate;
00116             
00117             $sqlFunction->castTo($this->cast);
00118             
00119             return $sqlFunction;
00120         }
00121         
00122         public function toDialectString(Dialect $dialect)
00123         {
00124             $args = array();
00125             
00126             if ($this->args) {
00127                 foreach ($this->args as $arg)
00128                     if ($arg instanceof DBValue)
00129                         $args[] = $arg->toDialectString($dialect);
00130                     // we're not using * anywhere but COUNT()
00131                     elseif ($arg === '*') {
00132                         Assert::isTrue(
00133                             (strtolower($this->name) === 'count')
00134                             || defined('__I_HATE_MY_KARMA__'),
00135                             
00136                             'do not want to use "*" with '.$this->args[0]
00137                         );
00138                         
00139                         $args[] = $dialect->quoteValue($arg);
00140                     } elseif ($arg instanceof SelectQuery)
00141                         $args[] = '('.$dialect->fieldToString($arg).')';
00142                     else
00143                         $args[] = $dialect->fieldToString($arg);
00144             }
00145             
00146             $out = $this->name.'(';
00147             
00148             if ($this->aggregate == self::AGGREGATE_ALL) {
00149                 $out .= 'ALL ';
00150             } elseif ($this->aggregate == self::AGGREGATE_DISTINCT) {
00151                 $out .= 'DISTINCT ';
00152             }
00153             
00154             $out .= ($args == array() ? null : implode(', ', $args)).')';
00155             
00156             $out =
00157                 $this->cast
00158                     ? $dialect->toCasted($out, $this->cast)
00159                     : $out;
00160             
00161             return
00162                 $this->alias
00163                     ? $out.' AS '.$dialect->quoteTable($this->alias)
00164                     : $out;
00165         }
00166     }
00167 ?>