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
a00afed1
Commit
a00afed1
authored
Dec 30, 2011
by
Qiang Xue
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
...
parent
c26c9396
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
143 additions
and
54 deletions
+143
-54
Query.php
framework/db/dao/Query.php
+16
-3
QueryBuilder.php
framework/db/dao/QueryBuilder.php
+127
-51
No files found.
framework/db/dao/Query.php
View file @
a00afed1
...
@@ -163,9 +163,22 @@ class Query extends \yii\base\Object
...
@@ -163,9 +163,22 @@ class Query extends \yii\base\Object
* specifying the values to be bound to the query.
* specifying the values to be bound to the query.
*
*
* The $condition parameter should be either a string (e.g. 'id=1') or an array.
* The $condition parameter should be either a string (e.g. 'id=1') or an array.
* If the latter, it must be in the format of `array(operator, operand1, operand2, ...)`,
* If the latter, it must be in one of the following two formats:
* where the operator can be one of the followings, and the possible operands depend on the corresponding
*
* operator:
* - 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,
* - `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,
* `array('and', 'id=1', 'id=2')` will generate `id=1 AND id=2`. If an operand is an array,
...
...
framework/db/dao/QueryBuilder.php
View file @
a00afed1
...
@@ -476,87 +476,163 @@ class QueryBuilder extends \yii\base\Object
...
@@ -476,87 +476,163 @@ class QueryBuilder extends \yii\base\Object
}
}
/**
/**
* Generates a SQL condition from the given PHP representation.
* Parses the condition specification and generates the corresponding SQL expression.
* @param string|array $condition the PHP representation of the SQL condition
* @param string|array $condition the condition specification. Please refer to [[Query::where()]]
* @return string the generated SQL condition.
* on how to specify a condition.
* @return string the generated SQL expression
* @throws \yii\db\Exception if the condition is in bad format
*/
*/
public
function
buildCondition
(
$condition
)
public
function
buildCondition
(
$condition
)
{
{
static
$builders
=
array
(
'and'
=>
'buildAndCondition'
,
'or'
=>
'buildAndCondition'
,
'between'
=>
'buildBetweenCondition'
,
'not between'
=>
'buildBetweenCondition'
,
'in'
=>
'buildInCondition'
,
'not in'
=>
'buildInCondition'
,
'like'
=>
'buildLikeCondition'
,
'not like'
=>
'buildLikeCondition'
,
'or like'
=>
'buildLikeCondition'
,
'or not like'
=>
'buildLikeCondition'
,
);
if
(
!
is_array
(
$condition
))
{
if
(
!
is_array
(
$condition
))
{
return
$condition
;
return
$condition
;
}
elseif
(
$condition
===
array
())
{
}
elseif
(
$condition
===
array
())
{
return
''
;
return
''
;
}
}
if
(
isset
(
$condition
[
0
]))
{
// operator format: operator, operand 1, operand 2, ...
$operator
=
$condition
[
0
];
if
(
isset
(
$builders
[
$operator
]))
{
$method
=
$builders
[
$operator
];
array_shift
(
$condition
);
return
$this
->
$method
(
$operator
,
$condition
);
}
else
{
throw
new
Exception
(
'Found unknown operator in query: '
.
$operator
);
}
}
else
{
// hash format: 'column1'=>'value1', 'column2'=>'value2', ...
return
$this
->
buildHashCondition
(
$condition
);
}
}
$n
=
count
(
$condition
);
private
function
buildHashCondition
(
$condition
)
$operator
=
strtoupper
(
$condition
[
0
]);
{
if
(
$operator
===
'OR'
||
$operator
===
'AND'
)
{
$parts
=
array
();
$parts
=
array
();
foreach
(
$condition
as
$column
=>
$value
)
{
for
(
$i
=
1
;
$i
<
$n
;
++
$i
)
{
if
(
is_array
(
$value
))
{
// IN condition
$part
=
$this
->
buildCondition
(
$condition
[
$i
]);
$parts
[]
=
$this
->
buildInCondition
(
'in'
,
array
(
$column
,
$value
));
if
(
$part
!==
''
)
{
}
else
{
$parts
[]
=
'('
.
$part
.
')'
;
if
(
strpos
(
$column
,
'('
)
===
false
)
{
$column
=
$this
->
quoteColumnName
(
$column
);
}
if
(
$value
===
null
)
{
$parts
[]
=
"
$column
IS NULL"
;
}
elseif
(
is_string
(
$value
))
{
$parts
[]
=
"
$column
="
.
$this
->
connection
->
quoteValue
(
$value
);
}
else
{
$parts
[]
=
"
$column
=
$value
"
;
}
}
}
}
return
$parts
===
array
()
?
''
:
implode
(
' '
.
$operator
.
' '
,
$parts
);
}
}
return
'('
.
implode
(
') AND ('
,
$parts
)
.
')'
;
}
if
(
!
isset
(
$condition
[
1
],
$condition
[
2
]))
{
private
function
buildAndCondition
(
$operator
,
$operands
)
throw
new
Exception
(
"Operator
$operator
requires at least two operands."
);
{
$parts
=
array
();
foreach
(
$operands
as
$operand
)
{
if
(
is_array
(
$operand
))
{
$operand
=
$this
->
buildCondition
(
$operand
);
}
if
(
$operand
!==
''
)
{
$parts
[]
=
$operand
;
}
}
}
if
(
$parts
!==
array
())
{
return
'('
.
implode
(
")
$operator
("
,
$parts
)
.
')'
;
}
else
{
return
''
;
}
}
private
function
buildBetweenCondition
(
$operator
,
$operands
)
{
if
(
!
isset
(
$operands
[
0
],
$operands
[
1
],
$operands
[
2
]))
{
throw
new
Exception
(
"Operator '
$operator
' requires three operands."
);
}
list
(
$column
,
$value1
,
$value2
)
=
$operands
;
$column
=
$condition
[
1
];
if
(
strpos
(
$column
,
'('
)
===
false
)
{
if
(
strpos
(
$column
,
'('
)
===
false
)
{
$column
=
$this
->
quoteColumnName
(
$column
);
$column
=
$this
->
quoteColumnName
(
$column
);
}
}
$value1
=
is_string
(
$value1
)
?
$this
->
connection
->
quoteValue
(
$value1
)
:
(
string
)
$value1
;
$value2
=
is_string
(
$value2
)
?
$this
->
connection
->
quoteValue
(
$value2
)
:
(
string
)
$value2
;
if
(
$operator
===
'BETWEEN'
||
$operator
===
'NOT BETWEEN'
)
{
return
"
$column
$operator
$value1
AND
$value2
"
;
if
(
!
isset
(
$condition
[
3
]))
{
}
throw
new
Exception
(
"Operator
$operator
requires three operands."
);
}
private
function
buildInCondition
(
$operator
,
$operands
)
$value1
=
is_string
(
$condition
[
2
])
?
$this
->
connection
->
quoteValue
(
$condition
[
2
])
:
(
string
)
$condition
[
2
];
{
$value2
=
is_string
(
$condition
[
3
])
?
$this
->
connection
->
quoteValue
(
$condition
[
3
])
:
(
string
)
$condition
[
3
];
if
(
!
isset
(
$operands
[
0
],
$operands
[
1
]))
{
return
"
$column
$operator
$value1
AND
$value2
"
;
throw
new
Exception
(
"Operator '
$operator
' requires two operands."
)
;
}
}
$values
=
$condition
[
2
];
list
(
$column
,
$values
)
=
$operands
;
if
(
!
is_array
(
$values
))
{
if
(
!
is_array
(
$values
))
{
$values
=
array
(
$values
);
$values
=
array
(
$values
);
}
}
if
(
$operator
===
'IN'
||
$operator
===
'NOT IN'
)
{
if
(
$values
===
array
())
{
if
(
$values
===
array
())
{
return
$operator
===
'in'
?
'0=1'
:
''
;
return
$operator
===
'IN'
?
'0=1'
:
''
;
}
foreach
(
$values
as
$i
=>
$value
)
{
if
(
is_string
(
$value
))
{
$values
[
$i
]
=
$this
->
connection
->
quoteValue
(
$value
);
}
else
{
$values
[
$i
]
=
(
string
)
$value
;
}
}
return
$column
.
' '
.
$operator
.
' ('
.
implode
(
', '
,
$values
)
.
')'
;
}
}
if
(
$operator
===
'LIKE'
||
$operator
===
'NOT LIKE'
||
$operator
===
'OR LIKE'
||
$operator
===
'OR NOT LIKE'
)
{
foreach
(
$values
as
$i
=>
$value
)
{
if
(
$values
===
array
())
{
$values
[
$i
]
=
is_string
(
$value
)
?
$this
->
connection
->
quoteValue
(
$value
)
:
(
string
)
$value
;
return
$operator
===
'LIKE'
||
$operator
===
'OR LIKE'
?
'0=1'
:
''
;
}
}
if
(
$operator
===
'LIKE'
||
$operator
===
'NOT LIKE'
)
{
if
(
strpos
(
$column
,
'('
)
===
false
)
{
$andor
=
' AND '
;
$column
=
$this
->
quoteColumnName
(
$column
);
}
else
{
}
$andor
=
' OR '
;
$operator
=
$operator
===
'OR LIKE'
?
'LIKE'
:
'NOT LIKE'
;
return
"
$column
$operator
("
.
implode
(
', '
,
$values
)
.
')'
;
}
}
$expressions
=
array
();
foreach
(
$values
as
$value
)
{
private
function
buildLikeCondition
(
$operator
,
$operands
)
$expressions
[]
=
$column
.
' '
.
$operator
.
' '
.
$this
->
connection
->
quoteValue
(
$value
);
{
}
if
(
!
isset
(
$operands
[
0
],
$operands
[
1
]))
{
return
implode
(
$andor
,
$expressions
);
throw
new
Exception
(
"Operator '
$operator
' requires two operands."
);
}
list
(
$column
,
$values
)
=
$operands
;
if
(
!
is_array
(
$values
))
{
$values
=
array
(
$values
);
}
if
(
$values
===
array
())
{
return
$operator
===
'like'
||
$operator
===
'or like'
?
'0=1'
:
''
;
}
if
(
$operator
===
'like'
||
$operator
===
'not like'
)
{
$andor
=
' and '
;
}
else
{
$andor
=
' or '
;
$operator
=
$operator
===
'or like'
?
'like'
:
'not like'
;
}
if
(
strpos
(
$column
,
'('
)
===
false
)
{
$column
=
$this
->
quoteColumnName
(
$column
);
}
$parts
=
array
();
foreach
(
$values
as
$value
)
{
$parts
[]
=
"
$column
$operator
"
.
$this
->
connection
->
quoteValue
(
$value
);
}
}
throw
new
Exception
(
'Unknown operator: '
.
$operator
);
return
implode
(
$andor
,
$parts
);
}
}
/**
/**
...
...
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