Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
Y
yii2
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
PSDI Army
yii2
Commits
1978a4ef
Commit
1978a4ef
authored
Jan 30, 2012
by
Qiang Xue
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
...
parent
e5534b3c
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
1283 additions
and
832 deletions
+1283
-832
YiiBase.php
framework/YiiBase.php
+14
-14
Object.php
framework/base/Object.php
+13
-14
ActiveQuery.php
framework/db/ar/ActiveQuery.php
+513
-29
ActiveQueryBuilder.php
framework/db/ar/ActiveQueryBuilder.php
+18
-0
ActiveRecord.php
framework/db/ar/ActiveRecord.php
+12
-16
BaseQuery.php
framework/db/dao/BaseQuery.php
+0
-724
Query.php
framework/db/dao/Query.php
+683
-2
QueryBuilder.php
framework/db/dao/QueryBuilder.php
+30
-33
No files found.
framework/YiiBase.php
View file @
1978a4ef
...
...
@@ -358,25 +358,25 @@ class YiiBase
$class
=
static
::
import
(
$class
,
true
);
}
if
((
$n
=
func_num_args
()
-
1
)
>
0
)
{
if
((
$n
=
func_num_args
()
)
>
1
)
{
$args
=
func_get_args
();
array_shift
(
$args
);
// remove $config
}
if
(
$n
===
0
)
{
$object
=
new
$class
;
}
elseif
(
$n
===
1
)
{
$object
=
new
$class
(
$args
[
0
]);
}
elseif
(
$n
===
2
)
{
$object
=
new
$class
(
$args
[
0
],
$args
[
1
]
);
}
elseif
(
$n
===
3
)
{
$object
=
new
$class
(
$args
[
0
],
$args
[
1
],
$args
[
2
]);
if
(
$n
===
2
)
{
$object
=
new
$class
(
$args
[
1
]);
}
elseif
(
$n
===
3
)
{
$object
=
new
$class
(
$args
[
1
],
$args
[
2
]);
}
elseif
(
$n
===
4
)
{
$object
=
new
$class
(
$args
[
1
],
$args
[
2
],
$args
[
3
]);
}
else
{
array_shift
(
$args
);
// remove $config
$r
=
new
\ReflectionClass
(
$class
);
$object
=
$r
->
newInstanceArgs
(
$args
);
}
}
else
{
$r
=
new
\ReflectionClass
(
$class
);
$object
=
$r
->
newInstanceArgs
(
$args
);
$object
=
new
$class
;
}
$class
=
'\\'
.
get_class
(
$object
);
if
(
isset
(
\Yii
::
$objectConfig
[
$class
]))
{
$config
=
array_merge
(
\Yii
::
$objectConfig
[
$class
],
$config
);
}
...
...
framework/base/Object.php
View file @
1978a4ef
...
...
@@ -302,22 +302,21 @@ class Object
{
$class
=
'\\'
.
get_called_class
();
if
((
$n
=
func_num_args
()
-
1
)
>
0
)
{
if
((
$n
=
func_num_args
()
)
>
1
)
{
$args
=
func_get_args
();
array_shift
(
$args
);
// remove $config
}
if
(
$n
===
0
)
{
$object
=
new
$class
;
}
elseif
(
$n
===
1
)
{
$object
=
new
$class
(
$args
[
0
]);
}
elseif
(
$n
===
2
)
{
$object
=
new
$class
(
$args
[
0
],
$args
[
1
]
);
}
elseif
(
$n
===
3
)
{
$object
=
new
$class
(
$args
[
0
],
$args
[
1
],
$args
[
2
]);
if
(
$n
===
2
)
{
$object
=
new
$class
(
$args
[
1
]);
}
elseif
(
$n
===
3
)
{
$object
=
new
$class
(
$args
[
1
],
$args
[
2
]);
}
elseif
(
$n
===
4
)
{
$object
=
new
$class
(
$args
[
1
],
$args
[
2
],
$args
[
3
]);
}
else
{
array_shift
(
$args
);
// remove $config
$r
=
new
\ReflectionClass
(
$class
);
$object
=
$r
->
newInstanceArgs
(
$args
);
}
}
else
{
$r
=
new
\ReflectionClass
(
$class
);
$object
=
$r
->
newInstanceArgs
(
$args
);
$object
=
new
$class
;
}
if
(
isset
(
\Yii
::
$objectConfig
[
$class
]))
{
...
...
framework/db/ar/ActiveQuery.php
View file @
1978a4ef
...
...
@@ -10,8 +10,8 @@
namespace
yii\db\ar
;
use
yii\db\dao\BaseQuery
;
use
yii\base\VectorIterator
;
use
yii\db\dao\Query
;
/**
* ActiveFinder.php is ...
...
...
@@ -20,31 +20,45 @@ use yii\base\VectorIterator;
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class
ActiveQuery
extends
BaseQuery
implements
\IteratorAggregate
,
\ArrayAccess
,
\Countable
class
ActiveQuery
extends
\yii\base\Object
implements
\IteratorAggregate
,
\ArrayAccess
,
\Countable
{
public
$modelClass
;
/**
* @var \yii\db\dao\Query the Query object
*/
public
$query
;
public
$with
;
public
$
a
lias
;
public
$
tableA
lias
;
public
$indexBy
;
public
$asArray
;
public
$scopes
;
public
$records
;
public
$sql
;
public
function
__construct
(
$modelClass
)
{
$this
->
modelClass
=
$modelClass
;
$this
->
query
=
new
Query
;
}
public
function
all
(
$refresh
=
false
)
{
if
(
$this
->
records
===
null
||
$refresh
)
{
$this
->
records
=
$this
->
performQuery
();
$this
->
records
=
$this
->
findRecords
();
}
return
$this
->
records
;
}
public
function
one
(
$refresh
=
false
)
public
function
one
(
$refresh
=
false
,
$limitOne
=
true
)
{
if
(
$this
->
records
===
null
||
$refresh
)
{
$this
->
limit
=
1
;
$this
->
records
=
$this
->
performQuery
();
if
(
$limitOne
)
{
$this
->
limit
(
1
);
}
$this
->
records
=
$this
->
findRecords
();
}
if
(
isset
(
$this
->
records
[
0
]))
{
return
$this
->
records
[
0
];
...
...
@@ -53,6 +67,11 @@ class ActiveQuery extends BaseQuery implements \IteratorAggregate, \ArrayAccess,
}
}
public
function
exists
()
{
}
public
function
asArray
(
$value
=
true
)
{
$this
->
asArray
=
$value
;
...
...
@@ -71,9 +90,9 @@ class ActiveQuery extends BaseQuery implements \IteratorAggregate, \ArrayAccess,
return
$this
;
}
public
function
alias
(
$tableAlias
)
public
function
tableAlias
(
$value
)
{
$this
->
alias
=
$tableAlias
;
$this
->
tableAlias
=
$value
;
return
$this
;
}
...
...
@@ -123,7 +142,7 @@ class ActiveQuery extends BaseQuery implements \IteratorAggregate, \ArrayAccess,
public
function
getIterator
()
{
if
(
$this
->
records
===
null
)
{
$this
->
records
=
$this
->
performQuery
();
$this
->
records
=
$this
->
findRecords
();
}
return
new
VectorIterator
(
$this
->
records
);
}
...
...
@@ -142,7 +161,7 @@ class ActiveQuery extends BaseQuery implements \IteratorAggregate, \ArrayAccess,
return
$this
->
performCountQuery
();
}
else
{
if
(
$this
->
records
===
null
)
{
$this
->
records
=
$this
->
performQuery
();
$this
->
records
=
$this
->
findRecords
();
}
return
count
(
$this
->
records
);
}
...
...
@@ -158,7 +177,7 @@ class ActiveQuery extends BaseQuery implements \IteratorAggregate, \ArrayAccess,
public
function
offsetExists
(
$offset
)
{
if
(
$this
->
records
===
null
)
{
$this
->
records
=
$this
->
performQuery
();
$this
->
records
=
$this
->
findRecords
();
}
return
isset
(
$this
->
records
[
$offset
]);
}
...
...
@@ -175,7 +194,7 @@ class ActiveQuery extends BaseQuery implements \IteratorAggregate, \ArrayAccess,
public
function
offsetGet
(
$offset
)
{
if
(
$this
->
records
===
null
)
{
$this
->
records
=
$this
->
performQuery
();
$this
->
records
=
$this
->
findRecords
();
}
return
isset
(
$this
->
records
[
$offset
])
?
$this
->
records
[
$offset
]
:
null
;
}
...
...
@@ -194,7 +213,7 @@ class ActiveQuery extends BaseQuery implements \IteratorAggregate, \ArrayAccess,
public
function
offsetSet
(
$offset
,
$item
)
{
if
(
$this
->
records
===
null
)
{
$this
->
records
=
$this
->
performQuery
();
$this
->
records
=
$this
->
findRecords
();
}
$this
->
records
[
$offset
]
=
$item
;
}
...
...
@@ -210,37 +229,502 @@ class ActiveQuery extends BaseQuery implements \IteratorAggregate, \ArrayAccess,
public
function
offsetUnset
(
$offset
)
{
if
(
$this
->
records
===
null
)
{
$this
->
records
=
$this
->
performQuery
();
$this
->
records
=
$this
->
findRecords
();
}
unset
(
$this
->
records
[
$offset
]);
}
protected
function
performQuery
()
/**
* Sets the SELECT part of the query.
* @param mixed $columns the columns to be selected. Defaults to '*', meaning all columns.
* Columns can be specified in either a string (e.g. "id, name") or an array (e.g. array('id', 'name')).
* Columns can contain table prefixes (e.g. "tbl_user.id") and/or column aliases (e.g. "tbl_user.id AS user_id").
* The method will automatically quote the column names unless a column contains some parenthesis
* (which means the column contains a DB expression).
* @param string $option additional option that should be appended to the 'SELECT' keyword. For example,
* in MySQL, the option 'SQL_CALC_FOUND_ROWS' can be used.
* @return BaseQuery the query object itself
*/
public
function
select
(
$columns
=
'*'
,
$option
=
''
)
{
$db
=
$this
->
getDbConnection
();
$this
->
sql
=
$this
->
getSql
(
$db
);
$command
=
$db
->
createCommand
(
$this
->
sql
);
$command
->
bindValues
(
$this
->
params
);
$this
->
query
->
select
(
$columns
,
$option
);
return
$this
;
}
/**
* Sets the value indicating whether to SELECT DISTINCT or not.
* @param bool $value whether to SELECT DISTINCT or not.
* @return BaseQuery the query object itself
*/
public
function
distinct
(
$value
=
true
)
{
$this
->
query
->
distinct
(
$value
);
return
$this
;
}
/**
* Sets the FROM part of the query.
* @param mixed $tables the table(s) to be selected from. This can be either a string (e.g. 'tbl_user')
* or an array (e.g. array('tbl_user', 'tbl_profile')) specifying one or several table names.
* Table names can contain schema prefixes (e.g. 'public.tbl_user') and/or table aliases (e.g. 'tbl_user u').
* The method will automatically quote the table names unless it contains some parenthesis
* (which means the table is given as a sub-query or DB expression).
* @return BaseQuery the query object itself
*/
public
function
from
(
$tables
)
{
$this
->
query
->
from
(
$tables
);
return
$this
;
}
/**
* Sets the WHERE part of the query.
*
* The method requires a $condition parameter, and optionally a $params parameter
* specifying the values to be bound to the query.
*
* The $condition parameter should be either a string (e.g. 'id=1') or an array.
* If the latter, it must be in one of the following two formats:
*
* - hash format: `array('column1' => value1, 'column2' => value2, ...)`
* - operator format: `array(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:
*
* - `array('type'=>1, 'status'=>2)` generates `(type=1) AND (status=2)`.
* - `array('id'=>array(1,2,3), 'status'=>2)` generates `(id IN (1,2,3)) AND (status=2)`.
* - `array('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,
* `array('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,
* `array('and', 'type=1', array('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, `array('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,
* `array('in', 'id', array(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, `array('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, `array('like', 'name', array('%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 string|array $condition the conditions that should be put in the WHERE part.
* @param array $params the parameters (name=>value) to be bound to the query.
* For anonymous parameters, they can alternatively be specified as separate parameters to this method.
* For example, `where('type=? AND status=?', 100, 1)`.
* @return BaseQuery the query object itself
* @see andWhere()
* @see orWhere()
*/
public
function
where
(
$condition
,
$params
=
array
())
{
if
(
is_array
(
$params
))
{
$this
->
query
->
where
(
$condition
,
$params
);
}
else
{
call_user_func_array
(
array
(
$this
->
query
,
__FUNCTION__
),
func_get_args
());
}
return
$this
;
}
/**
* 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.
* @param array $params the parameters (name=>value) to be bound to the query.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* @return BaseQuery the query object itself
* @see where()
* @see orWhere()
*/
public
function
andWhere
(
$condition
,
$params
=
array
())
{
if
(
is_array
(
$params
))
{
$this
->
query
->
andWhere
(
$condition
,
$params
);
}
else
{
call_user_func_array
(
array
(
$this
->
query
,
__FUNCTION__
),
func_get_args
());
}
return
$this
;
}
/**
* 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.
* @param array $params the parameters (name=>value) to be bound to the query.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* @return BaseQuery the query object itself
* @see where()
* @see andWhere()
*/
public
function
orWhere
(
$condition
,
$params
=
array
())
{
if
(
is_array
(
$params
))
{
$this
->
query
->
orWhere
(
$condition
,
$params
);
}
else
{
call_user_func_array
(
array
(
$this
->
query
,
__FUNCTION__
),
func_get_args
());
}
return
$this
;
}
/**
* Appends an INNER JOIN part to the query.
* @param string $table the table to be joined.
* Table name can contain schema prefix (e.g. 'public.tbl_user') and/or table alias (e.g. 'tbl_user u').
* The method will automatically quote the table name unless it contains some parenthesis
* (which means the table is given as a sub-query or DB expression).
* @param string|array $condition the join condition that should appear in the ON part.
* Please refer to [[where()]] on how to specify this parameter.
* @param array $params the parameters (name=>value) to be bound to the query.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* @return BaseQuery the query object itself
*/
public
function
join
(
$table
,
$condition
,
$params
=
array
())
{
if
(
is_array
(
$params
))
{
$this
->
query
->
join
(
$table
,
$condition
,
$params
);
}
else
{
call_user_func_array
(
array
(
$this
->
query
,
__FUNCTION__
),
func_get_args
());
}
return
$this
;
}
/**
* Appends a LEFT OUTER JOIN part to the query.
* @param string $table the table to be joined.
* Table name can contain schema prefix (e.g. 'public.tbl_user') and/or table alias (e.g. 'tbl_user u').
* The method will automatically quote the table name unless it contains some parenthesis
* (which means the table is given as a sub-query or DB expression).
* @param string|array $condition the join condition that should appear in the ON part.
* Please refer to [[where()]] on how to specify this parameter.
* @param array $params the parameters (name=>value) to be bound to the query
* @return BaseQuery the query object itself
*/
public
function
leftJoin
(
$table
,
$condition
,
$params
=
array
())
{
if
(
is_array
(
$params
))
{
$this
->
query
->
leftJoin
(
$table
,
$condition
,
$params
);
}
else
{
call_user_func_array
(
array
(
$this
->
query
,
__FUNCTION__
),
func_get_args
());
}
return
$this
;
}
/**
* Appends a RIGHT OUTER JOIN part to the query.
* @param string $table the table to be joined.
* Table name can contain schema prefix (e.g. 'public.tbl_user') and/or table alias (e.g. 'tbl_user u').
* The method will automatically quote the table name unless it contains some parenthesis
* (which means the table is given as a sub-query or DB expression).
* @param string|array $condition the join condition that should appear in the ON part.
* Please refer to [[where()]] on how to specify this parameter.
* @param array $params the parameters (name=>value) to be bound to the query
* @return BaseQuery the query object itself
*/
public
function
rightJoin
(
$table
,
$condition
,
$params
=
array
())
{
if
(
is_array
(
$params
))
{
$this
->
query
->
rightJoin
(
$table
,
$condition
,
$params
);
}
else
{
call_user_func_array
(
array
(
$this
->
query
,
__FUNCTION__
),
func_get_args
());
}
return
$this
;
}
/**
* Appends a CROSS JOIN part to the query.
* Note that not all DBMS support CROSS JOIN.
* @param string $table the table to be joined.
* Table name can contain schema prefix (e.g. 'public.tbl_user') and/or table alias (e.g. 'tbl_user u').
* The method will automatically quote the table name unless it contains some parenthesis
* (which means the table is given as a sub-query or DB expression).
* @return BaseQuery the query object itself
*/
public
function
crossJoin
(
$table
)
{
$this
->
query
->
crossJoin
(
$table
);
return
$this
;
}
/**
* Appends a NATURAL JOIN part to the query.
* Note that not all DBMS support NATURAL JOIN.
* @param string $table the table to be joined.
* Table name can contain schema prefix (e.g. 'public.tbl_user') and/or table alias (e.g. 'tbl_user u').
* The method will automatically quote the table name unless it contains some parenthesis
* (which means the table is given as a sub-query or DB expression).
* @return BaseQuery the query object itself
*/
public
function
naturalJoin
(
$table
)
{
$this
->
query
->
naturalJoin
(
$table
);
return
$this
;
}
/**
* Sets the GROUP BY part of the query.
* @param string|array $columns the columns to be grouped by.
* Columns can be specified in either a string (e.g. "id, name") or an array (e.g. array('id', 'name')).
* The method will automatically quote the column names unless a column contains some parenthesis
* (which means the column contains a DB expression).
* @return BaseQuery the query object itself
* @see addGroupBy()
*/
public
function
groupBy
(
$columns
)
{
$this
->
query
->
groupBy
(
$columns
);
return
$this
;
}
/**
* Adds additional group-by columns to the existing ones.
* @param string|array $columns additional columns to be grouped by.
* Columns can be specified in either a string (e.g. "id, name") or an array (e.g. array('id', 'name')).
* The method will automatically quote the column names unless a column contains some parenthesis
* (which means the column contains a DB expression).
* @return BaseQuery the query object itself
* @see groupBy()
*/
public
function
addGroupBy
(
$columns
)
{
$this
->
query
->
addGroupBy
(
$columns
);
return
$this
;
}
/**
* Sets the HAVING part of the query.
* @param string|array $condition the conditions to be put after HAVING.
* Please refer to [[where()]] on how to specify this parameter.
* @param array $params the parameters (name=>value) to be bound to the query.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* @return BaseQuery the query object itself
* @see andHaving()
* @see orHaving()
*/
public
function
having
(
$condition
,
$params
=
array
())
{
if
(
is_array
(
$params
))
{
$this
->
query
->
having
(
$condition
,
$params
);
}
else
{
call_user_func_array
(
array
(
$this
->
query
,
__FUNCTION__
),
func_get_args
());
}
return
$this
;
}
/**
* Adds an additional HAVING 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 HAVING condition. Please refer to [[where()]]
* on how to specify this parameter.
* @param array $params the parameters (name=>value) to be bound to the query.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* @return BaseQuery the query object itself
* @see having()
* @see orHaving()
*/
public
function
andHaving
(
$condition
,
$params
=
array
())
{
if
(
is_array
(
$params
))
{
$this
->
query
->
andHaving
(
$condition
,
$params
);
}
else
{
call_user_func_array
(
array
(
$this
->
query
,
__FUNCTION__
),
func_get_args
());
}
return
$this
;
}
/**
* Adds an additional HAVING 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 HAVING condition. Please refer to [[where()]]
* on how to specify this parameter.
* @param array $params the parameters (name=>value) to be bound to the query.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* @return BaseQuery the query object itself
* @see having()
* @see andHaving()
*/
public
function
orHaving
(
$condition
,
$params
=
array
())
{
if
(
is_array
(
$params
))
{
$this
->
query
->
orHaving
(
$condition
,
$params
);
}
else
{
call_user_func_array
(
array
(
$this
->
query
,
__FUNCTION__
),
func_get_args
());
}
return
$this
;
}
/**
* 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. array('id ASC', 'name DESC')).
* The method will automatically quote the column names unless a column contains some parenthesis
* (which means the column contains a DB expression).
* @return BaseQuery the query object itself
* @see addOrderBy()
*/
public
function
orderBy
(
$columns
)
{
$this
->
query
->
orderBy
(
$columns
);
return
$this
;
}
/**
* 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. array('id ASC', 'name DESC')).
* The method will automatically quote the column names unless a column contains some parenthesis
* (which means the column contains a DB expression).
* @return BaseQuery the query object itself
* @see orderBy()
*/
public
function
addOrderBy
(
$columns
)
{
$this
->
query
->
addOrderBy
(
$columns
);
return
$this
;
}
/**
* Sets the LIMIT part of the query.
* @param integer $limit the limit
* @return BaseQuery the query object itself
*/
public
function
limit
(
$limit
)
{
$this
->
query
->
limit
(
$limit
);
return
$this
;
}
/**
* Sets the OFFSET part of the query.
* @param integer $offset the offset
* @return BaseQuery the query object itself
*/
public
function
offset
(
$offset
)
{
$this
->
query
->
offset
(
$offset
);
return
$this
;
}
/**
* Appends a SQL statement using UNION operator.
* @param string|Query $sql the SQL statement to be appended using UNION
* @return BaseQuery the query object itself
*/
public
function
union
(
$sql
)
{
$this
->
query
->
union
(
$sql
);
return
$this
;
}
/**
* Sets the parameters to be bound to the query.
* @param array list of query parameter values indexed by parameter placeholders.
* For example, `array(':name'=>'Dan', ':age'=>31)`.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* @return BaseQuery the query object itself
* @see addParams()
*/
public
function
params
(
$params
)
{
$this
->
query
->
params
(
$params
);
return
$this
;
}
/**
* Adds additional parameters to be bound to the query.
* @param array list of query parameter values indexed by parameter placeholders.
* For example, `array(':name'=>'Dan', ':age'=>31)`.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* @return BaseQuery the query object itself
* @see params()
*/
public
function
addParams
(
$params
)
{
$this
->
query
->
addParams
(
$params
);
return
$this
;
}
protected
function
findRecords
()
{
/*
* public $with;
*/
if
(
$this
->
query
->
from
===
null
)
{
$modelClass
=
$this
->
modelClass
;
$this
->
query
->
from
=
$modelClass
::
tableName
();
if
(
$this
->
tableAlias
!==
null
)
{
$this
->
query
->
from
.=
$this
->
tableAlias
;
}
}
$command
=
$this
->
query
->
createCommand
(
$this
->
getDbConnection
());
$this
->
sql
=
$command
->
getSql
();
$rows
=
$command
->
queryAll
();
if
(
$this
->
asArray
)
{
$records
=
$rows
;
if
(
$this
->
indexBy
===
null
)
{
return
$rows
;
}
$records
=
array
();
foreach
(
$rows
as
$row
)
{
$records
[
$row
[
$this
->
indexBy
]]
=
$row
;
}
return
$records
;
}
else
{
$records
=
array
();
$class
=
$this
->
modelClass
;
foreach
(
$rows
as
$row
)
{
$records
[]
=
$class
::
populateData
(
$row
);
if
(
$this
->
indexBy
===
null
)
{
foreach
(
$rows
as
$row
)
{
$records
[]
=
$class
::
populateData
(
$row
);
}
}
else
{
$attribute
=
$this
->
indexBy
;
foreach
(
$rows
as
$row
)
{
$record
=
$class
::
populateData
(
$row
);
$records
[
$record
->
$attribute
]
=
$record
;
}
}
return
$records
;
}
return
$records
;
}
protected
function
performCountQuery
()
{
$this
->
select
=
'COUNT(*)'
;
$class
=
$this
->
modelClass
;
$command
=
$this
->
createCommand
(
$class
::
getDbConnection
());
$this
->
query
->
select
=
'COUNT(*)'
;
$command
=
$this
->
query
->
createCommand
(
$this
->
getDbConnection
());
$this
->
sql
=
$command
->
getSql
();
$count
=
$command
->
queryScalar
();
return
$count
;
return
$command
->
queryScalar
();
}
}
framework/db/ar/ActiveQueryBuilder.php
View file @
1978a4ef
...
...
@@ -17,5 +17,22 @@ namespace yii\db\ar;
*/
class
ActiveQueryBuilder
extends
\yii\base\Object
{
/**
* @var \yii\db\dao\QueryBuilder
*/
public
$queryBuilder
;
/**
* @var ActiveQuery
*/
public
$query
;
public
function
__construct
(
$query
)
{
$this
->
query
=
$query
;
}
public
function
build
()
{
}
}
\ No newline at end of file
framework/db/ar/ActiveRecord.php
View file @
1978a4ef
...
...
@@ -53,23 +53,25 @@ abstract class ActiveRecord extends \yii\base\Model
/**
* @static
* @param string|array|
Active
Query $q
* @param string|array|Query $q
* @return ActiveQuery
* @throws \yii\db\Exception
*/
public
static
function
find
(
$q
=
null
)
{
$query
=
$q
instanceof
ActiveQuery
?
$q
:
static
::
createQuery
();
$query
->
modelClass
=
'\\'
.
get_called_class
();
$query
->
from
=
static
::
tableName
();
if
(
is_array
(
$q
))
{
$query
=
static
::
createActiveQuery
();
if
(
$q
instanceof
Query
)
{
$query
->
query
=
$q
;
}
elseif
(
is_array
(
$q
))
{
// query by attributes
$query
->
where
(
$q
);
}
elseif
(
$q
!==
null
&&
$query
!==
$q
)
{
}
elseif
(
$q
!==
null
)
{
// query by primary key
$primaryKey
=
static
::
getMetaData
()
->
table
->
primaryKey
;
if
(
is_string
(
$primaryKey
))
{
$query
->
where
(
array
(
$primaryKey
=>
$q
));
}
else
{
throw
new
Exception
(
"Multiple column values are required to find by composite primary keys."
);
throw
new
Exception
(
'Composite primary keys require multiple column values.'
);
}
}
return
$query
;
...
...
@@ -77,21 +79,15 @@ abstract class ActiveRecord extends \yii\base\Model
public
static
function
findBySql
(
$sql
,
$params
=
array
())
{
$query
=
static
::
createQuery
();
if
(
!
is_array
(
$params
))
{
$params
=
func_get_args
();
array_shift
(
$params
);
}
$query
->
setSql
(
$sql
);
$query
->
modelClass
=
'\\'
.
get_called_class
()
;
$query
=
static
::
createActiveQuery
(
);
$query
->
sql
=
$sql
;
return
$query
->
params
(
$params
);
}
public
static
function
exists
(
$condition
,
$params
)
{
}
public
static
function
updateAll
()
{
...
...
@@ -107,7 +103,7 @@ abstract class ActiveRecord extends \yii\base\Model
}
public
static
function
createQuery
()
public
static
function
create
Active
Query
()
{
return
new
ActiveQuery
(
'\\'
.
get_called_class
());
}
...
...
framework/db/dao/BaseQuery.php
deleted
100644 → 0
View file @
e5534b3c
<?php
/**
* BaseQuery class file.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.yiiframework.com/
* @copyright Copyright © 2008-2012 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace
yii\db\dao
;
/**
* BaseQuery represents a SQL statement in a way that is independent of DBMS.
*
* BaseQuery not only can represent a SELECT statement, it can also represent INSERT, UPDATE, DELETE,
* and other commonly used DDL statements, such as CREATE TABLE, CREATE INDEX, etc.
*
* BaseQuery provides a set of methods to facilitate the specification of different clauses.
* These methods can be chained together. For example,
*
* ~~~
* $query = new Query;
* $query->select('id, name')
* ->from('tbl_user')
* ->limit(10);
* // get the actual SQL statement
* echo $query->getSql();
* // or execute the query
* $users = $query->createCommand()->queryAll();
* ~~~
*
* By calling [[getSql()]], we can obtain the actual SQL statement from a Query object.
* And by calling [[createCommand()]], we can get a [[Command]] instance which can be further
* used to perform/execute the DB query against a database.
*
* @property string $sql the SQL statement represented by this query object.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class
BaseQuery
extends
\yii\base\Object
{
/**
* @var string|array the columns being selected. This refers to the SELECT clause in a SQL
* statement. It can be either a string (e.g. `'id, name'`) or an array (e.g. `array('id', 'name')`).
* If not set, if means all columns.
* @see select()
*/
public
$select
;
/**
* @var string additional option that should be appended to the 'SELECT' keyword. For example,
* in MySQL, the option 'SQL_CALC_FOUND_ROWS' can be used.
*/
public
$selectOption
;
/**
* @var boolean whether to select distinct rows of data only. If this is set true,
* the SELECT clause would be changed to SELECT DISTINCT.
*/
public
$distinct
;
/**
* @var string|array the table(s) to be selected from. This refers to the FROM clause in a SQL statement.
* It can be either a string (e.g. `'tbl_user, tbl_post'`) or an array (e.g. `array('tbl_user', 'tbl_post')`).
* @see from()
*/
public
$from
;
/**
* @var string|array query condition. This refers to the WHERE clause in a SQL statement.
* For example, `age > 31 AND team = 1`.
* @see where()
*/
public
$where
;
/**
* @var integer maximum number of records to be returned. If not set or less than 0, it means no limit.
*/
public
$limit
;
/**
* @var integer zero-based offset from where the records are to be returned. If not set or
* less than 0, it means starting from the beginning.
*/
public
$offset
;
/**
* @var string|array how to sort the query results. This refers to the ORDER BY clause in a SQL statement.
* It can be either a string (e.g. `'id ASC, name DESC'`) or an array (e.g. `array('id ASC', 'name DESC')`).
*/
public
$orderBy
;
/**
* @var string|array how to group the query results. This refers to the GROUP BY clause in a SQL statement.
* It can be either a string (e.g. `'company, department'`) or an array (e.g. `array('company', 'department')`).
*/
public
$groupBy
;
/**
* @var string|array how to join with other tables. This refers to the JOIN clause in a SQL statement.
* It can either a string (e.g. `'LEFT JOIN tbl_user ON tbl_user.id=author_id'`) or an array (e.g.
* `array('LEFT JOIN tbl_user ON tbl_user.id=author_id', 'LEFT JOIN tbl_team ON tbl_team.id=team_id')`).
* @see join()
*/
public
$join
;
/**
* @var string|array the condition to be applied in the GROUP BY clause.
* It can be either a string or an array. Please refer to [[where()]] on how to specify the condition.
*/
public
$having
;
/**
* @var array list of query parameter values indexed by parameter placeholders.
* For example, `array(':name'=>'Dan', ':age'=>31)`.
*/
public
$params
;
/**
* @var string|array the UNION clause(s) in a SQL statement. This can be either a string
* representing a single UNION clause or an array representing multiple UNION clauses.
* Each union clause can be a string or a `Query` object which refers to the SQL statement.
*/
public
$union
;
/**
* Sets the SELECT part of the query.
* @param mixed $columns the columns to be selected. Defaults to '*', meaning all columns.
* Columns can be specified in either a string (e.g. "id, name") or an array (e.g. array('id', 'name')).
* Columns can contain table prefixes (e.g. "tbl_user.id") and/or column aliases (e.g. "tbl_user.id AS user_id").
* The method will automatically quote the column names unless a column contains some parenthesis
* (which means the column contains a DB expression).
* @param string $option additional option that should be appended to the 'SELECT' keyword. For example,
* in MySQL, the option 'SQL_CALC_FOUND_ROWS' can be used.
* @return BaseQuery the query object itself
*/
public
function
select
(
$columns
=
'*'
,
$option
=
''
)
{
$this
->
select
=
$columns
;
$this
->
selectOption
=
$option
;
return
$this
;
}
/**
* Sets the value indicating whether to SELECT DISTINCT or not.
* @param bool $value whether to SELECT DISTINCT or not.
* @return BaseQuery the query object itself
*/
public
function
distinct
(
$value
=
true
)
{
$this
->
distinct
=
$value
;
return
$this
;
}
/**
* Sets the FROM part of the query.
* @param mixed $tables the table(s) to be selected from. This can be either a string (e.g. 'tbl_user')
* or an array (e.g. array('tbl_user', 'tbl_profile')) specifying one or several table names.
* Table names can contain schema prefixes (e.g. 'public.tbl_user') and/or table aliases (e.g. 'tbl_user u').
* The method will automatically quote the table names unless it contains some parenthesis
* (which means the table is given as a sub-query or DB expression).
* @return BaseQuery the query object itself
*/
public
function
from
(
$tables
)
{
$this
->
from
=
$tables
;
return
$this
;
}
/**
* Sets the WHERE part of the query.
*
* The method requires a $condition parameter, and optionally a $params parameter
* specifying the values to be bound to the query.
*
* The $condition parameter should be either a string (e.g. 'id=1') or an array.
* If the latter, it must be in one of the following two formats:
*
* - hash format: `array('column1' => value1, 'column2' => value2, ...)`
* - operator format: `array(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:
*
* - `array('type'=>1, 'status'=>2)` generates `(type=1) AND (status=2)`.
* - `array('id'=>array(1,2,3), 'status'=>2)` generates `(id IN (1,2,3)) AND (status=2)`.
* - `array('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,
* `array('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,
* `array('and', 'type=1', array('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, `array('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,
* `array('in', 'id', array(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, `array('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, `array('like', 'name', array('%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 string|array $condition the conditions that should be put in the WHERE part.
* @param array $params the parameters (name=>value) to be bound to the query.
* For anonymous parameters, they can alternatively be specified as separate parameters to this method.
* For example, `where('type=? AND status=?', 100, 1)`.
* @return BaseQuery the query object itself
* @see andWhere()
* @see orWhere()
*/
public
function
where
(
$condition
,
$params
=
array
())
{
$this
->
where
=
$condition
;
if
(
!
is_array
(
$params
))
{
$params
=
func_get_args
();
unset
(
$params
[
0
]);
}
$this
->
addParams
(
$params
);
return
$this
;
}
/**
* 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.
* @param array $params the parameters (name=>value) to be bound to the query.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* @return BaseQuery the query object itself
* @see where()
* @see orWhere()
*/
public
function
andWhere
(
$condition
,
$params
=
array
())
{
if
(
$this
->
where
===
null
)
{
$this
->
where
=
$condition
;
}
else
{
$this
->
where
=
array
(
'and'
,
$this
->
where
,
$condition
);
}
if
(
!
is_array
(
$params
))
{
$params
=
func_get_args
();
unset
(
$params
[
0
]);
}
$this
->
addParams
(
$params
);
return
$this
;
}
/**
* 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.
* @param array $params the parameters (name=>value) to be bound to the query.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* @return BaseQuery the query object itself
* @see where()
* @see andWhere()
*/
public
function
orWhere
(
$condition
,
$params
=
array
())
{
if
(
$this
->
where
===
null
)
{
$this
->
where
=
$condition
;
}
else
{
$this
->
where
=
array
(
'or'
,
$this
->
where
,
$condition
);
}
if
(
!
is_array
(
$params
))
{
$params
=
func_get_args
();
unset
(
$params
[
0
]);
}
$this
->
addParams
(
$params
);
return
$this
;
}
/**
* Appends an INNER JOIN part to the query.
* @param string $table the table to be joined.
* Table name can contain schema prefix (e.g. 'public.tbl_user') and/or table alias (e.g. 'tbl_user u').
* The method will automatically quote the table name unless it contains some parenthesis
* (which means the table is given as a sub-query or DB expression).
* @param string|array $condition the join condition that should appear in the ON part.
* Please refer to [[where()]] on how to specify this parameter.
* @param array $params the parameters (name=>value) to be bound to the query.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* @return BaseQuery the query object itself
*/
public
function
join
(
$table
,
$condition
,
$params
=
array
())
{
$this
->
join
[]
=
array
(
'JOIN'
,
$table
,
$condition
);
if
(
!
is_array
(
$params
))
{
$params
=
func_get_args
();
array_shift
(
$params
);
unset
(
$params
[
0
]);
}
return
$this
->
addParams
(
$params
);
}
/**
* Appends a LEFT OUTER JOIN part to the query.
* @param string $table the table to be joined.
* Table name can contain schema prefix (e.g. 'public.tbl_user') and/or table alias (e.g. 'tbl_user u').
* The method will automatically quote the table name unless it contains some parenthesis
* (which means the table is given as a sub-query or DB expression).
* @param string|array $condition the join condition that should appear in the ON part.
* Please refer to [[where()]] on how to specify this parameter.
* @param array $params the parameters (name=>value) to be bound to the query
* @return BaseQuery the query object itself
*/
public
function
leftJoin
(
$table
,
$condition
,
$params
=
array
())
{
$this
->
join
[]
=
array
(
'LEFT JOIN'
,
$table
,
$condition
);
if
(
!
is_array
(
$params
))
{
$params
=
func_get_args
();
array_shift
(
$params
);
unset
(
$params
[
0
]);
}
return
$this
->
addParams
(
$params
);
}
/**
* Appends a RIGHT OUTER JOIN part to the query.
* @param string $table the table to be joined.
* Table name can contain schema prefix (e.g. 'public.tbl_user') and/or table alias (e.g. 'tbl_user u').
* The method will automatically quote the table name unless it contains some parenthesis
* (which means the table is given as a sub-query or DB expression).
* @param string|array $condition the join condition that should appear in the ON part.
* Please refer to [[where()]] on how to specify this parameter.
* @param array $params the parameters (name=>value) to be bound to the query
* @return BaseQuery the query object itself
*/
public
function
rightJoin
(
$table
,
$condition
,
$params
=
array
())
{
$this
->
join
[]
=
array
(
'RIGHT JOIN'
,
$table
,
$condition
);
if
(
!
is_array
(
$params
))
{
$params
=
func_get_args
();
array_shift
(
$params
);
unset
(
$params
[
0
]);
}
return
$this
->
addParams
(
$params
);
}
/**
* Appends a CROSS JOIN part to the query.
* Note that not all DBMS support CROSS JOIN.
* @param string $table the table to be joined.
* Table name can contain schema prefix (e.g. 'public.tbl_user') and/or table alias (e.g. 'tbl_user u').
* The method will automatically quote the table name unless it contains some parenthesis
* (which means the table is given as a sub-query or DB expression).
* @return BaseQuery the query object itself
*/
public
function
crossJoin
(
$table
)
{
$this
->
join
[]
=
array
(
'CROSS JOIN'
,
$table
);
return
$this
;
}
/**
* Appends a NATURAL JOIN part to the query.
* Note that not all DBMS support NATURAL JOIN.
* @param string $table the table to be joined.
* Table name can contain schema prefix (e.g. 'public.tbl_user') and/or table alias (e.g. 'tbl_user u').
* The method will automatically quote the table name unless it contains some parenthesis
* (which means the table is given as a sub-query or DB expression).
* @return BaseQuery the query object itself
*/
public
function
naturalJoin
(
$table
)
{
$this
->
join
[]
=
array
(
'NATURAL JOIN'
,
$table
);
return
$this
;
}
/**
* Sets the GROUP BY part of the query.
* @param string|array $columns the columns to be grouped by.
* Columns can be specified in either a string (e.g. "id, name") or an array (e.g. array('id', 'name')).
* The method will automatically quote the column names unless a column contains some parenthesis
* (which means the column contains a DB expression).
* @return BaseQuery the query object itself
* @see addGroupBy()
*/
public
function
groupBy
(
$columns
)
{
$this
->
groupBy
=
$columns
;
return
$this
;
}
/**
* Adds additional group-by columns to the existing ones.
* @param string|array $columns additional columns to be grouped by.
* Columns can be specified in either a string (e.g. "id, name") or an array (e.g. array('id', 'name')).
* The method will automatically quote the column names unless a column contains some parenthesis
* (which means the column contains a DB expression).
* @return BaseQuery the query object itself
* @see groupBy()
*/
public
function
addGroupBy
(
$columns
)
{
if
(
empty
(
$this
->
groupBy
))
{
$this
->
groupBy
=
$columns
;
}
else
{
if
(
!
is_array
(
$this
->
groupBy
))
{
$this
->
groupBy
=
preg_split
(
'/\s*,\s*/'
,
trim
(
$this
->
groupBy
),
-
1
,
PREG_SPLIT_NO_EMPTY
);
}
if
(
!
is_array
(
$columns
))
{
$columns
=
preg_split
(
'/\s*,\s*/'
,
trim
(
$columns
),
-
1
,
PREG_SPLIT_NO_EMPTY
);
}
$this
->
groupBy
=
array_merge
(
$this
->
groupBy
,
$columns
);
}
return
$this
;
}
/**
* Sets the HAVING part of the query.
* @param string|array $condition the conditions to be put after HAVING.
* Please refer to [[where()]] on how to specify this parameter.
* @param array $params the parameters (name=>value) to be bound to the query.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* @return BaseQuery the query object itself
* @see andHaving()
* @see orHaving()
*/
public
function
having
(
$condition
,
$params
=
array
())
{
$this
->
having
=
$condition
;
if
(
!
is_array
(
$params
))
{
$params
=
func_get_args
();
unset
(
$params
[
0
]);
}
$this
->
addParams
(
$params
);
return
$this
;
}
/**
* Adds an additional HAVING 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 HAVING condition. Please refer to [[where()]]
* on how to specify this parameter.
* @param array $params the parameters (name=>value) to be bound to the query.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* @return BaseQuery the query object itself
* @see having()
* @see orHaving()
*/
public
function
andHaving
(
$condition
,
$params
=
array
())
{
if
(
$this
->
having
===
null
)
{
$this
->
having
=
$condition
;
}
else
{
$this
->
having
=
array
(
'and'
,
$this
->
having
,
$condition
);
}
if
(
!
is_array
(
$params
))
{
$params
=
func_get_args
();
unset
(
$params
[
0
]);
}
$this
->
addParams
(
$params
);
return
$this
;
}
/**
* Adds an additional HAVING 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 HAVING condition. Please refer to [[where()]]
* on how to specify this parameter.
* @param array $params the parameters (name=>value) to be bound to the query.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* @return BaseQuery the query object itself
* @see having()
* @see andHaving()
*/
public
function
orHaving
(
$condition
,
$params
=
array
())
{
if
(
$this
->
having
===
null
)
{
$this
->
having
=
$condition
;
}
else
{
$this
->
having
=
array
(
'or'
,
$this
->
having
,
$condition
);
}
if
(
!
is_array
(
$params
))
{
$params
=
func_get_args
();
unset
(
$params
[
0
]);
}
$this
->
addParams
(
$params
);
return
$this
;
}
/**
* 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. array('id ASC', 'name DESC')).
* The method will automatically quote the column names unless a column contains some parenthesis
* (which means the column contains a DB expression).
* @return BaseQuery the query object itself
* @see addOrderBy()
*/
public
function
orderBy
(
$columns
)
{
$this
->
orderBy
=
$columns
;
return
$this
;
}
/**
* 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. array('id ASC', 'name DESC')).
* The method will automatically quote the column names unless a column contains some parenthesis
* (which means the column contains a DB expression).
* @return BaseQuery the query object itself
* @see orderBy()
*/
public
function
addOrderBy
(
$columns
)
{
if
(
empty
(
$this
->
orderBy
))
{
$this
->
orderBy
=
$columns
;
}
else
{
if
(
!
is_array
(
$this
->
orderBy
))
{
$this
->
orderBy
=
preg_split
(
'/\s*,\s*/'
,
trim
(
$this
->
orderBy
),
-
1
,
PREG_SPLIT_NO_EMPTY
);
}
if
(
!
is_array
(
$columns
))
{
$columns
=
preg_split
(
'/\s*,\s*/'
,
trim
(
$columns
),
-
1
,
PREG_SPLIT_NO_EMPTY
);
}
$this
->
orderBy
=
array_merge
(
$this
->
orderBy
,
$columns
);
}
return
$this
;
}
/**
* Sets the LIMIT part of the query.
* @param integer $limit the limit
* @return BaseQuery the query object itself
*/
public
function
limit
(
$limit
)
{
$this
->
limit
=
$limit
;
return
$this
;
}
/**
* Sets the OFFSET part of the query.
* @param integer $offset the offset
* @return BaseQuery the query object itself
*/
public
function
offset
(
$offset
)
{
$this
->
offset
=
$offset
;
return
$this
;
}
/**
* Appends a SQL statement using UNION operator.
* @param string $sql the SQL statement to be appended using UNION
* @return BaseQuery the query object itself
*/
public
function
union
(
$sql
)
{
$this
->
union
[]
=
$sql
;
return
$this
;
}
/**
* Sets the parameters to be bound to the query.
* @param array list of query parameter values indexed by parameter placeholders.
* For example, `array(':name'=>'Dan', ':age'=>31)`.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* @return BaseQuery the query object itself
* @see addParams()
*/
public
function
params
(
$params
)
{
$this
->
params
=
$params
;
return
$this
;
}
/**
* Adds additional parameters to be bound to the query.
* @param array list of query parameter values indexed by parameter placeholders.
* For example, `array(':name'=>'Dan', ':age'=>31)`.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* @return BaseQuery the query object itself
* @see params()
*/
public
function
addParams
(
$params
)
{
if
(
$this
->
params
===
null
)
{
$this
->
params
=
$params
;
}
else
{
foreach
(
$params
as
$name
=>
$value
)
{
if
(
is_integer
(
$name
))
{
$this
->
params
[]
=
$value
;
}
else
{
$this
->
params
[
$name
]
=
$value
;
}
}
}
return
$this
;
}
/**
* Merges this query with another one.
*
* The merging is done according to the following rules:
*
* - [[select]]: the union of both queries' [[select]] property values.
* - [[selectOption]], [[distinct]], [[limit]], [[offset]]: the new query
* takes precedence over this query.
* - [[where]], [[having]]: the new query's corresponding property value
* will be 'AND' together with the existing one.
* - [[params]], [[orderBy]], [[groupBy]], [[join]], [[union]]: the new query's
* corresponding property value will be appended to the existing one.
*
* In general, the merging makes the resulting query more restrictive and specific.
* @param BaseQuery $query the new query to be merged with this query.
* @return BaseQuery the query object itself
*/
public
function
mergeWith
(
$query
)
{
if
(
$this
->
select
!==
$query
->
select
)
{
if
(
empty
(
$this
->
select
))
{
$this
->
select
=
$query
->
select
;
}
elseif
(
!
empty
(
$query
->
select
))
{
$select1
=
is_string
(
$this
->
select
)
?
preg_split
(
'/\s*,\s*/'
,
trim
(
$this
->
select
),
-
1
,
PREG_SPLIT_NO_EMPTY
)
:
$this
->
select
;
$select2
=
is_string
(
$query
->
select
)
?
preg_split
(
'/\s*,\s*/'
,
trim
(
$query
->
select
),
-
1
,
PREG_SPLIT_NO_EMPTY
)
:
$query
->
select
;
$this
->
select
=
array_merge
(
$select1
,
array_diff
(
$select2
,
$select1
));
}
}
if
(
$query
->
selectOption
!==
null
)
{
$this
->
selectOption
=
$query
->
selectOption
;
}
if
(
$query
->
distinct
!==
null
)
{
$this
->
distinct
=
$query
->
distinct
;
}
if
(
$query
->
limit
!==
null
)
{
$this
->
limit
=
$query
->
limit
;
}
if
(
$query
->
offset
!==
null
)
{
$this
->
offset
=
$query
->
offset
;
}
if
(
$query
->
where
!==
null
)
{
$this
->
andWhere
(
$query
->
where
);
}
if
(
$query
->
having
!==
null
)
{
$this
->
andHaving
(
$query
->
having
);
}
if
(
$query
->
params
!==
null
)
{
$this
->
addParams
(
$query
->
params
);
}
if
(
$query
->
orderBy
!==
null
)
{
$this
->
addOrderBy
(
$query
->
orderBy
);
}
if
(
$query
->
groupBy
!==
null
)
{
$this
->
addGroupBy
(
$query
->
groupBy
);
}
if
(
$query
->
join
!==
null
)
{
if
(
empty
(
$this
->
join
))
{
$this
->
join
=
$query
->
join
;
}
else
{
if
(
!
is_array
(
$this
->
join
))
{
$this
->
join
=
array
(
$this
->
join
);
}
if
(
is_array
(
$query
->
join
))
{
$this
->
join
=
array_merge
(
$this
->
join
,
$query
->
join
);
}
else
{
$this
->
join
[]
=
$query
->
join
;
}
}
}
if
(
$query
->
union
!==
null
)
{
if
(
empty
(
$this
->
union
))
{
$this
->
union
=
$query
->
union
;
}
else
{
if
(
!
is_array
(
$this
->
union
))
{
$this
->
union
=
array
(
$this
->
union
);
}
if
(
is_array
(
$query
->
union
))
{
$this
->
union
=
array_merge
(
$this
->
union
,
$query
->
union
);
}
else
{
$this
->
union
[]
=
$query
->
union
;
}
}
}
return
$this
;
}
/**
* Resets the query object to its original state.
* @return BaseQuery the query object itself
*/
public
function
reset
()
{
foreach
(
get_object_vars
(
$this
)
as
$name
=>
$value
)
{
$this
->
$name
=
null
;
}
return
$this
;
}
}
framework/db/dao/Query.php
View file @
1978a4ef
...
...
@@ -39,7 +39,7 @@ namespace yii\db\dao;
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class
Query
extends
BaseQuery
class
Query
extends
\yii\base\Object
{
/**
* @var array the operation that this query represents. This refers to the method call as well as
...
...
@@ -48,7 +48,77 @@ class Query extends BaseQuery
* If this property is not set, it means this query represents a SELECT statement.
*/
public
$operation
;
/**
* @var string|array the columns being selected. This refers to the SELECT clause in a SQL
* statement. It can be either a string (e.g. `'id, name'`) or an array (e.g. `array('id', 'name')`).
* If not set, if means all columns.
* @see select()
*/
public
$select
;
/**
* @var string additional option that should be appended to the 'SELECT' keyword. For example,
* in MySQL, the option 'SQL_CALC_FOUND_ROWS' can be used.
*/
public
$selectOption
;
/**
* @var boolean whether to select distinct rows of data only. If this is set true,
* the SELECT clause would be changed to SELECT DISTINCT.
*/
public
$distinct
;
/**
* @var string|array the table(s) to be selected from. This refers to the FROM clause in a SQL statement.
* It can be either a string (e.g. `'tbl_user, tbl_post'`) or an array (e.g. `array('tbl_user', 'tbl_post')`).
* @see from()
*/
public
$from
;
/**
* @var string|array query condition. This refers to the WHERE clause in a SQL statement.
* For example, `age > 31 AND team = 1`.
* @see where()
*/
public
$where
;
/**
* @var integer maximum number of records to be returned. If not set or less than 0, it means no limit.
*/
public
$limit
;
/**
* @var integer zero-based offset from where the records are to be returned. If not set or
* less than 0, it means starting from the beginning.
*/
public
$offset
;
/**
* @var string|array how to sort the query results. This refers to the ORDER BY clause in a SQL statement.
* It can be either a string (e.g. `'id ASC, name DESC'`) or an array (e.g. `array('id ASC', 'name DESC')`).
*/
public
$orderBy
;
/**
* @var string|array how to group the query results. This refers to the GROUP BY clause in a SQL statement.
* It can be either a string (e.g. `'company, department'`) or an array (e.g. `array('company', 'department')`).
*/
public
$groupBy
;
/**
* @var string|array how to join with other tables. This refers to the JOIN clause in a SQL statement.
* It can either a string (e.g. `'LEFT JOIN tbl_user ON tbl_user.id=author_id'`) or an array (e.g.
* `array('LEFT JOIN tbl_user ON tbl_user.id=author_id', 'LEFT JOIN tbl_team ON tbl_team.id=team_id')`).
* @see join()
*/
public
$join
;
/**
* @var string|array the condition to be applied in the GROUP BY clause.
* It can be either a string or an array. Please refer to [[where()]] on how to specify the condition.
*/
public
$having
;
/**
* @var array list of query parameter values indexed by parameter placeholders.
* For example, `array(':name'=>'Dan', ':age'=>31)`.
*/
public
$params
;
/**
* @var string|Query[] the UNION clause(s) in a SQL statement. This can be either a string
* representing a single UNION clause or an array representing multiple UNION clauses.
* Each union clause can be a string or a `Query` object which refers to the SQL statement.
*/
public
$union
;
/**
* Generates and returns the SQL statement according to this query.
...
...
@@ -304,4 +374,615 @@ class Query extends BaseQuery
$this
->
operation
=
array
(
__FUNCTION__
,
$name
,
$table
);
return
$this
;
}
/**
* Sets the SELECT part of the query.
* @param mixed $columns the columns to be selected. Defaults to '*', meaning all columns.
* Columns can be specified in either a string (e.g. "id, name") or an array (e.g. array('id', 'name')).
* Columns can contain table prefixes (e.g. "tbl_user.id") and/or column aliases (e.g. "tbl_user.id AS user_id").
* The method will automatically quote the column names unless a column contains some parenthesis
* (which means the column contains a DB expression).
* @param string $option additional option that should be appended to the 'SELECT' keyword. For example,
* in MySQL, the option 'SQL_CALC_FOUND_ROWS' can be used.
* @return Query the query object itself
*/
public
function
select
(
$columns
=
'*'
,
$option
=
''
)
{
$this
->
select
=
$columns
;
$this
->
selectOption
=
$option
;
return
$this
;
}
/**
* Sets the value indicating whether to SELECT DISTINCT or not.
* @param bool $value whether to SELECT DISTINCT or not.
* @return Query the query object itself
*/
public
function
distinct
(
$value
=
true
)
{
$this
->
distinct
=
$value
;
return
$this
;
}
/**
* Sets the FROM part of the query.
* @param mixed $tables the table(s) to be selected from. This can be either a string (e.g. 'tbl_user')
* or an array (e.g. array('tbl_user', 'tbl_profile')) specifying one or several table names.
* Table names can contain schema prefixes (e.g. 'public.tbl_user') and/or table aliases (e.g. 'tbl_user u').
* The method will automatically quote the table names unless it contains some parenthesis
* (which means the table is given as a sub-query or DB expression).
* @return Query the query object itself
*/
public
function
from
(
$tables
)
{
$this
->
from
=
$tables
;
return
$this
;
}
/**
* Sets the WHERE part of the query.
*
* The method requires a $condition parameter, and optionally a $params parameter
* specifying the values to be bound to the query.
*
* The $condition parameter should be either a string (e.g. 'id=1') or an array.
* If the latter, it must be in one of the following two formats:
*
* - hash format: `array('column1' => value1, 'column2' => value2, ...)`
* - operator format: `array(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:
*
* - `array('type'=>1, 'status'=>2)` generates `(type=1) AND (status=2)`.
* - `array('id'=>array(1,2,3), 'status'=>2)` generates `(id IN (1,2,3)) AND (status=2)`.
* - `array('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,
* `array('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,
* `array('and', 'type=1', array('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, `array('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,
* `array('in', 'id', array(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, `array('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, `array('like', 'name', array('%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 string|array $condition the conditions that should be put in the WHERE part.
* @param array $params the parameters (name=>value) to be bound to the query.
* For anonymous parameters, they can alternatively be specified as separate parameters to this method.
* For example, `where('type=? AND status=?', 100, 1)`.
* @return Query the query object itself
* @see andWhere()
* @see orWhere()
*/
public
function
where
(
$condition
,
$params
=
array
())
{
$this
->
where
=
$condition
;
if
(
!
is_array
(
$params
))
{
$params
=
func_get_args
();
unset
(
$params
[
0
]);
}
$this
->
addParams
(
$params
);
return
$this
;
}
/**
* 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.
* @param array $params the parameters (name=>value) to be bound to the query.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* @return Query the query object itself
* @see where()
* @see orWhere()
*/
public
function
andWhere
(
$condition
,
$params
=
array
())
{
if
(
$this
->
where
===
null
)
{
$this
->
where
=
$condition
;
}
else
{
$this
->
where
=
array
(
'and'
,
$this
->
where
,
$condition
);
}
if
(
!
is_array
(
$params
))
{
$params
=
func_get_args
();
unset
(
$params
[
0
]);
}
$this
->
addParams
(
$params
);
return
$this
;
}
/**
* 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.
* @param array $params the parameters (name=>value) to be bound to the query.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* @return Query the query object itself
* @see where()
* @see andWhere()
*/
public
function
orWhere
(
$condition
,
$params
=
array
())
{
if
(
$this
->
where
===
null
)
{
$this
->
where
=
$condition
;
}
else
{
$this
->
where
=
array
(
'or'
,
$this
->
where
,
$condition
);
}
if
(
!
is_array
(
$params
))
{
$params
=
func_get_args
();
unset
(
$params
[
0
]);
}
$this
->
addParams
(
$params
);
return
$this
;
}
/**
* Appends an INNER JOIN part to the query.
* @param string $table the table to be joined.
* Table name can contain schema prefix (e.g. 'public.tbl_user') and/or table alias (e.g. 'tbl_user u').
* The method will automatically quote the table name unless it contains some parenthesis
* (which means the table is given as a sub-query or DB expression).
* @param string|array $condition the join condition that should appear in the ON part.
* Please refer to [[where()]] on how to specify this parameter.
* @param array $params the parameters (name=>value) to be bound to the query.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* @return Query the query object itself
*/
public
function
join
(
$table
,
$condition
,
$params
=
array
())
{
$this
->
join
[]
=
array
(
'JOIN'
,
$table
,
$condition
);
if
(
!
is_array
(
$params
))
{
$params
=
func_get_args
();
array_shift
(
$params
);
unset
(
$params
[
0
]);
}
return
$this
->
addParams
(
$params
);
}
/**
* Appends a LEFT OUTER JOIN part to the query.
* @param string $table the table to be joined.
* Table name can contain schema prefix (e.g. 'public.tbl_user') and/or table alias (e.g. 'tbl_user u').
* The method will automatically quote the table name unless it contains some parenthesis
* (which means the table is given as a sub-query or DB expression).
* @param string|array $condition the join condition that should appear in the ON part.
* Please refer to [[where()]] on how to specify this parameter.
* @param array $params the parameters (name=>value) to be bound to the query
* @return Query the query object itself
*/
public
function
leftJoin
(
$table
,
$condition
,
$params
=
array
())
{
$this
->
join
[]
=
array
(
'LEFT JOIN'
,
$table
,
$condition
);
if
(
!
is_array
(
$params
))
{
$params
=
func_get_args
();
array_shift
(
$params
);
unset
(
$params
[
0
]);
}
return
$this
->
addParams
(
$params
);
}
/**
* Appends a RIGHT OUTER JOIN part to the query.
* @param string $table the table to be joined.
* Table name can contain schema prefix (e.g. 'public.tbl_user') and/or table alias (e.g. 'tbl_user u').
* The method will automatically quote the table name unless it contains some parenthesis
* (which means the table is given as a sub-query or DB expression).
* @param string|array $condition the join condition that should appear in the ON part.
* Please refer to [[where()]] on how to specify this parameter.
* @param array $params the parameters (name=>value) to be bound to the query
* @return Query the query object itself
*/
public
function
rightJoin
(
$table
,
$condition
,
$params
=
array
())
{
$this
->
join
[]
=
array
(
'RIGHT JOIN'
,
$table
,
$condition
);
if
(
!
is_array
(
$params
))
{
$params
=
func_get_args
();
array_shift
(
$params
);
unset
(
$params
[
0
]);
}
return
$this
->
addParams
(
$params
);
}
/**
* Appends a CROSS JOIN part to the query.
* Note that not all DBMS support CROSS JOIN.
* @param string $table the table to be joined.
* Table name can contain schema prefix (e.g. 'public.tbl_user') and/or table alias (e.g. 'tbl_user u').
* The method will automatically quote the table name unless it contains some parenthesis
* (which means the table is given as a sub-query or DB expression).
* @return Query the query object itself
*/
public
function
crossJoin
(
$table
)
{
$this
->
join
[]
=
array
(
'CROSS JOIN'
,
$table
);
return
$this
;
}
/**
* Appends a NATURAL JOIN part to the query.
* Note that not all DBMS support NATURAL JOIN.
* @param string $table the table to be joined.
* Table name can contain schema prefix (e.g. 'public.tbl_user') and/or table alias (e.g. 'tbl_user u').
* The method will automatically quote the table name unless it contains some parenthesis
* (which means the table is given as a sub-query or DB expression).
* @return Query the query object itself
*/
public
function
naturalJoin
(
$table
)
{
$this
->
join
[]
=
array
(
'NATURAL JOIN'
,
$table
);
return
$this
;
}
/**
* Sets the GROUP BY part of the query.
* @param string|array $columns the columns to be grouped by.
* Columns can be specified in either a string (e.g. "id, name") or an array (e.g. array('id', 'name')).
* The method will automatically quote the column names unless a column contains some parenthesis
* (which means the column contains a DB expression).
* @return Query the query object itself
* @see addGroupBy()
*/
public
function
groupBy
(
$columns
)
{
$this
->
groupBy
=
$columns
;
return
$this
;
}
/**
* Adds additional group-by columns to the existing ones.
* @param string|array $columns additional columns to be grouped by.
* Columns can be specified in either a string (e.g. "id, name") or an array (e.g. array('id', 'name')).
* The method will automatically quote the column names unless a column contains some parenthesis
* (which means the column contains a DB expression).
* @return Query the query object itself
* @see groupBy()
*/
public
function
addGroupBy
(
$columns
)
{
if
(
empty
(
$this
->
groupBy
))
{
$this
->
groupBy
=
$columns
;
}
else
{
if
(
!
is_array
(
$this
->
groupBy
))
{
$this
->
groupBy
=
preg_split
(
'/\s*,\s*/'
,
trim
(
$this
->
groupBy
),
-
1
,
PREG_SPLIT_NO_EMPTY
);
}
if
(
!
is_array
(
$columns
))
{
$columns
=
preg_split
(
'/\s*,\s*/'
,
trim
(
$columns
),
-
1
,
PREG_SPLIT_NO_EMPTY
);
}
$this
->
groupBy
=
array_merge
(
$this
->
groupBy
,
$columns
);
}
return
$this
;
}
/**
* Sets the HAVING part of the query.
* @param string|array $condition the conditions to be put after HAVING.
* Please refer to [[where()]] on how to specify this parameter.
* @param array $params the parameters (name=>value) to be bound to the query.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* @return Query the query object itself
* @see andHaving()
* @see orHaving()
*/
public
function
having
(
$condition
,
$params
=
array
())
{
$this
->
having
=
$condition
;
if
(
!
is_array
(
$params
))
{
$params
=
func_get_args
();
unset
(
$params
[
0
]);
}
$this
->
addParams
(
$params
);
return
$this
;
}
/**
* Adds an additional HAVING 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 HAVING condition. Please refer to [[where()]]
* on how to specify this parameter.
* @param array $params the parameters (name=>value) to be bound to the query.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* @return Query the query object itself
* @see having()
* @see orHaving()
*/
public
function
andHaving
(
$condition
,
$params
=
array
())
{
if
(
$this
->
having
===
null
)
{
$this
->
having
=
$condition
;
}
else
{
$this
->
having
=
array
(
'and'
,
$this
->
having
,
$condition
);
}
if
(
!
is_array
(
$params
))
{
$params
=
func_get_args
();
unset
(
$params
[
0
]);
}
$this
->
addParams
(
$params
);
return
$this
;
}
/**
* Adds an additional HAVING 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 HAVING condition. Please refer to [[where()]]
* on how to specify this parameter.
* @param array $params the parameters (name=>value) to be bound to the query.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* @return Query the query object itself
* @see having()
* @see andHaving()
*/
public
function
orHaving
(
$condition
,
$params
=
array
())
{
if
(
$this
->
having
===
null
)
{
$this
->
having
=
$condition
;
}
else
{
$this
->
having
=
array
(
'or'
,
$this
->
having
,
$condition
);
}
if
(
!
is_array
(
$params
))
{
$params
=
func_get_args
();
unset
(
$params
[
0
]);
}
$this
->
addParams
(
$params
);
return
$this
;
}
/**
* 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. array('id ASC', 'name DESC')).
* The method will automatically quote the column names unless a column contains some parenthesis
* (which means the column contains a DB expression).
* @return Query the query object itself
* @see addOrderBy()
*/
public
function
orderBy
(
$columns
)
{
$this
->
orderBy
=
$columns
;
return
$this
;
}
/**
* 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. array('id ASC', 'name DESC')).
* The method will automatically quote the column names unless a column contains some parenthesis
* (which means the column contains a DB expression).
* @return Query the query object itself
* @see orderBy()
*/
public
function
addOrderBy
(
$columns
)
{
if
(
empty
(
$this
->
orderBy
))
{
$this
->
orderBy
=
$columns
;
}
else
{
if
(
!
is_array
(
$this
->
orderBy
))
{
$this
->
orderBy
=
preg_split
(
'/\s*,\s*/'
,
trim
(
$this
->
orderBy
),
-
1
,
PREG_SPLIT_NO_EMPTY
);
}
if
(
!
is_array
(
$columns
))
{
$columns
=
preg_split
(
'/\s*,\s*/'
,
trim
(
$columns
),
-
1
,
PREG_SPLIT_NO_EMPTY
);
}
$this
->
orderBy
=
array_merge
(
$this
->
orderBy
,
$columns
);
}
return
$this
;
}
/**
* Sets the LIMIT part of the query.
* @param integer $limit the limit
* @return Query the query object itself
*/
public
function
limit
(
$limit
)
{
$this
->
limit
=
$limit
;
return
$this
;
}
/**
* Sets the OFFSET part of the query.
* @param integer $offset the offset
* @return Query the query object itself
*/
public
function
offset
(
$offset
)
{
$this
->
offset
=
$offset
;
return
$this
;
}
/**
* Appends a SQL statement using UNION operator.
* @param string|Query $sql the SQL statement to be appended using UNION
* @return Query the query object itself
*/
public
function
union
(
$sql
)
{
$this
->
union
[]
=
$sql
;
return
$this
;
}
/**
* Sets the parameters to be bound to the query.
* @param array list of query parameter values indexed by parameter placeholders.
* For example, `array(':name'=>'Dan', ':age'=>31)`.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* @return Query the query object itself
* @see addParams()
*/
public
function
params
(
$params
)
{
$this
->
params
=
$params
;
return
$this
;
}
/**
* Adds additional parameters to be bound to the query.
* @param array list of query parameter values indexed by parameter placeholders.
* For example, `array(':name'=>'Dan', ':age'=>31)`.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* @return Query the query object itself
* @see params()
*/
public
function
addParams
(
$params
)
{
if
(
$params
!==
array
())
{
if
(
$this
->
params
===
null
)
{
$this
->
params
=
$params
;
}
else
{
foreach
(
$params
as
$name
=>
$value
)
{
if
(
is_integer
(
$name
))
{
$this
->
params
[]
=
$value
;
}
else
{
$this
->
params
[
$name
]
=
$value
;
}
}
}
}
return
$this
;
}
/**
* Merges this query with another one.
*
* The merging is done according to the following rules:
*
* - [[select]]: the union of both queries' [[select]] property values.
* - [[selectOption]], [[distinct]], [[limit]], [[offset]]: the new query
* takes precedence over this query.
* - [[where]], [[having]]: the new query's corresponding property value
* will be 'AND' together with the existing one.
* - [[params]], [[orderBy]], [[groupBy]], [[join]], [[union]]: the new query's
* corresponding property value will be appended to the existing one.
*
* In general, the merging makes the resulting query more restrictive and specific.
* @param Query $query the new query to be merged with this query.
* @return Query the query object itself
*/
public
function
mergeWith
(
$query
)
{
if
(
$this
->
select
!==
$query
->
select
)
{
if
(
empty
(
$this
->
select
))
{
$this
->
select
=
$query
->
select
;
}
elseif
(
!
empty
(
$query
->
select
))
{
$select1
=
is_string
(
$this
->
select
)
?
preg_split
(
'/\s*,\s*/'
,
trim
(
$this
->
select
),
-
1
,
PREG_SPLIT_NO_EMPTY
)
:
$this
->
select
;
$select2
=
is_string
(
$query
->
select
)
?
preg_split
(
'/\s*,\s*/'
,
trim
(
$query
->
select
),
-
1
,
PREG_SPLIT_NO_EMPTY
)
:
$query
->
select
;
$this
->
select
=
array_merge
(
$select1
,
array_diff
(
$select2
,
$select1
));
}
}
if
(
$query
->
selectOption
!==
null
)
{
$this
->
selectOption
=
$query
->
selectOption
;
}
if
(
$query
->
distinct
!==
null
)
{
$this
->
distinct
=
$query
->
distinct
;
}
if
(
$query
->
limit
!==
null
)
{
$this
->
limit
=
$query
->
limit
;
}
if
(
$query
->
offset
!==
null
)
{
$this
->
offset
=
$query
->
offset
;
}
if
(
$query
->
where
!==
null
)
{
$this
->
andWhere
(
$query
->
where
);
}
if
(
$query
->
having
!==
null
)
{
$this
->
andHaving
(
$query
->
having
);
}
if
(
$query
->
params
!==
null
)
{
$this
->
addParams
(
$query
->
params
);
}
if
(
$query
->
orderBy
!==
null
)
{
$this
->
addOrderBy
(
$query
->
orderBy
);
}
if
(
$query
->
groupBy
!==
null
)
{
$this
->
addGroupBy
(
$query
->
groupBy
);
}
if
(
$query
->
join
!==
null
)
{
if
(
empty
(
$this
->
join
))
{
$this
->
join
=
$query
->
join
;
}
else
{
if
(
!
is_array
(
$this
->
join
))
{
$this
->
join
=
array
(
$this
->
join
);
}
if
(
is_array
(
$query
->
join
))
{
$this
->
join
=
array_merge
(
$this
->
join
,
$query
->
join
);
}
else
{
$this
->
join
[]
=
$query
->
join
;
}
}
}
if
(
$query
->
union
!==
null
)
{
if
(
empty
(
$this
->
union
))
{
$this
->
union
=
$query
->
union
;
}
else
{
if
(
!
is_array
(
$this
->
union
))
{
$this
->
union
=
array
(
$this
->
union
);
}
if
(
is_array
(
$query
->
union
))
{
$this
->
union
=
array_merge
(
$this
->
union
,
$query
->
union
);
}
else
{
$this
->
union
[]
=
$query
->
union
;
}
}
}
return
$this
;
}
/**
* Resets the query object to its original state.
* @return Query the query object itself
*/
public
function
reset
()
{
foreach
(
get_object_vars
(
$this
)
as
$name
=>
$value
)
{
$this
->
$name
=
null
;
}
return
$this
;
}
}
framework/db/dao/QueryBuilder.php
View file @
1978a4ef
...
...
@@ -24,33 +24,28 @@ use yii\db\Exception;
class
QueryBuilder
extends
\yii\base\Object
{
/**
* @var array the abstract column types mapped to physical column types.
* This is mainly used to support creating/modifying tables using DB-independent data type specifications.
* Child classes should override this property to declare supported type mappings.
*/
public
$typeMap
=
array
();
/**
* @var Connection the database connection.
*/
public
$connection
;
/**
* @var Driver the database driver used for this query builder.
*/
public
$driver
;
/**
* @var string the separator between different fragments of a SQL statement.
* Defaults to an empty space. This is mainly used by [[build()]] when generating a SQL statement.
*/
public
$separator
=
" "
;
/**
* @var Query the Query object that is currently processed by the query builder to generate a SQL statement.
* This property will be set null upon completion of [[build()]].
*/
public
$query
;
/**
* @var boolean whether to automatically quote table and column names when generating SQL statements.
*/
public
$autoQuote
=
true
;
/**
* @var array the abstract column types mapped to physical column types.
* This is mainly used to support creating/modifying tables using DB-independent data type specifications.
* Child classes should override this property to declare supported type mappings.
*/
public
$typeMap
=
array
();
/**
* @var Query the Query object that is currently processed by the query builder to generate a SQL statement.
*/
public
$query
;
/**
* Constructor.
...
...
@@ -59,7 +54,6 @@ class QueryBuilder extends \yii\base\Object
public
function
__construct
(
$connection
)
{
$this
->
connection
=
$connection
;
$this
->
driver
=
$connection
->
getDriver
();
}
/**
...
...
@@ -74,8 +68,9 @@ class QueryBuilder extends \yii\base\Object
$this
->
query
=
$query
;
if
(
$query
->
operation
!==
null
)
{
// non-SELECT query
$method
=
array_shift
(
$query
->
operation
);
$sql
=
call_user_func_array
(
array
(
$this
,
$method
),
$query
->
operation
);
$params
=
$query
->
operation
;
$method
=
array_shift
(
$params
);
return
call_user_func_array
(
array
(
$this
,
$method
),
$params
);
}
else
{
// SELECT query
$clauses
=
array
(
...
...
@@ -89,10 +84,8 @@ class QueryBuilder extends \yii\base\Object
$this
->
buildOrderBy
(),
$this
->
buildLimit
(),
);
$sql
=
implode
(
$this
->
separator
,
array_filter
(
$clauses
));
return
implode
(
$this
->
separator
,
array_filter
(
$clauses
));
}
$this
->
query
=
null
;
return
$sql
;
}
/**
...
...
@@ -477,7 +470,7 @@ class QueryBuilder extends \yii\base\Object
/**
* Parses the condition specification and generates the corresponding SQL expression.
* @param string|array $condition the condition specification. Please refer to [[Query::where()]]
* @param string|array $condition the condition specification. Please refer to [[
Base
Query::where()]]
* on how to specify a condition.
* @return string the generated SQL expression
* @throws \yii\db\Exception if the condition is in bad format
...
...
@@ -651,6 +644,7 @@ class QueryBuilder extends \yii\base\Object
}
if
(
$this
->
autoQuote
)
{
$driver
=
$this
->
connection
->
driver
;
if
(
!
is_array
(
$columns
))
{
if
(
strpos
(
$columns
,
'('
)
!==
false
)
{
return
$select
.
' '
.
$columns
;
...
...
@@ -663,9 +657,9 @@ class QueryBuilder extends \yii\base\Object
$columns
[
$i
]
=
(
string
)
$column
;
}
elseif
(
strpos
(
$column
,
'('
)
===
false
)
{
if
(
preg_match
(
'/^(.*?)(?i:\s+as\s+|\s+)([\w\-\.])$/'
,
$column
,
$matches
))
{
$columns
[
$i
]
=
$
this
->
driver
->
quoteColumnName
(
$matches
[
1
])
.
' AS '
.
$this
->
driver
->
quoteSimpleColumnName
(
$matches
[
2
]);
$columns
[
$i
]
=
$
driver
->
quoteColumnName
(
$matches
[
1
])
.
' AS '
.
$
driver
->
quoteSimpleColumnName
(
$matches
[
2
]);
}
else
{
$columns
[
$i
]
=
$
this
->
driver
->
quoteColumnName
(
$column
);
$columns
[
$i
]
=
$driver
->
quoteColumnName
(
$column
);
}
}
}
...
...
@@ -690,6 +684,7 @@ class QueryBuilder extends \yii\base\Object
$tables
=
$this
->
query
->
from
;
if
(
$this
->
autoQuote
)
{
$driver
=
$this
->
connection
->
driver
;
if
(
!
is_array
(
$tables
))
{
if
(
strpos
(
$tables
,
'('
)
!==
false
)
{
return
'FROM '
.
$tables
;
...
...
@@ -700,9 +695,9 @@ class QueryBuilder extends \yii\base\Object
foreach
(
$tables
as
$i
=>
$table
)
{
if
(
strpos
(
$table
,
'('
)
===
false
)
{
if
(
preg_match
(
'/^(.*?)(?i:\s+as\s+|\s+)(.*)$/i'
,
$table
,
$matches
))
{
// with alias
$tables
[
$i
]
=
$
this
->
driver
->
quoteTableName
(
$matches
[
1
])
.
' '
.
$this
->
driver
->
quoteTableName
(
$matches
[
2
]);
$tables
[
$i
]
=
$
driver
->
quoteTableName
(
$matches
[
1
])
.
' '
.
$
driver
->
quoteTableName
(
$matches
[
2
]);
}
else
{
$tables
[
$i
]
=
$
this
->
driver
->
quoteTableName
(
$table
);
$tables
[
$i
]
=
$driver
->
quoteTableName
(
$table
);
}
}
}
...
...
@@ -733,10 +728,11 @@ class QueryBuilder extends \yii\base\Object
if
(
isset
(
$join
[
0
],
$join
[
1
]))
{
$table
=
$join
[
1
];
if
(
$this
->
autoQuote
&&
strpos
(
$table
,
'('
)
===
false
)
{
$driver
=
$this
->
connection
->
driver
;
if
(
preg_match
(
'/^(.*?)(?i:\s+as\s+|\s+)(.*)$/'
,
$table
,
$matches
))
{
// with alias
$table
=
$
this
->
driver
->
quoteTableName
(
$matches
[
1
])
.
' '
.
$this
->
driver
->
quoteTableName
(
$matches
[
2
]);
$table
=
$
driver
->
quoteTableName
(
$matches
[
1
])
.
' '
.
$
driver
->
quoteTableName
(
$matches
[
2
]);
}
else
{
$table
=
$
this
->
driver
->
quoteTableName
(
$table
);
$table
=
$driver
->
quoteTableName
(
$table
);
}
}
$joins
[
$i
]
=
strtoupper
(
$join
[
0
])
.
' '
.
$table
;
...
...
@@ -792,6 +788,7 @@ class QueryBuilder extends \yii\base\Object
}
$columns
=
$this
->
query
->
orderBy
;
if
(
$this
->
autoQuote
)
{
$driver
=
$this
->
connection
->
driver
;
if
(
!
is_array
(
$columns
))
{
if
(
strpos
(
$columns
,
'('
)
!==
false
)
{
return
'ORDER BY '
.
$columns
;
...
...
@@ -804,9 +801,9 @@ class QueryBuilder extends \yii\base\Object
$columns
[
$i
]
=
(
string
)
$column
;
}
elseif
(
strpos
(
$column
,
'('
)
===
false
)
{
if
(
preg_match
(
'/^(.*?)\s+(asc|desc)$/i'
,
$column
,
$matches
))
{
$columns
[
$i
]
=
$
this
->
driver
->
quoteColumnName
(
$matches
[
1
])
.
' '
.
$matches
[
2
];
$columns
[
$i
]
=
$driver
->
quoteColumnName
(
$matches
[
1
])
.
' '
.
$matches
[
2
];
}
else
{
$columns
[
$i
]
=
$
this
->
driver
->
quoteColumnName
(
$column
);
$columns
[
$i
]
=
$driver
->
quoteColumnName
(
$column
);
}
}
}
...
...
@@ -873,7 +870,7 @@ class QueryBuilder extends \yii\base\Object
if
(
is_object
(
$column
))
{
$columns
[
$i
]
=
(
string
)
$column
;
}
elseif
(
strpos
(
$column
,
'('
)
===
false
)
{
$columns
[
$i
]
=
$this
->
driver
->
quoteColumnName
(
$column
);
$columns
[
$i
]
=
$this
->
quoteColumnName
(
$column
);
}
}
}
...
...
@@ -890,7 +887,7 @@ class QueryBuilder extends \yii\base\Object
protected
function
quoteTableName
(
$name
,
$simple
=
false
)
{
if
(
$this
->
autoQuote
)
{
return
$
simple
?
$this
->
driver
->
quoteSimpleTableName
(
$name
)
:
$this
->
driver
->
quoteTableName
(
$nam
e
);
return
$
this
->
connection
->
quoteTableName
(
$name
,
$simpl
e
);
}
else
{
return
$name
;
}
...
...
@@ -906,7 +903,7 @@ class QueryBuilder extends \yii\base\Object
protected
function
quoteColumnName
(
$name
,
$simple
=
false
)
{
if
(
$this
->
autoQuote
)
{
return
$
simple
?
$this
->
driver
->
quoteSimpleColumnName
(
$name
)
:
$this
->
driver
->
quoteColumnName
(
$nam
e
);
return
$
this
->
connection
->
quoteColumnName
(
$name
,
$simpl
e
);
}
else
{
return
$name
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment