From 65338972c7f7e6fee0e86bb300cc2502f42edcc1 Mon Sep 17 00:00:00 2001 From: Carsten Brandt Date: Wed, 13 Nov 2013 18:42:50 +0100 Subject: [PATCH] refactored ActiveRecord classes to use Interfaces and traits this allows us to implement other activerecord implementations based on NoSQL dbms --- docs/guide/query-builder.md | 4 +- framework/yii/ar/ActiveQueryInterface.php | 59 ++++++++ framework/yii/ar/ActiveQueryTrait.php | 16 ++- framework/yii/ar/ActiveRelationInterface.php | 36 +++++ framework/yii/ar/ActiveRelationTrait.php | 1 + framework/yii/data/ActiveDataProvider.php | 20 +-- framework/yii/db/ActiveQuery.php | 10 +- framework/yii/db/ActiveRecord.php | 28 ++-- framework/yii/db/ActiveRelation.php | 13 +- framework/yii/db/Query.php | 20 +-- framework/yii/db/QueryBuilder.php | 2 +- framework/yii/db/QueryInterface.php | 205 +++++++++++++++++++++++++++ framework/yii/db/QueryTrait.php | 109 ++------------ 13 files changed, 369 insertions(+), 154 deletions(-) create mode 100644 framework/yii/ar/ActiveQueryInterface.php create mode 100644 framework/yii/ar/ActiveRelationInterface.php create mode 100644 framework/yii/db/QueryInterface.php diff --git a/docs/guide/query-builder.md b/docs/guide/query-builder.md index 7625c0b..ac79f1d 100644 --- a/docs/guide/query-builder.md +++ b/docs/guide/query-builder.md @@ -167,8 +167,8 @@ For ordering results `orderBy` and `addOrderBy` could be used: ```php $query->orderBy([ - 'id' => Query::SORT_ASC, - 'name' => Query::SORT_DESC, + 'id' => SORT_ASC, + 'name' => SORT_DESC, ]); ``` diff --git a/framework/yii/ar/ActiveQueryInterface.php b/framework/yii/ar/ActiveQueryInterface.php new file mode 100644 index 0000000..e2bb780 --- /dev/null +++ b/framework/yii/ar/ActiveQueryInterface.php @@ -0,0 +1,59 @@ + + * @author Carsten Brandt + * @since 2.0 + */ +interface ActiveQueryInterface extends QueryInterface +{ + /** + * Sets the [[asArray]] property. + * @param boolean $value whether to return the query results in terms of arrays instead of Active Records. + * @return static the query object itself + */ + public function asArray($value = true); + + /** + * Specifies the relations with which this query should be performed. + * + * The parameters to this method can be either one or multiple strings, or a single array + * of relation names and the optional callbacks to customize the relations. + * + * A relation name can refer to a relation defined in [[modelClass]] + * or a sub-relation that stands for a relation of a related record. + * For example, `orders.address` means the `address` relation defined + * in the model class corresponding to the `orders` relation. + * + * The followings are some usage examples: + * + * ~~~ + * // find customers together with their orders and country + * Customer::find()->with('orders', 'country')->all(); + * // find customers together with their orders and the orders' shipping address + * Customer::find()->with('orders.address')->all(); + * // find customers together with their country and orders of status 1 + * Customer::find()->with([ + * 'orders' => function($query) { + * $query->andWhere('status = 1'); + * }, + * 'country', + * ])->all(); + * ~~~ + * + * @return static the query object itself + */ + public function with(); +} diff --git a/framework/yii/ar/ActiveQueryTrait.php b/framework/yii/ar/ActiveQueryTrait.php index 1a4336f..8c8d6c0 100644 --- a/framework/yii/ar/ActiveQueryTrait.php +++ b/framework/yii/ar/ActiveQueryTrait.php @@ -10,10 +10,7 @@ namespace yii\ar; use yii\db\ActiveRecord; /** - * ActiveQuery represents a DB query associated with an Active Record class. - * - * ActiveQuery instances are usually created by [[ActiveRecord::find()]], [[ActiveRecord::findBySql()]] - * and [[ActiveRecord::count()]]. + * ActiveQueryTrait implements the common set of methods that are used by DB queries associated with an Active Record class. * * ActiveQuery mainly provides the following methods to retrieve the query results: * @@ -150,6 +147,11 @@ trait ActiveQueryTrait return parent::indexBy($column); } + /** + * Converts found rows into model instances + * @param array $rows + * @return array|ActiveRecord[] + */ private function createModels($rows) { $models = []; @@ -187,6 +189,10 @@ trait ActiveQueryTrait return $models; } + /** + * @param ActiveRecord[] $models + * @param array $with + */ private function populateRelations(&$models, $with) { $primaryModel = new $this->modelClass; @@ -203,7 +209,7 @@ trait ActiveQueryTrait /** * @param ActiveRecord $model * @param array $with - * @return ActiveRelation[] + * @return ActiveRelationInterface[] */ private function normalizeRelations($model, $with) { diff --git a/framework/yii/ar/ActiveRelationInterface.php b/framework/yii/ar/ActiveRelationInterface.php new file mode 100644 index 0000000..70b723a --- /dev/null +++ b/framework/yii/ar/ActiveRelationInterface.php @@ -0,0 +1,36 @@ + + * @author Carsten Brandt + * @since 2.0 + */ +interface ActiveRelationInterface extends ActiveQueryInterface +{ + /** + * Specifies the relation associated with the pivot table. + * @param string $relationName the relation name. This refers to a relation declared in [[primaryModel]]. + * @param callable $callable a PHP callback for customizing the relation associated with the pivot table. + * Its signature should be `function($query)`, where `$query` is the query to be customized. + * @return static the relation object itself. + */ + public function via($relationName, $callable = null); + + /** + * Finds the related records and populates them into the primary models. + * This method is internally used by [[ActiveQuery]]. Do not call it directly. + * @param string $name the relation name + * @param array $primaryModels primary models + * @return array the related models + */ + public function findWith($name, &$primaryModels); +} diff --git a/framework/yii/ar/ActiveRelationTrait.php b/framework/yii/ar/ActiveRelationTrait.php index 6d30ebc..350718d 100644 --- a/framework/yii/ar/ActiveRelationTrait.php +++ b/framework/yii/ar/ActiveRelationTrait.php @@ -23,6 +23,7 @@ use yii\db\ActiveRecord; * If a relation involves a pivot table, it may be specified by [[via()]] or [[viaTable()]] method. * * @author Qiang Xue + * @author Carsten Brandt * @since 2.0 */ trait ActiveRelationTrait diff --git a/framework/yii/data/ActiveDataProvider.php b/framework/yii/data/ActiveDataProvider.php index ca7696f..3766692 100644 --- a/framework/yii/data/ActiveDataProvider.php +++ b/framework/yii/data/ActiveDataProvider.php @@ -8,11 +8,11 @@ namespace yii\data; use Yii; +use yii\ar\ActiveQueryInterface; use yii\base\InvalidConfigException; use yii\base\Model; -use yii\db\Query; -use yii\db\ActiveQuery; use yii\db\Connection; +use yii\db\QueryInterface; /** * ActiveDataProvider implements a data provider based on [[Query]] and [[ActiveQuery]]. @@ -54,7 +54,7 @@ use yii\db\Connection; class ActiveDataProvider extends BaseDataProvider { /** - * @var Query the query that is used to fetch data models and [[totalCount]] + * @var QueryInterface the query that is used to fetch data models and [[totalCount]] * if it is not explicitly set. */ public $query; @@ -97,8 +97,8 @@ class ActiveDataProvider extends BaseDataProvider */ protected function prepareModels() { - if (!$this->query instanceof Query) { - throw new InvalidConfigException('The "query" property must be an instance of Query or its subclass.'); + if (!$this->query instanceof QueryInterface) { + throw new InvalidConfigException('The "query" property must be an instance of a class that implements the QueryInterface e.g. yii\db\Query or its subclasses.'); } if (($pagination = $this->getPagination()) !== false) { $pagination->totalCount = $this->getTotalCount(); @@ -125,7 +125,7 @@ class ActiveDataProvider extends BaseDataProvider } } return $keys; - } elseif ($this->query instanceof ActiveQuery) { + } elseif ($this->query instanceof ActiveQueryInterface) { /** @var \yii\db\ActiveRecord $class */ $class = $this->query->modelClass; $pks = $class::primaryKey(); @@ -154,11 +154,11 @@ class ActiveDataProvider extends BaseDataProvider */ protected function prepareTotalCount() { - if (!$this->query instanceof Query) { - throw new InvalidConfigException('The "query" property must be an instance of Query or its subclass.'); + if (!$this->query instanceof QueryInterface) { + throw new InvalidConfigException('The "query" property must be an instance of a class that implements the QueryInterface e.g. yii\db\Query or its subclasses.'); } $query = clone $this->query; - return (int) $query->limit(-1)->offset(-1)->count('*', $this->db); + return (int) $query->limit(-1)->offset(-1)->count($this->db); } /** @@ -167,7 +167,7 @@ class ActiveDataProvider extends BaseDataProvider public function setSort($value) { parent::setSort($value); - if (($sort = $this->getSort()) !== false && empty($sort->attributes) && $this->query instanceof ActiveQuery) { + if (($sort = $this->getSort()) !== false && empty($sort->attributes) && $this->query instanceof ActiveQueryInterface) { /** @var Model $model */ $model = new $this->query->modelClass; foreach ($model->attributes() as $attribute) { diff --git a/framework/yii/db/ActiveQuery.php b/framework/yii/db/ActiveQuery.php index 94494bc..3995b1b 100644 --- a/framework/yii/db/ActiveQuery.php +++ b/framework/yii/db/ActiveQuery.php @@ -7,12 +7,13 @@ */ namespace yii\db; +use yii\ar\ActiveQueryInterface; +use yii\ar\ActiveQueryTrait; /** * ActiveQuery represents a DB query associated with an Active Record class. * - * ActiveQuery instances are usually created by [[ActiveRecord::find()]], [[ActiveRecord::findBySql()]] - * and [[ActiveRecord::count()]]. + * ActiveQuery instances are usually created by [[ActiveRecord::find()]] and [[ActiveRecord::findBySql()]]. * * ActiveQuery mainly provides the following methods to retrieve the query results: * @@ -42,11 +43,12 @@ namespace yii\db; * ~~~ * * @author Qiang Xue + * @author Carsten Brandt * @since 2.0 */ -class ActiveQuery extends Query +class ActiveQuery extends Query implements ActiveQueryInterface { - use \yii\ar\ActiveQueryTrait; + use ActiveQueryTrait; /** * @var string the SQL statement to be executed for retrieving AR records. diff --git a/framework/yii/db/ActiveRecord.php b/framework/yii/db/ActiveRecord.php index 57c5c8b..852d6f5 100644 --- a/framework/yii/db/ActiveRecord.php +++ b/framework/yii/db/ActiveRecord.php @@ -8,6 +8,7 @@ namespace yii\db; +use yii\ar\ActiveRelationInterface; use yii\base\InvalidConfigException; use yii\base\Model; use yii\base\InvalidParamException; @@ -36,6 +37,7 @@ use yii\helpers\Inflector; * the key value is null). This property is read-only. * * @author Qiang Xue + * @author Carsten Brandt * @since 2.0 */ class ActiveRecord extends Model @@ -95,10 +97,6 @@ class ActiveRecord extends Model const OP_ALL = 0x07; /** - * @var string the name of the class to use for relations. - */ - protected $relationClassName = 'yii\\db\\ActiveRelation'; - /** * @var array attribute values indexed by attribute names */ private $_attributes = []; @@ -256,7 +254,7 @@ class ActiveRecord extends Model /** * Creates an [[ActiveQuery]] instance. - * This method is called by [[find()]], [[findBySql()]] and [[count()]] to start a SELECT query. + * This method is called by [[find()]], [[findBySql()]] to start a SELECT query. * You may override this method to return a customized query (e.g. `CustomerQuery` specified * written for querying `Customer` purpose.) * @return ActiveQuery the newly created [[ActiveQuery]] instance. @@ -389,7 +387,7 @@ class ActiveRecord extends Model return $this->_related[$name]; } $value = parent::__get($name); - if ($value instanceof $this->relationClassName) { + if ($value instanceof ActiveRelationInterface) { return $this->_related[$name] = $value->multiple ? $value->all() : $value->one(); } else { return $value; @@ -478,7 +476,7 @@ class ActiveRecord extends Model */ public function hasOne($class, $link) { - return new $this->relationClassName([ + return $this->createActiveRelation([ 'modelClass' => $class, 'primaryModel' => $this, 'link' => $link, @@ -516,7 +514,7 @@ class ActiveRecord extends Model */ public function hasMany($class, $link) { - return new $this->relationClassName([ + return $this->createActiveRelation([ 'modelClass' => $class, 'primaryModel' => $this, 'link' => $link, @@ -525,6 +523,18 @@ class ActiveRecord extends Model } /** + * Creates an [[ActiveRelation]] instance. + * This method is called by [[hasOne()]] and [[hasMany()]] to create a relation instance. + * You may override this method to return a customized relation. + * @param array $config the configuration passed to the ActiveRelation class. + * @return ActiveRelation the newly created [[ActiveRelation]] instance. + */ + protected function createActiveRelation($config = []) + { + return new ActiveRelation($config); + } + + /** * Populates the named relation with the related records. * Note that this method does not check if the relation exists or not. * @param string $name the relation name (case-sensitive) @@ -1287,7 +1297,7 @@ class ActiveRecord extends Model $getter = 'get' . $name; try { $relation = $this->$getter(); - if ($relation instanceof $this->relationClassName) { + if ($relation instanceof ActiveRelationInterface) { return $relation; } else { return null; diff --git a/framework/yii/db/ActiveRelation.php b/framework/yii/db/ActiveRelation.php index 13ceb14..7bc449a 100644 --- a/framework/yii/db/ActiveRelation.php +++ b/framework/yii/db/ActiveRelation.php @@ -7,6 +7,8 @@ */ namespace yii\db; +use yii\ar\ActiveRelationInterface; +use yii\ar\ActiveRelationTrait; /** * ActiveRelation represents a relation between two Active Record classes. @@ -24,17 +26,12 @@ namespace yii\db; * or [[viaTable()]] to set this property instead of directly setting it. * * @author Qiang Xue + * @author Carsten Brandt * @since 2.0 */ -class ActiveRelation extends ActiveQuery +class ActiveRelation extends ActiveQuery implements ActiveRelationInterface { - use \yii\ar\ActiveRelationTrait; - - /** - * @var array|ActiveRelation the query associated with the pivot table. Please call [[via()]] - * or [[viaTable()]] to set this property instead of directly setting it. - */ - public $via; + use ActiveRelationTrait; /** * Specifies the pivot table. diff --git a/framework/yii/db/Query.php b/framework/yii/db/Query.php index 0a26fd9..0ae5f44 100644 --- a/framework/yii/db/Query.php +++ b/framework/yii/db/Query.php @@ -33,24 +33,14 @@ use yii\base\Component; * ~~~ * * @author Qiang Xue + * @author Carsten Brandt * @since 2.0 */ -class Query extends Component +class Query extends Component implements QueryInterface { use QueryTrait; /** - * Sort ascending - * @see orderBy() - */ - const SORT_ASC = false; - /** - * Sort descending - * @see orderBy() - */ - const SORT_DESC = true; - - /** * @var array the columns being selected. For example, `['id', 'name']`. * This is used to construct the SELECT clause in a SQL statement. If not set, if means selecting all columns. * @see select() @@ -189,13 +179,13 @@ class Query extends Component /** * Returns the number of records. + * @param Connection $db the database connection used to generate the SQL statement. + * If this parameter is not given (or null), the `db` application component will be used. * @param string $q the COUNT expression. Defaults to '*'. * Make sure you properly quote column names in the expression. - * @param Connection $db the database connection used to generate the SQL statement. - * If this parameter is not given, the `db` application component will be used. * @return integer number of records */ - public function count($q = '*', $db = null) + public function count($db = null, $q = '*') { $this->select = ["COUNT($q)"]; return $this->createCommand($db)->queryScalar(); diff --git a/framework/yii/db/QueryBuilder.php b/framework/yii/db/QueryBuilder.php index 09948c8..0a547ae 100644 --- a/framework/yii/db/QueryBuilder.php +++ b/framework/yii/db/QueryBuilder.php @@ -683,7 +683,7 @@ class QueryBuilder extends \yii\base\Object if (is_object($direction)) { $orders[] = (string)$direction; } else { - $orders[] = $this->db->quoteColumnName($name) . ($direction === Query::SORT_DESC ? ' DESC' : ''); + $orders[] = $this->db->quoteColumnName($name) . ($direction === SORT_DESC ? ' DESC' : ''); } } diff --git a/framework/yii/db/QueryInterface.php b/framework/yii/db/QueryInterface.php new file mode 100644 index 0000000..d13fa2b --- /dev/null +++ b/framework/yii/db/QueryInterface.php @@ -0,0 +1,205 @@ + + * @author Carsten Brandt + * @since 2.0 + */ +interface QueryInterface +{ + /** + * Executes the query and returns all results as an array. + * @param Connection $db the database connection used to execute the query. + * If this parameter is not given, the `db` application component will be used. + * @return array the query results. If the query results in nothing, an empty array will be returned. + */ + public function all($db = null); + + /** + * Executes the query and returns a single row of result. + * @param Connection $db the database connection used to execute the query. + * If this parameter is not given, the `db` application component will be used. + * @return array|boolean the first row (in terms of an array) of the query result. False is returned if the query + * results in nothing. + */ + public function one($db = null); + + /** + * Returns the number of records. + * @param Connection $db the database connection used to execute the query. + * If this parameter is not given, the `db` application component will be used. + * @return integer number of records + */ + public function count($db = null); + + /** + * Returns a value indicating whether the query result contains any row of data. + * @param Connection $db the database connection used to execute the query. + * If this parameter is not given, the `db` application component will be used. + * @return boolean whether the query result contains any row of data. + */ + public function exists($db = null); + + /** + * Sets the [[indexBy]] property. + * @param string|callable $column the name of the column by which the query results should be indexed by. + * This can also be a callable (e.g. anonymous function) that returns the index value based on the given + * row data. The signature of the callable should be: + * + * ~~~ + * function ($row) + * { + * // return the index value corresponding to $row + * } + * ~~~ + * + * @return static the query object itself + */ + public function indexBy($column); + + /** + * Sets the WHERE part of the query. + * + * The method requires a $condition parameter. + * + * The $condition parameter should be an array in one of the following two formats: + * + * - hash format: `['column1' => value1, 'column2' => value2, ...]` + * - operator format: `[operator, operand1, operand2, ...]` + * + * A condition in hash format represents the following SQL expression in general: + * `column1=value1 AND column2=value2 AND ...`. In case when a value is an array, + * an `IN` expression will be generated. And if a value is null, `IS NULL` will be used + * in the generated expression. Below are some examples: + * + * - `['type' => 1, 'status' => 2]` generates `(type = 1) AND (status = 2)`. + * - `['id' => [1, 2, 3], 'status' => 2]` generates `(id IN (1, 2, 3)) AND (status = 2)`. + * - `['status' => null] generates `status IS NULL`. + * + * A condition in operator format generates the SQL expression according to the specified operator, which + * can be one of the followings: + * + * - `and`: the operands should be concatenated together using `AND`. For example, + * `['and', 'id=1', 'id=2']` will generate `id=1 AND id=2`. If an operand is an array, + * it will be converted into a string using the rules described here. For example, + * `['and', 'type=1', ['or', 'id=1', 'id=2']]` will generate `type=1 AND (id=1 OR id=2)`. + * The method will NOT do any quoting or escaping. + * + * - `or`: similar to the `and` operator except that the operands are concatenated using `OR`. + * + * - `between`: operand 1 should be the column name, and operand 2 and 3 should be the + * starting and ending values of the range that the column is in. + * For example, `['between', 'id', 1, 10]` will generate `id BETWEEN 1 AND 10`. + * + * - `not between`: similar to `between` except the `BETWEEN` is replaced with `NOT BETWEEN` + * in the generated condition. + * + * - `in`: operand 1 should be a column or DB expression, and operand 2 be an array representing + * the range of the values that the column or DB expression should be in. For example, + * `['in', 'id', [1, 2, 3]]` will generate `id IN (1, 2, 3)`. + * The method will properly quote the column name and escape values in the range. + * + * - `not in`: similar to the `in` operator except that `IN` is replaced with `NOT IN` in the generated condition. + * + * - `like`: operand 1 should be a column or DB expression, and operand 2 be a string or an array representing + * the values that the column or DB expression should be like. + * For example, `['like', 'name', '%tester%']` will generate `name LIKE '%tester%'`. + * When the value range is given as an array, multiple `LIKE` predicates will be generated and concatenated + * using `AND`. For example, `['like', 'name', ['%test%', '%sample%']]` will generate + * `name LIKE '%test%' AND name LIKE '%sample%'`. + * The method will properly quote the column name and escape values in the range. + * + * - `or like`: similar to the `like` operator except that `OR` is used to concatenate the `LIKE` + * predicates when operand 2 is an array. + * + * - `not like`: similar to the `like` operator except that `LIKE` is replaced with `NOT LIKE` + * in the generated condition. + * + * - `or not like`: similar to the `not like` operator except that `OR` is used to concatenate + * the `NOT LIKE` predicates. + * + * @param array $condition the conditions that should be put in the WHERE part. + * @return static the query object itself + * @see andWhere() + * @see orWhere() + */ + public function where($condition); + + /** + * Adds an additional WHERE condition to the existing one. + * The new condition and the existing one will be joined using the 'AND' operator. + * @param string|array $condition the new WHERE condition. Please refer to [[where()]] + * on how to specify this parameter. + * @return static the query object itself + * @see where() + * @see orWhere() + */ + public function andWhere($condition); + + /** + * Adds an additional WHERE condition to the existing one. + * The new condition and the existing one will be joined using the 'OR' operator. + * @param string|array $condition the new WHERE condition. Please refer to [[where()]] + * on how to specify this parameter. + * @return static the query object itself + * @see where() + * @see andWhere() + */ + public function orWhere($condition); + + /** + * Sets the ORDER BY part of the query. + * @param string|array $columns the columns (and the directions) to be ordered by. + * Columns can be specified in either a string (e.g. "id ASC, name DESC") or an array + * (e.g. `['id' => SORT_ASC, 'name' => SORT_DESC]`). + * The method will automatically quote the column names unless a column contains some parenthesis + * (which means the column contains a DB expression). + * @return static the query object itself + * @see addOrderBy() + */ + public function orderBy($columns); + + /** + * Adds additional ORDER BY columns to the query. + * @param string|array $columns the columns (and the directions) to be ordered by. + * Columns can be specified in either a string (e.g. "id ASC, name DESC") or an array + * (e.g. `['id' => SORT_ASC, 'name' => SORT_DESC]`). + * The method will automatically quote the column names unless a column contains some parenthesis + * (which means the column contains a DB expression). + * @return static the query object itself + * @see orderBy() + */ + public function addOrderBy($columns); + + /** + * Sets the LIMIT part of the query. + * @param integer $limit the limit. Use null or negative value to disable limit. + * @return static the query object itself + */ + public function limit($limit); + + /** + * Sets the OFFSET part of the query. + * @param integer $offset the offset. Use null or negative value to disable offset. + * @return static the query object itself + */ + public function offset($offset); +} \ No newline at end of file diff --git a/framework/yii/db/QueryTrait.php b/framework/yii/db/QueryTrait.php index 92051ab..a963869 100644 --- a/framework/yii/db/QueryTrait.php +++ b/framework/yii/db/QueryTrait.php @@ -7,18 +7,6 @@ namespace yii\db; -// TODO where to put these constants? -/** - * Sort ascending - * @see orderBy - */ -const SORT_ASC = false; -/** - * Sort descending - * @see orderBy - */ -const SORT_DESC = true; - /** * The BaseQuery trait represents the minimum method set of a database Query. * @@ -53,8 +41,10 @@ trait QueryTrait /** * @var array how to sort the query results. This is used to construct the ORDER BY clause in a SQL statement. * The array keys are the columns to be sorted by, and the array values are the corresponding sort directions which - * can be either [[Query::SORT_ASC]] or [[Query::SORT_DESC]]. The array may also contain [[Expression]] objects. - * If that is the case, the expressions will be converted into strings without any change. + * can be either [SORT_ASC](http://php.net/manual/en/array.constants.php#constant.sort-asc) + * or [SORT_DESC](http://php.net/manual/en/array.constants.php#constant.sort-desc). + * The array may also contain [[Expression]] objects. If that is the case, the expressions + * will be converted into strings without any change. */ public $orderBy; /** @@ -86,90 +76,9 @@ trait QueryTrait } /** - * Executes the query and returns all results as an array. - * @return array the query results. If the query results in nothing, an empty array will be returned. - */ - abstract public function all(); - - /** - * Executes the query and returns a single row of result. - * @return array|boolean the first row (in terms of an array) of the query result. False is returned if the query - * results in nothing. - */ - abstract public function one(); - - /** - * Returns the number of records. - * @return integer number of records - */ - abstract public function count(); - - /** - * Returns a value indicating whether the query result contains any row of data. - * @return boolean whether the query result contains any row of data. - */ - abstract public function exists(); - - /** * Sets the WHERE part of the query. * - * The method requires a $condition parameter. - * - * The $condition parameter should be an array in one of the following two formats: - * - * - hash format: `['column1' => value1, 'column2' => value2, ...]` - * - operator format: `[operator, operand1, operand2, ...]` - * - * A condition in hash format represents the following SQL expression in general: - * `column1=value1 AND column2=value2 AND ...`. In case when a value is an array, - * an `IN` expression will be generated. And if a value is null, `IS NULL` will be used - * in the generated expression. Below are some examples: - * - * - `['type' => 1, 'status' => 2]` generates `(type = 1) AND (status = 2)`. - * - `['id' => [1, 2, 3], 'status' => 2]` generates `(id IN (1, 2, 3)) AND (status = 2)`. - * - `['status' => null] generates `status IS NULL`. - * - * A condition in operator format generates the SQL expression according to the specified operator, which - * can be one of the followings: - * - * - `and`: the operands should be concatenated together using `AND`. For example, - * `['and', 'id=1', 'id=2']` will generate `id=1 AND id=2`. If an operand is an array, - * it will be converted into a string using the rules described here. For example, - * `['and', 'type=1', ['or', 'id=1', 'id=2']]` will generate `type=1 AND (id=1 OR id=2)`. - * The method will NOT do any quoting or escaping. - * - * - `or`: similar to the `and` operator except that the operands are concatenated using `OR`. - * - * - `between`: operand 1 should be the column name, and operand 2 and 3 should be the - * starting and ending values of the range that the column is in. - * For example, `['between', 'id', 1, 10]` will generate `id BETWEEN 1 AND 10`. - * - * - `not between`: similar to `between` except the `BETWEEN` is replaced with `NOT BETWEEN` - * in the generated condition. - * - * - `in`: operand 1 should be a column or DB expression, and operand 2 be an array representing - * the range of the values that the column or DB expression should be in. For example, - * `['in', 'id', [1, 2, 3]]` will generate `id IN (1, 2, 3)`. - * The method will properly quote the column name and escape values in the range. - * - * - `not in`: similar to the `in` operator except that `IN` is replaced with `NOT IN` in the generated condition. - * - * - `like`: operand 1 should be a column or DB expression, and operand 2 be a string or an array representing - * the values that the column or DB expression should be like. - * For example, `['like', 'name', '%tester%']` will generate `name LIKE '%tester%'`. - * When the value range is given as an array, multiple `LIKE` predicates will be generated and concatenated - * using `AND`. For example, `['like', 'name', ['%test%', '%sample%']]` will generate - * `name LIKE '%test%' AND name LIKE '%sample%'`. - * The method will properly quote the column name and escape values in the range. - * - * - `or like`: similar to the `like` operator except that `OR` is used to concatenate the `LIKE` - * predicates when operand 2 is an array. - * - * - `not like`: similar to the `like` operator except that `LIKE` is replaced with `NOT LIKE` - * in the generated condition. - * - * - `or not like`: similar to the `not like` operator except that `OR` is used to concatenate - * the `NOT LIKE` predicates. + * See [[QueryInterface::where()]] for detailed documentation. * * @param array $condition the conditions that should be put in the WHERE part. * @return static the query object itself @@ -224,7 +133,7 @@ trait QueryTrait * Sets the ORDER BY part of the query. * @param string|array $columns the columns (and the directions) to be ordered by. * Columns can be specified in either a string (e.g. "id ASC, name DESC") or an array - * (e.g. `['id' => Query::SORT_ASC, 'name' => Query::SORT_DESC]`). + * (e.g. `['id' => SORT_ASC, 'name' => SORT_DESC]`). * The method will automatically quote the column names unless a column contains some parenthesis * (which means the column contains a DB expression). * @return static the query object itself @@ -240,7 +149,7 @@ trait QueryTrait * Adds additional ORDER BY columns to the query. * @param string|array $columns the columns (and the directions) to be ordered by. * Columns can be specified in either a string (e.g. "id ASC, name DESC") or an array - * (e.g. `['id' => Query::SORT_ASC, 'name' => Query::SORT_DESC]`). + * (e.g. `['id' => SORT_ASC, 'name' => SORT_DESC]`). * The method will automatically quote the column names unless a column contains some parenthesis * (which means the column contains a DB expression). * @return static the query object itself @@ -266,9 +175,9 @@ trait QueryTrait $result = []; foreach ($columns as $column) { if (preg_match('/^(.*?)\s+(asc|desc)$/i', $column, $matches)) { - $result[$matches[1]] = strcasecmp($matches[2], 'desc') ? self::SORT_ASC : self::SORT_DESC; + $result[$matches[1]] = strcasecmp($matches[2], 'desc') ? SORT_ASC : SORT_DESC; } else { - $result[$column] = self::SORT_ASC; + $result[$column] = SORT_ASC; } } return $result;