mirror of
https://github.com/yiisoft/yii2.git
synced 2025-11-15 22:09:48 +08:00
Merge pull request #1621 from lucianobaraglia/master
Get DB unique indexes information
This commit is contained in:
@@ -247,6 +247,28 @@ abstract class Schema extends Object
|
|||||||
throw new NotSupportedException(get_class($this) . ' does not support fetching all table names.');
|
throw new NotSupportedException(get_class($this) . ' does not support fetching all table names.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all unique indexes for the given table.
|
||||||
|
* Each array element is of the following structure:
|
||||||
|
*
|
||||||
|
* ~~~
|
||||||
|
* [
|
||||||
|
* 'IndexName1' => ['col1' [, ...]],
|
||||||
|
* 'IndexName2' => ['col2' [, ...]],
|
||||||
|
* ]
|
||||||
|
* ~~~
|
||||||
|
*
|
||||||
|
* This method should be overridden by child classes in order to support this feature
|
||||||
|
* because the default implementation simply throws an exception
|
||||||
|
* @param TableSchema $table the table metadata
|
||||||
|
* @return array all unique indexes for the given table.
|
||||||
|
* @throws NotSupportedException if this method is called
|
||||||
|
*/
|
||||||
|
public function findUniqueIndexes($schema = '')
|
||||||
|
{
|
||||||
|
throw new NotSupportedException(get_class($this) . ' does not support getting unique indexes information.');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the ID of the last inserted row or sequence value.
|
* Returns the ID of the last inserted row or sequence value.
|
||||||
* @param string $sequenceName name of the sequence object (required by some DBMS)
|
* @param string $sequenceName name of the sequence object (required by some DBMS)
|
||||||
|
|||||||
@@ -207,10 +207,11 @@ class Schema extends \yii\db\Schema
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Collects the foreign key column details for the given table.
|
* Gets the CREATE TABLE sql string.
|
||||||
* @param TableSchema $table the table metadata
|
* @param TableSchema $table the table metadata
|
||||||
|
* @return string $sql the result of 'SHOW CREATE TABLE'
|
||||||
*/
|
*/
|
||||||
protected function findConstraints($table)
|
protected function getCreateTableSql($table)
|
||||||
{
|
{
|
||||||
$row = $this->db->createCommand('SHOW CREATE TABLE ' . $this->quoteSimpleTableName($table->name))->queryOne();
|
$row = $this->db->createCommand('SHOW CREATE TABLE ' . $this->quoteSimpleTableName($table->name))->queryOne();
|
||||||
if (isset($row['Create Table'])) {
|
if (isset($row['Create Table'])) {
|
||||||
@@ -219,6 +220,16 @@ class Schema extends \yii\db\Schema
|
|||||||
$row = array_values($row);
|
$row = array_values($row);
|
||||||
$sql = $row[1];
|
$sql = $row[1];
|
||||||
}
|
}
|
||||||
|
return $sql;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Collects the foreign key column details for the given table.
|
||||||
|
* @param TableSchema $table the table metadata
|
||||||
|
*/
|
||||||
|
protected function findConstraints($table)
|
||||||
|
{
|
||||||
|
$sql = $this->getCreateTableSql($table);
|
||||||
|
|
||||||
$regexp = '/FOREIGN KEY\s+\(([^\)]+)\)\s+REFERENCES\s+([^\(^\s]+)\s*\(([^\)]+)\)/mi';
|
$regexp = '/FOREIGN KEY\s+\(([^\)]+)\)\s+REFERENCES\s+([^\(^\s]+)\s*\(([^\)]+)\)/mi';
|
||||||
if (preg_match_all($regexp, $sql, $matches, PREG_SET_ORDER)) {
|
if (preg_match_all($regexp, $sql, $matches, PREG_SET_ORDER)) {
|
||||||
@@ -234,6 +245,36 @@ class Schema extends \yii\db\Schema
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all unique indexes for the given table.
|
||||||
|
* Each array element is of the following structure:
|
||||||
|
*
|
||||||
|
* ~~~
|
||||||
|
* [
|
||||||
|
* 'IndexName1' => ['col1' [, ...]],
|
||||||
|
* 'IndexName2' => ['col2' [, ...]],
|
||||||
|
* ]
|
||||||
|
* ~~~
|
||||||
|
*
|
||||||
|
* @param TableSchema $table the table metadata
|
||||||
|
* @return array all unique indexes for the given table.
|
||||||
|
*/
|
||||||
|
public function findUniqueIndexes($table)
|
||||||
|
{
|
||||||
|
$sql = $this->getCreateTableSql($table);
|
||||||
|
$uniqueIndexes = [];
|
||||||
|
|
||||||
|
$regexp = '/UNIQUE KEY\s+([^\(^\s]+)\s*\(([^\)]+)\)/mi';
|
||||||
|
if (preg_match_all($regexp, $sql, $matches, PREG_SET_ORDER)) {
|
||||||
|
foreach ($matches as $match) {
|
||||||
|
$indexName = str_replace('`', '', $match[2]);
|
||||||
|
$indexColumns = array_map('trim', explode(',', str_replace('`', '', $match[3])));
|
||||||
|
$uniqueIndexes[$indexName] = $indexColumns;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $uniqueIndexes;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all table names in the database.
|
* 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.
|
* @param string $schema the schema of the tables. Defaults to empty string, meaning the current or default schema.
|
||||||
|
|||||||
@@ -226,6 +226,74 @@ SQL;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets information about given table unique indexes.
|
||||||
|
* @param TableSchema $table the table metadata
|
||||||
|
* @return array with index names, columns and if it is an expression tree
|
||||||
|
*/
|
||||||
|
protected function getUniqueIndexInformation($table)
|
||||||
|
{
|
||||||
|
$tableName = $this->quoteValue($table->name);
|
||||||
|
$tableSchema = $this->quoteValue($table->schemaName);
|
||||||
|
|
||||||
|
$sql = <<<SQL
|
||||||
|
SELECT
|
||||||
|
i.relname as indexname,
|
||||||
|
ARRAY(
|
||||||
|
SELECT pg_get_indexdef(idx.indexrelid, k + 1, True)
|
||||||
|
FROM generate_subscripts(idx.indkey, 1) AS k
|
||||||
|
ORDER BY k
|
||||||
|
) AS indexcolumns,
|
||||||
|
idx.indexprs IS NOT NULL AS indexprs
|
||||||
|
FROM pg_index idx
|
||||||
|
INNER JOIN pg_class i ON i.oid = idx.indexrelid
|
||||||
|
INNER JOIN pg_class c ON c.oid = idx.indrelid
|
||||||
|
INNER JOIN pg_namespace ns ON c.relnamespace = ns.oid
|
||||||
|
WHERE idx.indisprimary != True
|
||||||
|
AND idx.indisunique = True
|
||||||
|
AND c.relname = {$tableName}
|
||||||
|
AND ns.nspname = {$tableSchema}
|
||||||
|
;
|
||||||
|
SQL;
|
||||||
|
|
||||||
|
return $this->db->createCommand($sql)->queryAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all unique indexes for the given table.
|
||||||
|
* Each array element is of the following structure:
|
||||||
|
*
|
||||||
|
* ~~~
|
||||||
|
* [
|
||||||
|
* 'IndexName1' => ['col1' [, ...]],
|
||||||
|
* 'IndexName2' => ['col2' [, ...]],
|
||||||
|
* ]
|
||||||
|
* ~~~
|
||||||
|
*
|
||||||
|
* @param TableSchema $table the table metadata
|
||||||
|
* @return array all unique indexes for the given table.
|
||||||
|
*/
|
||||||
|
public function findUniqueIndexes($table)
|
||||||
|
{
|
||||||
|
$indexes = $this->getUniqueIndexInformation($table);
|
||||||
|
$uniqueIndexes = [];
|
||||||
|
|
||||||
|
foreach ($indexes as $index) {
|
||||||
|
$indexName = $index['indexname'];
|
||||||
|
|
||||||
|
if ($index['indexprs']) {
|
||||||
|
// Index is an expression like "lower(colname::text)"
|
||||||
|
$indexColumns = preg_replace("/.*\(([^\:]+).*/mi", "$1", $index['indexcolumns']);
|
||||||
|
} else {
|
||||||
|
$indexColumns = array_map('trim', explode(',', str_replace(['{', '}'], '', $index['indexcolumns'])));
|
||||||
|
}
|
||||||
|
|
||||||
|
$uniqueIndexes[$indexName] = $indexColumns;
|
||||||
|
|
||||||
|
}
|
||||||
|
return $uniqueIndexes;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Collects the metadata of table columns.
|
* Collects the metadata of table columns.
|
||||||
* @param TableSchema $table the table metadata
|
* @param TableSchema $table the table metadata
|
||||||
|
|||||||
@@ -158,6 +158,40 @@ class Schema extends \yii\db\Schema
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all unique indexes for the given table.
|
||||||
|
* Each array element is of the following structure:
|
||||||
|
*
|
||||||
|
* ~~~
|
||||||
|
* [
|
||||||
|
* 'IndexName1' => ['col1' [, ...]],
|
||||||
|
* 'IndexName2' => ['col2' [, ...]],
|
||||||
|
* ]
|
||||||
|
* ~~~
|
||||||
|
*
|
||||||
|
* @param TableSchema $table the table metadata
|
||||||
|
* @return array all unique indexes for the given table.
|
||||||
|
*/
|
||||||
|
public function findUniqueIndexes($table)
|
||||||
|
{
|
||||||
|
$sql = "PRAGMA index_list(" . $this->quoteSimpleTableName($table->name) . ')';
|
||||||
|
$indexes = $this->db->createCommand($sql)->queryAll();
|
||||||
|
$uniqueIndexes = [];
|
||||||
|
|
||||||
|
foreach ($indexes as $index) {
|
||||||
|
$indexName = $index['name'];
|
||||||
|
$indexInfo = $this->db->createCommand("PRAGMA index_info(" . $this->quoteValue($index['name']) . ")")->queryAll();
|
||||||
|
|
||||||
|
if ($index['unique']) {
|
||||||
|
$uniqueIndexes[$indexName] = [];
|
||||||
|
foreach ($indexInfo as $row) {
|
||||||
|
$uniqueIndexes[$indexName][] = $row['name'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $uniqueIndexes;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads the column information into a [[ColumnSchema]] object.
|
* Loads the column information into a [[ColumnSchema]] object.
|
||||||
* @param array $info column information
|
* @param array $info column information
|
||||||
|
|||||||
Reference in New Issue
Block a user