包 | system.db.schema.pgsql |
---|---|
继承 | class CPgsqlSchema » CDbSchema » CComponent |
源自 | 1.0 |
版本 | $Id: CPgsqlSchema.php 3515 2011-12-28 12:29:24Z mdomba $ |
源码 |
CPgsqlSchema是从PostgreSQL数据库检索元数据信息的类。
公共属性
属性 | 类型 | 描述 | 定义在 |
---|---|---|---|
columnTypes | array | 映射到实体列类型的抽象列类型。 | CPgsqlSchema |
commandBuilder | CDbCommandBuilder | the SQL command builder for this connection. | CDbSchema |
dbConnection | CDbConnection | database connection. | CDbSchema |
tableNames | array | Returns all table names in the database. | CDbSchema |
tables | array | Returns the metadata for all tables in the database. | CDbSchema |
公共方法
方法 | 描述 | 定义在 |
---|---|---|
__call() | 如果类中没有调的方法名,则调用这个方法。 | CComponent |
__construct() | Constructor. | CDbSchema |
__get() | 返回一个属性值、一个事件处理程序列表或一个行为名称。 | CComponent |
__isset() | 检查一个属性是否为null。 | CComponent |
__set() | 设置一个组件的属性值。 | CComponent |
__unset() | 设置一个组件的属性为null。 | CComponent |
addColumn() | 构造添加新列的SQL语句。 | CPgsqlSchema |
addForeignKey() | Builds a SQL statement for adding a foreign key constraint to an existing table. | CDbSchema |
alterColumn() | 构造改变列定义的SQL语句。 | CPgsqlSchema |
asa() | 返回这个名字的行为对象。 | CComponent |
attachBehavior() | 附加一个行为到组件。 | CComponent |
attachBehaviors() | 附加一个行为列表到组件。 | CComponent |
attachEventHandler() | 为事件附加一个事件处理程序。 | CComponent |
canGetProperty() | 确定属性是否可读。 | CComponent |
canSetProperty() | 确定属性是否可写。 | CComponent |
checkIntegrity() | 启用或禁用完整性检查。 | CPgsqlSchema |
compareTableNames() | Compares two table names. | CDbSchema |
createIndex() | Builds a SQL statement for creating a new index. | CDbSchema |
createTable() | Builds a SQL statement for creating a new DB table. | CDbSchema |
detachBehavior() | 从组件中分离一个行为。 | CComponent |
detachBehaviors() | 从组件中分离所有行为。 | CComponent |
detachEventHandler() | 分离一个存在的事件处理程序。 | CComponent |
disableBehavior() | 禁用一个附加行为。 | CComponent |
disableBehaviors() | 禁用组件附加的所有行为。 | CComponent |
dropColumn() | Builds a SQL statement for dropping a DB column. | CDbSchema |
dropForeignKey() | Builds a SQL statement for dropping a foreign key constraint. | CDbSchema |
dropIndex() | 构造删除索引的SQL语句。 | CPgsqlSchema |
dropTable() | Builds a SQL statement for dropping a DB table. | CDbSchema |
enableBehavior() | 启用一个附加行为。 | CComponent |
enableBehaviors() | 启用组件附加的所有行为。 | CComponent |
evaluateExpression() | 计算一个PHP表达式,或根据组件上下文执行回调。 | CComponent |
getColumnType() | Converts an abstract column type into a physical column type. | CDbSchema |
getCommandBuilder() | 返回the SQL command builder for this connection. | CDbSchema |
getDbConnection() | 返回database connection. The connection is active. | CDbSchema |
getEventHandlers() | 返回一个事件的附加处理程序列表。 | CComponent |
getTable() | Obtains the metadata for the named table. | CDbSchema |
getTableNames() | Returns all table names in the database. | CDbSchema |
getTables() | Returns the metadata for all tables in the database. | CDbSchema |
hasEvent() | 确定一个事件是否定义。 | CComponent |
hasEventHandler() | 检查事件是否有附加的处理程序。 | CComponent |
hasProperty() | 确定属性是否被定义。 | CComponent |
quoteColumnName() | Quotes a column name for use in a query. | CDbSchema |
quoteSimpleColumnName() | Quotes a simple column name for use in a query. | CDbSchema |
quoteSimpleTableName() | 用引号引用表名以便查询时使用。 | CPgsqlSchema |
quoteTableName() | Quotes a table name for use in a query. | CDbSchema |
raiseEvent() | 发起一个事件。 | CComponent |
refresh() | Refreshes the schema. | CDbSchema |
renameColumn() | Builds a SQL statement for renaming a column. | CDbSchema |
renameTable() | 构造重命名数据表的SQL语句。 | CPgsqlSchema |
resetSequence() | 重置表的主键的序列值。 | CPgsqlSchema |
truncateTable() | Builds a SQL statement for truncating a DB table. | CDbSchema |
受保护方法
方法 | 描述 | 定义在 |
---|---|---|
createColumn() | 创建一个列。 | CPgsqlSchema |
createCommandBuilder() | Creates a command builder for the database. | CDbSchema |
findColumns() | 收集列的元数据。 | CPgsqlSchema |
findConstraints() | 收集给定表主键列和外键列的详细信息。 | CPgsqlSchema |
findForeignKey() | 收集外键信息。 | CPgsqlSchema |
findPrimaryKey() | 收集主键信息。 | CPgsqlSchema |
findTableNames() | 返回所有数据库里的表名。 | CPgsqlSchema |
loadTable() | 为指定表载入元数据。 | CPgsqlSchema |
resolveTableNames() | 生成各种表名。 | CPgsqlSchema |
属性详细
columnTypes
属性
(可用自 v1.1.6)
public array $columnTypes;
映射到实体列类型的抽象列类型。
方法详细
addColumn()
方法
(可用自 v1.1.6)
public string addColumn(string $table, string $column, string $type)
| ||
$table | string | 要添加新列的表。该表名会被指定方法正确引用。 |
$column | string | 新列名。该列名会被指定方法正确引用。 |
$type | string | 列类型。getColumnType方法会被调用来将虚拟列类型(若存在) 转换为对应的实体列类型。任何未被识别为虚拟类型的类型会被保留在生成的SQL中。 例如,‘string’会被转为‘varchar(255)’,而‘string not null’会被转为‘varchar(255) not null’。 |
{return} | string | 改变列定义的SQL语句。 |
public function addColumn($table, $column, $type)
{
$type=$this->getColumnType($type);
$sql='ALTER TABLE ' . $this->quoteTableName($table)
. ' ADD COLUMN ' . $this->quoteColumnName($column) . ' '
. $this->getColumnType($type);
return $sql;
}
构造添加新列的SQL语句。
alterColumn()
方法
(可用自 v1.1.6)
public string alterColumn(string $table, string $column, string $type)
| ||
$table | string | 要改变的列所在表。该表名会被指定方法正确引用。 |
$column | string | 要改变的列名。该列名会被指定方法正确引用。 |
$type | string | 新的列类型。getColumnType方法会被调用来将虚拟列类型(若存在) 转换为对应的实体列类型。任何未被识别为虚拟类型的类型会被保留在生成的SQL中。 例如,‘string’会被转为‘varchar(255)’,而‘string not null’会被转为‘varchar(255) not null’。 |
{return} | string | 改变列定义的SQL语句。 |
public function alterColumn($table, $column, $type)
{
$type=$this->getColumnType($type);
$sql='ALTER TABLE ' . $this->quoteTableName($table) . ' ALTER COLUMN '
. $this->quoteColumnName($column) . ' TYPE ' . $this->getColumnType($type);
return $sql;
}
构造改变列定义的SQL语句。
checkIntegrity()
方法
(可用自 v1.1)
public void checkIntegrity(boolean $check=true, string $schema='')
| ||
$check | boolean | 是否开启完整性检查。 |
$schema | string | 各表schema。默认为空字符串,意味着当前或默认schema。 |
public function checkIntegrity($check=true,$schema='')
{
$enable=$check ? 'ENABLE' : 'DISABLE';
$tableNames=$this->getTableNames($schema);
$db=$this->getDbConnection();
foreach($tableNames as $tableName)
{
$tableName='"'.$tableName.'"';
if(strpos($tableName,'.')!==false)
$tableName=str_replace('.','"."',$tableName);
$db->createCommand("ALTER TABLE $tableName $enable TRIGGER ALL")->execute();
}
}
启用或禁用完整性检查。
createColumn()
方法
protected CDbColumnSchema createColumn(array $column)
| ||
$column | array | 列元数据 |
{return} | CDbColumnSchema | 规范的列元数据 |
protected function createColumn($column)
{
$c=new CPgsqlColumnSchema;
$c->name=$column['attname'];
$c->rawName=$this->quoteColumnName($c->name);
$c->allowNull=!$column['attnotnull'];
$c->isPrimaryKey=false;
$c->isForeignKey=false;
$c->init($column['type'],$column['atthasdef'] ? $column['adsrc'] : null);
return $c;
}
创建一个列。
dropIndex()
方法
(可用自 v1.1.6)
public string dropIndex(string $name, string $table)
| ||
$name | string | 要删除的索引名。该索引名会被指定方法正确引用。 |
$table | string | 要删除的索引所在表。该表名会被指定方法正确引用。 |
{return} | string | 删除索引的SQL语句。 |
public function dropIndex($name, $table)
{
return 'DROP INDEX '.$this->quoteTableName($name);
}
构造删除索引的SQL语句。
findColumns()
方法
protected boolean findColumns(CPgsqlTableSchema $table)
| ||
$table | CPgsqlTableSchema | 表元数据 |
{return} | boolean | 表是否存在于数据库里 |
protected function findColumns($table)
{
$sql=<<<EOD
SELECT a.attname, LOWER(format_type(a.atttypid, a.atttypmod)) AS type, d.adsrc, a.attnotnull, a.atthasdef
FROM pg_attribute a LEFT JOIN pg_attrdef d ON a.attrelid = d.adrelid AND a.attnum = d.adnum
WHERE a.attnum > 0 AND NOT a.attisdropped
AND a.attrelid = (SELECT oid FROM pg_catalog.pg_class WHERE relname=:table
AND relnamespace = (SELECT oid FROM pg_catalog.pg_namespace WHERE nspname = :schema))
ORDER BY a.attnum
EOD;
$command=$this->getDbConnection()->createCommand($sql);
$command->bindValue(':table',$table->name);
$command->bindValue(':schema',$table->schemaName);
if(($columns=$command->queryAll())===array())
return false;
foreach($columns as $column)
{
$c=$this->createColumn($column);
$table->columns[$c->name]=$c;
if(stripos($column['adsrc'],'nextval')===0 && preg_match('/nextval\([^\']*\'([^\']+)\'[^\)]*\)/i',$column['adsrc'],$matches))
{
if(strpos($matches[1],'.')!==false || $table->schemaName===self::DEFAULT_SCHEMA)
$this->_sequences[$table->rawName.'.'.$c->name]=$matches[1];
else
$this->_sequences[$table->rawName.'.'.$c->name]=$table->schemaName.'.'.$matches[1];
$c->autoIncrement=true;
}
}
return true;
}
收集列的元数据。
findConstraints()
方法
protected void findConstraints(CPgsqlTableSchema $table)
| ||
$table | CPgsqlTableSchema | 表元数据 |
protected function findConstraints($table)
{
$sql=<<<EOD
SELECT conname, consrc, contype, indkey FROM (
SELECT
conname,
CASE WHEN contype='f' THEN
pg_catalog.pg_get_constraintdef(oid)
ELSE
'CHECK (' || consrc || ')'
END AS consrc,
contype,
conrelid AS relid,
NULL AS indkey
FROM
pg_catalog.pg_constraint
WHERE
contype IN ('f', 'c')
UNION ALL
SELECT
pc.relname,
NULL,
CASE WHEN indisprimary THEN
'p'
ELSE
'u'
END,
pi.indrelid,
indkey
FROM
pg_catalog.pg_class pc,
pg_catalog.pg_index pi
WHERE
pc.oid=pi.indexrelid
AND EXISTS (
SELECT 1 FROM pg_catalog.pg_depend d JOIN pg_catalog.pg_constraint c
ON (d.refclassid = c.tableoid AND d.refobjid = c.oid)
WHERE d.classid = pc.tableoid AND d.objid = pc.oid AND d.deptype = 'i' AND c.contype IN ('u', 'p')
)
) AS sub
WHERE relid = (SELECT oid FROM pg_catalog.pg_class WHERE relname=:table
AND relnamespace = (SELECT oid FROM pg_catalog.pg_namespace
WHERE nspname=:schema))
EOD;
$command=$this->getDbConnection()->createCommand($sql);
$command->bindValue(':table',$table->name);
$command->bindValue(':schema',$table->schemaName);
foreach($command->queryAll() as $row)
{
if($row['contype']==='p') // primary key
$this->findPrimaryKey($table,$row['indkey']);
else if($row['contype']==='f') // foreign key
$this->findForeignKey($table,$row['consrc']);
}
}
收集给定表主键列和外键列的详细信息。
findForeignKey()
方法
protected void findForeignKey(CPgsqlTableSchema $table, string $src)
| ||
$table | CPgsqlTableSchema | 表元数据 |
$src | string | pgsql外键定义 |
protected function findForeignKey($table,$src)
{
$matches=array();
$brackets='\(([^\)]+)\)';
$pattern="/FOREIGN\s+KEY\s+{$brackets}\s+REFERENCES\s+([^\(]+){$brackets}/i";
if(preg_match($pattern,str_replace('"','',$src),$matches))
{
$keys=preg_split('/,\s+/', $matches[1]);
$tableName=$matches[2];
$fkeys=preg_split('/,\s+/', $matches[3]);
foreach($keys as $i=>$key)
{
$table->foreignKeys[$key]=array($tableName,$fkeys[$i]);
if(isset($table->columns[$key]))
$table->columns[$key]->isForeignKey=true;
}
}
}
收集外键信息。
findPrimaryKey()
方法
protected void findPrimaryKey(CPgsqlTableSchema $table, string $indices)
| ||
$table | CPgsqlTableSchema | 表元数据 |
$indices | string | pgsql主键索引列表 |
protected function findPrimaryKey($table,$indices)
{
$indices=implode(', ',preg_split('/\s+/',$indices));
$sql=<<<EOD
SELECT attnum, attname FROM pg_catalog.pg_attribute WHERE
attrelid=(
SELECT oid FROM pg_catalog.pg_class WHERE relname=:table AND relnamespace=(
SELECT oid FROM pg_catalog.pg_namespace WHERE nspname=:schema
)
)
AND attnum IN ({$indices})
EOD;
$command=$this->getDbConnection()->createCommand($sql);
$command->bindValue(':table',$table->name);
$command->bindValue(':schema',$table->schemaName);
foreach($command->queryAll() as $row)
{
$name=$row['attname'];
if(isset($table->columns[$name]))
{
$table->columns[$name]->isPrimaryKey=true;
if($table->primaryKey===null)
$table->primaryKey=$name;
else if(is_string($table->primaryKey))
$table->primaryKey=array($table->primaryKey,$name);
else
$table->primaryKey[]=$name;
}
}
}
收集主键信息。
findTableNames()
方法
protected array findTableNames(string $schema='')
| ||
$schema | string | 表schema。默认是空字符串,意味着当前或默认schema。 若为空,则返回的表名会被加上schema名前缀。 |
{return} | array | 数据库里的所有表名。 |
protected function findTableNames($schema='')
{
if($schema==='')
$schema=self::DEFAULT_SCHEMA;
$sql=<<<EOD
SELECT table_name, table_schema FROM information_schema.tables
WHERE table_schema=:schema AND table_type='BASE TABLE'
EOD;
$command=$this->getDbConnection()->createCommand($sql);
$command->bindParam(':schema',$schema);
$rows=$command->queryAll();
$names=array();
foreach($rows as $row)
{
if($schema===self::DEFAULT_SCHEMA)
$names[]=$row['table_name'];
else
$names[]=$row['table_schema'].'.'.$row['table_name'];
}
return $names;
}
返回所有数据库里的表名。
loadTable()
方法
protected CDbTableSchema loadTable(string $name)
| ||
$name | string | 表名 |
{return} | CDbTableSchema | 取决于表元数据的驱动。 |
protected function loadTable($name)
{
$table=new CPgsqlTableSchema;
$this->resolveTableNames($table,$name);
if(!$this->findColumns($table))
return null;
$this->findConstraints($table);
if(is_string($table->primaryKey) && isset($this->_sequences[$table->rawName.'.'.$table->primaryKey]))
$table->sequenceName=$this->_sequences[$table->rawName.'.'.$table->primaryKey];
else if(is_array($table->primaryKey))
{
foreach($table->primaryKey as $pk)
{
if(isset($this->_sequences[$table->rawName.'.'.$pk]))
{
$table->sequenceName=$this->_sequences[$table->rawName.'.'.$pk];
break;
}
}
}
return $table;
}
为指定表载入元数据。
quoteSimpleTableName()
方法
(可用自 v1.1.6)
public string quoteSimpleTableName(string $name)
| ||
$name | string | 表名 |
{return} | string | 正确引用的表名 |
public function quoteSimpleTableName($name)
{
return '"'.$name.'"';
}
用引号引用表名以便查询时使用。 一个不包括前缀的简单表名。
renameTable()
方法
(可用自 v1.1.6)
public string renameTable(string $table, string $newName)
| ||
$table | string | 要重命名的表。该表名会被指定方法正确引用。 |
$newName | string | 新表名。 该表名会被指定方法正确引用。 |
{return} | string | 重命名数据表的SQL语句。 |
public function renameTable($table, $newName)
{
return 'ALTER TABLE ' . $this->quoteTableName($table) . ' RENAME TO ' . $this->quoteTableName($newName);
}
构造重命名数据表的SQL语句。
resetSequence()
方法
(可用自 v1.1)
public void resetSequence(CDbTableSchema $table, mixed $value=NULL)
| ||
$table | CDbTableSchema | 要重置主键序列的表schema |
$value | mixed | 新插入行的主键值。如果未设置, 则新行主键值为1。 |
public function resetSequence($table,$value=null)
{
if($table->sequenceName!==null)
{
$seq='"'.$table->sequenceName.'"';
if(strpos($seq,'.')!==false)
$seq=str_replace('.','"."',$seq);
if($value===null)
$value="(SELECT COALESCE(MAX(\"{$table->primaryKey}\"),0) FROM {$table->rawName}) + 1";
else
$value=(int)$value;
$this->getDbConnection()->createCommand("SELECT SETVAL('$seq', $value, false)")->execute();
}
}
重置表的主键的序列值。 序列会被充值,这样一来,新插入行的主键值 将会是指定值或者1。
resolveTableNames()
方法
protected void resolveTableNames(CPgsqlTableSchema $table, string $name)
| ||
$table | CPgsqlTableSchema | 表元数据 |
$name | string | 未引用的表名 |
protected function resolveTableNames($table,$name)
{
$parts=explode('.',str_replace('"','',$name));
if(isset($parts[1]))
{
$schemaName=$parts[0];
$tableName=$parts[1];
}
else
{
$schemaName=self::DEFAULT_SCHEMA;
$tableName=$parts[0];
}
$table->name=$tableName;
$table->schemaName=$schemaName;
if($schemaName===self::DEFAULT_SCHEMA)
$table->rawName=$this->quoteTableName($tableName);
else
$table->rawName=$this->quoteTableName($schemaName).'.'.$this->quoteTableName($tableName);
}
生成各种表名。