mirror of
https://github.com/yiisoft/yii2.git
synced 2025-11-15 13:58:24 +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.');
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @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
|
||||
* @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();
|
||||
if (isset($row['Create Table'])) {
|
||||
@@ -219,6 +220,16 @@ class Schema extends \yii\db\Schema
|
||||
$row = array_values($row);
|
||||
$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';
|
||||
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.
|
||||
* @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.
|
||||
* @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.
|
||||
* @param array $info column information
|
||||
|
||||
Reference in New Issue
Block a user