QuerySkeleton.class.php

Go to the documentation of this file.
00001 <?php
00002 /***************************************************************************
00003  *   Copyright (C) 2004-2008 by 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 
00015     abstract class QuerySkeleton extends QueryIdentification
00016     {
00017         protected $where        = array();  // where clauses
00018         protected $whereLogic   = array();  // logic between where's
00019         protected $aliases      = array();
00020         protected $returning    = array();
00021         
00022         public function getWhere()
00023         {
00024             return $this->where;
00025         }
00026         
00027         public function getWhereLogic()
00028         {
00029             return $this->whereLogic;
00030         }
00031         
00036         public function where(LogicalObject $exp, $logic = null)
00037         {
00038             if ($this->where && !$logic)
00039                 throw new WrongArgumentException(
00040                     'you have to specify expression logic'
00041                 );
00042             else {
00043                 if (!$this->where && $logic)
00044                     $logic = null;
00045                 
00046                 $this->whereLogic[] = $logic;
00047                 $this->where[] = $exp;
00048             }
00049             
00050             return $this;
00051         }
00052         
00056         public function andWhere(LogicalObject $exp)
00057         {
00058             return $this->where($exp, 'AND');
00059         }
00060         
00064         public function orWhere(LogicalObject $exp)
00065         {
00066             return $this->where($exp, 'OR');
00067         }
00068         
00072         public function returning($field, $alias = null)
00073         {
00074             $this->returning[] =
00075                 $this->resolveSelectField(
00076                     $field,
00077                     $alias,
00078                     $this->table
00079                 );
00080             
00081             if ($alias = $this->resolveAliasByField($field, $alias)) {
00082                 $this->aliases[$alias] = true;
00083             }
00084             
00085             return $this;
00086         }
00087         
00091         public function dropReturning()
00092         {
00093             $this->returning = array();
00094             
00095             return $this;
00096         }
00097         
00098         public function toDialectString(Dialect $dialect)
00099         {
00100             if ($this->where) {
00101                 $clause = ' WHERE';
00102                 $outputLogic = false;
00103                 
00104                 for ($i = 0, $size = count($this->where); $i < $size; ++$i) {
00105                     
00106                     if ($exp = $this->where[$i]->toDialectString($dialect)) {
00107                         
00108                         $clause .= "{$this->whereLogic[$i]} {$exp} ";
00109                         $outputLogic = true;
00110                         
00111                     } elseif (!$outputLogic && isset($this->whereLogic[$i + 1]))
00112                         $this->whereLogic[$i + 1] = null;
00113                     
00114                 }
00115                 
00116                 return rtrim($clause, ' ');
00117             }
00118             
00119             return null;
00120         }
00121         
00122         protected function resolveSelectField($field, $alias, $table)
00123         {
00124             if (is_object($field)) {
00125                 if (
00126                     ($field instanceof DBField)
00127                     && ($field->getTable() === null)
00128                 ) {
00129                     $result = new SelectField(
00130                         $field->setTable($table),
00131                         $alias
00132                     );
00133                 } elseif ($field instanceof SelectQuery) {
00134                     $result = $field;
00135                 } elseif ($field instanceof DialectString) {
00136                     $result = new SelectField($field, $alias);
00137                 } else
00138                     throw new WrongArgumentException('unknown field type');
00139                 
00140                 return $result;
00141             } elseif (false !== strpos($field, '*'))
00142                 throw new WrongArgumentException(
00143                     'do not fsck with us: specify fields explicitly'
00144                 );
00145             elseif (false !== strpos($field, '.'))
00146                 throw new WrongArgumentException(
00147                     'forget about dot: use DBField'
00148                 );
00149             else
00150                 $fieldName = $field;
00151             
00152             $result = new SelectField(
00153                 new DBField($fieldName, $table), $alias
00154             );
00155             
00156             return $result;
00157         }
00158         
00159         protected function resolveAliasByField($field, $alias)
00160         {
00161             if (is_object($field)) {
00162                 if (
00163                     ($field instanceof DBField)
00164                     && ($field->getTable() === null)
00165                 ) {
00166                     return null;
00167                 }
00168                 
00169                 if (
00170                     $field instanceof SelectQuery
00171                     || ($field instanceof DialectString && $field instanceof Aliased)
00172                 ) {
00173                     return $field->getAlias();
00174                 }
00175             }
00176             
00177             return $alias;
00178         }
00179         
00183         protected function checkReturning(Dialect $dialect)
00184         {
00185             if (
00186                 $this->returning
00187                 && !$dialect->hasReturning()
00188             ) {
00189                 throw new UnimplementedFeatureException();
00190             }
00191             
00192             return $this;
00193         }
00194         
00195         protected function toDialectStringField($field, Dialect $dialect)
00196         {
00197             if ($field instanceof SelectQuery) {
00198                 Assert::isTrue(
00199                     null !== $alias = $field->getName(),
00200                     'can not use SelectQuery without name as get field'
00201                 );
00202                 
00203                 return
00204                     "({$field->toDialectString($dialect)}) AS ".
00205                     $dialect->quoteField($alias);
00206             } else
00207                 return $field->toDialectString($dialect);
00208         }
00209         
00210         protected function toDialectStringReturning(Dialect $dialect)
00211         {
00212             $fields = array();
00213             
00214             foreach ($this->returning as $field)
00215                 $fields[] = $this->toDialectStringField($field, $dialect);
00216             
00217             return implode(', ', $fields);
00218         }
00219     }
00220 ?>