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
06feccff
Commit
06feccff
authored
Mar 06, 2013
by
Qiang Xue
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
refactored query builder.
finished Sort.
parent
1f522d22
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
134 additions
and
118 deletions
+134
-118
Query.php
framework/db/Query.php
+81
-38
QueryBuilder.php
framework/db/QueryBuilder.php
+36
-70
Pagination.php
framework/web/Pagination.php
+2
-1
Sort.php
framework/web/Sort.php
+0
-0
QueryTest.php
tests/unit/framework/db/QueryTest.php
+15
-9
No files found.
framework/db/Query.php
View file @
06feccff
...
...
@@ -35,9 +35,19 @@ namespace yii\db;
class
Query
extends
\yii\base\Component
{
/**
* @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.
* Sort ascending
* @see orderBy
*/
const
SORT_ASC
=
false
;
/**
* Sort ascending
* @see orderBy
*/
const
SORT_DESC
=
true
;
/**
* @var array the columns being selected. For example, `array('id', 'name')`.
* This is used to construct the SELECT clause in a SQL statement. If not set, if means selecting all columns.
* @see select()
*/
public
$select
;
...
...
@@ -52,8 +62,8 @@ class Query extends \yii\base\Component
*/
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')`)
.
* @var
array the table(s) to be selected from. For example, `array('tbl_user', 'tbl_post')`
.
*
This is used to construct the FROM clause in a SQL statement
.
* @see from()
*/
public
$from
;
...
...
@@ -73,20 +83,33 @@ class Query extends \yii\base\Component
*/
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')`).
* @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.
*/
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')`)
.
* @var
array how to group the query results. For example, `array('company', 'department')`
.
*
This is used to construct the GROUP BY clause in a SQL statement
.
*/
public
$groupBy
;
/**
* @var string|array how to join with other tables. This refers to the JOIN clause in a SQL statement.
* It can be 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()
* @var array how to join with other tables. Each array element represents the specification
* of one join which has the following structure:
*
* ~~~
* array($joinType, $tableName, $joinCondition)
* ~~~
*
* For example,
*
* ~~~
* array(
* array('INNER JOIN', 'tbl_user', 'tbl_user.id = author_id'),
* array('LEFT JOIN', 'tbl_team', 'tbl_team.id = team_id'),
* )
* ~~~
*/
public
$join
;
/**
...
...
@@ -95,9 +118,8 @@ class Query extends \yii\base\Component
*/
public
$having
;
/**
* @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.
* @var array this is used to construct the UNION clause(s) in a SQL statement.
* Each array element can be either a string or a [[Query]] object representing a sub-query.
*/
public
$union
;
/**
...
...
@@ -134,6 +156,9 @@ class Query extends \yii\base\Component
*/
public
function
select
(
$columns
,
$option
=
null
)
{
if
(
!
is_array
(
$columns
))
{
$columns
=
preg_split
(
'/\s*,\s*/'
,
trim
(
$columns
),
-
1
,
PREG_SPLIT_NO_EMPTY
);
}
$this
->
select
=
$columns
;
$this
->
selectOption
=
$option
;
return
$this
;
...
...
@@ -161,6 +186,9 @@ class Query extends \yii\base\Component
*/
public
function
from
(
$tables
)
{
if
(
!
is_array
(
$tables
))
{
$tables
=
preg_split
(
'/\s*,\s*/'
,
trim
(
$tables
),
-
1
,
PREG_SPLIT_NO_EMPTY
);
}
$this
->
from
=
$tables
;
return
$this
;
}
...
...
@@ -360,10 +388,13 @@ class Query extends \yii\base\Component
* 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 addGroup()
* @see addGroup
By
()
*/
public
function
groupBy
(
$columns
)
{
if
(
!
is_array
(
$columns
))
{
$columns
=
preg_split
(
'/\s*,\s*/'
,
trim
(
$columns
),
-
1
,
PREG_SPLIT_NO_EMPTY
);
}
$this
->
groupBy
=
$columns
;
return
$this
;
}
...
...
@@ -375,19 +406,16 @@ class Query extends \yii\base\Component
* 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 group()
* @see group
By
()
*/
public
function
addGroup
(
$columns
)
public
function
addGroup
By
(
$columns
)
{
if
(
empty
(
$this
->
groupBy
))
{
if
(
!
is_array
(
$columns
))
{
$columns
=
preg_split
(
'/\s*,\s*/'
,
trim
(
$columns
),
-
1
,
PREG_SPLIT_NO_EMPTY
);
}
if
(
$this
->
groupBy
===
null
)
{
$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
;
...
...
@@ -454,43 +482,58 @@ class Query extends \yii\base\Component
/**
* 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')).
* Columns can be specified in either a string (e.g. "id ASC, name DESC") or an array
* (e.g. `array('id' => Query::SORT_ASC ASC, 'name' => Query::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 Query the query object itself
* @see addOrder()
* @see addOrder
By
()
*/
public
function
orderBy
(
$columns
)
{
$this
->
orderBy
=
$
columns
;
$this
->
orderBy
=
$
this
->
normalizeOrderBy
(
$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')).
* Columns can be specified in either a string (e.g. "id ASC, name DESC") or an array
* (e.g. `array('id' => Query::SORT_ASC ASC, 'name' => Query::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 Query the query object itself
* @see order()
* @see order
By
()
*/
public
function
addOrderBy
(
$columns
)
{
if
(
empty
(
$this
->
orderBy
))
{
$columns
=
$this
->
normalizeOrderBy
(
$columns
);
if
(
$this
->
orderBy
===
null
)
{
$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
;
}
protected
function
normalizeOrderBy
(
$columns
)
{
if
(
is_array
(
$columns
))
{
return
$columns
;
}
else
{
$columns
=
preg_split
(
'/\s*,\s*/'
,
trim
(
$columns
),
-
1
,
PREG_SPLIT_NO_EMPTY
);
$result
=
array
();
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
;
}
else
{
$result
[
$column
]
=
self
::
SORT_ASC
;
}
}
return
$result
;
}
}
/**
* Sets the LIMIT part of the query.
* @param integer $limit the limit
...
...
framework/db/QueryBuilder.php
View file @
06feccff
...
...
@@ -60,10 +60,10 @@ class QueryBuilder extends \yii\base\Object
$this
->
buildFrom
(
$query
->
from
),
$this
->
buildJoin
(
$query
->
join
),
$this
->
buildWhere
(
$query
->
where
),
$this
->
buildGroup
(
$query
->
groupBy
),
$this
->
buildGroup
By
(
$query
->
groupBy
),
$this
->
buildHaving
(
$query
->
having
),
$this
->
buildUnion
(
$query
->
union
),
$this
->
buildOrder
(
$query
->
orderBy
),
$this
->
buildOrder
By
(
$query
->
orderBy
),
$this
->
buildLimit
(
$query
->
limit
,
$query
->
offset
),
);
return
implode
(
$this
->
separator
,
array_filter
(
$clauses
));
...
...
@@ -673,7 +673,7 @@ class QueryBuilder extends \yii\base\Object
}
/**
* @param
string|
array $columns
* @param array $columns
* @param boolean $distinct
* @param string $selectOption
* @return string the SELECT clause built from [[query]].
...
...
@@ -689,13 +689,6 @@ class QueryBuilder extends \yii\base\Object
return
$select
.
' *'
;
}
if
(
!
is_array
(
$columns
))
{
if
(
strpos
(
$columns
,
'('
)
!==
false
)
{
return
$select
.
' '
.
$columns
;
}
else
{
$columns
=
preg_split
(
'/\s*,\s*/'
,
trim
(
$columns
),
-
1
,
PREG_SPLIT_NO_EMPTY
);
}
}
foreach
(
$columns
as
$i
=>
$column
)
{
if
(
is_object
(
$column
))
{
$columns
[
$i
]
=
(
string
)
$column
;
...
...
@@ -716,7 +709,7 @@ class QueryBuilder extends \yii\base\Object
}
/**
* @param
string|
array $tables
* @param array $tables
* @return string the FROM clause built from [[query]].
*/
public
function
buildFrom
(
$tables
)
...
...
@@ -725,13 +718,6 @@ class QueryBuilder extends \yii\base\Object
return
''
;
}
if
(
!
is_array
(
$tables
))
{
if
(
strpos
(
$tables
,
'('
)
!==
false
)
{
return
'FROM '
.
$tables
;
}
else
{
$tables
=
preg_split
(
'/\s*,\s*/'
,
trim
(
$tables
),
-
1
,
PREG_SPLIT_NO_EMPTY
);
}
}
foreach
(
$tables
as
$i
=>
$table
)
{
if
(
strpos
(
$table
,
'('
)
===
false
)
{
if
(
preg_match
(
'/^(.*?)(?i:\s+as\s+|\s+)(.*)$/i'
,
$table
,
$matches
))
{
// with alias
...
...
@@ -752,37 +738,36 @@ class QueryBuilder extends \yii\base\Object
/**
* @param string|array $joins
* @return string the JOIN clause built from [[query]].
* @throws Exception if the $joins parameter is not in proper format
*/
public
function
buildJoin
(
$joins
)
{
if
(
empty
(
$joins
))
{
return
''
;
}
if
(
is_string
(
$joins
))
{
return
$joins
;
}
foreach
(
$joins
as
$i
=>
$join
)
{
if
(
is_array
(
$join
))
{
// 0:join type, 1:table name, 2:on-condition
if
(
isset
(
$join
[
0
],
$join
[
1
]))
{
$table
=
$join
[
1
];
if
(
strpos
(
$table
,
'('
)
===
false
)
{
if
(
preg_match
(
'/^(.*?)(?i:\s+as\s+|\s+)(.*)$/'
,
$table
,
$matches
))
{
// with alias
$table
=
$this
->
db
->
quoteTableName
(
$matches
[
1
])
.
' '
.
$this
->
db
->
quoteTableName
(
$matches
[
2
]);
}
else
{
$table
=
$this
->
db
->
quoteTableName
(
$table
);
}
if
(
is_object
(
$join
))
{
$joins
[
$i
]
=
(
string
)
$join
;
}
elseif
(
is_array
(
$join
)
&&
isset
(
$join
[
0
],
$join
[
1
]))
{
// 0:join type, 1:table name, 2:on-condition
$table
=
$join
[
1
];
if
(
strpos
(
$table
,
'('
)
===
false
)
{
if
(
preg_match
(
'/^(.*?)(?i:\s+as\s+|\s+)(.*)$/'
,
$table
,
$matches
))
{
// with alias
$table
=
$this
->
db
->
quoteTableName
(
$matches
[
1
])
.
' '
.
$this
->
db
->
quoteTableName
(
$matches
[
2
]);
}
else
{
$table
=
$this
->
db
->
quoteTableName
(
$table
);
}
$joins
[
$i
]
=
$join
[
0
]
.
' '
.
$table
;
if
(
isset
(
$join
[
2
]))
{
$condition
=
$this
->
buildCondition
(
$join
[
2
]);
if
(
$condition
!==
''
)
{
$joins
[
$i
]
.=
' ON '
.
$this
->
buildCondition
(
$join
[
2
]);
}
}
$joins
[
$i
]
=
$join
[
0
]
.
' '
.
$table
;
if
(
isset
(
$join
[
2
]))
{
$condition
=
$this
->
buildCondition
(
$join
[
2
]);
if
(
$condition
!==
''
)
{
$joins
[
$i
]
.=
' ON '
.
$this
->
buildCondition
(
$join
[
2
]);
}
}
else
{
throw
new
Exception
(
'A join clause must be specified as an array of at least two elements.'
);
}
}
else
{
throw
new
Exception
(
'A join clause must be specified as an array of join type, join table, and optionally join condition.'
);
}
}
...
...
@@ -800,16 +785,12 @@ class QueryBuilder extends \yii\base\Object
}
/**
* @param
string|
array $columns
* @param array $columns
* @return string the GROUP BY clause
*/
public
function
buildGroup
(
$columns
)
public
function
buildGroup
By
(
$columns
)
{
if
(
empty
(
$columns
))
{
return
''
;
}
else
{
return
'GROUP BY '
.
$this
->
buildColumns
(
$columns
);
}
return
empty
(
$columns
)
?
''
:
'GROUP BY '
.
$this
->
buildColumns
(
$columns
);
}
/**
...
...
@@ -823,36 +804,24 @@ class QueryBuilder extends \yii\base\Object
}
/**
* @param
string|
array $columns
* @param array $columns
* @return string the ORDER BY clause built from [[query]].
*/
public
function
buildOrder
(
$columns
)
public
function
buildOrder
By
(
$columns
)
{
if
(
empty
(
$columns
))
{
return
''
;
}
if
(
!
is_array
(
$columns
))
{
if
(
strpos
(
$columns
,
'('
)
!==
false
)
{
return
'ORDER BY '
.
$columns
;
$orders
=
array
();
foreach
(
$columns
as
$name
=>
$direction
)
{
if
(
is_object
(
$direction
))
{
$orders
[]
=
(
string
)
$direction
;
}
else
{
$columns
=
preg_split
(
'/\s*,\s*/'
,
trim
(
$columns
),
-
1
,
PREG_SPLIT_NO_EMPTY
);
}
}
foreach
(
$columns
as
$i
=>
$column
)
{
if
(
is_object
(
$column
))
{
$columns
[
$i
]
=
(
string
)
$column
;
}
elseif
(
strpos
(
$column
,
'('
)
===
false
)
{
if
(
preg_match
(
'/^(.*?)\s+(asc|desc)$/i'
,
$column
,
$matches
))
{
$columns
[
$i
]
=
$this
->
db
->
quoteColumnName
(
$matches
[
1
])
.
' '
.
$matches
[
2
];
}
else
{
$columns
[
$i
]
=
$this
->
db
->
quoteColumnName
(
$column
);
}
$orders
[]
=
$this
->
db
->
quoteColumnName
(
$name
)
.
(
$direction
===
Query
::
SORT_DESC
?
' DESC'
:
''
);
}
}
if
(
is_array
(
$columns
))
{
$columns
=
implode
(
', '
,
$columns
);
}
return
'ORDER BY '
.
$columns
;
return
'ORDER BY '
.
implode
(
', '
,
$orders
);
}
/**
...
...
@@ -873,7 +842,7 @@ class QueryBuilder extends \yii\base\Object
}
/**
* @param
string|
array $unions
* @param array $unions
* @return string the UNION clause built from [[query]].
*/
public
function
buildUnion
(
$unions
)
...
...
@@ -881,9 +850,6 @@ class QueryBuilder extends \yii\base\Object
if
(
empty
(
$unions
))
{
return
''
;
}
if
(
!
is_array
(
$unions
))
{
$unions
=
array
(
$unions
);
}
foreach
(
$unions
as
$i
=>
$union
)
{
if
(
$union
instanceof
Query
)
{
$unions
[
$i
]
=
$this
->
build
(
$union
);
...
...
framework/web/Pagination.php
View file @
06feccff
...
...
@@ -65,7 +65,8 @@ use Yii;
class
Pagination
extends
\yii\base\Object
{
/**
* @var string name of the GET variable storing the current page index. Defaults to 'page'.
* @var string name of the parameter storing the current page index. Defaults to 'page'.
* @see params
*/
public
$pageVar
=
'page'
;
/**
...
...
framework/web/Sort.php
View file @
06feccff
This diff is collapsed.
Click to expand it.
tests/unit/framework/db/QueryTest.php
View file @
06feccff
...
...
@@ -14,13 +14,13 @@ class QueryTest extends \yiiunit\MysqlTestCase
// default
$query
=
new
Query
;
$query
->
select
(
'*'
);
$this
->
assertEquals
(
'*'
,
$query
->
select
);
$this
->
assertEquals
(
array
(
'*'
)
,
$query
->
select
);
$this
->
assertNull
(
$query
->
distinct
);
$this
->
assertEquals
(
null
,
$query
->
selectOption
);
$query
=
new
Query
;
$query
->
select
(
'id, name'
,
'something'
)
->
distinct
(
true
);
$this
->
assertEquals
(
'id, name'
,
$query
->
select
);
$this
->
assertEquals
(
array
(
'id'
,
'name'
)
,
$query
->
select
);
$this
->
assertTrue
(
$query
->
distinct
);
$this
->
assertEquals
(
'something'
,
$query
->
selectOption
);
}
...
...
@@ -29,7 +29,7 @@ class QueryTest extends \yiiunit\MysqlTestCase
{
$query
=
new
Query
;
$query
->
from
(
'tbl_user'
);
$this
->
assertEquals
(
'tbl_user'
,
$query
->
from
);
$this
->
assertEquals
(
array
(
'tbl_user'
)
,
$query
->
from
);
}
function
testWhere
()
...
...
@@ -57,12 +57,12 @@ class QueryTest extends \yiiunit\MysqlTestCase
{
$query
=
new
Query
;
$query
->
groupBy
(
'team'
);
$this
->
assertEquals
(
'team'
,
$query
->
groupBy
);
$this
->
assertEquals
(
array
(
'team'
)
,
$query
->
groupBy
);
$query
->
addGroup
(
'company'
);
$query
->
addGroup
By
(
'company'
);
$this
->
assertEquals
(
array
(
'team'
,
'company'
),
$query
->
groupBy
);
$query
->
addGroup
(
'age'
);
$query
->
addGroup
By
(
'age'
);
$this
->
assertEquals
(
array
(
'team'
,
'company'
,
'age'
),
$query
->
groupBy
);
}
...
...
@@ -86,13 +86,19 @@ class QueryTest extends \yiiunit\MysqlTestCase
{
$query
=
new
Query
;
$query
->
orderBy
(
'team'
);
$this
->
assertEquals
(
'team'
,
$query
->
orderBy
);
$this
->
assertEquals
(
array
(
'team'
=>
false
)
,
$query
->
orderBy
);
$query
->
addOrderBy
(
'company'
);
$this
->
assertEquals
(
array
(
'team'
,
'company'
),
$query
->
orderBy
);
$this
->
assertEquals
(
array
(
'team'
=>
false
,
'company'
=>
false
),
$query
->
orderBy
);
$query
->
addOrderBy
(
'age'
);
$this
->
assertEquals
(
array
(
'team'
,
'company'
,
'age'
),
$query
->
orderBy
);
$this
->
assertEquals
(
array
(
'team'
=>
false
,
'company'
=>
false
,
'age'
=>
false
),
$query
->
orderBy
);
$query
->
addOrderBy
(
array
(
'age'
=>
true
));
$this
->
assertEquals
(
array
(
'team'
=>
false
,
'company'
=>
false
,
'age'
=>
true
),
$query
->
orderBy
);
$query
->
addOrderBy
(
'age ASC, company DESC'
);
$this
->
assertEquals
(
array
(
'team'
=>
false
,
'company'
=>
true
,
'age'
=>
false
),
$query
->
orderBy
);
}
function
testLimitOffset
()
...
...
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