QueryTrait.php 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. <?php
  2. /**
  3. * @link http://www.yiiframework.com/
  4. * @copyright Copyright (c) 2008 Yii Software LLC
  5. * @license http://www.yiiframework.com/license/
  6. */
  7. namespace yii\db;
  8. /**
  9. * The BaseQuery trait represents the minimum method set of a database Query.
  10. *
  11. * It has support for getting [[one]] instance or [[all]].
  12. * Allows pagination via [[limit]] and [[offset]].
  13. * Sorting is supported via [[orderBy]] and items can be limited to match some conditions unsing [[where]].
  14. *
  15. * By calling [[createCommand()]], we can get a [[Command]] instance which can be further
  16. * used to perform/execute the DB query against a database.
  17. *
  18. * @author Qiang Xue <[email protected]>
  19. * @author Carsten Brandt <[email protected]>
  20. * @since 2.0
  21. */
  22. trait QueryTrait
  23. {
  24. /**
  25. * @var string|array query condition. This refers to the WHERE clause in a SQL statement.
  26. * For example, `age > 31 AND team = 1`.
  27. * @see where()
  28. */
  29. public $where;
  30. /**
  31. * @var integer maximum number of records to be returned. If not set or less than 0, it means no limit.
  32. */
  33. public $limit;
  34. /**
  35. * @var integer zero-based offset from where the records are to be returned. If not set or
  36. * less than 0, it means starting from the beginning.
  37. */
  38. public $offset;
  39. /**
  40. * @var array how to sort the query results. This is used to construct the ORDER BY clause in a SQL statement.
  41. * The array keys are the columns to be sorted by, and the array values are the corresponding sort directions which
  42. * can be either [SORT_ASC](http://php.net/manual/en/array.constants.php#constant.sort-asc)
  43. * or [SORT_DESC](http://php.net/manual/en/array.constants.php#constant.sort-desc).
  44. * The array may also contain [[Expression]] objects. If that is the case, the expressions
  45. * will be converted into strings without any change.
  46. */
  47. public $orderBy;
  48. /**
  49. * @var string|callable $column the name of the column by which the query results should be indexed by.
  50. * This can also be a callable (e.g. anonymous function) that returns the index value based on the given
  51. * row data. For more details, see [[indexBy()]]. This property is only used by [[all()]].
  52. */
  53. public $indexBy;
  54. /**
  55. * Sets the [[indexBy]] property.
  56. * @param string|callable $column the name of the column by which the query results should be indexed by.
  57. * This can also be a callable (e.g. anonymous function) that returns the index value based on the given
  58. * row data. The signature of the callable should be:
  59. *
  60. * ~~~
  61. * function ($row)
  62. * {
  63. * // return the index value corresponding to $row
  64. * }
  65. * ~~~
  66. *
  67. * @return static the query object itself
  68. */
  69. public function indexBy($column)
  70. {
  71. $this->indexBy = $column;
  72. return $this;
  73. }
  74. /**
  75. * Sets the WHERE part of the query.
  76. *
  77. * See [[QueryInterface::where()]] for detailed documentation.
  78. *
  79. * @param array $condition the conditions that should be put in the WHERE part.
  80. * @return static the query object itself
  81. * @see andWhere()
  82. * @see orWhere()
  83. */
  84. public function where($condition)
  85. {
  86. $this->where = $condition;
  87. return $this;
  88. }
  89. /**
  90. * Adds an additional WHERE condition to the existing one.
  91. * The new condition and the existing one will be joined using the 'AND' operator.
  92. * @param string|array $condition the new WHERE condition. Please refer to [[where()]]
  93. * on how to specify this parameter.
  94. * @return static the query object itself
  95. * @see where()
  96. * @see orWhere()
  97. */
  98. public function andWhere($condition)
  99. {
  100. if ($this->where === null) {
  101. $this->where = $condition;
  102. } else {
  103. $this->where = ['and', $this->where, $condition];
  104. }
  105. return $this;
  106. }
  107. /**
  108. * Adds an additional WHERE condition to the existing one.
  109. * The new condition and the existing one will be joined using the 'OR' operator.
  110. * @param string|array $condition the new WHERE condition. Please refer to [[where()]]
  111. * on how to specify this parameter.
  112. * @return static the query object itself
  113. * @see where()
  114. * @see andWhere()
  115. */
  116. public function orWhere($condition)
  117. {
  118. if ($this->where === null) {
  119. $this->where = $condition;
  120. } else {
  121. $this->where = ['or', $this->where, $condition];
  122. }
  123. return $this;
  124. }
  125. /**
  126. * Sets the ORDER BY part of the query.
  127. * @param string|array $columns the columns (and the directions) to be ordered by.
  128. * Columns can be specified in either a string (e.g. "id ASC, name DESC") or an array
  129. * (e.g. `['id' => SORT_ASC, 'name' => SORT_DESC]`).
  130. * The method will automatically quote the column names unless a column contains some parenthesis
  131. * (which means the column contains a DB expression).
  132. * Note that if your order-by is an expression containing commas, you should always use an array
  133. * to represent the order-by information. Otherwise, the method will not be able to correctly determine
  134. * the order-by columns.
  135. * @return static the query object itself
  136. * @see addOrderBy()
  137. */
  138. public function orderBy($columns)
  139. {
  140. $this->orderBy = $this->normalizeOrderBy($columns);
  141. return $this;
  142. }
  143. /**
  144. * Adds additional ORDER BY columns to the query.
  145. * @param string|array $columns the columns (and the directions) to be ordered by.
  146. * Columns can be specified in either a string (e.g. "id ASC, name DESC") or an array
  147. * (e.g. `['id' => SORT_ASC, 'name' => SORT_DESC]`).
  148. * The method will automatically quote the column names unless a column contains some parenthesis
  149. * (which means the column contains a DB expression).
  150. * @return static the query object itself
  151. * @see orderBy()
  152. */
  153. public function addOrderBy($columns)
  154. {
  155. $columns = $this->normalizeOrderBy($columns);
  156. if ($this->orderBy === null) {
  157. $this->orderBy = $columns;
  158. } else {
  159. $this->orderBy = array_merge($this->orderBy, $columns);
  160. }
  161. return $this;
  162. }
  163. protected function normalizeOrderBy($columns)
  164. {
  165. if (is_array($columns)) {
  166. return $columns;
  167. } else {
  168. $columns = preg_split('/\s*,\s*/', trim($columns), -1, PREG_SPLIT_NO_EMPTY);
  169. $result = [];
  170. foreach ($columns as $column) {
  171. if (preg_match('/^(.*?)\s+(asc|desc)$/i', $column, $matches)) {
  172. $result[$matches[1]] = strcasecmp($matches[2], 'desc') ? SORT_ASC : SORT_DESC;
  173. } else {
  174. $result[$column] = SORT_ASC;
  175. }
  176. }
  177. return $result;
  178. }
  179. }
  180. /**
  181. * Sets the LIMIT part of the query.
  182. * @param integer $limit the limit. Use null or negative value to disable limit.
  183. * @return static the query object itself
  184. */
  185. public function limit($limit)
  186. {
  187. $this->limit = $limit;
  188. return $this;
  189. }
  190. /**
  191. * Sets the OFFSET part of the query.
  192. * @param integer $offset the offset. Use null or negative value to disable offset.
  193. * @return static the query object itself
  194. */
  195. public function offset($offset)
  196. {
  197. $this->offset = $offset;
  198. return $this;
  199. }
  200. }