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
3335f09d
Commit
3335f09d
authored
Aug 21, 2011
by
Qiang Xue
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
w
parent
05c7915d
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
811 additions
and
491 deletions
+811
-491
ColumnSchema.php
framework/db/dao/ColumnSchema.php
+16
-13
Command.php
framework/db/dao/Command.php
+1
-1
Query.php
framework/db/dao/Query.php
+5
-0
QueryBuilder.php
framework/db/dao/QueryBuilder.php
+361
-247
Schema.php
framework/db/dao/Schema.php
+9
-220
TableSchema.php
framework/db/dao/TableSchema.php
+14
-10
ColumnSchema.php
framework/db/dao/mysql/ColumnSchema.php
+71
-0
Schema.php
framework/db/dao/mysql/Schema.php
+310
-0
TableSchema.php
framework/db/dao/mysql/TableSchema.php
+24
-0
No files found.
framework/db/dao/ColumnSchema.php
View file @
3335f09d
<?php
<?php
/**
/**
* C
DbC
olumnSchema class file.
* ColumnSchema class file.
*
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.yiiframework.com/
* @link http://www.yiiframework.com/
* @copyright Copyright © 2008-201
1
Yii Software LLC
* @copyright Copyright © 2008-201
2
Yii Software LLC
* @license http://www.yiiframework.com/license/
* @license http://www.yiiframework.com/license/
*/
*/
/**
/**
* C
DbC
olumnSchema class describes the column meta data of a database table.
* ColumnSchema class describes the column meta data of a database table.
*
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @author Qiang Xue <qiang.xue@gmail.com>
* @version $Id: CDbColumnSchema.php 3099 2011-03-19 01:26:47Z qiang.xue $
* @since 2.0
* @package system.db.schema
* @since 1.0
*/
*/
class
C
DbC
olumnSchema
extends
CComponent
class
ColumnSchema
extends
CComponent
{
{
/**
/**
* @var string name of this column (without quotes).
* @var string name of this column (without quotes).
...
@@ -25,19 +23,25 @@ class CDbColumnSchema extends CComponent
...
@@ -25,19 +23,25 @@ class CDbColumnSchema extends CComponent
/**
/**
* @var string raw name of this column. This is the quoted name that can be used in SQL queries.
* @var string raw name of this column. This is the quoted name that can be used in SQL queries.
*/
*/
public
$
raw
Name
;
public
$
quoted
Name
;
/**
/**
* @var boolean whether this column can be null.
* @var boolean whether this column can be null.
*/
*/
public
$allowNull
;
public
$allowNull
;
/**
/**
* @var string the DB type of this column.
* @var string logical type of this column. Possible logic types include:
* string, text, boolean, integer, float, decimal, datetime, timestamp, time, date, binary
*/
*/
public
$
dbT
ype
;
public
$
t
ype
;
/**
/**
* @var string the PHP type of this column.
* @var string the PHP type of this column. Possible PHP types include:
* string, boolean, integer, double.
*/
*/
public
$type
;
public
$phpType
;
/**
* @var string the DB type of this column.
*/
public
$dbType
;
/**
/**
* @var mixed default value of this column
* @var mixed default value of this column
*/
*/
...
@@ -64,7 +68,6 @@ class CDbColumnSchema extends CComponent
...
@@ -64,7 +68,6 @@ class CDbColumnSchema extends CComponent
public
$isForeignKey
;
public
$isForeignKey
;
/**
/**
* @var boolean whether this column is auto-incremental
* @var boolean whether this column is auto-incremental
* @since 1.1.7
*/
*/
public
$autoIncrement
=
false
;
public
$autoIncrement
=
false
;
...
...
framework/db/dao/Command.php
View file @
3335f09d
...
@@ -78,7 +78,7 @@ class Command extends \yii\base\Component
...
@@ -78,7 +78,7 @@ class Command extends \yii\base\Component
* {@link setFetchMode FetchMode}. See {@link http://www.php.net/manual/en/function.PDOStatement-setFetchMode.php}
* {@link setFetchMode FetchMode}. See {@link http://www.php.net/manual/en/function.PDOStatement-setFetchMode.php}
* for more details.
* for more details.
*/
*/
public
function
__construct
(
CDbConnection
$connection
,
$query
=
null
)
public
function
__construct
(
$connection
,
$query
=
null
)
{
{
$this
->
_connection
=
$connection
;
$this
->
_connection
=
$connection
;
if
(
is_array
(
$query
))
if
(
is_array
(
$query
))
...
...
framework/db/dao/Query.php
View file @
3335f09d
...
@@ -24,6 +24,11 @@ class Query extends CComponent
...
@@ -24,6 +24,11 @@ class Query extends CComponent
* or an array of column names. Defaults to '*', meaning all columns.
* or an array of column names. Defaults to '*', meaning all columns.
*/
*/
public
$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
;
public
$from
;
public
$from
;
/**
/**
...
...
framework/db/dao/QueryBuilder.php
View file @
3335f09d
...
@@ -20,7 +20,7 @@ class QueryBuilder extends \yii\base\Component
...
@@ -20,7 +20,7 @@ class QueryBuilder extends \yii\base\Component
{
{
private
$_connection
;
private
$_connection
;
public
function
__construct
(
Connection
$connection
)
public
function
__construct
(
$connection
)
{
{
$this
->
_connection
=
$connection
;
$this
->
_connection
=
$connection
;
}
}
...
@@ -36,24 +36,228 @@ class QueryBuilder extends \yii\base\Component
...
@@ -36,24 +36,228 @@ class QueryBuilder extends \yii\base\Component
public
function
build
(
$query
)
public
function
build
(
$query
)
{
{
$clauses
=
array
(
$clauses
=
array
(
$this
->
buildSelect
(
$query
->
select
,
$query
->
distinct
),
$this
->
buildSelect
(
$query
),
$this
->
buildFrom
(
$query
->
from
),
$this
->
buildFrom
(
$query
),
$this
->
buildJoin
(
$query
->
join
),
$this
->
buildJoin
(
$query
),
$this
->
buildWhere
(
$query
->
where
),
$this
->
buildWhere
(
$query
),
$this
->
buildGroupBy
(
$query
->
groupBy
),
$this
->
buildGroupBy
(
$query
),
$this
->
buildHaving
(
$query
->
having
),
$this
->
buildHaving
(
$query
),
$this
->
build
OrderBy
(
$query
->
orderB
y
),
$this
->
build
Union
(
$quer
y
),
$this
->
build
Limit
(
$query
->
offset
,
$query
->
limit
),
$this
->
build
OrderBy
(
$query
),
$this
->
build
Union
(
$query
->
union
),
$this
->
build
Limit
(
$query
),
);
);
return
implode
(
"
\n
"
,
array_filter
(
$clauses
));
return
implode
(
"
\n
"
,
array_filter
(
$clauses
));
}
}
protected
function
buildSelect
(
$columns
,
$distinct
)
/**
* Builds a SQL statement for creating a new DB table.
*
* The columns in the new table should be specified as name-definition pairs (e.g. 'name'=>'string'),
* where name stands for a column name which will be properly quoted by the method, and definition
* stands for the column type which can contain an abstract DB type.
* The {@link getColumnType} method will be invoked to convert any abstract type into a physical one.
*
* If a column is specified with definition only (e.g. 'PRIMARY KEY (name, type)'), it will be directly
* inserted into the generated SQL.
*
* @param string $table the name of the table to be created. The name will be properly quoted by the method.
* @param array $columns the columns (name=>definition) in the new table.
* @param string $options additional SQL fragment that will be appended to the generated SQL.
* @return string the SQL statement for creating a new DB table.
*/
public
function
createTable
(
$table
,
$columns
,
$options
=
null
)
{
$cols
=
array
();
foreach
(
$columns
as
$name
=>
$type
)
{
if
(
is_string
(
$name
))
$cols
[]
=
"
\t
"
.
$this
->
quoteColumnName
(
$name
)
.
' '
.
$this
->
getColumnType
(
$type
);
else
$cols
[]
=
"
\t
"
.
$type
;
}
$sql
=
"CREATE TABLE "
.
$this
->
quoteTableName
(
$table
)
.
" (
\n
"
.
implode
(
",
\n
"
,
$cols
)
.
"
\n
)"
;
return
$options
===
null
?
$sql
:
$sql
.
' '
.
$options
;
}
/**
* Builds a SQL statement for renaming a DB table.
* @param string $table the table to be renamed. The name will be properly quoted by the method.
* @param string $newName the new table name. The name will be properly quoted by the method.
* @return string the SQL statement for renaming a DB table.
*/
public
function
renameTable
(
$table
,
$newName
)
{
return
'RENAME TABLE '
.
$this
->
quoteTableName
(
$table
)
.
' TO '
.
$this
->
quoteTableName
(
$newName
);
}
/**
* Builds a SQL statement for dropping a DB table.
* @param string $table the table to be dropped. The name will be properly quoted by the method.
* @return string the SQL statement for dropping a DB table.
*/
public
function
dropTable
(
$table
)
{
return
"DROP TABLE "
.
$this
->
quoteTableName
(
$table
);
}
/**
* Builds a SQL statement for truncating a DB table.
* @param string $table the table to be truncated. The name will be properly quoted by the method.
* @return string the SQL statement for truncating a DB table.
*/
public
function
truncateTable
(
$table
)
{
{
$select
=
$distinct
?
'SELECT DISTINCT'
:
'SELECT'
;
return
"TRUNCATE TABLE "
.
$this
->
quoteTableName
(
$table
);
}
/**
* Builds a SQL statement for adding a new DB column.
* @param string $table the table that the new column will be added to. The table name will be properly quoted by the method.
* @param string $column the name of the new column. The name will be properly quoted by the method.
* @param string $type the column type. The {@link getColumnType} method will be invoked to convert abstract column type (if any)
* into the physical one. Anything that is not recognized as abstract type will be kept in the generated SQL.
* For example, 'string' will be turned into 'varchar(255)', while 'string not null' will become 'varchar(255) not null'.
* @return string the SQL statement for adding a new column.
* @since 1.1.6
*/
public
function
addColumn
(
$table
,
$column
,
$type
)
{
return
'ALTER TABLE '
.
$this
->
quoteTableName
(
$table
)
.
' ADD '
.
$this
->
quoteColumnName
(
$column
)
.
' '
.
$this
->
getColumnType
(
$type
);
}
/**
* Builds a SQL statement for dropping a DB column.
* @param string $table the table whose column is to be dropped. The name will be properly quoted by the method.
* @param string $column the name of the column to be dropped. The name will be properly quoted by the method.
* @return string the SQL statement for dropping a DB column.
* @since 1.1.6
*/
public
function
dropColumn
(
$table
,
$column
)
{
return
"ALTER TABLE "
.
$this
->
quoteTableName
(
$table
)
.
" DROP COLUMN "
.
$this
->
quoteColumnName
(
$column
);
}
/**
* Builds a SQL statement for renaming a column.
* @param string $table the table whose column is to be renamed. The name will be properly quoted by the method.
* @param string $name 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.
* @since 1.1.6
*/
public
function
renameColumn
(
$table
,
$name
,
$newName
)
{
return
"ALTER TABLE "
.
$this
->
quoteTableName
(
$table
)
.
" RENAME COLUMN "
.
$this
->
quoteColumnName
(
$name
)
.
" TO "
.
$this
->
quoteColumnName
(
$newName
);
}
/**
* Builds a SQL statement for changing the definition of a column.
* @param string $table the table whose column is to be changed. The table name will be properly quoted by the method.
* @param string $column the name of the column to be changed. The name will be properly quoted by the method.
* @param string $type the new column type. The {@link getColumnType} method will be invoked to convert abstract column type (if any)
* into the physical one. Anything that is not recognized as abstract type will be kept in the generated SQL.
* For example, 'string' will be turned into 'varchar(255)', while 'string not null' will become 'varchar(255) not null'.
* @return string the SQL statement for changing the definition of a column.
*/
public
function
alterColumn
(
$table
,
$column
,
$type
)
{
return
'ALTER TABLE '
.
$this
->
quoteTableName
(
$table
)
.
' CHANGE '
.
$this
->
quoteColumnName
(
$column
)
.
' '
.
$this
->
quoteColumnName
(
$column
)
.
' '
.
$this
->
getColumnType
(
$type
);
}
/**
* Builds a SQL statement for adding a foreign key constraint to an existing table.
* The method will properly quote the table and column names.
* @param string $name the name of the foreign key constraint.
* @param string $table the table that the foreign key constraint will be added to.
* @param string $columns the name of the column to that the constraint will be added on. If there are multiple columns, separate them with commas.
* @param string $refTable the table that the foreign key references to.
* @param string $refColumns the name of the column that the foreign key references to. If there are multiple columns, separate them with commas.
* @param string $delete the ON DELETE option. Most DBMS support these options: RESTRICT, CASCADE, NO ACTION, SET DEFAULT, SET NULL
* @param string $update the ON UPDATE option. Most DBMS support these options: RESTRICT, CASCADE, NO ACTION, SET DEFAULT, SET NULL
* @return string the SQL statement for adding a foreign key constraint to an existing table.
*/
public
function
addForeignKey
(
$name
,
$table
,
$columns
,
$refTable
,
$refColumns
,
$delete
=
null
,
$update
=
null
)
{
$columns
=
preg_split
(
'/\s*,\s*/'
,
$columns
,
-
1
,
PREG_SPLIT_NO_EMPTY
);
foreach
(
$columns
as
$i
=>
$col
)
$columns
[
$i
]
=
$this
->
quoteColumnName
(
$col
);
$refColumns
=
preg_split
(
'/\s*,\s*/'
,
$refColumns
,
-
1
,
PREG_SPLIT_NO_EMPTY
);
foreach
(
$refColumns
as
$i
=>
$col
)
$refColumns
[
$i
]
=
$this
->
quoteColumnName
(
$col
);
$sql
=
'ALTER TABLE '
.
$this
->
quoteTableName
(
$table
)
.
' ADD CONSTRAINT '
.
$this
->
quoteColumnName
(
$name
)
.
' FOREIGN KEY ('
.
implode
(
', '
,
$columns
)
.
')'
.
' REFERENCES '
.
$this
->
quoteTableName
(
$refTable
)
.
' ('
.
implode
(
', '
,
$refColumns
)
.
')'
;
if
(
$delete
!==
null
)
$sql
.=
' ON DELETE '
.
$delete
;
if
(
$update
!==
null
)
$sql
.=
' ON UPDATE '
.
$update
;
return
$sql
;
}
/**
* Builds a SQL statement for dropping a foreign key constraint.
* @param string $name the name of the foreign key constraint to be dropped. The name will be properly quoted by the method.
* @param string $table the table whose foreign is to be dropped. The name will be properly quoted by the method.
* @return string the SQL statement for dropping a foreign key constraint.
*/
public
function
dropForeignKey
(
$name
,
$table
)
{
return
'ALTER TABLE '
.
$this
->
quoteTableName
(
$table
)
.
' DROP CONSTRAINT '
.
$this
->
quoteColumnName
(
$name
);
}
/**
* Builds a SQL statement for creating a new index.
* @param string $name the name of the index. The name will be properly quoted by the method.
* @param string $table the table that the new index will be created for. The table name will be properly quoted by the method.
* @param string $column the column(s) that should be included in the index. If there are multiple columns, please separate them
* by commas. Each column name will be properly quoted by the method, unless a parenthesis is found in the name.
* @param boolean $unique whether to add UNIQUE constraint on the created index.
* @return string the SQL statement for creating a new index.
*/
public
function
createIndex
(
$name
,
$table
,
$column
,
$unique
=
false
)
{
$cols
=
array
();
$columns
=
preg_split
(
'/\s*,\s*/'
,
$column
,
-
1
,
PREG_SPLIT_NO_EMPTY
);
foreach
(
$columns
as
$col
)
{
if
(
strpos
(
$col
,
'('
)
!==
false
)
$cols
[]
=
$col
;
else
$cols
[]
=
$this
->
quoteColumnName
(
$col
);
}
return
(
$unique
?
'CREATE UNIQUE INDEX '
:
'CREATE INDEX '
)
.
$this
->
quoteTableName
(
$name
)
.
' ON '
.
$this
->
quoteTableName
(
$table
)
.
' ('
.
implode
(
', '
,
$cols
)
.
')'
;
}
/**
* Builds a SQL statement for dropping an index.
* @param string $name the name of the index to be dropped. The name will be properly quoted by the method.
* @param string $table the table whose index is to be dropped. The name will be properly quoted by the method.
* @return string the SQL statement for dropping an index.
*/
public
function
dropIndex
(
$name
,
$table
)
{
return
'DROP INDEX '
.
$this
->
quoteTableName
(
$name
)
.
' ON '
.
$this
->
quoteTableName
(
$table
);
}
protected
function
buildSelect
(
$query
)
{
$select
=
$query
->
distinct
?
'SELECT DISTINCT'
:
'SELECT'
;
$columns
=
$query
->
select
;
if
(
empty
(
$columns
))
{
if
(
empty
(
$columns
))
{
return
$select
.
' *'
;
return
$select
.
' *'
;
}
}
...
@@ -70,8 +274,8 @@ class QueryBuilder extends \yii\base\Component
...
@@ -70,8 +274,8 @@ class QueryBuilder extends \yii\base\Component
$columns
[
$i
]
=
(
string
)
$column
;
$columns
[
$i
]
=
(
string
)
$column
;
}
}
elseif
(
strpos
(
$column
,
'('
)
===
false
)
{
elseif
(
strpos
(
$column
,
'('
)
===
false
)
{
if
(
preg_match
(
'/^(.*?)(?i:\s+as\s+|\s+)(
.*
)$/'
,
$column
,
$matches
))
{
if
(
preg_match
(
'/^(.*?)(?i:\s+as\s+|\s+)(
[\w\-\.]
)$/'
,
$column
,
$matches
))
{
$columns
[
$i
]
=
$this
->
_connection
->
quoteColumnName
(
$matches
[
1
])
.
' AS '
.
$this
->
_connection
->
quoteColumnName
(
$matches
[
2
]);
$columns
[
$i
]
=
$this
->
_connection
->
quoteColumnName
(
$matches
[
1
])
.
' AS '
.
$this
->
_connection
->
quote
Simple
ColumnName
(
$matches
[
2
]);
}
}
else
{
else
{
$columns
[
$i
]
=
$this
->
_connection
->
quoteColumnName
(
$column
);
$columns
[
$i
]
=
$this
->
_connection
->
quoteColumnName
(
$column
);
...
@@ -82,10 +286,11 @@ class QueryBuilder extends \yii\base\Component
...
@@ -82,10 +286,11 @@ class QueryBuilder extends \yii\base\Component
return
$select
.
' '
.
implode
(
', '
,
$columns
);
return
$select
.
' '
.
implode
(
', '
,
$columns
);
}
}
protected
function
buildFrom
(
$
tables
)
protected
function
buildFrom
(
$
query
)
{
{
$tables
=
$query
->
from
;
if
(
is_string
(
$tables
)
&&
strpos
(
$tables
,
'('
)
!==
false
)
{
if
(
is_string
(
$tables
)
&&
strpos
(
$tables
,
'('
)
!==
false
)
{
return
$tables
;
return
'FROM '
.
$tables
;
}
}
if
(
!
is_array
(
$tables
))
{
if
(
!
is_array
(
$tables
))
{
...
@@ -93,7 +298,7 @@ class QueryBuilder extends \yii\base\Component
...
@@ -93,7 +298,7 @@ class QueryBuilder extends \yii\base\Component
}
}
foreach
(
$tables
as
$i
=>
$table
)
{
foreach
(
$tables
as
$i
=>
$table
)
{
if
(
strpos
(
$table
,
'('
)
===
false
)
{
if
(
strpos
(
$table
,
'('
)
===
false
)
{
if
(
preg_match
(
'/^(.*?)(?i:\s+as\s+|\s+)(.*)$/'
,
$table
,
$matches
))
{
// with alias
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
]);
$tables
[
$i
]
=
$this
->
_connection
->
quoteTableName
(
$matches
[
1
])
.
' '
.
$this
->
_connection
->
quoteTableName
(
$matches
[
2
]);
}
}
else
{
else
{
...
@@ -101,302 +306,211 @@ class QueryBuilder extends \yii\base\Component
...
@@ -101,302 +306,211 @@ class QueryBuilder extends \yii\base\Component
}
}
}
}
}
}
return
implode
(
', '
,
$tables
);
}
$this
->
buildJoin
(
$query
->
join
),
return
'FROM '
.
implode
(
', '
,
$tables
);
$this
->
buildWhere
(
$query
->
where
),
}
$this
->
buildGroupBy
(
$query
->
groupBy
),
$this
->
buildHaving
(
$query
->
having
),
$this
->
buildOrderBy
(
$query
->
orderBy
),
$this
->
buildLimit
(
$query
->
offset
,
$query
->
limit
),
protected
function
buildJoin
(
$query
)
{
$joins
=
$query
->
join
;
if
(
empty
(
$joins
))
{
return
''
;
}
if
(
is_string
(
$joins
))
{
return
$joins
;
}
if
(
isset
(
$query
[
'union'
]))
foreach
(
$joins
as
$i
=>
$join
)
{
$sql
.=
"
\n
UNION (
\n
"
.
(
is_array
(
$query
[
'union'
])
?
implode
(
"
\n
) UNION (
\n
"
,
$query
[
'union'
])
:
$query
[
'union'
])
.
')'
;
if
(
is_array
(
$join
))
{
// join type, table name, 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
->
_connection
->
quoteTableName
(
$matches
[
1
])
.
' '
.
$this
->
_connection
->
quoteTableName
(
$matches
[
2
]);
}
else
{
$table
=
$this
->
_connection
->
quoteTableName
(
$table
);
}
}
$joins
[
$i
]
=
strtoupper
(
$join
[
0
])
.
' '
.
$table
;
if
(
isset
(
$join
[
2
]))
{
// join condition
$condition
=
$this
->
processCondition
(
$join
[
2
]);
$joins
[
$i
]
.=
' ON '
.
$condition
;
}
}
else
{
throw
new
Exception
(
'The join clause may be specified as an array of at least two elements.'
);
}
}
}
return
$sql
;
return
implode
(
"
\n
"
,
$joins
)
;
}
}
protected
function
buildWhere
(
$query
)
/**
* Sets the WHERE part of the query.
*
* The method requires a $conditions parameter, and optionally a $params parameter
* specifying the values to be bound to the query.
*
* The $conditions parameter should be either a string (e.g. 'id=1') or an array.
* If the latter, it must be of the format <code>array(operator, operand1, operand2, ...)</code>,
* where the operator can be one of the followings, and the possible operands depend on the corresponding
* operator:
* <ul>
* <li><code>and</code>: 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 same 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.</li>
* <li><code>or</code>: similar as the <code>and</code> operator except that the operands are concatenated using OR.</li>
* <li><code>in</code>: 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.</li>
* <li><code>not in</code>: similar as the <code>in</code> operator except that IN is replaced with NOT IN in the generated condition.</li>
* <li><code>like</code>: 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.</li>
* <li><code>not like</code>: similar as the <code>like</code> operator except that LIKE is replaced with NOT LIKE in the generated condition.</li>
* <li><code>or like</code>: similar as the <code>like</code> operator except that OR is used to concatenated the LIKE predicates.</li>
* <li><code>or not like</code>: similar as the <code>not like</code> operator except that OR is used to concatenated the NOT LIKE predicates.</li>
* </ul>
* @param mixed $conditions the conditions that should be put in the WHERE part.
* @param array $params the parameters (name=>value) to be bound to the query
* @return Command the command object itself
* @since 1.1.6
*/
public
function
where
(
$conditions
,
$params
=
array
())
{
{
$this
->
_query
[
'where'
]
=
$this
->
processConditions
(
$conditions
);
$where
=
$this
->
processConditions
(
$query
->
where
);
foreach
(
$params
as
$name
=>
$value
)
return
empty
(
$where
)
?
''
:
'WHERE '
.
$where
;
$this
->
params
[
$name
]
=
$value
;
return
$this
;
}
}
/**
protected
function
buildGroupBy
(
$query
)
* 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 mixed $conditions the join condition that should appear in the ON part.
* Please refer to {@link where} on how to specify conditions.
* @param array $params the parameters (name=>value) to be bound to the query
* @return Command the command object itself
* @since 1.1.6
*/
public
function
join
(
$table
,
$conditions
,
$params
=
array
())
{
{
return
$this
->
joinInternal
(
'join'
,
$table
,
$conditions
,
$params
);
$columns
=
$query
->
groupBy
;
}
if
(
empty
(
$columns
))
{
return
''
;
}
if
(
is_string
(
$columns
)
&&
strpos
(
$columns
,
'('
)
!==
false
)
{
return
'GROUP BY '
.
$columns
;
}
/**
if
(
!
is_array
(
$columns
))
{
* Sets the GROUP BY part of the query.
$columns
=
preg_split
(
'/\s*,\s*/'
,
trim
(
$columns
),
-
1
,
PREG_SPLIT_NO_EMPTY
);
* @param mixed $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')).
foreach
(
$columns
as
$i
=>
$column
)
{
* The method will automatically quote the column names unless a column contains some parenthesis
if
(
is_object
(
$column
))
{
* (which means the column contains a DB expression).
$columns
[
$i
]
=
(
string
)
$column
;
* @return Command the command object itself
}
* @since 1.1.6
elseif
(
strpos
(
$column
,
'('
)
===
false
)
{
*/
$columns
[
$i
]
=
$this
->
_connection
->
quoteColumnName
(
$column
);
public
function
group
(
$columns
)
{
if
(
is_string
(
$columns
)
&&
strpos
(
$columns
,
'('
)
!==
false
)
$this
->
_query
[
'group'
]
=
$columns
;
else
{
if
(
!
is_array
(
$columns
))
$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
)
$columns
[
$i
]
=
$this
->
_connection
->
quoteColumnName
(
$column
);
}
}
$this
->
_query
[
'group'
]
=
implode
(
', '
,
$columns
);
}
}
return
$this
;
return
'GROUP BY '
.
implode
(
', '
,
$columns
)
;
}
}
/**
protected
function
buildHaving
(
$query
)
* Sets the HAVING part of the query.
* @param mixed $conditions the conditions to be put after HAVING.
* Please refer to {@link where} on how to specify conditions.
* @param array $params the parameters (name=>value) to be bound to the query
* @return Command the command object itself
* @since 1.1.6
*/
public
function
having
(
$conditions
,
$params
=
array
())
{
{
$this
->
_query
[
'having'
]
=
$this
->
processConditions
(
$conditions
);
$having
=
$this
->
processConditions
(
$query
->
having
);
foreach
(
$params
as
$name
=>
$value
)
return
empty
(
$having
)
?
''
:
'HAVING '
.
$having
;
$this
->
params
[
$name
]
=
$value
;
return
$this
;
}
}
/**
protected
function
buildOrderBy
(
$query
)
* Sets the ORDER BY part of the query.
* @param mixed $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 Command the command object itself
* @since 1.1.6
*/
public
function
order
(
$columns
)
{
{
if
(
is_string
(
$columns
)
&&
strpos
(
$columns
,
'('
)
!==
false
)
$columns
=
$query
->
orderBy
;
$this
->
_query
[
'order'
]
=
$columns
;
if
(
empty
(
$columns
))
{
else
return
''
;
{
}
if
(
!
is_array
(
$columns
))
if
(
is_string
(
$columns
)
&&
strpos
(
$columns
,
'('
)
!==
false
)
{
$columns
=
preg_split
(
'/\s*,\s*/'
,
trim
(
$columns
),
-
1
,
PREG_SPLIT_NO_EMPTY
);
return
'ORDER BY '
.
$columns
;
foreach
(
$columns
as
$i
=>
$column
)
}
{
if
(
is_object
(
$column
))
if
(
!
is_array
(
$columns
))
{
$columns
[
$i
]
=
(
string
)
$column
;
$columns
=
preg_split
(
'/\s*,\s*/'
,
trim
(
$columns
),
-
1
,
PREG_SPLIT_NO_EMPTY
);
elseif
(
strpos
(
$column
,
'('
)
===
false
)
}
{
foreach
(
$columns
as
$i
=>
$column
)
{
if
(
preg_match
(
'/^(.*?)\s+(asc|desc)$/i'
,
$column
,
$matches
))
if
(
is_object
(
$column
))
{
$columns
[
$i
]
=
$this
->
_connection
->
quoteColumnName
(
$matches
[
1
])
.
' '
.
strtoupper
(
$matches
[
2
]);
$columns
[
$i
]
=
(
string
)
$column
;
else
}
$columns
[
$i
]
=
$this
->
_connection
->
quoteColumnName
(
$column
);
elseif
(
strpos
(
$column
,
'('
)
===
false
)
{
if
(
preg_match
(
'/^(.*?)\s+(asc|desc)$/i'
,
$column
,
$matches
))
{
$columns
[
$i
]
=
$this
->
_connection
->
quoteColumnName
(
$matches
[
1
])
.
' '
.
strtoupper
(
$matches
[
2
]);
}
else
{
$columns
[
$i
]
=
$this
->
_connection
->
quoteColumnName
(
$column
);
}
}
}
}
$this
->
_query
[
'order'
]
=
implode
(
', '
,
$columns
);
}
}
return
$this
;
return
'ORDER BY '
.
implode
(
', '
,
$columns
)
;
}
}
/**
protected
function
buildLimit
(
$query
)
* Sets the LIMIT part of the query.
* @param integer $limit the limit
* @param integer $offset the offset
* @return Command the command object itself
* @since 1.1.6
*/
public
function
limit
(
$limit
,
$offset
=
null
)
{
{
$this
->
_query
[
'limit'
]
=
(
int
)
$limit
;
$sql
=
''
;
if
(
$offset
!==
null
)
if
(
$query
->
limit
!==
null
&&
$query
->
limit
>=
0
)
{
$this
->
offset
(
$offset
);
$sql
=
'LIMIT '
.
(
int
)
$query
->
limit
;
return
$this
;
}
if
(
$query
->
offset
>
0
)
{
$sql
.=
' OFFSET '
.
(
int
)
$query
->
offset
;
}
return
ltrim
(
$sql
);
}
}
/**
protected
function
buildUnion
(
$query
)
* Appends a SQL statement using UNION operator.
* @param string $sql the SQL statement to be appended using UNION
* @return Command the command object itself
* @since 1.1.6
*/
public
function
union
(
$sql
)
{
{
if
(
isset
(
$this
->
_query
[
'union'
])
&&
is_string
(
$this
->
_query
[
'union'
]))
$unions
=
$query
->
union
;
$this
->
_query
[
'union'
]
=
array
(
$this
->
_query
[
'union'
]);
if
(
empty
(
$unions
))
{
return
''
;
$this
->
_query
[
'union'
][]
=
$sql
;
}
if
(
!
is_array
(
$unions
))
{
return
$this
;
$unions
=
array
(
$unions
);
}
foreach
(
$unions
as
$i
=>
$union
)
{
if
(
$union
instanceof
Query
)
{
$unions
[
$i
]
=
$union
->
getSql
(
$this
->
_connection
);
}
}
return
"UNION (
\n
"
.
implode
(
"
\n
) UNION (
\n
"
,
$unions
)
.
"
\n
)"
;
}
}
/**
protected
function
processCondition
(
$conditions
)
* Generates the condition string that will be put in the WHERE part
* @param mixed $conditions the conditions that will be put in the WHERE part.
* @return string the condition string to put in the WHERE part
*/
private
function
buildConditions
(
$conditions
)
{
{
if
(
!
is_array
(
$conditions
))
if
(
!
is_array
(
$conditions
))
{
return
$conditions
;
return
$conditions
;
elseif
(
$conditions
===
array
())
}
elseif
(
$conditions
===
array
())
{
return
''
;
return
''
;
}
$n
=
count
(
$conditions
);
$n
=
count
(
$conditions
);
$operator
=
strtoupper
(
$conditions
[
0
]);
$operator
=
strtoupper
(
$conditions
[
0
]);
if
(
$operator
===
'OR'
||
$operator
===
'AND'
)
if
(
$operator
===
'OR'
||
$operator
===
'AND'
)
{
{
$parts
=
array
();
$parts
=
array
();
for
(
$i
=
1
;
$i
<
$n
;
++
$i
)
for
(
$i
=
1
;
$i
<
$n
;
++
$i
)
{
{
$condition
=
$this
->
processCondition
(
$conditions
[
$i
]);
$condition
=
$this
->
processConditions
(
$conditions
[
$i
]);
if
(
$condition
!==
''
)
{
if
(
$condition
!==
''
)
$parts
[]
=
'('
.
$condition
.
')'
;
$parts
[]
=
'('
.
$condition
.
')'
;
}
}
}
return
$parts
===
array
()
?
''
:
implode
(
' '
.
$operator
.
' '
,
$parts
);
return
$parts
===
array
()
?
''
:
implode
(
' '
.
$operator
.
' '
,
$parts
);
}
}
if
(
!
isset
(
$conditions
[
1
],
$conditions
[
2
]))
if
(
!
isset
(
$conditions
[
1
],
$conditions
[
2
]))
{
return
''
;
return
''
;
}
$column
=
$conditions
[
1
];
$column
=
$conditions
[
1
];
if
(
strpos
(
$column
,
'('
)
===
false
)
if
(
strpos
(
$column
,
'('
)
===
false
)
{
$column
=
$this
->
_connection
->
quoteColumnName
(
$column
);
$column
=
$this
->
_connection
->
quoteColumnName
(
$column
);
}
$values
=
$conditions
[
2
];
$values
=
$conditions
[
2
];
if
(
!
is_array
(
$values
))
if
(
!
is_array
(
$values
))
{
$values
=
array
(
$values
);
$values
=
array
(
$values
);
}
if
(
$operator
===
'IN'
||
$operator
===
'NOT IN'
)
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
)
}
{
foreach
(
$values
as
$i
=>
$value
)
{
if
(
is_string
(
$value
))
if
(
is_string
(
$value
))
{
$values
[
$i
]
=
$this
->
_connection
->
quoteValue
(
$value
);
$values
[
$i
]
=
$this
->
_connection
->
quoteValue
(
$value
);
else
}
else
{
$values
[
$i
]
=
(
string
)
$value
;
$values
[
$i
]
=
(
string
)
$value
;
}
}
}
return
$column
.
' '
.
$operator
.
' ('
.
implode
(
', '
,
$values
)
.
')'
;
return
$column
.
' '
.
$operator
.
' ('
.
implode
(
', '
,
$values
)
.
')'
;
}
}
if
(
$operator
===
'LIKE'
||
$operator
===
'NOT LIKE'
||
$operator
===
'OR LIKE'
||
$operator
===
'OR NOT LIKE'
)
if
(
$operator
===
'LIKE'
||
$operator
===
'NOT LIKE'
||
$operator
===
'OR LIKE'
||
$operator
===
'OR NOT LIKE'
)
{
{
if
(
$values
===
array
())
{
if
(
$values
===
array
())
return
$operator
===
'LIKE'
||
$operator
===
'OR LIKE'
?
'0=1'
:
''
;
return
$operator
===
'LIKE'
||
$operator
===
'OR LIKE'
?
'0=1'
:
''
;
}
if
(
$operator
===
'LIKE'
||
$operator
===
'NOT LIKE'
)
if
(
$operator
===
'LIKE'
||
$operator
===
'NOT LIKE'
)
{
$andor
=
' AND '
;
$andor
=
' AND '
;
else
}
{
else
{
$andor
=
' OR '
;
$andor
=
' OR '
;
$operator
=
$operator
===
'OR LIKE'
?
'LIKE'
:
'NOT LIKE'
;
$operator
=
$operator
===
'OR LIKE'
?
'LIKE'
:
'NOT LIKE'
;
}
}
$expressions
=
array
();
$expressions
=
array
();
foreach
(
$values
as
$value
)
foreach
(
$values
as
$value
)
{
$expressions
[]
=
$column
.
' '
.
$operator
.
' '
.
$this
->
_connection
->
quoteValue
(
$value
);
$expressions
[]
=
$column
.
' '
.
$operator
.
' '
.
$this
->
_connection
->
quoteValue
(
$value
);
}
return
implode
(
$andor
,
$expressions
);
return
implode
(
$andor
,
$expressions
);
}
}
throw
new
CDbException
(
Yii
::
t
(
'yii'
,
'Unknown operator "{operator}".'
,
array
(
'{operator}'
=>
$operator
)));
throw
new
Exception
(
'Unknown operator: '
.
$operator
);
}
/**
* Appends an JOIN part to the query.
* @param string $type the join type ('join', 'left join', 'right join', 'cross join', '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).
* @param mixed $conditions the join condition that should appear in the ON part.
* Please refer to {@link where} on how to specify conditions.
* @param array $params the parameters (name=>value) to be bound to the query
* @return Command the command object itself
* @since 1.1.6
*/
private
function
joinInternal
(
$type
,
$table
,
$conditions
=
''
,
$params
=
array
())
{
if
(
strpos
(
$table
,
'('
)
===
false
)
{
if
(
preg_match
(
'/^(.*?)(?i:\s+as\s+|\s+)(.*)$/'
,
$table
,
$matches
))
// with alias
$table
=
$this
->
_connection
->
quoteTableName
(
$matches
[
1
])
.
' '
.
$this
->
_connection
->
quoteTableName
(
$matches
[
2
]);
else
$table
=
$this
->
_connection
->
quoteTableName
(
$table
);
}
$conditions
=
$this
->
processConditions
(
$conditions
);
if
(
$conditions
!=
''
)
$conditions
=
' ON '
.
$conditions
;
if
(
isset
(
$this
->
_query
[
'join'
])
&&
is_string
(
$this
->
_query
[
'join'
]))
$this
->
_query
[
'join'
]
=
array
(
$this
->
_query
[
'join'
]);
$this
->
_query
[
'join'
][]
=
strtoupper
(
$type
)
.
' '
.
$table
.
$conditions
;
foreach
(
$params
as
$name
=>
$value
)
$this
->
params
[
$name
]
=
$value
;
return
$this
;
}
}
}
}
framework/db/dao/Schema.php
View file @
3335f09d
<?php
<?php
/**
/**
*
CDb
Schema class file.
* Schema class file.
*
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.yiiframework.com/
* @link http://www.yiiframework.com/
...
@@ -8,15 +8,15 @@
...
@@ -8,15 +8,15 @@
* @license http://www.yiiframework.com/license/
* @license http://www.yiiframework.com/license/
*/
*/
namespace
yii\db\dao
;
/**
/**
*
CDb
Schema is the base class for retrieving metadata information.
* Schema is the base class for retrieving metadata information.
*
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @author Qiang Xue <qiang.xue@gmail.com>
* @version $Id: CDbSchema.php 3359 2011-07-18 11:25:17Z qiang.xue $
* @since 2.0
* @package system.db.schema
* @since 1.0
*/
*/
abstract
class
CDbSchema
extends
C
Component
abstract
class
Schema
extends
\yii\base\
Component
{
{
/**
/**
* @var array the abstract column types mapped to physical column types.
* @var array the abstract column types mapped to physical column types.
...
@@ -41,10 +41,10 @@ abstract class CDbSchema extends CComponent
...
@@ -41,10 +41,10 @@ abstract class CDbSchema extends CComponent
* Constructor.
* Constructor.
* @param CDbConnection $conn database connection.
* @param CDbConnection $conn database connection.
*/
*/
public
function
__construct
(
$conn
)
public
function
__construct
(
$conn
ection
)
{
{
$this
->
_connection
=
$conn
;
$this
->
_connection
=
$conn
ection
;
foreach
(
$conn
->
schemaCachingExclude
as
$name
)
foreach
(
$conn
ection
->
schemaCachingExclude
as
$name
)
$this
->
_cacheExclude
[
$name
]
=
true
;
$this
->
_cacheExclude
[
$name
]
=
true
;
}
}
...
@@ -342,215 +342,4 @@ abstract class CDbSchema extends CComponent
...
@@ -342,215 +342,4 @@ abstract class CDbSchema extends CComponent
return
$type
;
return
$type
;
}
}
/**
* Builds a SQL statement for creating a new DB table.
*
* The columns in the new table should be specified as name-definition pairs (e.g. 'name'=>'string'),
* where name stands for a column name which will be properly quoted by the method, and definition
* stands for the column type which can contain an abstract DB type.
* The {@link getColumnType} method will be invoked to convert any abstract type into a physical one.
*
* If a column is specified with definition only (e.g. 'PRIMARY KEY (name, type)'), it will be directly
* inserted into the generated SQL.
*
* @param string $table the name of the table to be created. The name will be properly quoted by the method.
* @param array $columns the columns (name=>definition) in the new table.
* @param string $options additional SQL fragment that will be appended to the generated SQL.
* @return string the SQL statement for creating a new DB table.
* @since 1.1.6
*/
public
function
createTable
(
$table
,
$columns
,
$options
=
null
)
{
$cols
=
array
();
foreach
(
$columns
as
$name
=>
$type
)
{
if
(
is_string
(
$name
))
$cols
[]
=
"
\t
"
.
$this
->
quoteColumnName
(
$name
)
.
' '
.
$this
->
getColumnType
(
$type
);
else
$cols
[]
=
"
\t
"
.
$type
;
}
$sql
=
"CREATE TABLE "
.
$this
->
quoteTableName
(
$table
)
.
" (
\n
"
.
implode
(
",
\n
"
,
$cols
)
.
"
\n
)"
;
return
$options
===
null
?
$sql
:
$sql
.
' '
.
$options
;
}
/**
* Builds a SQL statement for renaming a DB table.
* @param string $table the table to be renamed. The name will be properly quoted by the method.
* @param string $newName the new table name. The name will be properly quoted by the method.
* @return string the SQL statement for renaming a DB table.
* @since 1.1.6
*/
public
function
renameTable
(
$table
,
$newName
)
{
return
'RENAME TABLE '
.
$this
->
quoteTableName
(
$table
)
.
' TO '
.
$this
->
quoteTableName
(
$newName
);
}
/**
* Builds a SQL statement for dropping a DB table.
* @param string $table the table to be dropped. The name will be properly quoted by the method.
* @return string the SQL statement for dropping a DB table.
* @since 1.1.6
*/
public
function
dropTable
(
$table
)
{
return
"DROP TABLE "
.
$this
->
quoteTableName
(
$table
);
}
/**
* Builds a SQL statement for truncating a DB table.
* @param string $table the table to be truncated. The name will be properly quoted by the method.
* @return string the SQL statement for truncating a DB table.
* @since 1.1.6
*/
public
function
truncateTable
(
$table
)
{
return
"TRUNCATE TABLE "
.
$this
->
quoteTableName
(
$table
);
}
/**
* Builds a SQL statement for adding a new DB column.
* @param string $table the table that the new column will be added to. The table name will be properly quoted by the method.
* @param string $column the name of the new column. The name will be properly quoted by the method.
* @param string $type the column type. The {@link getColumnType} method will be invoked to convert abstract column type (if any)
* into the physical one. Anything that is not recognized as abstract type will be kept in the generated SQL.
* For example, 'string' will be turned into 'varchar(255)', while 'string not null' will become 'varchar(255) not null'.
* @return string the SQL statement for adding a new column.
* @since 1.1.6
*/
public
function
addColumn
(
$table
,
$column
,
$type
)
{
return
'ALTER TABLE '
.
$this
->
quoteTableName
(
$table
)
.
' ADD '
.
$this
->
quoteColumnName
(
$column
)
.
' '
.
$this
->
getColumnType
(
$type
);
}
/**
* Builds a SQL statement for dropping a DB column.
* @param string $table the table whose column is to be dropped. The name will be properly quoted by the method.
* @param string $column the name of the column to be dropped. The name will be properly quoted by the method.
* @return string the SQL statement for dropping a DB column.
* @since 1.1.6
*/
public
function
dropColumn
(
$table
,
$column
)
{
return
"ALTER TABLE "
.
$this
->
quoteTableName
(
$table
)
.
" DROP COLUMN "
.
$this
->
quoteColumnName
(
$column
);
}
/**
* Builds a SQL statement for renaming a column.
* @param string $table the table whose column is to be renamed. The name will be properly quoted by the method.
* @param string $name 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.
* @since 1.1.6
*/
public
function
renameColumn
(
$table
,
$name
,
$newName
)
{
return
"ALTER TABLE "
.
$this
->
quoteTableName
(
$table
)
.
" RENAME COLUMN "
.
$this
->
quoteColumnName
(
$name
)
.
" TO "
.
$this
->
quoteColumnName
(
$newName
);
}
/**
* Builds a SQL statement for changing the definition of a column.
* @param string $table the table whose column is to be changed. The table name will be properly quoted by the method.
* @param string $column the name of the column to be changed. The name will be properly quoted by the method.
* @param string $type the new column type. The {@link getColumnType} method will be invoked to convert abstract column type (if any)
* into the physical one. Anything that is not recognized as abstract type will be kept in the generated SQL.
* For example, 'string' will be turned into 'varchar(255)', while 'string not null' will become 'varchar(255) not null'.
* @return string the SQL statement for changing the definition of a column.
* @since 1.1.6
*/
public
function
alterColumn
(
$table
,
$column
,
$type
)
{
return
'ALTER TABLE '
.
$this
->
quoteTableName
(
$table
)
.
' CHANGE '
.
$this
->
quoteColumnName
(
$column
)
.
' '
.
$this
->
quoteColumnName
(
$column
)
.
' '
.
$this
->
getColumnType
(
$type
);
}
/**
* Builds a SQL statement for adding a foreign key constraint to an existing table.
* The method will properly quote the table and column names.
* @param string $name the name of the foreign key constraint.
* @param string $table the table that the foreign key constraint will be added to.
* @param string $columns the name of the column to that the constraint will be added on. If there are multiple columns, separate them with commas.
* @param string $refTable the table that the foreign key references to.
* @param string $refColumns the name of the column that the foreign key references to. If there are multiple columns, separate them with commas.
* @param string $delete the ON DELETE option. Most DBMS support these options: RESTRICT, CASCADE, NO ACTION, SET DEFAULT, SET NULL
* @param string $update the ON UPDATE option. Most DBMS support these options: RESTRICT, CASCADE, NO ACTION, SET DEFAULT, SET NULL
* @return string the SQL statement for adding a foreign key constraint to an existing table.
* @since 1.1.6
*/
public
function
addForeignKey
(
$name
,
$table
,
$columns
,
$refTable
,
$refColumns
,
$delete
=
null
,
$update
=
null
)
{
$columns
=
preg_split
(
'/\s*,\s*/'
,
$columns
,
-
1
,
PREG_SPLIT_NO_EMPTY
);
foreach
(
$columns
as
$i
=>
$col
)
$columns
[
$i
]
=
$this
->
quoteColumnName
(
$col
);
$refColumns
=
preg_split
(
'/\s*,\s*/'
,
$refColumns
,
-
1
,
PREG_SPLIT_NO_EMPTY
);
foreach
(
$refColumns
as
$i
=>
$col
)
$refColumns
[
$i
]
=
$this
->
quoteColumnName
(
$col
);
$sql
=
'ALTER TABLE '
.
$this
->
quoteTableName
(
$table
)
.
' ADD CONSTRAINT '
.
$this
->
quoteColumnName
(
$name
)
.
' FOREIGN KEY ('
.
implode
(
', '
,
$columns
)
.
')'
.
' REFERENCES '
.
$this
->
quoteTableName
(
$refTable
)
.
' ('
.
implode
(
', '
,
$refColumns
)
.
')'
;
if
(
$delete
!==
null
)
$sql
.=
' ON DELETE '
.
$delete
;
if
(
$update
!==
null
)
$sql
.=
' ON UPDATE '
.
$update
;
return
$sql
;
}
/**
* Builds a SQL statement for dropping a foreign key constraint.
* @param string $name the name of the foreign key constraint to be dropped. The name will be properly quoted by the method.
* @param string $table the table whose foreign is to be dropped. The name will be properly quoted by the method.
* @return string the SQL statement for dropping a foreign key constraint.
* @since 1.1.6
*/
public
function
dropForeignKey
(
$name
,
$table
)
{
return
'ALTER TABLE '
.
$this
->
quoteTableName
(
$table
)
.
' DROP CONSTRAINT '
.
$this
->
quoteColumnName
(
$name
);
}
/**
* Builds a SQL statement for creating a new index.
* @param string $name the name of the index. The name will be properly quoted by the method.
* @param string $table the table that the new index will be created for. The table name will be properly quoted by the method.
* @param string $column the column(s) that should be included in the index. If there are multiple columns, please separate them
* by commas. Each column name will be properly quoted by the method, unless a parenthesis is found in the name.
* @param boolean $unique whether to add UNIQUE constraint on the created index.
* @return string the SQL statement for creating a new index.
* @since 1.1.6
*/
public
function
createIndex
(
$name
,
$table
,
$column
,
$unique
=
false
)
{
$cols
=
array
();
$columns
=
preg_split
(
'/\s*,\s*/'
,
$column
,
-
1
,
PREG_SPLIT_NO_EMPTY
);
foreach
(
$columns
as
$col
)
{
if
(
strpos
(
$col
,
'('
)
!==
false
)
$cols
[]
=
$col
;
else
$cols
[]
=
$this
->
quoteColumnName
(
$col
);
}
return
(
$unique
?
'CREATE UNIQUE INDEX '
:
'CREATE INDEX '
)
.
$this
->
quoteTableName
(
$name
)
.
' ON '
.
$this
->
quoteTableName
(
$table
)
.
' ('
.
implode
(
', '
,
$cols
)
.
')'
;
}
/**
* Builds a SQL statement for dropping an index.
* @param string $name the name of the index to be dropped. The name will be properly quoted by the method.
* @param string $table the table whose index is to be dropped. The name will be properly quoted by the method.
* @return string the SQL statement for dropping an index.
* @since 1.1.6
*/
public
function
dropIndex
(
$name
,
$table
)
{
return
'DROP INDEX '
.
$this
->
quoteTableName
(
$name
)
.
' ON '
.
$this
->
quoteTableName
(
$table
);
}
}
}
framework/db/dao/TableSchema.php
View file @
3335f09d
<?php
<?php
/**
/**
*
CDb
TableSchema class file.
* TableSchema class file.
*
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.yiiframework.com/
* @link http://www.yiiframework.com/
...
@@ -8,12 +8,14 @@
...
@@ -8,12 +8,14 @@
* @license http://www.yiiframework.com/license/
* @license http://www.yiiframework.com/license/
*/
*/
namespace
yii\db\dao
;
/**
/**
*
CDb
TableSchema is the base class for representing the metadata of a database table.
* TableSchema is the base class for representing the metadata of a database table.
*
*
* It may be extended by different DBMS driver to provide DBMS-specific table metadata.
* It may be extended by different DBMS driver to provide DBMS-specific table metadata.
*
*
*
CDb
TableSchema provides the following information about a table:
* TableSchema provides the following information about a table:
* <ul>
* <ul>
* <li>{@link name}</li>
* <li>{@link name}</li>
* <li>{@link rawName}</li>
* <li>{@link rawName}</li>
...
@@ -24,20 +26,22 @@
...
@@ -24,20 +26,22 @@
* </ul>
* </ul>
*
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @author Qiang Xue <qiang.xue@gmail.com>
* @version $Id: CDbTableSchema.php 2799 2011-01-01 19:31:13Z qiang.xue $
* @since 2.0
* @package system.db.schema
* @since 1.0
*/
*/
class
CDbTableSchema
extends
C
Component
class
TableSchema
extends
\yii\base\
Component
{
{
/**
/**
* @var string name of the schema that this table belongs to.
*/
public
$schemaName
;
/**
* @var string name of this table.
* @var string name of this table.
*/
*/
public
$name
;
public
$name
;
/**
/**
* @var string
raw name of this table. This is the quoted version of table name with optional schema name. It can be directly used in SQLs
.
* @var string
quoted name of this table. This may include [[schemaName]] if it is not empty
.
*/
*/
public
$
raw
Name
;
public
$
quoted
Name
;
/**
/**
* @var string|array primary key name of this table. If composite key, an array of key names is returned.
* @var string|array primary key name of this table. If composite key, an array of key names is returned.
*/
*/
...
@@ -51,7 +55,7 @@ class CDbTableSchema extends CComponent
...
@@ -51,7 +55,7 @@ class CDbTableSchema extends CComponent
*/
*/
public
$foreignKeys
=
array
();
public
$foreignKeys
=
array
();
/**
/**
* @var array column metadata of this table. Each array element is a
CDbColumnSchema
object, indexed by column names.
* @var array column metadata of this table. Each array element is a
[[ColumnSchema]]
object, indexed by column names.
*/
*/
public
$columns
=
array
();
public
$columns
=
array
();
...
...
framework/db/dao/mysql/ColumnSchema.php
0 → 100644
View file @
3335f09d
<?php
/**
* ColumnSchema 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/
*/
/**
* ColumnSchema class describes the column meta data of a MySQL table.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class
ColumnSchema
extends
\yii\db\dao\ColumnSchema
{
/**
* Extracts the PHP type from DB type.
* @param string $dbType DB type
*/
protected
function
extractType
(
$dbType
)
{
if
(
strncmp
(
$dbType
,
'enum'
,
4
)
===
0
)
$this
->
type
=
'string'
;
elseif
(
strpos
(
$dbType
,
'float'
)
!==
false
||
strpos
(
$dbType
,
'double'
)
!==
false
)
$this
->
type
=
'double'
;
elseif
(
strpos
(
$dbType
,
'bool'
)
!==
false
)
$this
->
type
=
'boolean'
;
elseif
(
strpos
(
$dbType
,
'int'
)
===
0
&&
strpos
(
$dbType
,
'unsigned'
)
===
false
||
preg_match
(
'/(bit|tinyint|smallint|mediumint)/'
,
$dbType
))
$this
->
type
=
'integer'
;
else
$this
->
type
=
'string'
;
}
/**
* Extracts the default value for the column.
* The value is typecasted to correct PHP type.
* @param mixed $defaultValue the default value obtained from metadata
*/
protected
function
extractDefault
(
$defaultValue
)
{
if
(
$this
->
dbType
===
'timestamp'
&&
$defaultValue
===
'CURRENT_TIMESTAMP'
)
$this
->
defaultValue
=
null
;
else
parent
::
extractDefault
(
$defaultValue
);
}
/**
* Extracts size, precision and scale information from column's DB type.
* @param string $dbType the column's DB type
*/
protected
function
extractLimit
(
$dbType
)
{
if
(
strncmp
(
$dbType
,
'enum'
,
4
)
===
0
&&
preg_match
(
'/\((.*)\)/'
,
$dbType
,
$matches
))
{
$values
=
explode
(
','
,
$matches
[
1
]);
$size
=
0
;
foreach
(
$values
as
$value
)
{
if
((
$n
=
strlen
(
$value
))
>
$size
)
$size
=
$n
;
}
$this
->
size
=
$this
->
precision
=
$size
-
2
;
}
else
parent
::
extractLimit
(
$dbType
);
}
}
\ No newline at end of file
framework/db/dao/mysql/Schema.php
0 → 100644
View file @
3335f09d
<?php
/**
* CMysqlSchema class file.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.yiiframework.com/
* @copyright Copyright © 2008-2011 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
/**
* CMysqlSchema is the class for retrieving metadata information from a MySQL database (version 4.1.x and 5.x).
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @version $Id: CMysqlSchema.php 3304 2011-06-23 14:53:50Z qiang.xue $
* @package system.db.schema.mysql
* @since 1.0
*/
class
CMysqlSchema
extends
CDbSchema
{
/**
* @var array the abstract column types mapped to physical column types.
* @since 1.1.6
*/
public
$columnTypes
=
array
(
'pk'
=>
'int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY'
,
'string'
=>
'varchar(255)'
,
'text'
=>
'text'
,
'integer'
=>
'int(11)'
,
'float'
=>
'float'
,
'decimal'
=>
'decimal'
,
'datetime'
=>
'datetime'
,
'timestamp'
=>
'timestamp'
,
'time'
=>
'time'
,
'date'
=>
'date'
,
'binary'
=>
'blob'
,
'boolean'
=>
'tinyint(1)'
,
'money'
=>
'decimal(19,4)'
,
);
/**
* Quotes a 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
* @since 1.1.6
*/
public
function
quoteSimpleTableName
(
$name
)
{
return
'`'
.
$name
.
'`'
;
}
/**
* Quotes a 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
* @since 1.1.6
*/
public
function
quoteSimpleColumnName
(
$name
)
{
return
'`'
.
$name
.
'`'
;
}
/**
* Compares two table names.
* The table names can be either quoted or unquoted. This method
* will consider both cases.
* @param string $name1 table name 1
* @param string $name2 table name 2
* @return boolean whether the two table names refer to the same table.
*/
public
function
compareTableNames
(
$name1
,
$name2
)
{
return
parent
::
compareTableNames
(
strtolower
(
$name1
),
strtolower
(
$name2
));
}
/**
* Resets the sequence value of a table's primary key.
* The sequence will be reset such that the primary key of the next new row inserted
* will have the specified value or 1.
* @param CDbTableSchema $table the table schema whose primary key sequence will be reset
* @param mixed $value the value for the primary key of the next new row inserted. If this is not set,
* the next new row's primary key will have a value 1.
* @since 1.1
*/
public
function
resetSequence
(
$table
,
$value
=
null
)
{
if
(
$table
->
sequenceName
!==
null
)
{
if
(
$value
===
null
)
$value
=
$this
->
getDbConnection
()
->
createCommand
(
"SELECT MAX(`
{
$table
->
primaryKey
}
`) FROM
{
$table
->
rawName
}
"
)
->
queryScalar
()
+
1
;
else
$value
=
(
int
)
$value
;
$this
->
getDbConnection
()
->
createCommand
(
"ALTER TABLE
{
$table
->
rawName
}
AUTO_INCREMENT=
$value
"
)
->
execute
();
}
}
/**
* Enables or disables integrity check.
* @param boolean $check whether to turn on or off the integrity check.
* @param string $schema the schema of the tables. Defaults to empty string, meaning the current or default schema.
* @since 1.1
*/
public
function
checkIntegrity
(
$check
=
true
,
$schema
=
''
)
{
$this
->
getDbConnection
()
->
createCommand
(
'SET FOREIGN_KEY_CHECKS='
.
(
$check
?
1
:
0
))
->
execute
();
}
/**
* Loads the metadata for the specified table.
* @param string $name table name
* @return CMysqlTableSchema driver dependent table metadata. Null if the table does not exist.
*/
protected
function
loadTable
(
$name
)
{
$table
=
new
CMysqlTableSchema
;
$this
->
resolveTableNames
(
$table
,
$name
);
if
(
$this
->
findColumns
(
$table
))
{
$this
->
findConstraints
(
$table
);
return
$table
;
}
else
return
null
;
}
/**
* Generates various kinds of table names.
* @param CMysqlTableSchema $table the table instance
* @param string $name the unquoted table name
*/
protected
function
resolveTableNames
(
$table
,
$name
)
{
$parts
=
explode
(
'.'
,
str_replace
(
'`'
,
''
,
$name
));
if
(
isset
(
$parts
[
1
]))
{
$table
->
schemaName
=
$parts
[
0
];
$table
->
name
=
$parts
[
1
];
$table
->
rawName
=
$this
->
quoteTableName
(
$table
->
schemaName
)
.
'.'
.
$this
->
quoteTableName
(
$table
->
name
);
}
else
{
$table
->
name
=
$parts
[
0
];
$table
->
rawName
=
$this
->
quoteTableName
(
$table
->
name
);
}
}
/**
* Collects the table column metadata.
* @param CMysqlTableSchema $table the table metadata
* @return boolean whether the table exists in the database
*/
protected
function
findColumns
(
$table
)
{
$sql
=
'SHOW COLUMNS FROM '
.
$table
->
rawName
;
try
{
$columns
=
$this
->
getDbConnection
()
->
createCommand
(
$sql
)
->
queryAll
();
}
catch
(
Exception
$e
)
{
return
false
;
}
foreach
(
$columns
as
$column
)
{
$c
=
$this
->
createColumn
(
$column
);
$table
->
columns
[
$c
->
name
]
=
$c
;
if
(
$c
->
isPrimaryKey
)
{
if
(
$table
->
primaryKey
===
null
)
$table
->
primaryKey
=
$c
->
name
;
elseif
(
is_string
(
$table
->
primaryKey
))
$table
->
primaryKey
=
array
(
$table
->
primaryKey
,
$c
->
name
);
else
$table
->
primaryKey
[]
=
$c
->
name
;
if
(
$c
->
autoIncrement
)
$table
->
sequenceName
=
''
;
}
}
return
true
;
}
/**
* Creates a table column.
* @param array $column column metadata
* @return CDbColumnSchema normalized column metadata
*/
protected
function
createColumn
(
$column
)
{
$c
=
new
CMysqlColumnSchema
;
$c
->
name
=
$column
[
'Field'
];
$c
->
rawName
=
$this
->
quoteColumnName
(
$c
->
name
);
$c
->
allowNull
=
$column
[
'Null'
]
===
'YES'
;
$c
->
isPrimaryKey
=
strpos
(
$column
[
'Key'
],
'PRI'
)
!==
false
;
$c
->
isForeignKey
=
false
;
$c
->
init
(
$column
[
'Type'
],
$column
[
'Default'
]);
$c
->
autoIncrement
=
strpos
(
strtolower
(
$column
[
'Extra'
]),
'auto_increment'
)
!==
false
;
return
$c
;
}
/**
* @return float server version.
*/
protected
function
getServerVersion
()
{
$version
=
$this
->
getDbConnection
()
->
getAttribute
(
PDO
::
ATTR_SERVER_VERSION
);
$digits
=
array
();
preg_match
(
'/(\d+)\.(\d+)\.(\d+)/'
,
$version
,
$digits
);
return
floatval
(
$digits
[
1
]
.
'.'
.
$digits
[
2
]
.
$digits
[
3
]);
}
/**
* Collects the foreign key column details for the given table.
* @param CMysqlTableSchema $table the table metadata
*/
protected
function
findConstraints
(
$table
)
{
$row
=
$this
->
getDbConnection
()
->
createCommand
(
'SHOW CREATE TABLE '
.
$table
->
rawName
)
->
queryRow
();
$matches
=
array
();
$regexp
=
'/FOREIGN KEY\s+\(([^\)]+)\)\s+REFERENCES\s+([^\(^\s]+)\s*\(([^\)]+)\)/mi'
;
foreach
(
$row
as
$sql
)
{
if
(
preg_match_all
(
$regexp
,
$sql
,
$matches
,
PREG_SET_ORDER
))
break
;
}
foreach
(
$matches
as
$match
)
{
$keys
=
array_map
(
'trim'
,
explode
(
','
,
str_replace
(
'`'
,
''
,
$match
[
1
])));
$fks
=
array_map
(
'trim'
,
explode
(
','
,
str_replace
(
'`'
,
''
,
$match
[
3
])));
foreach
(
$keys
as
$k
=>
$name
)
{
$table
->
foreignKeys
[
$name
]
=
array
(
str_replace
(
'`'
,
''
,
$match
[
2
]),
$fks
[
$k
]);
if
(
isset
(
$table
->
columns
[
$name
]))
$table
->
columns
[
$name
]
->
isForeignKey
=
true
;
}
}
}
/**
* Returns all table names in the database.
* @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.
* @since 1.0.2
*/
protected
function
findTableNames
(
$schema
=
''
)
{
if
(
$schema
===
''
)
return
$this
->
getDbConnection
()
->
createCommand
(
'SHOW TABLES'
)
->
queryColumn
();
$names
=
$this
->
getDbConnection
()
->
createCommand
(
'SHOW TABLES FROM '
.
$this
->
quoteTableName
(
$schema
))
->
queryColumn
();
foreach
(
$names
as
&
$name
)
$name
=
$schema
.
'.'
.
$name
;
return
$names
;
}
/**
* Builds a SQL statement for renaming a column.
* @param string $table the table whose column is to be renamed. The name will be properly quoted by the method.
* @param string $name 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.
* @since 1.1.6
*/
public
function
renameColumn
(
$table
,
$name
,
$newName
)
{
$db
=
$this
->
getDbConnection
();
$row
=
$db
->
createCommand
(
'SHOW CREATE TABLE '
.
$db
->
quoteTableName
(
$table
))
->
queryRow
();
if
(
$row
===
false
)
throw
new
CDbException
(
Yii
::
t
(
'yii'
,
'Unable to find "{column}" in table "{table}".'
,
array
(
'{column}'
=>
$name
,
'{table}'
=>
$table
)));
if
(
isset
(
$row
[
'Create Table'
]))
$sql
=
$row
[
'Create Table'
];
else
{
$row
=
array_values
(
$row
);
$sql
=
$row
[
1
];
}
if
(
preg_match_all
(
'/^\s*`(.*?)`\s+(.*?),?$/m'
,
$sql
,
$matches
))
{
foreach
(
$matches
[
1
]
as
$i
=>
$c
)
{
if
(
$c
===
$name
)
{
return
"ALTER TABLE "
.
$db
->
quoteTableName
(
$table
)
.
" CHANGE "
.
$db
->
quoteColumnName
(
$name
)
.
' '
.
$db
->
quoteColumnName
(
$newName
)
.
' '
.
$matches
[
2
][
$i
];
}
}
}
// try to give back a SQL anyway
return
"ALTER TABLE "
.
$db
->
quoteTableName
(
$table
)
.
" CHANGE "
.
$db
->
quoteColumnName
(
$name
)
.
' '
.
$newName
;
}
/**
* Builds a SQL statement for dropping a foreign key constraint.
* @param string $name the name of the foreign key constraint to be dropped. The name will be properly quoted by the method.
* @param string $table the table whose foreign is to be dropped. The name will be properly quoted by the method.
* @return string the SQL statement for dropping a foreign key constraint.
* @since 1.1.6
*/
public
function
dropForeignKey
(
$name
,
$table
)
{
return
'ALTER TABLE '
.
$this
->
quoteTableName
(
$table
)
.
' DROP FOREIGN KEY '
.
$this
->
quoteColumnName
(
$name
);
}
}
framework/db/dao/mysql/TableSchema.php
0 → 100644
View file @
3335f09d
<?php
/**
* TableSchema 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/
*/
/**
* TableSchema represents the metadata for a MySQL table.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class
TableSchema
extends
CDbTableSchema
{
/**
* @var string name of the schema (database) that this table belongs to.
* Defaults to null, meaning no schema (or the current database).
*/
public
$schemaName
;
}
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