# 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 ?>