Go to the documentation of this file.00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00015 final class SelectQuery
00016 extends QuerySkeleton
00017 implements Named, JoinCapableQuery, Aliased
00018 {
00019 private $distinct = false;
00020
00021 private $name = null;
00022
00023 private $joiner = null;
00024
00025 private $limit = null;
00026 private $offset = null;
00027
00028 private $fields = array();
00029
00030 private $order = null;
00031
00032 private $group = array();
00033
00034 private $having = null;
00035
00036 public function __construct()
00037 {
00038 $this->joiner = new Joiner();
00039 $this->order = new OrderChain();
00040 }
00041
00042 public function __clone()
00043 {
00044 $this->joiner = clone $this->joiner;
00045 $this->order = clone $this->order;
00046 }
00047
00048 public function hasAliasInside($alias)
00049 {
00050 return isset($this->aliases[$alias]);
00051 }
00052
00053 public function getAlias()
00054 {
00055 return $this->name;
00056 }
00057
00058 public function getName()
00059 {
00060 return $this->name;
00061 }
00062
00066 public function setName($name)
00067 {
00068 $this->name = $name;
00069 $this->aliases[$name] = true;
00070
00071 return $this;
00072 }
00073
00077 public function distinct()
00078 {
00079 $this->distinct = true;
00080 return $this;
00081 }
00082
00083 public function isDistinct()
00084 {
00085 return $this->distinct;
00086 }
00087
00091 public function unDistinct()
00092 {
00093 $this->distinct = false;
00094 return $this;
00095 }
00096
00097 public function hasJoinedTable($table)
00098 {
00099 return $this->joiner->hasJoinedTable($table);
00100 }
00101
00105 public function join($table, LogicalObject $logic, $alias = null)
00106 {
00107 $this->joiner->join(new SQLJoin($table, $logic, $alias));
00108 $this->aliases[$alias] = true;
00109
00110 return $this;
00111 }
00112
00116 public function leftJoin($table, LogicalObject $logic, $alias = null)
00117 {
00118 $this->joiner->leftJoin(new SQLLeftJoin($table, $logic, $alias));
00119 $this->aliases[$alias] = true;
00120
00121 return $this;
00122 }
00123
00127 public function rightJoin($table, LogicalObject $logic, $alias = null)
00128 {
00129 $this->joiner->rightJoin(new SQLRightJoin($table, $logic, $alias));
00130 $this->aliases[$alias] = true;
00131
00132 return $this;
00133 }
00134
00138 public function setOrderChain(OrderChain $chain)
00139 {
00140 $this->order = $chain;
00141
00142 return $this;
00143 }
00144
00148 public function orderBy($field, $table = null)
00149 {
00150 $this->order->add($this->makeOrder($field, $table));
00151
00152 return $this;
00153 }
00154
00158 public function prependOrderBy($field, $table = null)
00159 {
00160 $this->order->prepend($this->makeOrder($field, $table));
00161
00162 return $this;
00163 }
00164
00169 public function desc()
00170 {
00171 if (!$last = $this->order->getLast())
00172 throw new WrongStateException('no fields to sort');
00173
00174 $last->desc();
00175
00176 return $this;
00177 }
00178
00183 public function asc()
00184 {
00185 if (!$last = $this->order->getLast())
00186 throw new WrongStateException('no fields to sort');
00187
00188 $last->asc();
00189
00190 return $this;
00191 }
00192
00196 public function groupBy($field, $table = null)
00197 {
00198 if ($field instanceof DialectString)
00199 $this->group[] = $field;
00200 else
00201 $this->group[] =
00202 new DBField($field, $this->getLastTable($table));
00203
00204 return $this;
00205 }
00206
00210 public function dropGroupBy()
00211 {
00212 $this->group = array();
00213 return $this;
00214 }
00215
00219 public function having(LogicalObject $exp)
00220 {
00221 $this->having = $exp;
00222
00223 return $this;
00224 }
00225
00226 public function getLimit()
00227 {
00228 return $this->limit;
00229 }
00230
00231 public function getOffset()
00232 {
00233 return $this->offset;
00234 }
00235
00240 public function limit($limit = null, $offset = null)
00241 {
00242 if ($limit !== null)
00243 Assert::isPositiveInteger($limit, 'invalid limit specified');
00244
00245 if ($offset !== null)
00246 Assert::isInteger($offset, 'invalid offset specified');
00247
00248 $this->limit = $limit;
00249 $this->offset = $offset;
00250
00251 return $this;
00252 }
00253
00257 public function from($table, $alias = null)
00258 {
00259 $this->joiner->from(new FromTable($table, $alias));
00260
00261 $this->aliases[$alias] = true;
00262
00263 return $this;
00264 }
00265
00266 public function getFirstTable()
00267 {
00268 return $this->joiner->getFirstTable();
00269 }
00270
00275 public function get($field, $alias = null)
00276 {
00277 $this->fields[] =
00278 $this->resolveSelectField(
00279 $field,
00280 $alias,
00281 $this->getLastTable()
00282 );
00283
00284 if ($alias = $this->resolveAliasByField($field, $alias)) {
00285 $this->aliases[$alias] = true;
00286 }
00287
00288 return $this;
00289 }
00290
00294 public function multiGet()
00295 {
00296 $size = func_num_args();
00297
00298 if ($size && $args = func_get_args())
00299 for ($i = 0; $i < $size; ++$i)
00300 $this->get($args[$i]);
00301
00302 return $this;
00303 }
00304
00308 public function arrayGet($array, $prefix = null)
00309 {
00310 $size = count($array);
00311
00312 if ($prefix) {
00313 for ($i = 0; $i < $size; ++$i) {
00314 if ($array[$i] instanceof DialectString) {
00315 if ($array[$i] instanceof DBField) {
00316 $alias = $prefix.$array[$i]->getField();
00317 } else {
00318 if ($array[$i] instanceof SQLFunction) {
00319 $alias =
00320 $array[$i]->setAlias(
00321 $prefix.$array[$i]->getName()
00322 )->
00323 getAlias();
00324 } else {
00325 $alias = $array[$i];
00326 }
00327 }
00328 } else {
00329 $alias = $prefix.$array[$i];
00330 }
00331
00332 $this->get($array[$i], $alias);
00333 }
00334 } else {
00335 for ($i = 0; $i < $size; ++$i) {
00336 $this->get($array[$i]);
00337 }
00338 }
00339
00340 return $this;
00341 }
00342
00343 public function getFieldsCount()
00344 {
00345 return count($this->fields);
00346 }
00347
00348 public function getTablesCount()
00349 {
00350 return $this->joiner->getTablesCount();
00351 }
00352
00353 public function getFieldNames()
00354 {
00355 $nameList = array();
00356
00357 foreach ($this->fields as $field) {
00358 if ($field instanceof SelectField)
00359 if ($alias = $field->getAlias()) {
00360 $nameList[] = $alias;
00361 continue;
00362 }
00363
00364 $nameList[] = $field->getName();
00365 }
00366
00367 return $nameList;
00368 }
00369
00370 public function returning($field, $alias = null)
00371 {
00372 throw new UnsupportedMethodException();
00373 }
00374
00375 public function toDialectString(Dialect $dialect)
00376 {
00377 $fieldList = array();
00378
00379 foreach ($this->fields as $field)
00380 $fieldList[] = $this->toDialectStringField($field, $dialect);
00381
00382 $query =
00383 'SELECT '.($this->distinct ? 'DISTINCT ' : null)
00384 .implode(', ', $fieldList)
00385 .$this->joiner->toDialectString($dialect);
00386
00387
00388 $query .= parent::toDialectString($dialect);
00389
00390 if ($this->group) {
00391 $groupList = array();
00392
00393 foreach ($this->group as $group)
00394 $groupList[] = $group->toDialectString($dialect);
00395
00396 if ($groupList)
00397 $query .= ' GROUP BY '.implode(', ', $groupList);
00398 }
00399
00400 if ($this->having)
00401 $query .= ' HAVING '.$this->having->toDialectString($dialect);
00402
00403 if ($this->order->getCount()) {
00404 $query .= ' ORDER BY '.$this->order->toDialectString($dialect);
00405 }
00406
00407 if ($this->limit)
00408 $query .= ' LIMIT '.$this->limit;
00409
00410 if ($this->offset)
00411 $query .= ' OFFSET '.$this->offset;
00412
00413 return $query;
00414 }
00415
00419 public function dropFields()
00420 {
00421 $this->fields = array();
00422 return $this;
00423 }
00424
00428 public function dropOrder()
00429 {
00430 $this->order = new OrderChain();
00431 return $this;
00432 }
00433
00437 public function dropLimit()
00438 {
00439 $this->limit = $this->offset = null;
00440 return $this;
00441 }
00442
00443 private function getLastTable($table = null)
00444 {
00445 if (!$table && ($last = $this->joiner->getLastTable()))
00446 return $last;
00447
00448 return $table;
00449 }
00450
00454 private function makeOrder($field, $table = null)
00455 {
00456 if (
00457 $field instanceof OrderBy
00458 || $field instanceof DialectString
00459 )
00460 return $field;
00461 else
00462 return
00463 new OrderBy(
00464 new DBField($field, $this->getLastTable($table))
00465 );
00466 }
00467 }
00468 ?>