Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
Select.php
Go to the documentation of this file.
1 <?php
27 #require_once 'Zend/Db/Adapter/Abstract.php';
28 
32 #require_once 'Zend/Db/Expr.php';
33 
34 
45 {
46 
47  const DISTINCT = 'distinct';
48  const COLUMNS = 'columns';
49  const FROM = 'from';
50  const UNION = 'union';
51  const WHERE = 'where';
52  const GROUP = 'group';
53  const HAVING = 'having';
54  const ORDER = 'order';
55  const LIMIT_COUNT = 'limitcount';
56  const LIMIT_OFFSET = 'limitoffset';
57  const FOR_UPDATE = 'forupdate';
58 
59  const INNER_JOIN = 'inner join';
60  const LEFT_JOIN = 'left join';
61  const RIGHT_JOIN = 'right join';
62  const FULL_JOIN = 'full join';
63  const CROSS_JOIN = 'cross join';
64  const NATURAL_JOIN = 'natural join';
65 
66  const SQL_WILDCARD = '*';
67  const SQL_SELECT = 'SELECT';
68  const SQL_UNION = 'UNION';
69  const SQL_UNION_ALL = 'UNION ALL';
70  const SQL_FROM = 'FROM';
71  const SQL_WHERE = 'WHERE';
72  const SQL_DISTINCT = 'DISTINCT';
73  const SQL_GROUP_BY = 'GROUP BY';
74  const SQL_ORDER_BY = 'ORDER BY';
75  const SQL_HAVING = 'HAVING';
76  const SQL_FOR_UPDATE = 'FOR UPDATE';
77  const SQL_AND = 'AND';
78  const SQL_AS = 'AS';
79  const SQL_OR = 'OR';
80  const SQL_ON = 'ON';
81  const SQL_ASC = 'ASC';
82  const SQL_DESC = 'DESC';
83 
84  const REGEX_COLUMN_EXPR = '/^([\w]*\s*\(([^\(\)]|(?1))*\))$/';
85  const REGEX_COLUMN_EXPR_ORDER = '/^([\w]+\s*\(([^\(\)]|(?1))*\))$/';
86  const REGEX_COLUMN_EXPR_GROUP = '/^([\w]+\s*\(([^\(\)]|(?1))*\))$/';
87 
88  // @see http://stackoverflow.com/a/13823184/2028814
89  const REGEX_SQL_COMMENTS = '@
90  (([\'"]).*?[^\\\]\2) # $1 : Skip single & double quoted expressions
91  |( # $3 : Match comments
92  (?:\#|--).*?$ # - Single line comments
93  | # - Multi line (nested) comments
94  /\* # . comment open marker
95  (?: [^/*] # . non comment-marker characters
96  |/(?!\*) # . ! not a comment open
97  |\*(?!/) # . ! not a comment close
98  |(?R) # . recursive case
99  )* # . repeat eventually
100  \*\/ # . comment close marker
101  )\s* # Trim after comments
102  |(?<=;)\s+ # Trim after semi-colon
103  @msx';
104 
110  protected $_bind = array();
111 
117  protected $_adapter;
118 
126  protected static $_partsInit = array(
127  self::DISTINCT => false,
128  self::COLUMNS => array(),
129  self::UNION => array(),
130  self::FROM => array(),
131  self::WHERE => array(),
132  self::GROUP => array(),
133  self::HAVING => array(),
134  self::ORDER => array(),
135  self::LIMIT_COUNT => null,
136  self::LIMIT_OFFSET => null,
137  self::FOR_UPDATE => false
138  );
139 
145  protected static $_joinTypes = array(
146  self::INNER_JOIN,
147  self::LEFT_JOIN,
148  self::RIGHT_JOIN,
149  self::FULL_JOIN,
150  self::CROSS_JOIN,
151  self::NATURAL_JOIN,
152  );
153 
159  protected static $_unionTypes = array(
160  self::SQL_UNION,
161  self::SQL_UNION_ALL
162  );
163 
170  protected $_parts = array();
171 
177  protected $_tableCols = array();
178 
185  {
186  $this->_adapter = $adapter;
187  $this->_parts = self::$_partsInit;
188  }
189 
195  public function getBind()
196  {
197  return $this->_bind;
198  }
199 
206  public function bind($bind)
207  {
208  $this->_bind = $bind;
209 
210  return $this;
211  }
212 
219  public function distinct($flag = true)
220  {
221  $this->_parts[self::DISTINCT] = (bool) $flag;
222  return $this;
223  }
224 
249  public function from($name, $cols = '*', $schema = null)
250  {
251  return $this->_join(self::FROM, $name, null, $cols, $schema);
252  }
253 
264  public function columns($cols = '*', $correlationName = null)
265  {
266  if ($correlationName === null && count($this->_parts[self::FROM])) {
267  $correlationNameKeys = array_keys($this->_parts[self::FROM]);
268  $correlationName = current($correlationNameKeys);
269  }
270 
271  if (!array_key_exists($correlationName, $this->_parts[self::FROM])) {
275  #require_once 'Zend/Db/Select/Exception.php';
276  throw new Zend_Db_Select_Exception("No table has been specified for the FROM clause");
277  }
278 
279  $this->_tableCols($correlationName, $cols);
280 
281  return $this;
282  }
283 
301  public function union($select = array(), $type = self::SQL_UNION)
302  {
303  if (!is_array($select)) {
304  #require_once 'Zend/Db/Select/Exception.php';
305  throw new Zend_Db_Select_Exception(
306  "union() only accepts an array of Zend_Db_Select instances of sql query strings."
307  );
308  }
309 
310  if (!in_array($type, self::$_unionTypes)) {
311  #require_once 'Zend/Db/Select/Exception.php';
312  throw new Zend_Db_Select_Exception("Invalid union type '{$type}'");
313  }
314 
315  foreach ($select as $target) {
316  $this->_parts[self::UNION][] = array($target, $type);
317  }
318 
319  return $this;
320  }
321 
334  public function join($name, $cond, $cols = self::SQL_WILDCARD, $schema = null)
335  {
336  return $this->joinInner($name, $cond, $cols, $schema);
337  }
338 
355  public function joinInner($name, $cond, $cols = self::SQL_WILDCARD, $schema = null)
356  {
357  return $this->_join(self::INNER_JOIN, $name, $cond, $cols, $schema);
358  }
359 
376  public function joinLeft($name, $cond, $cols = self::SQL_WILDCARD, $schema = null)
377  {
378  return $this->_join(self::LEFT_JOIN, $name, $cond, $cols, $schema);
379  }
380 
398  public function joinRight($name, $cond, $cols = self::SQL_WILDCARD, $schema = null)
399  {
400  return $this->_join(self::RIGHT_JOIN, $name, $cond, $cols, $schema);
401  }
402 
420  public function joinFull($name, $cond, $cols = self::SQL_WILDCARD, $schema = null)
421  {
422  return $this->_join(self::FULL_JOIN, $name, $cond, $cols, $schema);
423  }
424 
437  public function joinCross($name, $cols = self::SQL_WILDCARD, $schema = null)
438  {
439  return $this->_join(self::CROSS_JOIN, $name, null, $cols, $schema);
440  }
441 
457  public function joinNatural($name, $cols = self::SQL_WILDCARD, $schema = null)
458  {
459  return $this->_join(self::NATURAL_JOIN, $name, null, $cols, $schema);
460  }
461 
494  public function where($cond, $value = null, $type = null)
495  {
496  $this->_parts[self::WHERE][] = $this->_where($cond, $value, $type, true);
497 
498  return $this;
499  }
500 
513  public function orWhere($cond, $value = null, $type = null)
514  {
515  $this->_parts[self::WHERE][] = $this->_where($cond, $value, $type, false);
516 
517  return $this;
518  }
519 
526  public function group($spec)
527  {
528  if (!is_array($spec)) {
529  $spec = array($spec);
530  }
531 
532  foreach ($spec as $val) {
533  // Remove comments from SQL statement
534  $noComments = preg_replace(self::REGEX_SQL_COMMENTS, '$1', (string) $val);
535  if (preg_match(self::REGEX_COLUMN_EXPR_GROUP, $noComments)) {
536  $val = new Zend_Db_Expr($val);
537  }
538  $this->_parts[self::GROUP][] = $val;
539  }
540 
541  return $this;
542  }
543 
556  public function having($cond, $value = null, $type = null)
557  {
558  if ($value !== null) {
559  $cond = $this->_adapter->quoteInto($cond, $value, $type);
560  }
561 
562  if ($this->_parts[self::HAVING]) {
563  $this->_parts[self::HAVING][] = self::SQL_AND . " ($cond)";
564  } else {
565  $this->_parts[self::HAVING][] = "($cond)";
566  }
567 
568  return $this;
569  }
570 
583  public function orHaving($cond, $value = null, $type = null)
584  {
585  if ($value !== null) {
586  $cond = $this->_adapter->quoteInto($cond, $value, $type);
587  }
588 
589  if ($this->_parts[self::HAVING]) {
590  $this->_parts[self::HAVING][] = self::SQL_OR . " ($cond)";
591  } else {
592  $this->_parts[self::HAVING][] = "($cond)";
593  }
594 
595  return $this;
596  }
597 
604  public function order($spec)
605  {
606  if (!is_array($spec)) {
607  $spec = array($spec);
608  }
609 
610  // force 'ASC' or 'DESC' on each order spec, default is ASC.
611  foreach ($spec as $val) {
612  if ($val instanceof Zend_Db_Expr) {
613  $expr = $val->__toString();
614  if (empty($expr)) {
615  continue;
616  }
617  $this->_parts[self::ORDER][] = $val;
618  } else {
619  if (empty($val)) {
620  continue;
621  }
622  $direction = self::SQL_ASC;
623  if (preg_match('/(.*\W)(' . self::SQL_ASC . '|' . self::SQL_DESC . ')\b/si', $val, $matches)) {
624  $val = trim($matches[1]);
625  $direction = $matches[2];
626  }
627  // Remove comments from SQL statement
628  $noComments = preg_replace(self::REGEX_SQL_COMMENTS, '$1', (string) $val);
629  if (preg_match(self::REGEX_COLUMN_EXPR_ORDER, $noComments)) {
630  $val = new Zend_Db_Expr($val);
631  }
632  $this->_parts[self::ORDER][] = array($val, $direction);
633  }
634  }
635 
636  return $this;
637  }
638 
646  public function limit($count = null, $offset = null)
647  {
648  $this->_parts[self::LIMIT_COUNT] = (int) $count;
649  $this->_parts[self::LIMIT_OFFSET] = (int) $offset;
650  return $this;
651  }
652 
660  public function limitPage($page, $rowCount)
661  {
662  $page = ($page > 0) ? $page : 1;
663  $rowCount = ($rowCount > 0) ? $rowCount : 1;
664  $this->_parts[self::LIMIT_COUNT] = (int) $rowCount;
665  $this->_parts[self::LIMIT_OFFSET] = (int) $rowCount * ($page - 1);
666  return $this;
667  }
668 
675  public function forUpdate($flag = true)
676  {
677  $this->_parts[self::FOR_UPDATE] = (bool) $flag;
678  return $this;
679  }
680 
688  public function getPart($part)
689  {
690  $part = strtolower($part);
691  if (!array_key_exists($part, $this->_parts)) {
692  #require_once 'Zend/Db/Select/Exception.php';
693  throw new Zend_Db_Select_Exception("Invalid Select part '$part'");
694  }
695  return $this->_parts[$part];
696  }
697 
705  public function query($fetchMode = null, $bind = array())
706  {
707  if (!empty($bind)) {
708  $this->bind($bind);
709  }
710 
711  $stmt = $this->_adapter->query($this);
712  if ($fetchMode == null) {
713  $fetchMode = $this->_adapter->getFetchMode();
714  }
715  $stmt->setFetchMode($fetchMode);
716  return $stmt;
717  }
718 
724  public function assemble()
725  {
726  $sql = self::SQL_SELECT;
727  foreach (array_keys(self::$_partsInit) as $part) {
728  $method = '_render' . ucfirst($part);
729  if (method_exists($this, $method)) {
730  $sql = $this->$method($sql);
731  }
732  }
733  return $sql;
734  }
735 
742  public function reset($part = null)
743  {
744  if ($part == null) {
745  $this->_parts = self::$_partsInit;
746  } elseif (array_key_exists($part, self::$_partsInit)) {
747  $this->_parts[$part] = self::$_partsInit[$part];
748  }
749  return $this;
750  }
751 
758  public function getAdapter()
759  {
760  return $this->_adapter;
761  }
762 
779  protected function _join($type, $name, $cond, $cols, $schema = null)
780  {
781  if (!in_array($type, self::$_joinTypes) && $type != self::FROM) {
785  #require_once 'Zend/Db/Select/Exception.php';
786  throw new Zend_Db_Select_Exception("Invalid join type '$type'");
787  }
788 
789  if (count($this->_parts[self::UNION])) {
790  #require_once 'Zend/Db/Select/Exception.php';
791  throw new Zend_Db_Select_Exception("Invalid use of table with " . self::SQL_UNION);
792  }
793 
794  if (empty($name)) {
795  $correlationName = $tableName = '';
796  } elseif (is_array($name)) {
797  // Must be array($correlationName => $tableName) or array($ident, ...)
798  foreach ($name as $_correlationName => $_tableName) {
799  if (is_string($_correlationName)) {
800  // We assume the key is the correlation name and value is the table name
801  $tableName = $_tableName;
802  $correlationName = $_correlationName;
803  } else {
804  // We assume just an array of identifiers, with no correlation name
805  $tableName = $_tableName;
806  $correlationName = $this->_uniqueCorrelation($tableName);
807  }
808  break;
809  }
810  } elseif ($name instanceof Zend_Db_Expr|| $name instanceof Zend_Db_Select) {
811  $tableName = $name;
812  $correlationName = $this->_uniqueCorrelation('t');
813  } elseif (preg_match('/^(.+)\s+AS\s+(.+)$/i', $name, $m)) {
814  $tableName = $m[1];
815  $correlationName = $m[2];
816  } else {
817  $tableName = $name;
818  $correlationName = $this->_uniqueCorrelation($tableName);
819  }
820 
821  // Schema from table name overrides schema argument
822  if (!is_object($tableName) && false !== strpos($tableName, '.')) {
823  list($schema, $tableName) = explode('.', $tableName);
824  }
825 
826  $lastFromCorrelationName = null;
827  if (!empty($correlationName)) {
828  if (array_key_exists($correlationName, $this->_parts[self::FROM])) {
832  #require_once 'Zend/Db/Select/Exception.php';
833  throw new Zend_Db_Select_Exception("You cannot define a correlation name '$correlationName' more than once");
834  }
835 
836  if ($type == self::FROM) {
837  // append this from after the last from joinType
838  $tmpFromParts = $this->_parts[self::FROM];
839  $this->_parts[self::FROM] = array();
840  // move all the froms onto the stack
841  while ($tmpFromParts) {
842  $currentCorrelationName = key($tmpFromParts);
843  if ($tmpFromParts[$currentCorrelationName]['joinType'] != self::FROM) {
844  break;
845  }
846  $lastFromCorrelationName = $currentCorrelationName;
847  $this->_parts[self::FROM][$currentCorrelationName] = array_shift($tmpFromParts);
848  }
849  } else {
850  $tmpFromParts = array();
851  }
852  $this->_parts[self::FROM][$correlationName] = array(
853  'joinType' => $type,
854  'schema' => $schema,
855  'tableName' => $tableName,
856  'joinCondition' => $cond
857  );
858  while ($tmpFromParts) {
859  $currentCorrelationName = key($tmpFromParts);
860  $this->_parts[self::FROM][$currentCorrelationName] = array_shift($tmpFromParts);
861  }
862  }
863 
864  // add to the columns from this joined table
865  if ($type == self::FROM && $lastFromCorrelationName == null) {
866  $lastFromCorrelationName = true;
867  }
868  $this->_tableCols($correlationName, $cols, $lastFromCorrelationName);
869 
870  return $this;
871  }
872 
898  public function _joinUsing($type, $name, $cond, $cols = '*', $schema = null)
899  {
900  if (empty($this->_parts[self::FROM])) {
901  #require_once 'Zend/Db/Select/Exception.php';
902  throw new Zend_Db_Select_Exception("You can only perform a joinUsing after specifying a FROM table");
903  }
904 
905  $join = $this->_adapter->quoteIdentifier(key($this->_parts[self::FROM]), true);
906  $from = $this->_adapter->quoteIdentifier($this->_uniqueCorrelation($name), true);
907 
908  $joinCond = array();
909  foreach ((array)$cond as $fieldName) {
910  $cond1 = $from . '.' . $fieldName;
911  $cond2 = $join . '.' . $fieldName;
912  $joinCond[] = $cond1 . ' = ' . $cond2;
913  }
914  $cond = implode(' '.self::SQL_AND.' ', $joinCond);
915 
916  return $this->_join($type, $name, $cond, $cols, $schema);
917  }
918 
925  private function _uniqueCorrelation($name)
926  {
927  if (is_array($name)) {
928  $k = key($name);
929  $c = is_string($k) ? $k : end($name);
930  } else {
931  // Extract just the last name of a qualified table name
932  $dot = strrpos($name,'.');
933  $c = ($dot === false) ? $name : substr($name, $dot+1);
934  }
935  for ($i = 2; array_key_exists($c, $this->_parts[self::FROM]); ++$i) {
936  $c = $name . '_' . (string) $i;
937  }
938  return $c;
939  }
940 
950  protected function _tableCols($correlationName, $cols, $afterCorrelationName = null)
951  {
952  if (!is_array($cols)) {
953  $cols = array($cols);
954  }
955 
956  if ($correlationName == null) {
957  $correlationName = '';
958  }
959 
960  $columnValues = array();
961 
962  foreach (array_filter($cols) as $alias => $col) {
963  $currentCorrelationName = $correlationName;
964  if (is_string($col)) {
965  // Check for a column matching "<column> AS <alias>" and extract the alias name
966  $col = trim(str_replace("\n", ' ', $col));
967  if (preg_match('/^(.+)\s+' . self::SQL_AS . '\s+(.+)$/i', $col, $m)) {
968  $col = $m[1];
969  $alias = $m[2];
970  }
971  // Check for columns that look like functions and convert to Zend_Db_Expr
972  if (preg_match(self::REGEX_COLUMN_EXPR, $col)) {
973  $col = new Zend_Db_Expr($col);
974  } elseif (preg_match('/(.+)\.(.+)/', $col, $m)) {
975  $currentCorrelationName = $m[1];
976  $col = $m[2];
977  }
978  }
979  $columnValues[] = array($currentCorrelationName, $col, is_string($alias) ? $alias : null);
980  }
981 
982  if ($columnValues) {
983 
984  // should we attempt to prepend or insert these values?
985  if ($afterCorrelationName === true || is_string($afterCorrelationName)) {
986  $tmpColumns = $this->_parts[self::COLUMNS];
987  $this->_parts[self::COLUMNS] = array();
988  } else {
989  $tmpColumns = array();
990  }
991 
992  // find the correlation name to insert after
993  if (is_string($afterCorrelationName)) {
994  while ($tmpColumns) {
995  $this->_parts[self::COLUMNS][] = $currentColumn = array_shift($tmpColumns);
996  if ($currentColumn[0] == $afterCorrelationName) {
997  break;
998  }
999  }
1000  }
1001 
1002  // apply current values to current stack
1003  foreach ($columnValues as $columnValue) {
1004  array_push($this->_parts[self::COLUMNS], $columnValue);
1005  }
1006 
1007  // finish ensuring that all previous values are applied (if they exist)
1008  while ($tmpColumns) {
1009  array_push($this->_parts[self::COLUMNS], array_shift($tmpColumns));
1010  }
1011  }
1012  }
1013 
1023  protected function _where($condition, $value = null, $type = null, $bool = true)
1024  {
1025  if (count($this->_parts[self::UNION])) {
1026  #require_once 'Zend/Db/Select/Exception.php';
1027  throw new Zend_Db_Select_Exception("Invalid use of where clause with " . self::SQL_UNION);
1028  }
1029 
1030  if ($value !== null) {
1031  $condition = $this->_adapter->quoteInto($condition, $value, $type);
1032  }
1033 
1034  $cond = "";
1035  if ($this->_parts[self::WHERE]) {
1036  if ($bool === true) {
1037  $cond = self::SQL_AND . ' ';
1038  } else {
1039  $cond = self::SQL_OR . ' ';
1040  }
1041  }
1042 
1043  return $cond . "($condition)";
1044  }
1045 
1049  protected function _getDummyTable()
1050  {
1051  return array();
1052  }
1053 
1060  protected function _getQuotedSchema($schema = null)
1061  {
1062  if ($schema === null) {
1063  return null;
1064  }
1065  return $this->_adapter->quoteIdentifier($schema, true) . '.';
1066  }
1067 
1075  protected function _getQuotedTable($tableName, $correlationName = null)
1076  {
1077  return $this->_adapter->quoteTableAs($tableName, $correlationName, true);
1078  }
1079 
1086  protected function _renderDistinct($sql)
1087  {
1088  if ($this->_parts[self::DISTINCT]) {
1089  $sql .= ' ' . self::SQL_DISTINCT;
1090  }
1091 
1092  return $sql;
1093  }
1094 
1101  protected function _renderColumns($sql)
1102  {
1103  if (!count($this->_parts[self::COLUMNS])) {
1104  return null;
1105  }
1106 
1107  $columns = array();
1108  foreach ($this->_parts[self::COLUMNS] as $columnEntry) {
1109  list($correlationName, $column, $alias) = $columnEntry;
1110  if ($column instanceof Zend_Db_Expr) {
1111  $columns[] = $this->_adapter->quoteColumnAs($column, $alias, true);
1112  } else {
1113  if ($column == self::SQL_WILDCARD) {
1114  $column = new Zend_Db_Expr(self::SQL_WILDCARD);
1115  $alias = null;
1116  }
1117  if (empty($correlationName)) {
1118  $columns[] = $this->_adapter->quoteColumnAs($column, $alias, true);
1119  } else {
1120  $columns[] = $this->_adapter->quoteColumnAs(array($correlationName, $column), $alias, true);
1121  }
1122  }
1123  }
1124 
1125  return $sql . ' ' . implode(', ', $columns);
1126  }
1127 
1134  protected function _renderFrom($sql)
1135  {
1136  /*
1137  * If no table specified, use RDBMS-dependent solution
1138  * for table-less query. e.g. DUAL in Oracle.
1139  */
1140  if (empty($this->_parts[self::FROM])) {
1141  $this->_parts[self::FROM] = $this->_getDummyTable();
1142  }
1143 
1144  $from = array();
1145 
1146  foreach ($this->_parts[self::FROM] as $correlationName => $table) {
1147  $tmp = '';
1148 
1149  $joinType = ($table['joinType'] == self::FROM) ? self::INNER_JOIN : $table['joinType'];
1150 
1151  // Add join clause (if applicable)
1152  if (! empty($from)) {
1153  $tmp .= ' ' . strtoupper($joinType) . ' ';
1154  }
1155 
1156  $tmp .= $this->_getQuotedSchema($table['schema']);
1157  $tmp .= $this->_getQuotedTable($table['tableName'], $correlationName);
1158 
1159  // Add join conditions (if applicable)
1160  if (!empty($from) && ! empty($table['joinCondition'])) {
1161  $tmp .= ' ' . self::SQL_ON . ' ' . $table['joinCondition'];
1162  }
1163 
1164  // Add the table name and condition add to the list
1165  $from[] = $tmp;
1166  }
1167 
1168  // Add the list of all joins
1169  if (!empty($from)) {
1170  $sql .= ' ' . self::SQL_FROM . ' ' . implode("\n", $from);
1171  }
1172 
1173  return $sql;
1174  }
1175 
1182  protected function _renderUnion($sql)
1183  {
1184  if ($this->_parts[self::UNION]) {
1185  $parts = count($this->_parts[self::UNION]);
1186  foreach ($this->_parts[self::UNION] as $cnt => $union) {
1187  list($target, $type) = $union;
1188  if ($target instanceof Zend_Db_Select) {
1189  $target = $target->assemble();
1190  }
1191  $sql .= $target;
1192  if ($cnt < $parts - 1) {
1193  $sql .= ' ' . $type . ' ';
1194  }
1195  }
1196  }
1197 
1198  return $sql;
1199  }
1200 
1207  protected function _renderWhere($sql)
1208  {
1209  if ($this->_parts[self::FROM] && $this->_parts[self::WHERE]) {
1210  $sql .= ' ' . self::SQL_WHERE . ' ' . implode(' ', $this->_parts[self::WHERE]);
1211  }
1212 
1213  return $sql;
1214  }
1215 
1222  protected function _renderGroup($sql)
1223  {
1224  if ($this->_parts[self::FROM] && $this->_parts[self::GROUP]) {
1225  $group = array();
1226  foreach ($this->_parts[self::GROUP] as $term) {
1227  $group[] = $this->_adapter->quoteIdentifier($term, true);
1228  }
1229  $sql .= ' ' . self::SQL_GROUP_BY . ' ' . implode(",\n\t", $group);
1230  }
1231 
1232  return $sql;
1233  }
1234 
1241  protected function _renderHaving($sql)
1242  {
1243  if ($this->_parts[self::FROM] && $this->_parts[self::HAVING]) {
1244  $sql .= ' ' . self::SQL_HAVING . ' ' . implode(' ', $this->_parts[self::HAVING]);
1245  }
1246 
1247  return $sql;
1248  }
1249 
1256  protected function _renderOrder($sql)
1257  {
1258  if ($this->_parts[self::ORDER]) {
1259  $order = array();
1260  foreach ($this->_parts[self::ORDER] as $term) {
1261  if (is_array($term)) {
1262  if(is_numeric($term[0]) && strval(intval($term[0])) == $term[0]) {
1263  $order[] = (int)trim($term[0]) . ' ' . $term[1];
1264  } else {
1265  $order[] = $this->_adapter->quoteIdentifier($term[0], true) . ' ' . $term[1];
1266  }
1267  } elseif (is_numeric($term) && strval(intval($term)) == $term) {
1268  $order[] = (int)trim($term);
1269  } else {
1270  $order[] = $this->_adapter->quoteIdentifier($term, true);
1271  }
1272  }
1273  $sql .= ' ' . self::SQL_ORDER_BY . ' ' . implode(', ', $order);
1274  }
1275 
1276  return $sql;
1277  }
1278 
1285  protected function _renderLimitoffset($sql)
1286  {
1287  $count = 0;
1288  $offset = 0;
1289 
1290  if (!empty($this->_parts[self::LIMIT_OFFSET])) {
1291  $offset = (int) $this->_parts[self::LIMIT_OFFSET];
1292  $count = PHP_INT_MAX;
1293  }
1294 
1295  if (!empty($this->_parts[self::LIMIT_COUNT])) {
1296  $count = (int) $this->_parts[self::LIMIT_COUNT];
1297  }
1298 
1299  /*
1300  * Add limits clause
1301  */
1302  if ($count > 0) {
1303  $sql = trim($this->_adapter->limit($sql, $count, $offset));
1304  }
1305 
1306  return $sql;
1307  }
1308 
1315  protected function _renderForupdate($sql)
1316  {
1317  if ($this->_parts[self::FOR_UPDATE]) {
1318  $sql .= ' ' . self::SQL_FOR_UPDATE;
1319  }
1320 
1321  return $sql;
1322  }
1323 
1333  public function __call($method, array $args)
1334  {
1335  $matches = array();
1336 
1343  if (preg_match('/^join([a-zA-Z]*?)Using$/', $method, $matches)) {
1344  $type = strtolower($matches[1]);
1345  if ($type) {
1346  $type .= ' join';
1347  if (!in_array($type, self::$_joinTypes)) {
1348  #require_once 'Zend/Db/Select/Exception.php';
1349  throw new Zend_Db_Select_Exception("Unrecognized method '$method()'");
1350  }
1351  if (in_array($type, array(self::CROSS_JOIN, self::NATURAL_JOIN))) {
1352  #require_once 'Zend/Db/Select/Exception.php';
1353  throw new Zend_Db_Select_Exception("Cannot perform a joinUsing with method '$method()'");
1354  }
1355  } else {
1357  }
1358  array_unshift($args, $type);
1359  return call_user_func_array(array($this, '_joinUsing'), $args);
1360  }
1361 
1362  #require_once 'Zend/Db/Select/Exception.php';
1363  throw new Zend_Db_Select_Exception("Unrecognized method '$method()'");
1364  }
1365 
1371  public function __toString()
1372  {
1373  try {
1374  $sql = $this->assemble();
1375  } catch (Exception $e) {
1376  trigger_error($e->getMessage(), E_USER_WARNING);
1377  $sql = '';
1378  }
1379  return (string)$sql;
1380  }
1381 
1382 }
const SQL_AS
Definition: Select.php:78
const FOR_UPDATE
Definition: Select.php:57
_renderLimitoffset($sql)
Definition: Select.php:1285
orHaving($cond, $value=null, $type=null)
Definition: Select.php:583
joinRight($name, $cond, $cols=self::SQL_WILDCARD, $schema=null)
Definition: Select.php:398
where($cond, $value=null, $type=null)
Definition: Select.php:494
const HAVING
Definition: Select.php:53
const SQL_GROUP_BY
Definition: Select.php:73
$tableName
Definition: trigger.php:13
const SQL_ON
Definition: Select.php:80
const ORDER
Definition: Select.php:54
elseif(isset( $params[ 'redirect_parent']))
Definition: iframe.phtml:17
orWhere($cond, $value=null, $type=null)
Definition: Select.php:513
static $_partsInit
Definition: Select.php:126
_renderColumns($sql)
Definition: Select.php:1101
_renderOrder($sql)
Definition: Select.php:1256
joinLeft($name, $cond, $cols=self::SQL_WILDCARD, $schema=null)
Definition: Select.php:376
const FULL_JOIN
Definition: Select.php:62
static $_unionTypes
Definition: Select.php:159
const SQL_FROM
Definition: Select.php:70
$count
Definition: recent.phtml:13
$target
Definition: skip.phtml:8
$order
Definition: order.php:55
$group
Definition: sections.phtml:16
group($spec)
Definition: Select.php:526
getPart($part)
Definition: Select.php:688
const SQL_SELECT
Definition: Select.php:67
_getQuotedSchema($schema=null)
Definition: Select.php:1060
const FROM
Definition: Select.php:49
$adapter
Definition: webapi_user.php:16
_renderWhere($sql)
Definition: Select.php:1207
$columns
Definition: default.phtml:15
joinCross($name, $cols=self::SQL_WILDCARD, $schema=null)
Definition: Select.php:437
const SQL_WILDCARD
Definition: Select.php:66
$type
Definition: item.phtml:13
bind($bind)
Definition: Select.php:206
__construct(Zend_Db_Adapter_Abstract $adapter)
Definition: Select.php:184
const REGEX_SQL_COMMENTS
Definition: Select.php:89
join($name, $cond, $cols=self::SQL_WILDCARD, $schema=null)
Definition: Select.php:334
const SQL_WHERE
Definition: Select.php:71
reset($part=null)
Definition: Select.php:742
$value
Definition: gender.phtml:16
forUpdate($flag=true)
Definition: Select.php:675
_getQuotedTable($tableName, $correlationName=null)
Definition: Select.php:1075
joinInner($name, $cond, $cols=self::SQL_WILDCARD, $schema=null)
Definition: Select.php:355
_renderGroup($sql)
Definition: Select.php:1222
const REGEX_COLUMN_EXPR_ORDER
Definition: Select.php:85
$page
Definition: pages.php:8
const DISTINCT
Definition: Select.php:47
const SQL_AND
Definition: Select.php:77
static $_joinTypes
Definition: Select.php:145
const INNER_JOIN
Definition: Select.php:59
joinNatural($name, $cols=self::SQL_WILDCARD, $schema=null)
Definition: Select.php:457
const COLUMNS
Definition: Select.php:48
const LIMIT_OFFSET
Definition: Select.php:56
const SQL_HAVING
Definition: Select.php:75
from($name, $cols=' *', $schema=null)
Definition: Select.php:249
const GROUP
Definition: Select.php:52
columns($cols=' *', $correlationName=null)
Definition: Select.php:264
const SQL_UNION_ALL
Definition: Select.php:69
const SQL_DESC
Definition: Select.php:82
_renderDistinct($sql)
Definition: Select.php:1086
const SQL_ORDER_BY
Definition: Select.php:74
const WHERE
Definition: Select.php:51
query($fetchMode=null, $bind=array())
Definition: Select.php:705
const SQL_UNION
Definition: Select.php:68
limitPage($page, $rowCount)
Definition: Select.php:660
having($cond, $value=null, $type=null)
Definition: Select.php:556
$method
Definition: info.phtml:13
limit($count=null, $offset=null)
Definition: Select.php:646
_renderForupdate($sql)
Definition: Select.php:1315
joinFull($name, $cond, $cols=self::SQL_WILDCARD, $schema=null)
Definition: Select.php:420
const REGEX_COLUMN_EXPR
Definition: Select.php:84
const SQL_FOR_UPDATE
Definition: Select.php:76
order($spec)
Definition: Select.php:604
const CROSS_JOIN
Definition: Select.php:63
const UNION
Definition: Select.php:50
const RIGHT_JOIN
Definition: Select.php:61
__call($method, array $args)
Definition: Select.php:1333
_renderFrom($sql)
Definition: Select.php:1134
_tableCols($correlationName, $cols, $afterCorrelationName=null)
Definition: Select.php:950
if(!trim($html)) $alias
Definition: details.phtml:20
_renderUnion($sql)
Definition: Select.php:1182
_renderHaving($sql)
Definition: Select.php:1241
_joinUsing($type, $name, $cond, $cols=' *', $schema=null)
Definition: Select.php:898
_where($condition, $value=null, $type=null, $bool=true)
Definition: Select.php:1023
$table
Definition: trigger.php:14
const LEFT_JOIN
Definition: Select.php:60
$i
Definition: gallery.phtml:31
_join($type, $name, $cond, $cols, $schema=null)
Definition: Select.php:779
const SQL_DISTINCT
Definition: Select.php:72
const NATURAL_JOIN
Definition: Select.php:64
const LIMIT_COUNT
Definition: Select.php:55
const SQL_OR
Definition: Select.php:79
const REGEX_COLUMN_EXPR_GROUP
Definition: Select.php:86
distinct($flag=true)
Definition: Select.php:219
const SQL_ASC
Definition: Select.php:81
if(!isset($_GET['name'])) $name
Definition: log.php:14