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
fe90d4dd
Commit
fe90d4dd
authored
Jan 06, 2013
by
Qiang Xue
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
implemented auto-quoting for DB commands.
parent
d15378ef
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
234 additions
and
253 deletions
+234
-253
Command.php
framework/db/Command.php
+20
-23
Connection.php
framework/db/Connection.php
+33
-36
Driver.php
framework/db/Driver.php
+67
-47
QueryBuilder.php
framework/db/QueryBuilder.php
+88
-137
QueryBuilder.php
framework/db/mysql/QueryBuilder.php
+8
-7
CommandTest.php
tests/unit/framework/db/CommandTest.php
+9
-0
ConnectionTest.php
tests/unit/framework/db/ConnectionTest.php
+9
-3
No files found.
framework/db/Command.php
View file @
fe90d4dd
...
...
@@ -62,21 +62,6 @@ class Command extends \yii\base\Component
private
$_params
=
array
();
/**
* Constructor.
* @param Connection $connection the database connection
* @param string $sql the SQL statement to be executed
* @param array $params the parameters to be bound to the SQL statement
* @param array $config name-value pairs that will be used to initialize the object properties
*/
public
function
__construct
(
$connection
,
$sql
=
null
,
$params
=
array
(),
$config
=
array
())
{
$this
->
connection
=
$connection
;
$this
->
_sql
=
$sql
;
$this
->
bindValues
(
$params
);
parent
::
__construct
(
$config
);
}
/**
* Returns the SQL statement for this command.
* @return string the SQL statement to be executed
*/
...
...
@@ -88,14 +73,26 @@ class Command extends \yii\base\Component
/**
* Specifies the SQL statement to be executed.
* Any previous execution will be terminated or cancelled.
* @param string $
value
the SQL statement to be set.
* @param string $
sql
the SQL statement to be set.
* @return Command this command instance
*/
public
function
setSql
(
$
value
)
public
function
setSql
(
$
sql
)
{
$this
->
_sql
=
$value
;
$this
->
_params
=
array
();
$this
->
cancel
();
if
(
$sql
!==
$this
->
_sql
)
{
if
(
$this
->
connection
->
enableAutoQuoting
&&
$sql
!=
''
)
{
$sql
=
preg_replace_callback
(
'/(\\{\\{(.*?)\\}\\}|\\[\\[(.*?)\\]\\])/'
,
function
(
$matches
)
{
if
(
isset
(
$matches
[
3
]))
{
return
$this
->
connection
->
quoteColumnName
(
$matches
[
3
]);
}
else
{
$name
=
str_replace
(
'%'
,
$this
->
connection
->
tablePrefix
,
$matches
[
2
]);
return
$this
->
connection
->
quoteTableName
(
$name
);
}
},
$sql
);
}
$this
->
_sql
=
$sql
;
$this
->
_params
=
array
();
$this
->
cancel
();
}
return
$this
;
}
...
...
@@ -110,7 +107,7 @@ class Command extends \yii\base\Component
public
function
prepare
()
{
if
(
$this
->
pdoStatement
==
null
)
{
$sql
=
$this
->
connection
->
expandTablePrefix
(
$this
->
getSql
()
);
$sql
=
$this
->
getSql
(
);
try
{
$this
->
pdoStatement
=
$this
->
connection
->
pdo
->
prepare
(
$sql
);
}
catch
(
\Exception
$e
)
{
...
...
@@ -223,7 +220,7 @@ class Command extends \yii\base\Component
*/
public
function
execute
(
$params
=
array
())
{
$sql
=
$this
->
connection
->
expandTablePrefix
(
$this
->
getSql
()
);
$sql
=
$this
->
getSql
(
);
$this
->
_params
=
array_merge
(
$this
->
_params
,
$params
);
if
(
$this
->
_params
===
array
())
{
$paramLog
=
''
;
...
...
@@ -356,7 +353,7 @@ class Command extends \yii\base\Component
private
function
queryInternal
(
$method
,
$params
,
$fetchMode
=
null
)
{
$db
=
$this
->
connection
;
$sql
=
$
db
->
expandTablePrefix
(
$this
->
getSql
()
);
$sql
=
$
this
->
getSql
(
);
$this
->
_params
=
array_merge
(
$this
->
_params
,
$params
);
if
(
$this
->
_params
===
array
())
{
$paramLog
=
''
;
...
...
framework/db/Connection.php
View file @
fe90d4dd
...
...
@@ -124,7 +124,7 @@ class Connection extends \yii\base\ApplicationComponent
public
$attributes
;
/**
* @var \PDO the PHP PDO instance associated with this DB connection.
* This property is mainly managed by [[open
]] and [[close
]] methods.
* This property is mainly managed by [[open
()]] and [[close()
]] methods.
* When a DB connection is active, this property will represent a PDO instance;
* otherwise, it will be null.
*/
...
...
@@ -132,7 +132,7 @@ class Connection extends \yii\base\ApplicationComponent
/**
* @var boolean whether to enable schema caching.
* Note that in order to enable truly schema caching, a valid cache component as specified
* by [[schemaCacheID]] must be enabled and [[
schemaCacheEnabled
]] must be set true.
* by [[schemaCacheID]] must be enabled and [[
enableSchemaCache
]] must be set true.
* @see schemaCacheDuration
* @see schemaCacheExclude
* @see schemaCacheID
...
...
@@ -159,7 +159,7 @@ class Connection extends \yii\base\ApplicationComponent
/**
* @var boolean whether to enable query caching.
* Note that in order to enable query caching, a valid cache component as specified
* by [[queryCacheID]] must be enabled and [[
queryCacheEnabled
]] must be set true.
* by [[queryCacheID]] must be enabled and [[
enableQueryCache
]] must be set true.
*
* Methods [[beginCache()]] and [[endCache()]] can be used as shortcuts to turn on
* and off query caching on the fly.
...
...
@@ -215,16 +215,24 @@ class Connection extends \yii\base\ApplicationComponent
*/
public
$enableProfiling
=
false
;
/**
* @var string the default prefix for table names. Defaults to null, meaning not using table prefix.
* By setting this property, any token like '{{TableName}}' in [[Command::sql]] will
* be replaced with 'prefixTableName', where 'prefix' refers to this property value.
* For example, '{{post}}' becomes 'tbl_post', if 'tbl_' is set as the table prefix.
*
* Note that if you set this property to be an empty string, then '{{post}}' will be replaced
* with 'post'.
* @var string the common prefix or suffix for table names. If a table name is given
* as `{{%TableName}}`, then the percentage character `%` will be replaced with this
* property value. For example, `{{%post}}` becomes `{{tbl_post}}` if this property is
* set as `"tbl_"`. Note that this property is only effective when [[enableAutoQuoting]]
* is true.
* @see enableAutoQuoting
*/
public
$tablePrefix
;
/**
* @var boolean whether to enable automatic quoting of table names and column names.
* Defaults to true. When this property is true, any token enclosed within double curly brackets
* (e.g. `{{post}}`) in a SQL statement will be treated as a table name and will be quoted
* accordingly when the SQL statement is executed; and any token enclosed within double square
* brackets (e.g. `[[name]]`) will be treated as a column name and quoted accordingly.
* @see tablePrefix
*/
public
$enableAutoQuoting
=
true
;
/**
* @var array a list of SQL statements that should be executed right after the DB connection is established.
*/
public
$initSQLs
;
...
...
@@ -411,7 +419,12 @@ class Connection extends \yii\base\ApplicationComponent
public
function
createCommand
(
$sql
=
null
,
$params
=
array
())
{
$this
->
open
();
return
new
Command
(
$this
,
$sql
,
$params
);
$command
=
new
Command
(
array
(
'connection'
=>
$this
,
'sql'
=>
$sql
,
));
$command
->
bindValues
(
$params
);
return
$command
;
}
/**
...
...
@@ -513,43 +526,27 @@ class Connection extends \yii\base\ApplicationComponent
/**
* Quotes a table name for use in a query.
* If the table name contains schema prefix, the prefix will also be properly quoted.
* If the table name is already quoted or contains special characters including '(', '[[' and '{{',
* then this method will do nothing.
* @param string $name table name
* @param boolean $simple if this is true, then the method will assume $name is a table name without schema prefix.
* @return string the properly quoted table name
*/
public
function
quoteTableName
(
$name
,
$simple
=
false
)
public
function
quoteTableName
(
$name
)
{
return
$
simple
?
$this
->
getDriver
()
->
quoteSimpleTableName
(
$name
)
:
$
this
->
getDriver
()
->
quoteTableName
(
$name
);
return
$this
->
getDriver
()
->
quoteTableName
(
$name
);
}
/**
* Quotes a column name for use in a query.
* If the column name contains table prefix, the prefix will also be properly quoted.
* If the column name contains prefix, the prefix will also be properly quoted.
* If the column name is already quoted or contains special characters including '(', '[[' and '{{',
* then this method will do nothing.
* @param string $name column name
* @param boolean $simple if this is true, then the method will assume $name is a column name without table prefix.
* @return string the properly quoted column name
*/
public
function
quoteColumnName
(
$name
,
$simple
=
false
)
{
return
$simple
?
$this
->
getDriver
()
->
quoteSimpleColumnName
(
$name
)
:
$this
->
getDriver
()
->
quoteColumnName
(
$name
);
}
/**
* Prefixes table names in a SQL statement with [[tablePrefix]].
* By calling this method, tokens like '{{TableName}}' in the given SQL statement will
* be replaced with 'prefixTableName', where 'prefix' refers to [[tablePrefix]].
* Note that if [[tablePrefix]] is null, this method will do nothing.
* @param string $sql the SQL statement whose table names need to be prefixed with [[tablePrefix]].
* @return string the expanded SQL statement
* @see tablePrefix
*/
public
function
expandTablePrefix
(
$sql
)
public
function
quoteColumnName
(
$name
)
{
if
(
$this
->
tablePrefix
!==
null
&&
strpos
(
$sql
,
'{{'
)
!==
false
)
{
return
preg_replace
(
'/{{(.*?)}}/'
,
$this
->
tablePrefix
.
'\1'
,
$sql
);
}
else
{
return
$sql
;
}
return
$this
->
getDriver
()
->
quoteColumnName
(
$name
);
}
/**
...
...
framework/db/Driver.php
View file @
fe90d4dd
...
...
@@ -92,8 +92,7 @@ abstract class Driver extends \yii\base\Object
}
$db
=
$this
->
connection
;
$realName
=
$db
->
expandTablePrefix
(
$name
);
$realName
=
$this
->
getRealTableName
(
$name
);
/** @var $cache \yii\caching\Cache */
if
(
$db
->
enableSchemaCache
&&
(
$cache
=
\Yii
::
$application
->
getComponent
(
$db
->
schemaCacheID
))
!==
null
&&
!
in_array
(
$name
,
$db
->
schemaCacheExclude
,
true
))
{
...
...
@@ -168,37 +167,57 @@ abstract class Driver extends \yii\base\Object
/**
* Refreshes the schema.
* This method cleans up the cached table schema and names
* so that they can be recreated to reflect the database schema change.
* @param string $tableName the name of the table that needs to be refreshed.
* If null, all currently loaded tables will be refreshed.
* This method cleans up all cached table schemas so that they can be re-created later
* to reflect the database schema change.
*/
public
function
refresh
(
$tableName
=
null
)
public
function
refresh
()
{
$db
=
$this
->
connection
;
/** @var $cache \yii\caching\Cache */
if
(
$db
->
enableSchemaCache
&&
(
$cache
=
\Yii
::
$application
->
getComponent
(
$db
->
schemaCacheID
))
!==
null
)
{
if
(
$tableName
===
null
)
{
foreach
(
$this
->
_tables
as
$name
=>
$table
)
{
$cache
->
delete
(
$this
->
getCacheKey
(
$name
));
}
$this
->
_tables
=
array
();
}
else
{
$cache
->
delete
(
$this
->
getCacheKey
(
$tableName
));
unset
(
$this
->
_tables
[
$tableName
]);
if
(
$this
->
connection
->
enableSchemaCache
&&
(
$cache
=
\Yii
::
$application
->
getComponent
(
$this
->
connection
->
schemaCacheID
))
!==
null
)
{
foreach
(
$this
->
_tables
as
$name
=>
$table
)
{
$cache
->
delete
(
$this
->
getCacheKey
(
$name
));
}
}
$this
->
_tables
=
array
();
}
/**
* Creates a query builder for the database.
* This method may be overridden by child classes to create a DBMS-specific query builder.
* @return QueryBuilder query builder instance
*/
public
function
createQueryBuilder
()
{
return
new
QueryBuilder
(
$this
->
connection
);
}
/**
* Returns all table names in the database.
* This method should be overridden by child classes in order to support this feature
* because the default implementation simply throws an exception.
* @param string $schema the schema of the tables. Defaults to empty string, meaning the current or default schema.
* If not empty, the returned table names will be prefixed with the schema name.
* @return array all table names in the database.
*/
protected
function
findTableNames
(
$schema
=
''
)
{
throw
new
Exception
(
get_class
(
$this
)
.
' does not support fetching all table names.'
);
}
/**
* Quotes a table name for use in a query.
* If the table name contains schema prefix, the prefix will also be properly quoted.
* If the table name is already quoted or contains special characters including '(', '[[' and '{{',
* then this method will do nothing.
* @param string $name table name
* @return string the properly quoted table name
* @see quoteSimpleTableName
*/
public
function
quoteTableName
(
$name
)
{
if
(
strpos
(
$name
,
'('
)
!==
false
||
strpos
(
$name
,
'[['
)
!==
false
||
strpos
(
$name
,
'{{'
)
!==
false
)
{
return
$name
;
}
if
(
strpos
(
$name
,
'.'
)
===
false
)
{
return
$this
->
quoteSimpleTableName
(
$name
);
}
...
...
@@ -211,25 +230,19 @@ abstract class Driver extends \yii\base\Object
}
/**
* Quotes a simple table name for use in a query.
* A simple table name does not schema prefix.
* @param string $name table name
* @return string the properly quoted table name
*/
public
function
quoteSimpleTableName
(
$name
)
{
return
strpos
(
$name
,
"'"
)
!==
false
?
$name
:
"'"
.
$name
.
"'"
;
}
/**
* Quotes a column name for use in a query.
* If the column name contains prefix, the prefix will also be properly quoted.
* If the column name is already quoted or contains special characters including '(', '[[' and '{{',
* then this method will do nothing.
* @param string $name column name
* @return string the properly quoted column name
* @see quoteSimpleColumnName
*/
public
function
quoteColumnName
(
$name
)
{
if
(
strpos
(
$name
,
'('
)
!==
false
||
strpos
(
$name
,
'[['
)
!==
false
||
strpos
(
$name
,
'{{'
)
!==
false
)
{
return
$name
;
}
if
((
$pos
=
strrpos
(
$name
,
'.'
))
!==
false
)
{
$prefix
=
$this
->
quoteTableName
(
substr
(
$name
,
0
,
$pos
))
.
'.'
;
$name
=
substr
(
$name
,
$pos
+
1
);
...
...
@@ -240,36 +253,43 @@ abstract class Driver extends \yii\base\Object
}
/**
* Quotes a simple column name for use in a query.
* A simple column name does not contain prefix.
* @param string $name column name
* @return string the properly quoted column name
* Quotes a simple table name for use in a query.
* A simple table name should contain the table name only without any schema prefix.
* If the table name is already quoted, this method will do nothing.
* @param string $name table name
* @return string the properly quoted table name
*/
public
function
quoteSimple
Column
Name
(
$name
)
public
function
quoteSimple
Table
Name
(
$name
)
{
return
strpos
(
$name
,
'"'
)
!==
false
||
$name
===
'*'
?
$name
:
'"'
.
$name
.
'"'
;
return
strpos
(
$name
,
"'"
)
!==
false
?
$name
:
"'"
.
$name
.
"'"
;
}
/**
* Creates a query builder for the database.
* This method may be overridden by child classes to create a DBMS-specific query builder.
* @return QueryBuilder query builder instance
* Quotes a simple column name for use in a query.
* A simple column name should contain the column name only without any prefix.
* If the column name is already quoted or is the asterisk character '*', this method will do nothing.
* @param string $name column name
* @return string the properly quoted column name
*/
public
function
createQueryBuilder
(
)
public
function
quoteSimpleColumnName
(
$name
)
{
return
new
QueryBuilder
(
$this
->
connection
)
;
return
strpos
(
$name
,
'"'
)
!==
false
||
$name
===
'*'
?
$name
:
'"'
.
$name
.
'"'
;
}
/**
* Returns all table names in the database.
* This method should be overridden by child classes in order to support this feature
* because the default implementation simply throws an exception.
* @param string $schema the schema of the tables. Defaults to empty string, meaning the current or default schema.
* If not empty, the returned table names will be prefixed with the schema name.
* @return array all table names in the database.
* Returns the real name of a table name.
* This method will strip off curly brackets from the given table name
* and replace the percentage character in the name with [[Connection::tablePrefix]].
* @param string $name the table name to be converted
* @return string the real name of the given table name
*/
p
rotected
function
findTableNames
(
$schema
=
''
)
p
ublic
function
getRealTableName
(
$name
)
{
throw
new
Exception
(
get_class
(
$this
)
.
'does not support fetching all table names.'
);
if
(
$this
->
connection
->
enableAutoQuoting
&&
strpos
(
$name
,
'{{'
)
!==
false
)
{
$name
=
preg_replace
(
'/\\{\\{(.*?)\\}\\}/'
,
'\1'
,
$name
);
return
str_replace
(
'%'
,
$this
->
connection
->
tablePrefix
,
$name
);
}
else
{
return
$name
;
}
}
}
framework/db/QueryBuilder.php
View file @
fe90d4dd
...
...
@@ -32,10 +32,6 @@ class QueryBuilder extends \yii\base\Object
*/
public
$separator
=
" "
;
/**
* @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.
...
...
@@ -99,7 +95,7 @@ class QueryBuilder extends \yii\base\Object
$placeholders
=
array
();
$count
=
0
;
foreach
(
$columns
as
$name
=>
$value
)
{
$names
[]
=
$this
->
quoteColumnName
(
$name
);
$names
[]
=
$this
->
connection
->
quoteColumnName
(
$name
);
if
(
$value
instanceof
Expression
)
{
$placeholders
[]
=
$value
->
expression
;
foreach
(
$value
->
params
as
$n
=>
$v
)
{
...
...
@@ -112,7 +108,7 @@ class QueryBuilder extends \yii\base\Object
}
}
return
'INSERT INTO '
.
$this
->
quoteTableName
(
$table
)
return
'INSERT INTO '
.
$this
->
connection
->
quoteTableName
(
$table
)
.
' ('
.
implode
(
', '
,
$names
)
.
') VALUES ('
.
implode
(
', '
,
$placeholders
)
.
')'
;
}
...
...
@@ -144,17 +140,17 @@ class QueryBuilder extends \yii\base\Object
$count
=
0
;
foreach
(
$columns
as
$name
=>
$value
)
{
if
(
$value
instanceof
Expression
)
{
$lines
[]
=
$this
->
quoteColumnName
(
$name
,
tru
e
)
.
'='
.
$value
->
expression
;
$lines
[]
=
$this
->
connection
->
quoteColumnName
(
$nam
e
)
.
'='
.
$value
->
expression
;
foreach
(
$value
->
params
as
$n
=>
$v
)
{
$params
[
$n
]
=
$v
;
}
}
else
{
$lines
[]
=
$this
->
quoteColumnName
(
$name
,
tru
e
)
.
'=:p'
.
$count
;
$lines
[]
=
$this
->
connection
->
quoteColumnName
(
$nam
e
)
.
'=:p'
.
$count
;
$params
[
':p'
.
$count
]
=
$value
;
$count
++
;
}
}
$sql
=
'UPDATE '
.
$this
->
quoteTableName
(
$table
)
.
' SET '
.
implode
(
', '
,
$lines
);
$sql
=
'UPDATE '
.
$this
->
connection
->
quoteTableName
(
$table
)
.
' SET '
.
implode
(
', '
,
$lines
);
if
((
$where
=
$this
->
buildCondition
(
$condition
))
!==
''
)
{
$sql
.=
' WHERE '
.
$where
;
}
...
...
@@ -179,7 +175,7 @@ class QueryBuilder extends \yii\base\Object
*/
public
function
delete
(
$table
,
$condition
=
''
)
{
$sql
=
'DELETE FROM '
.
$this
->
quoteTableName
(
$table
);
$sql
=
'DELETE FROM '
.
$this
->
connection
->
quoteTableName
(
$table
);
if
((
$where
=
$this
->
buildCondition
(
$condition
))
!==
''
)
{
$sql
.=
' WHERE '
.
$where
;
}
...
...
@@ -217,12 +213,12 @@ class QueryBuilder extends \yii\base\Object
$cols
=
array
();
foreach
(
$columns
as
$name
=>
$type
)
{
if
(
is_string
(
$name
))
{
$cols
[]
=
"
\t
"
.
$this
->
quoteColumnName
(
$name
)
.
' '
.
$this
->
getColumnType
(
$type
);
$cols
[]
=
"
\t
"
.
$this
->
connection
->
quoteColumnName
(
$name
)
.
' '
.
$this
->
getColumnType
(
$type
);
}
else
{
$cols
[]
=
"
\t
"
.
$type
;
}
}
$sql
=
"CREATE TABLE "
.
$this
->
quoteTableName
(
$table
)
.
" (
\n
"
.
implode
(
",
\n
"
,
$cols
)
.
"
\n
)"
;
$sql
=
"CREATE TABLE "
.
$this
->
connection
->
quoteTableName
(
$table
)
.
" (
\n
"
.
implode
(
",
\n
"
,
$cols
)
.
"
\n
)"
;
return
$options
===
null
?
$sql
:
$sql
.
' '
.
$options
;
}
...
...
@@ -234,7 +230,7 @@ class QueryBuilder extends \yii\base\Object
*/
public
function
renameTable
(
$oldName
,
$newName
)
{
return
'RENAME TABLE '
.
$this
->
quoteTableName
(
$oldName
)
.
' TO '
.
$this
->
quoteTableName
(
$newName
);
return
'RENAME TABLE '
.
$this
->
connection
->
quoteTableName
(
$oldName
)
.
' TO '
.
$this
->
connection
->
quoteTableName
(
$newName
);
}
/**
...
...
@@ -244,7 +240,7 @@ class QueryBuilder extends \yii\base\Object
*/
public
function
dropTable
(
$table
)
{
return
"DROP TABLE "
.
$this
->
quoteTableName
(
$table
);
return
"DROP TABLE "
.
$this
->
connection
->
quoteTableName
(
$table
);
}
/**
...
...
@@ -254,7 +250,7 @@ class QueryBuilder extends \yii\base\Object
*/
public
function
truncateTable
(
$table
)
{
return
"TRUNCATE TABLE "
.
$this
->
quoteTableName
(
$table
);
return
"TRUNCATE TABLE "
.
$this
->
connection
->
quoteTableName
(
$table
);
}
/**
...
...
@@ -268,8 +264,8 @@ class QueryBuilder extends \yii\base\Object
*/
public
function
addColumn
(
$table
,
$column
,
$type
)
{
return
'ALTER TABLE '
.
$this
->
quoteTableName
(
$table
)
.
' ADD '
.
$this
->
quoteColumnName
(
$column
)
.
' '
return
'ALTER TABLE '
.
$this
->
connection
->
quoteTableName
(
$table
)
.
' ADD '
.
$this
->
connection
->
quoteColumnName
(
$column
)
.
' '
.
$this
->
getColumnType
(
$type
);
}
...
...
@@ -281,8 +277,8 @@ class QueryBuilder extends \yii\base\Object
*/
public
function
dropColumn
(
$table
,
$column
)
{
return
"ALTER TABLE "
.
$this
->
quoteTableName
(
$table
)
.
" DROP COLUMN "
.
$this
->
quoteColumnName
(
$column
,
true
);
return
"ALTER TABLE "
.
$this
->
connection
->
quoteTableName
(
$table
)
.
" DROP COLUMN "
.
$this
->
connection
->
quoteColumnName
(
$column
);
}
/**
...
...
@@ -294,9 +290,9 @@ class QueryBuilder extends \yii\base\Object
*/
public
function
renameColumn
(
$table
,
$oldName
,
$newName
)
{
return
"ALTER TABLE "
.
$this
->
quoteTableName
(
$table
)
.
" RENAME COLUMN "
.
$this
->
quoteColumnName
(
$oldName
,
tru
e
)
.
" TO "
.
$this
->
quoteColumnName
(
$newName
,
tru
e
);
return
"ALTER TABLE "
.
$this
->
connection
->
quoteTableName
(
$table
)
.
" RENAME COLUMN "
.
$this
->
connection
->
quoteColumnName
(
$oldNam
e
)
.
" TO "
.
$this
->
connection
->
quoteColumnName
(
$newNam
e
);
}
/**
...
...
@@ -311,9 +307,9 @@ class QueryBuilder extends \yii\base\Object
*/
public
function
alterColumn
(
$table
,
$column
,
$type
)
{
return
'ALTER TABLE '
.
$this
->
quoteTableName
(
$table
)
.
' CHANGE '
.
$this
->
quoteColumnName
(
$column
,
true
)
.
' '
.
$this
->
quoteColumnName
(
$column
,
true
)
.
' '
return
'ALTER TABLE '
.
$this
->
connection
->
quoteTableName
(
$table
)
.
' CHANGE '
.
$this
->
connection
->
quoteColumnName
(
$column
)
.
' '
.
$this
->
connection
->
quoteColumnName
(
$column
)
.
' '
.
$this
->
getColumnType
(
$type
);
}
...
...
@@ -333,10 +329,10 @@ class QueryBuilder extends \yii\base\Object
*/
public
function
addForeignKey
(
$name
,
$table
,
$columns
,
$refTable
,
$refColumns
,
$delete
=
null
,
$update
=
null
)
{
$sql
=
'ALTER TABLE '
.
$this
->
quoteTableName
(
$table
)
.
' ADD CONSTRAINT '
.
$this
->
quoteColumnName
(
$name
)
$sql
=
'ALTER TABLE '
.
$this
->
connection
->
quoteTableName
(
$table
)
.
' ADD CONSTRAINT '
.
$this
->
connection
->
quoteColumnName
(
$name
)
.
' FOREIGN KEY ('
.
$this
->
buildColumns
(
$columns
)
.
')'
.
' REFERENCES '
.
$this
->
quoteTableName
(
$refTable
)
.
' REFERENCES '
.
$this
->
connection
->
quoteTableName
(
$refTable
)
.
' ('
.
$this
->
buildColumns
(
$refColumns
)
.
')'
;
if
(
$delete
!==
null
)
{
$sql
.=
' ON DELETE '
.
$delete
;
...
...
@@ -355,8 +351,8 @@ class QueryBuilder extends \yii\base\Object
*/
public
function
dropForeignKey
(
$name
,
$table
)
{
return
'ALTER TABLE '
.
$this
->
quoteTableName
(
$table
)
.
' DROP CONSTRAINT '
.
$this
->
quoteColumnName
(
$name
);
return
'ALTER TABLE '
.
$this
->
connection
->
quoteTableName
(
$table
)
.
' DROP CONSTRAINT '
.
$this
->
connection
->
quoteColumnName
(
$name
);
}
/**
...
...
@@ -372,8 +368,8 @@ class QueryBuilder extends \yii\base\Object
public
function
createIndex
(
$name
,
$table
,
$columns
,
$unique
=
false
)
{
return
(
$unique
?
'CREATE UNIQUE INDEX '
:
'CREATE INDEX '
)
.
$this
->
quoteTableName
(
$name
)
.
' ON '
.
$this
->
quoteTableName
(
$table
)
.
$this
->
connection
->
quoteTableName
(
$name
)
.
' ON '
.
$this
->
connection
->
quoteTableName
(
$table
)
.
' ('
.
$this
->
buildColumns
(
$columns
)
.
')'
;
}
...
...
@@ -385,7 +381,7 @@ class QueryBuilder extends \yii\base\Object
*/
public
function
dropIndex
(
$name
,
$table
)
{
return
'DROP INDEX '
.
$this
->
quoteTableName
(
$name
)
.
' ON '
.
$this
->
quoteTableName
(
$table
);
return
'DROP INDEX '
.
$this
->
connection
->
quoteTableName
(
$name
)
.
' ON '
.
$this
->
connection
->
quoteTableName
(
$table
);
}
/**
...
...
@@ -500,7 +496,7 @@ class QueryBuilder extends \yii\base\Object
$parts
[]
=
$this
->
buildInCondition
(
'in'
,
array
(
$column
,
$value
));
}
else
{
if
(
strpos
(
$column
,
'('
)
===
false
)
{
$column
=
$this
->
quoteColumnName
(
$column
);
$column
=
$this
->
connection
->
quoteColumnName
(
$column
);
}
if
(
$value
===
null
)
{
$parts
[]
=
"
$column
IS NULL"
;
...
...
@@ -541,7 +537,7 @@ class QueryBuilder extends \yii\base\Object
list
(
$column
,
$value1
,
$value2
)
=
$operands
;
if
(
strpos
(
$column
,
'('
)
===
false
)
{
$column
=
$this
->
quoteColumnName
(
$column
);
$column
=
$this
->
connection
->
quoteColumnName
(
$column
);
}
$value1
=
is_string
(
$value1
)
?
$this
->
connection
->
quoteValue
(
$value1
)
:
(
string
)
$value1
;
$value2
=
is_string
(
$value2
)
?
$this
->
connection
->
quoteValue
(
$value2
)
:
(
string
)
$value2
;
...
...
@@ -581,7 +577,7 @@ class QueryBuilder extends \yii\base\Object
}
}
if
(
strpos
(
$column
,
'('
)
===
false
)
{
$column
=
$this
->
quoteColumnName
(
$column
);
$column
=
$this
->
connection
->
quoteColumnName
(
$column
);
}
if
(
count
(
$values
)
>
1
)
{
...
...
@@ -596,7 +592,7 @@ class QueryBuilder extends \yii\base\Object
{
foreach
(
$columns
as
$i
=>
$column
)
{
if
(
strpos
(
$column
,
'('
)
===
false
)
{
$columns
[
$i
]
=
$this
->
quoteColumnName
(
$column
);
$columns
[
$i
]
=
$this
->
connection
->
quoteColumnName
(
$column
);
}
}
$vss
=
array
();
...
...
@@ -636,7 +632,7 @@ class QueryBuilder extends \yii\base\Object
}
if
(
strpos
(
$column
,
'('
)
===
false
)
{
$column
=
$this
->
quoteColumnName
(
$column
);
$column
=
$this
->
connection
->
quoteColumnName
(
$column
);
}
$parts
=
array
();
...
...
@@ -664,24 +660,21 @@ class QueryBuilder extends \yii\base\Object
return
$select
.
' *'
;
}
if
(
$this
->
autoQuote
)
{
$driver
=
$this
->
connection
->
driver
;
if
(
!
is_array
(
$columns
))
{
if
(
strpos
(
$columns
,
'('
)
!==
false
)
{
return
$select
.
' '
.
$columns
;
}
else
{
$columns
=
preg_split
(
'/\s*,\s*/'
,
trim
(
$columns
),
-
1
,
PREG_SPLIT_NO_EMPTY
);
}
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
;
}
elseif
(
strpos
(
$column
,
'('
)
===
false
)
{
if
(
preg_match
(
'/^(.*?)(?i:\s+as\s+|\s+)([\w\-_\.]+)$/'
,
$column
,
$matches
)
)
{
$columns
[
$i
]
=
$driver
->
quoteColumnName
(
$matches
[
1
])
.
' AS '
.
$driver
->
quoteSimpleColumnName
(
$matches
[
2
]);
}
else
{
$columns
[
$i
]
=
$driver
->
quoteColumnName
(
$column
);
}
}
foreach
(
$columns
as
$i
=>
$column
)
{
if
(
is_object
(
$column
))
{
$columns
[
$i
]
=
(
string
)
$column
;
}
elseif
(
strpos
(
$column
,
'('
)
===
false
)
{
if
(
preg_match
(
'/^(.*?)(?i:\s+as\s+|\s+)([\w\-_\.]+)$/'
,
$column
,
$matches
))
{
$columns
[
$i
]
=
$this
->
connection
->
quoteColumnName
(
$matches
[
1
])
.
' AS '
.
$this
->
connection
->
quoteColumnName
(
$matches
[
2
]);
}
else
{
$columns
[
$i
]
=
$this
->
connection
->
quoteColumnName
(
$column
);
}
}
}
...
...
@@ -703,22 +696,19 @@ class QueryBuilder extends \yii\base\Object
return
''
;
}
if
(
$this
->
autoQuote
)
{
$driver
=
$this
->
connection
->
driver
;
if
(
!
is_array
(
$tables
))
{
if
(
strpos
(
$tables
,
'('
)
!==
false
)
{
return
'FROM '
.
$tables
;
}
else
{
$tables
=
preg_split
(
'/\s*,\s*/'
,
trim
(
$tables
),
-
1
,
PREG_SPLIT_NO_EMPTY
);
}
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
,
'('
)
===
fals
e
)
{
if
(
preg_match
(
'/^(.*?)(?i:\s+as\s+|\s+)(.*)$/i'
,
$table
,
$matches
))
{
// with alias
$tables
[
$i
]
=
$driver
->
quoteTableName
(
$matches
[
1
])
.
' '
.
$driver
->
quoteTableName
(
$matches
[
2
]);
}
else
{
$tables
[
$i
]
=
$driver
->
quoteTableName
(
$table
);
}
}
foreach
(
$tables
as
$i
=>
$tabl
e
)
{
if
(
strpos
(
$table
,
'('
)
===
false
)
{
if
(
preg_match
(
'/^(.*?)(?i:\s+as\s+|\s+)(.*)$/i'
,
$table
,
$matches
))
{
// with alias
$tables
[
$i
]
=
$this
->
connection
->
quoteTableName
(
$matches
[
1
])
.
' '
.
$this
->
connection
->
quoteTableName
(
$matches
[
2
]);
}
else
{
$tables
[
$i
]
=
$this
->
connection
->
quoteTableName
(
$table
);
}
}
}
...
...
@@ -747,12 +737,11 @@ class QueryBuilder extends \yii\base\Object
if
(
is_array
(
$join
))
{
// 0:join type, 1:table name, 2:on-condition
if
(
isset
(
$join
[
0
],
$join
[
1
]))
{
$table
=
$join
[
1
];
if
(
$this
->
autoQuote
&&
strpos
(
$table
,
'('
)
===
false
)
{
$driver
=
$this
->
connection
->
driver
;
if
(
strpos
(
$table
,
'('
)
===
false
)
{
if
(
preg_match
(
'/^(.*?)(?i:\s+as\s+|\s+)(.*)$/'
,
$table
,
$matches
))
{
// with alias
$table
=
$
driver
->
quoteTableName
(
$matches
[
1
])
.
' '
.
$driver
->
quoteTableName
(
$matches
[
2
]);
$table
=
$
this
->
connection
->
quoteTableName
(
$matches
[
1
])
.
' '
.
$this
->
connection
->
quoteTableName
(
$matches
[
2
]);
}
else
{
$table
=
$
driver
->
quoteTableName
(
$table
);
$table
=
$
this
->
connection
->
quoteTableName
(
$table
);
}
}
$joins
[
$i
]
=
$join
[
0
]
.
' '
.
$table
;
...
...
@@ -813,24 +802,21 @@ class QueryBuilder extends \yii\base\Object
if
(
empty
(
$columns
))
{
return
''
;
}
if
(
$this
->
autoQuote
)
{
$driver
=
$this
->
connection
->
driver
;
if
(
!
is_array
(
$columns
))
{
if
(
strpos
(
$columns
,
'('
)
!==
false
)
{
return
'ORDER BY '
.
$columns
;
}
else
{
$columns
=
preg_split
(
'/\s*,\s*/'
,
trim
(
$columns
),
-
1
,
PREG_SPLIT_NO_EMPTY
);
}
if
(
!
is_array
(
$columns
))
{
if
(
strpos
(
$columns
,
'('
)
!==
false
)
{
return
'ORDER BY '
.
$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
;
}
elseif
(
strpos
(
$column
,
'('
)
===
false
)
{
if
(
preg_match
(
'/^(.*?)\s+(asc|desc)$/i'
,
$column
,
$matches
)
)
{
$columns
[
$i
]
=
$driver
->
quoteColumnName
(
$matches
[
1
])
.
' '
.
$matches
[
2
];
}
else
{
$columns
[
$i
]
=
$driver
->
quoteColumnName
(
$column
);
}
}
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
->
connection
->
quoteColumnName
(
$matches
[
1
])
.
' '
.
$matches
[
2
];
}
else
{
$columns
[
$i
]
=
$this
->
connection
->
quoteColumnName
(
$column
);
}
}
}
...
...
@@ -879,61 +865,26 @@ class QueryBuilder extends \yii\base\Object
/**
* Processes columns and properly quote them if necessary.
* This method will quote columns if [[autoQuote]] is true.
* It will join all columns into a string with comma as separators.
* @param string|array $columns the columns to be processed
* @return string the processing result
*/
protected
function
buildColumns
(
$columns
)
{
if
(
$this
->
autoQuote
)
{
if
(
!
is_array
(
$columns
))
{
if
(
strpos
(
$columns
,
'('
)
!==
false
)
{
return
$columns
;
}
else
{
$columns
=
preg_split
(
'/\s*,\s*/'
,
$columns
,
-
1
,
PREG_SPLIT_NO_EMPTY
);
}
if
(
!
is_array
(
$columns
))
{
if
(
strpos
(
$columns
,
'('
)
!==
false
)
{
return
$columns
;
}
else
{
$columns
=
preg_split
(
'/\s*,\s*/'
,
$columns
,
-
1
,
PREG_SPLIT_NO_EMPTY
);
}
foreach
(
$columns
as
$i
=>
$column
)
{
if
(
is_object
(
$column
)
)
{
$columns
[
$i
]
=
(
string
)
$column
;
}
elseif
(
strpos
(
$column
,
'('
)
===
false
)
{
$columns
[
$i
]
=
$this
->
quoteColumnName
(
$column
);
}
}
foreach
(
$columns
as
$i
=>
$column
)
{
if
(
is_object
(
$column
))
{
$columns
[
$i
]
=
(
string
)
$column
;
}
elseif
(
strpos
(
$column
,
'('
)
===
false
)
{
$columns
[
$i
]
=
$this
->
connection
->
quoteColumnName
(
$column
);
}
}
return
is_array
(
$columns
)
?
implode
(
', '
,
$columns
)
:
$columns
;
}
/**
* Quotes a table name for use in a query.
* This method will perform name quoting only when [[autoQuote]] is true.
* @param string $name table name
* @param boolean $simple whether the name should be treated as a simple table name without any prefix.
* @return string the properly quoted table name
*/
protected
function
quoteTableName
(
$name
,
$simple
=
false
)
{
if
(
$this
->
autoQuote
)
{
return
$this
->
connection
->
quoteTableName
(
$name
,
$simple
);
}
else
{
return
$name
;
}
}
/**
* Quotes a column name for use in a query.
* This method will perform name quoting only when [[autoQuote]] is true.
* @param string $name column name
* @param boolean $simple whether the name should be treated as a simple column name without any prefix.
* @return string the properly quoted column name
*/
protected
function
quoteColumnName
(
$name
,
$simple
=
false
)
{
if
(
$this
->
autoQuote
)
{
return
$this
->
connection
->
quoteColumnName
(
$name
,
$simple
);
}
else
{
return
$name
;
}
}
}
framework/db/mysql/QueryBuilder.php
View file @
fe90d4dd
...
...
@@ -46,10 +46,11 @@ class QueryBuilder extends \yii\db\QueryBuilder
* @param string $oldName the old name of the column. The name will be properly quoted by the method.
* @param string $newName the new name of the column. The name will be properly quoted by the method.
* @return string the SQL statement for renaming a DB column.
* @throws Exception
*/
public
function
renameColumn
(
$table
,
$oldName
,
$newName
)
{
$quotedTable
=
$this
->
quoteTableName
(
$table
);
$quotedTable
=
$this
->
connection
->
quoteTableName
(
$table
);
$row
=
$this
->
connection
->
createCommand
(
'SHOW CREATE TABLE '
.
$quotedTable
)
->
queryRow
();
if
(
$row
===
false
)
{
throw
new
Exception
(
"Unable to find '
$oldName
' in table '
$table
'."
);
...
...
@@ -64,16 +65,16 @@ class QueryBuilder extends \yii\db\QueryBuilder
foreach
(
$matches
[
1
]
as
$i
=>
$c
)
{
if
(
$c
===
$oldName
)
{
return
"ALTER TABLE
$quotedTable
CHANGE "
.
$this
->
quoteColumnName
(
$oldName
,
tru
e
)
.
' '
.
$this
->
quoteColumnName
(
$newName
,
tru
e
)
.
' '
.
$this
->
connection
->
quoteColumnName
(
$oldNam
e
)
.
' '
.
$this
->
connection
->
quoteColumnName
(
$newNam
e
)
.
' '
.
$matches
[
2
][
$i
];
}
}
}
// try to give back a SQL anyway
return
"ALTER TABLE
$quotedTable
CHANGE "
.
$this
->
quoteColumnName
(
$oldName
,
tru
e
)
.
' '
.
$this
->
quoteColumnName
(
$newName
,
tru
e
);
.
$this
->
connection
->
quoteColumnName
(
$oldNam
e
)
.
' '
.
$this
->
connection
->
quoteColumnName
(
$newNam
e
);
}
/**
...
...
@@ -84,7 +85,7 @@ class QueryBuilder extends \yii\db\QueryBuilder
*/
public
function
dropForeignKey
(
$name
,
$table
)
{
return
'ALTER TABLE '
.
$this
->
quoteTableName
(
$table
)
.
' DROP FOREIGN KEY '
.
$this
->
quoteColumnName
(
$name
);
return
'ALTER TABLE '
.
$this
->
connection
->
quoteTableName
(
$table
)
.
' DROP FOREIGN KEY '
.
$this
->
connection
->
quoteColumnName
(
$name
);
}
}
tests/unit/framework/db/CommandTest.php
View file @
fe90d4dd
...
...
@@ -36,6 +36,15 @@ class CommandTest extends \yiiunit\MysqlTestCase
$this
->
assertEquals
(
$sql2
,
$command
->
sql
);
}
function
testAutoQuoting
()
{
$db
=
$this
->
getConnection
(
false
);
$sql
=
'SELECT [[id]], [[t.name]] FROM {{tbl_customer}} t'
;
$command
=
$db
->
createCommand
(
$sql
);
$this
->
assertEquals
(
"SELECT `id`, `t`.`name` FROM `tbl_customer` t"
,
$command
->
sql
);
}
function
testPrepareCancel
()
{
$db
=
$this
->
getConnection
(
false
);
...
...
tests/unit/framework/db/ConnectionTest.php
View file @
fe90d4dd
...
...
@@ -49,7 +49,7 @@ class ConnectionTest extends \yiiunit\MysqlTestCase
$connection
=
$this
->
getConnection
(
false
);
$this
->
assertEquals
(
123
,
$connection
->
quoteValue
(
123
));
$this
->
assertEquals
(
"'string'"
,
$connection
->
quoteValue
(
'string'
));
$this
->
assertEquals
(
"'It\'s interesting'"
,
$connection
->
quoteValue
(
"It's interesting"
));
$this
->
assertEquals
(
"'It
\
\
's interesting'"
,
$connection
->
quoteValue
(
"It's interesting"
));
}
function
testQuoteTableName
()
...
...
@@ -58,7 +58,10 @@ class ConnectionTest extends \yiiunit\MysqlTestCase
$this
->
assertEquals
(
'`table`'
,
$connection
->
quoteTableName
(
'table'
));
$this
->
assertEquals
(
'`table`'
,
$connection
->
quoteTableName
(
'`table`'
));
$this
->
assertEquals
(
'`schema`.`table`'
,
$connection
->
quoteTableName
(
'schema.table'
));
$this
->
assertEquals
(
'`schema.table`'
,
$connection
->
quoteTableName
(
'schema.table'
,
true
));
$this
->
assertEquals
(
'`schema`.`table`'
,
$connection
->
quoteTableName
(
'schema.`table`'
));
$this
->
assertEquals
(
'[[table]]'
,
$connection
->
quoteTableName
(
'[[table]]'
));
$this
->
assertEquals
(
'{{table}}'
,
$connection
->
quoteTableName
(
'{{table}}'
));
$this
->
assertEquals
(
'(table)'
,
$connection
->
quoteTableName
(
'(table)'
));
}
function
testQuoteColumnName
()
...
...
@@ -67,7 +70,10 @@ class ConnectionTest extends \yiiunit\MysqlTestCase
$this
->
assertEquals
(
'`column`'
,
$connection
->
quoteColumnName
(
'column'
));
$this
->
assertEquals
(
'`column`'
,
$connection
->
quoteColumnName
(
'`column`'
));
$this
->
assertEquals
(
'`table`.`column`'
,
$connection
->
quoteColumnName
(
'table.column'
));
$this
->
assertEquals
(
'`table.column`'
,
$connection
->
quoteColumnName
(
'table.column'
,
true
));
$this
->
assertEquals
(
'`table`.`column`'
,
$connection
->
quoteColumnName
(
'table.`column`'
));
$this
->
assertEquals
(
'[[column]]'
,
$connection
->
quoteColumnName
(
'[[column]]'
));
$this
->
assertEquals
(
'{{column}}'
,
$connection
->
quoteColumnName
(
'{{column}}'
));
$this
->
assertEquals
(
'(column)'
,
$connection
->
quoteColumnName
(
'(column)'
));
}
function
testGetPdoType
()
...
...
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