init
This commit is contained in:
67
vendor/yiisoft/yii2/db/mysql/ColumnSchema.php
vendored
Normal file
67
vendor/yiisoft/yii2/db/mysql/ColumnSchema.php
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\db\mysql;
|
||||
|
||||
use yii\db\ExpressionInterface;
|
||||
use yii\db\JsonExpression;
|
||||
|
||||
/**
|
||||
* Class ColumnSchema for MySQL database
|
||||
*
|
||||
* @author Dmytro Naumenko <d.naumenko.a@gmail.com>
|
||||
* @since 2.0.14.1
|
||||
*/
|
||||
class ColumnSchema extends \yii\db\ColumnSchema
|
||||
{
|
||||
/**
|
||||
* @var bool whether the column schema should OMIT using JSON support feature.
|
||||
* You can use this property to make upgrade to Yii 2.0.14 easier.
|
||||
* Default to `false`, meaning JSON support is enabled.
|
||||
*
|
||||
* @since 2.0.14.1
|
||||
* @deprecated Since 2.0.14.1 and will be removed in 2.1.
|
||||
*/
|
||||
public $disableJsonSupport = false;
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function dbTypecast($value)
|
||||
{
|
||||
if ($value === null) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
if ($value instanceof ExpressionInterface) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
if (!$this->disableJsonSupport && $this->dbType === Schema::TYPE_JSON) {
|
||||
return new JsonExpression($value, $this->type);
|
||||
}
|
||||
|
||||
return $this->typecast($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function phpTypecast($value)
|
||||
{
|
||||
if ($value === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!$this->disableJsonSupport && $this->type === Schema::TYPE_JSON) {
|
||||
return json_decode($value, true);
|
||||
}
|
||||
|
||||
return parent::phpTypecast($value);
|
||||
}
|
||||
}
|
||||
72
vendor/yiisoft/yii2/db/mysql/ColumnSchemaBuilder.php
vendored
Normal file
72
vendor/yiisoft/yii2/db/mysql/ColumnSchemaBuilder.php
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\db\mysql;
|
||||
|
||||
use yii\db\ColumnSchemaBuilder as AbstractColumnSchemaBuilder;
|
||||
|
||||
/**
|
||||
* ColumnSchemaBuilder is the schema builder for MySQL databases.
|
||||
*
|
||||
* @author Chris Harris <chris@buckshotsoftware.com>
|
||||
* @since 2.0.8
|
||||
*/
|
||||
class ColumnSchemaBuilder extends AbstractColumnSchemaBuilder
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function buildUnsignedString()
|
||||
{
|
||||
return $this->isUnsigned ? ' UNSIGNED' : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function buildAfterString()
|
||||
{
|
||||
return $this->after !== null ?
|
||||
' AFTER ' . $this->db->quoteColumnName($this->after) :
|
||||
'';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function buildFirstString()
|
||||
{
|
||||
return $this->isFirst ? ' FIRST' : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function buildCommentString()
|
||||
{
|
||||
return $this->comment !== null ? ' COMMENT ' . $this->db->quoteValue($this->comment) : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
switch ($this->getTypeCategory()) {
|
||||
case self::CATEGORY_PK:
|
||||
$format = '{type}{length}{check}{comment}{append}{pos}';
|
||||
break;
|
||||
case self::CATEGORY_NUMERIC:
|
||||
$format = '{type}{length}{unsigned}{notnull}{unique}{default}{check}{comment}{append}{pos}';
|
||||
break;
|
||||
default:
|
||||
$format = '{type}{length}{notnull}{unique}{default}{check}{comment}{append}{pos}';
|
||||
}
|
||||
|
||||
return $this->buildCompleteString($format);
|
||||
}
|
||||
}
|
||||
48
vendor/yiisoft/yii2/db/mysql/JsonExpressionBuilder.php
vendored
Normal file
48
vendor/yiisoft/yii2/db/mysql/JsonExpressionBuilder.php
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\db\mysql;
|
||||
|
||||
use yii\db\ExpressionBuilderInterface;
|
||||
use yii\db\ExpressionBuilderTrait;
|
||||
use yii\db\ExpressionInterface;
|
||||
use yii\db\JsonExpression;
|
||||
use yii\db\Query;
|
||||
use yii\helpers\Json;
|
||||
|
||||
/**
|
||||
* Class JsonExpressionBuilder builds [[JsonExpression]] for MySQL DBMS.
|
||||
*
|
||||
* @author Dmytro Naumenko <d.naumenko.a@gmail.com>
|
||||
* @since 2.0.14
|
||||
*/
|
||||
class JsonExpressionBuilder implements ExpressionBuilderInterface
|
||||
{
|
||||
use ExpressionBuilderTrait;
|
||||
|
||||
const PARAM_PREFIX = ':qp';
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @param JsonExpression|ExpressionInterface $expression the expression to be built
|
||||
*/
|
||||
public function build(ExpressionInterface $expression, array &$params = [])
|
||||
{
|
||||
$value = $expression->getValue();
|
||||
|
||||
if ($value instanceof Query) {
|
||||
list ($sql, $params) = $this->queryBuilder->build($value, $params);
|
||||
return "($sql)";
|
||||
}
|
||||
|
||||
$placeholder = static::PARAM_PREFIX . count($params);
|
||||
$params[$placeholder] = Json::encode($value);
|
||||
|
||||
return "CAST($placeholder AS JSON)";
|
||||
}
|
||||
}
|
||||
365
vendor/yiisoft/yii2/db/mysql/QueryBuilder.php
vendored
Normal file
365
vendor/yiisoft/yii2/db/mysql/QueryBuilder.php
vendored
Normal file
@@ -0,0 +1,365 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\db\mysql;
|
||||
|
||||
use yii\base\InvalidArgumentException;
|
||||
use yii\base\NotSupportedException;
|
||||
use yii\db\Exception;
|
||||
use yii\db\Expression;
|
||||
use yii\db\Query;
|
||||
|
||||
/**
|
||||
* QueryBuilder is the query builder for MySQL databases.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class QueryBuilder extends \yii\db\QueryBuilder
|
||||
{
|
||||
/**
|
||||
* @var array mapping from abstract column types (keys) to physical column types (values).
|
||||
*/
|
||||
public $typeMap = [
|
||||
Schema::TYPE_PK => 'int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY',
|
||||
Schema::TYPE_UPK => 'int(10) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY',
|
||||
Schema::TYPE_BIGPK => 'bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY',
|
||||
Schema::TYPE_UBIGPK => 'bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY',
|
||||
Schema::TYPE_CHAR => 'char(1)',
|
||||
Schema::TYPE_STRING => 'varchar(255)',
|
||||
Schema::TYPE_TEXT => 'text',
|
||||
Schema::TYPE_TINYINT => 'tinyint(3)',
|
||||
Schema::TYPE_SMALLINT => 'smallint(6)',
|
||||
Schema::TYPE_INTEGER => 'int(11)',
|
||||
Schema::TYPE_BIGINT => 'bigint(20)',
|
||||
Schema::TYPE_FLOAT => 'float',
|
||||
Schema::TYPE_DOUBLE => 'double',
|
||||
Schema::TYPE_DECIMAL => 'decimal(10,0)',
|
||||
Schema::TYPE_DATETIME => 'datetime',
|
||||
Schema::TYPE_TIMESTAMP => 'timestamp',
|
||||
Schema::TYPE_TIME => 'time',
|
||||
Schema::TYPE_DATE => 'date',
|
||||
Schema::TYPE_BINARY => 'blob',
|
||||
Schema::TYPE_BOOLEAN => 'tinyint(1)',
|
||||
Schema::TYPE_MONEY => 'decimal(19,4)',
|
||||
Schema::TYPE_JSON => 'json'
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function defaultExpressionBuilders()
|
||||
{
|
||||
return array_merge(parent::defaultExpressionBuilders(), [
|
||||
'yii\db\JsonExpression' => 'yii\db\mysql\JsonExpressionBuilder',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 $oldName the old name of the column. The name will be properly quoted by the method.
|
||||
* @param string $newName the new name of the column. The name will be properly quoted by the method.
|
||||
* @return string the SQL statement for renaming a DB column.
|
||||
* @throws Exception
|
||||
*/
|
||||
public function renameColumn($table, $oldName, $newName)
|
||||
{
|
||||
$quotedTable = $this->db->quoteTableName($table);
|
||||
$row = $this->db->createCommand('SHOW CREATE TABLE ' . $quotedTable)->queryOne();
|
||||
if ($row === false) {
|
||||
throw new Exception("Unable to find column '$oldName' in 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 === $oldName) {
|
||||
return "ALTER TABLE $quotedTable CHANGE "
|
||||
. $this->db->quoteColumnName($oldName) . ' '
|
||||
. $this->db->quoteColumnName($newName) . ' '
|
||||
. $matches[2][$i];
|
||||
}
|
||||
}
|
||||
}
|
||||
// try to give back a SQL anyway
|
||||
return "ALTER TABLE $quotedTable CHANGE "
|
||||
. $this->db->quoteColumnName($oldName) . ' '
|
||||
. $this->db->quoteColumnName($newName);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see https://bugs.mysql.com/bug.php?id=48875
|
||||
*/
|
||||
public function createIndex($name, $table, $columns, $unique = false)
|
||||
{
|
||||
return 'ALTER TABLE '
|
||||
. $this->db->quoteTableName($table)
|
||||
. ($unique ? ' ADD UNIQUE INDEX ' : ' ADD INDEX ')
|
||||
. $this->db->quoteTableName($name)
|
||||
. ' (' . $this->buildColumns($columns) . ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* 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->db->quoteTableName($table)
|
||||
. ' DROP FOREIGN KEY ' . $this->db->quoteColumnName($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a SQL statement for removing a primary key constraint to an existing table.
|
||||
* @param string $name the name of the primary key constraint to be removed.
|
||||
* @param string $table the table that the primary key constraint will be removed from.
|
||||
* @return string the SQL statement for removing a primary key constraint from an existing table.
|
||||
*/
|
||||
public function dropPrimaryKey($name, $table)
|
||||
{
|
||||
return 'ALTER TABLE ' . $this->db->quoteTableName($table) . ' DROP PRIMARY KEY';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function dropUnique($name, $table)
|
||||
{
|
||||
return $this->dropIndex($name, $table);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @throws NotSupportedException this is not supported by MySQL.
|
||||
*/
|
||||
public function addCheck($name, $table, $expression)
|
||||
{
|
||||
throw new NotSupportedException(__METHOD__ . ' is not supported by MySQL.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @throws NotSupportedException this is not supported by MySQL.
|
||||
*/
|
||||
public function dropCheck($name, $table)
|
||||
{
|
||||
throw new NotSupportedException(__METHOD__ . ' is not supported by MySQL.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a SQL statement for resetting 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 string $tableName the name of the table 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.
|
||||
* @return string the SQL statement for resetting sequence
|
||||
* @throws InvalidArgumentException if the table does not exist or there is no sequence associated with the table.
|
||||
*/
|
||||
public function resetSequence($tableName, $value = null)
|
||||
{
|
||||
$table = $this->db->getTableSchema($tableName);
|
||||
if ($table !== null && $table->sequenceName !== null) {
|
||||
$tableName = $this->db->quoteTableName($tableName);
|
||||
if ($value === null) {
|
||||
$key = reset($table->primaryKey);
|
||||
$value = $this->db->createCommand("SELECT MAX(`$key`) FROM $tableName")->queryScalar() + 1;
|
||||
} else {
|
||||
$value = (int) $value;
|
||||
}
|
||||
|
||||
return "ALTER TABLE $tableName AUTO_INCREMENT=$value";
|
||||
} elseif ($table === null) {
|
||||
throw new InvalidArgumentException("Table not found: $tableName");
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException("There is no sequence associated with table '$tableName'.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a SQL statement for enabling or disabling integrity check.
|
||||
* @param bool $check whether to turn on or off the integrity check.
|
||||
* @param string $schema the schema of the tables. Meaningless for MySQL.
|
||||
* @param string $table the table name. Meaningless for MySQL.
|
||||
* @return string the SQL statement for checking integrity
|
||||
*/
|
||||
public function checkIntegrity($check = true, $schema = '', $table = '')
|
||||
{
|
||||
return 'SET FOREIGN_KEY_CHECKS = ' . ($check ? 1 : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildLimit($limit, $offset)
|
||||
{
|
||||
$sql = '';
|
||||
if ($this->hasLimit($limit)) {
|
||||
$sql = 'LIMIT ' . $limit;
|
||||
if ($this->hasOffset($offset)) {
|
||||
$sql .= ' OFFSET ' . $offset;
|
||||
}
|
||||
} elseif ($this->hasOffset($offset)) {
|
||||
// limit is not optional in MySQL
|
||||
// http://stackoverflow.com/a/271650/1106908
|
||||
// http://dev.mysql.com/doc/refman/5.0/en/select.html#idm47619502796240
|
||||
$sql = "LIMIT $offset, 18446744073709551615"; // 2^64-1
|
||||
}
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function hasLimit($limit)
|
||||
{
|
||||
// In MySQL limit argument must be nonnegative integer constant
|
||||
return ctype_digit((string) $limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function hasOffset($offset)
|
||||
{
|
||||
// In MySQL offset argument must be nonnegative integer constant
|
||||
$offset = (string) $offset;
|
||||
return ctype_digit($offset) && $offset !== '0';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function prepareInsertValues($table, $columns, $params = [])
|
||||
{
|
||||
list($names, $placeholders, $values, $params) = parent::prepareInsertValues($table, $columns, $params);
|
||||
if (!$columns instanceof Query && empty($names)) {
|
||||
$tableSchema = $this->db->getSchema()->getTableSchema($table);
|
||||
if ($tableSchema !== null) {
|
||||
$columns = !empty($tableSchema->primaryKey) ? $tableSchema->primaryKey : [reset($tableSchema->columns)->name];
|
||||
foreach ($columns as $name) {
|
||||
$names[] = $this->db->quoteColumnName($name);
|
||||
$placeholders[] = 'DEFAULT';
|
||||
}
|
||||
}
|
||||
}
|
||||
return [$names, $placeholders, $values, $params];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see https://downloads.mysql.com/docs/refman-5.1-en.pdf
|
||||
*/
|
||||
public function upsert($table, $insertColumns, $updateColumns, &$params)
|
||||
{
|
||||
$insertSql = $this->insert($table, $insertColumns, $params);
|
||||
list($uniqueNames, , $updateNames) = $this->prepareUpsertColumns($table, $insertColumns, $updateColumns);
|
||||
if (empty($uniqueNames)) {
|
||||
return $insertSql;
|
||||
}
|
||||
|
||||
if ($updateColumns === true) {
|
||||
$updateColumns = [];
|
||||
foreach ($updateNames as $name) {
|
||||
$updateColumns[$name] = new Expression('VALUES(' . $this->db->quoteColumnName($name) . ')');
|
||||
}
|
||||
} elseif ($updateColumns === false) {
|
||||
$name = $this->db->quoteColumnName(reset($uniqueNames));
|
||||
$updateColumns = [$name => new Expression($this->db->quoteTableName($table) . '.' . $name)];
|
||||
}
|
||||
list($updates, $params) = $this->prepareUpdateSets($table, $updateColumns, $params);
|
||||
return $insertSql . ' ON DUPLICATE KEY UPDATE ' . implode(', ', $updates);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @since 2.0.8
|
||||
*/
|
||||
public function addCommentOnColumn($table, $column, $comment)
|
||||
{
|
||||
// Strip existing comment which may include escaped quotes
|
||||
$definition = trim(preg_replace("/COMMENT '(?:''|[^'])*'/i", '',
|
||||
$this->getColumnDefinition($table, $column)));
|
||||
|
||||
return 'ALTER TABLE ' . $this->db->quoteTableName($table)
|
||||
. ' CHANGE ' . $this->db->quoteColumnName($column)
|
||||
. ' ' . $this->db->quoteColumnName($column)
|
||||
. (empty($definition) ? '' : ' ' . $definition)
|
||||
. ' COMMENT ' . $this->db->quoteValue($comment);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @since 2.0.8
|
||||
*/
|
||||
public function addCommentOnTable($table, $comment)
|
||||
{
|
||||
return 'ALTER TABLE ' . $this->db->quoteTableName($table) . ' COMMENT ' . $this->db->quoteValue($comment);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @since 2.0.8
|
||||
*/
|
||||
public function dropCommentFromColumn($table, $column)
|
||||
{
|
||||
return $this->addCommentOnColumn($table, $column, '');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @since 2.0.8
|
||||
*/
|
||||
public function dropCommentFromTable($table)
|
||||
{
|
||||
return $this->addCommentOnTable($table, '');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets column definition.
|
||||
*
|
||||
* @param string $table table name
|
||||
* @param string $column column name
|
||||
* @return null|string the column definition
|
||||
* @throws Exception in case when table does not contain column
|
||||
*/
|
||||
private function getColumnDefinition($table, $column)
|
||||
{
|
||||
$quotedTable = $this->db->quoteTableName($table);
|
||||
$row = $this->db->createCommand('SHOW CREATE TABLE ' . $quotedTable)->queryOne();
|
||||
if ($row === false) {
|
||||
throw new Exception("Unable to find column '$column' in 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 === $column) {
|
||||
return $matches[2][$i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
577
vendor/yiisoft/yii2/db/mysql/Schema.php
vendored
Normal file
577
vendor/yiisoft/yii2/db/mysql/Schema.php
vendored
Normal file
@@ -0,0 +1,577 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\db\mysql;
|
||||
|
||||
use yii\base\InvalidConfigException;
|
||||
use yii\base\NotSupportedException;
|
||||
use yii\db\Constraint;
|
||||
use yii\db\ConstraintFinderInterface;
|
||||
use yii\db\ConstraintFinderTrait;
|
||||
use yii\db\Exception;
|
||||
use yii\db\Expression;
|
||||
use yii\db\ForeignKeyConstraint;
|
||||
use yii\db\IndexConstraint;
|
||||
use yii\db\TableSchema;
|
||||
use yii\helpers\ArrayHelper;
|
||||
|
||||
/**
|
||||
* Schema is the class for retrieving metadata from a MySQL database (version 4.1.x and 5.x).
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class Schema extends \yii\db\Schema implements ConstraintFinderInterface
|
||||
{
|
||||
use ConstraintFinderTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public $columnSchemaClass = 'yii\db\mysql\ColumnSchema';
|
||||
/**
|
||||
* @var bool whether MySQL used is older than 5.1.
|
||||
*/
|
||||
private $_oldMysql;
|
||||
|
||||
|
||||
/**
|
||||
* @var array mapping from physical column types (keys) to abstract column types (values)
|
||||
*/
|
||||
public $typeMap = [
|
||||
'tinyint' => self::TYPE_TINYINT,
|
||||
'bit' => self::TYPE_INTEGER,
|
||||
'smallint' => self::TYPE_SMALLINT,
|
||||
'mediumint' => self::TYPE_INTEGER,
|
||||
'int' => self::TYPE_INTEGER,
|
||||
'integer' => self::TYPE_INTEGER,
|
||||
'bigint' => self::TYPE_BIGINT,
|
||||
'float' => self::TYPE_FLOAT,
|
||||
'double' => self::TYPE_DOUBLE,
|
||||
'real' => self::TYPE_FLOAT,
|
||||
'decimal' => self::TYPE_DECIMAL,
|
||||
'numeric' => self::TYPE_DECIMAL,
|
||||
'tinytext' => self::TYPE_TEXT,
|
||||
'mediumtext' => self::TYPE_TEXT,
|
||||
'longtext' => self::TYPE_TEXT,
|
||||
'longblob' => self::TYPE_BINARY,
|
||||
'blob' => self::TYPE_BINARY,
|
||||
'text' => self::TYPE_TEXT,
|
||||
'varchar' => self::TYPE_STRING,
|
||||
'string' => self::TYPE_STRING,
|
||||
'char' => self::TYPE_CHAR,
|
||||
'datetime' => self::TYPE_DATETIME,
|
||||
'year' => self::TYPE_DATE,
|
||||
'date' => self::TYPE_DATE,
|
||||
'time' => self::TYPE_TIME,
|
||||
'timestamp' => self::TYPE_TIMESTAMP,
|
||||
'enum' => self::TYPE_STRING,
|
||||
'varbinary' => self::TYPE_BINARY,
|
||||
'json' => self::TYPE_JSON,
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $tableQuoteCharacter = '`';
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $columnQuoteCharacter = '`';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function resolveTableName($name)
|
||||
{
|
||||
$resolvedName = new TableSchema();
|
||||
$parts = explode('.', str_replace('`', '', $name));
|
||||
if (isset($parts[1])) {
|
||||
$resolvedName->schemaName = $parts[0];
|
||||
$resolvedName->name = $parts[1];
|
||||
} else {
|
||||
$resolvedName->schemaName = $this->defaultSchema;
|
||||
$resolvedName->name = $name;
|
||||
}
|
||||
$resolvedName->fullName = ($resolvedName->schemaName !== $this->defaultSchema ? $resolvedName->schemaName . '.' : '') . $resolvedName->name;
|
||||
return $resolvedName;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function findTableNames($schema = '')
|
||||
{
|
||||
$sql = 'SHOW TABLES';
|
||||
if ($schema !== '') {
|
||||
$sql .= ' FROM ' . $this->quoteSimpleTableName($schema);
|
||||
}
|
||||
|
||||
return $this->db->createCommand($sql)->queryColumn();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function loadTableSchema($name)
|
||||
{
|
||||
$table = new TableSchema();
|
||||
$this->resolveTableNames($table, $name);
|
||||
|
||||
if ($this->findColumns($table)) {
|
||||
$this->findConstraints($table);
|
||||
return $table;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function loadTablePrimaryKey($tableName)
|
||||
{
|
||||
return $this->loadTableConstraints($tableName, 'primaryKey');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function loadTableForeignKeys($tableName)
|
||||
{
|
||||
return $this->loadTableConstraints($tableName, 'foreignKeys');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function loadTableIndexes($tableName)
|
||||
{
|
||||
static $sql = <<<'SQL'
|
||||
SELECT
|
||||
`s`.`INDEX_NAME` AS `name`,
|
||||
`s`.`COLUMN_NAME` AS `column_name`,
|
||||
`s`.`NON_UNIQUE` ^ 1 AS `index_is_unique`,
|
||||
`s`.`INDEX_NAME` = 'PRIMARY' AS `index_is_primary`
|
||||
FROM `information_schema`.`STATISTICS` AS `s`
|
||||
WHERE `s`.`TABLE_SCHEMA` = COALESCE(:schemaName, DATABASE()) AND `s`.`INDEX_SCHEMA` = `s`.`TABLE_SCHEMA` AND `s`.`TABLE_NAME` = :tableName
|
||||
ORDER BY `s`.`SEQ_IN_INDEX` ASC
|
||||
SQL;
|
||||
|
||||
$resolvedName = $this->resolveTableName($tableName);
|
||||
$indexes = $this->db->createCommand($sql, [
|
||||
':schemaName' => $resolvedName->schemaName,
|
||||
':tableName' => $resolvedName->name,
|
||||
])->queryAll();
|
||||
$indexes = $this->normalizePdoRowKeyCase($indexes, true);
|
||||
$indexes = ArrayHelper::index($indexes, null, 'name');
|
||||
$result = [];
|
||||
foreach ($indexes as $name => $index) {
|
||||
$result[] = new IndexConstraint([
|
||||
'isPrimary' => (bool) $index[0]['index_is_primary'],
|
||||
'isUnique' => (bool) $index[0]['index_is_unique'],
|
||||
'name' => $name !== 'PRIMARY' ? $name : null,
|
||||
'columnNames' => ArrayHelper::getColumn($index, 'column_name'),
|
||||
]);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function loadTableUniques($tableName)
|
||||
{
|
||||
return $this->loadTableConstraints($tableName, 'uniques');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @throws NotSupportedException if this method is called.
|
||||
*/
|
||||
protected function loadTableChecks($tableName)
|
||||
{
|
||||
throw new NotSupportedException('MySQL does not support check constraints.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @throws NotSupportedException if this method is called.
|
||||
*/
|
||||
protected function loadTableDefaultValues($tableName)
|
||||
{
|
||||
throw new NotSupportedException('MySQL does not support default value constraints.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a query builder for the MySQL database.
|
||||
* @return QueryBuilder query builder instance
|
||||
*/
|
||||
public function createQueryBuilder()
|
||||
{
|
||||
return new QueryBuilder($this->db);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the table name and schema name (if any).
|
||||
* @param TableSchema $table the table metadata object
|
||||
* @param string $name the 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->fullName = $table->schemaName . '.' . $table->name;
|
||||
} else {
|
||||
$table->fullName = $table->name = $parts[0];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the column information into a [[ColumnSchema]] object.
|
||||
* @param array $info column information
|
||||
* @return ColumnSchema the column schema object
|
||||
*/
|
||||
protected function loadColumnSchema($info)
|
||||
{
|
||||
$column = $this->createColumnSchema();
|
||||
|
||||
$column->name = $info['field'];
|
||||
$column->allowNull = $info['null'] === 'YES';
|
||||
$column->isPrimaryKey = strpos($info['key'], 'PRI') !== false;
|
||||
$column->autoIncrement = stripos($info['extra'], 'auto_increment') !== false;
|
||||
$column->comment = $info['comment'];
|
||||
|
||||
$column->dbType = $info['type'];
|
||||
$column->unsigned = stripos($column->dbType, 'unsigned') !== false;
|
||||
|
||||
$column->type = self::TYPE_STRING;
|
||||
if (preg_match('/^(\w+)(?:\(([^\)]+)\))?/', $column->dbType, $matches)) {
|
||||
$type = strtolower($matches[1]);
|
||||
if (isset($this->typeMap[$type])) {
|
||||
$column->type = $this->typeMap[$type];
|
||||
}
|
||||
if (!empty($matches[2])) {
|
||||
if ($type === 'enum') {
|
||||
preg_match_all("/'[^']*'/", $matches[2], $values);
|
||||
foreach ($values[0] as $i => $value) {
|
||||
$values[$i] = trim($value, "'");
|
||||
}
|
||||
$column->enumValues = $values;
|
||||
} else {
|
||||
$values = explode(',', $matches[2]);
|
||||
$column->size = $column->precision = (int) $values[0];
|
||||
if (isset($values[1])) {
|
||||
$column->scale = (int) $values[1];
|
||||
}
|
||||
if ($column->size === 1 && $type === 'bit') {
|
||||
$column->type = 'boolean';
|
||||
} elseif ($type === 'bit') {
|
||||
if ($column->size > 32) {
|
||||
$column->type = 'bigint';
|
||||
} elseif ($column->size === 32) {
|
||||
$column->type = 'integer';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$column->phpType = $this->getColumnPhpType($column);
|
||||
|
||||
if (!$column->isPrimaryKey) {
|
||||
if (($column->type === 'timestamp' || $column->type ==='datetime') && $info['default'] === 'CURRENT_TIMESTAMP') {
|
||||
$column->defaultValue = new Expression('CURRENT_TIMESTAMP');
|
||||
} elseif (isset($type) && $type === 'bit') {
|
||||
$column->defaultValue = bindec(trim($info['default'], 'b\''));
|
||||
} else {
|
||||
$column->defaultValue = $column->phpTypecast($info['default']);
|
||||
}
|
||||
}
|
||||
|
||||
return $column;
|
||||
}
|
||||
|
||||
/**
|
||||
* Collects the metadata of table columns.
|
||||
* @param TableSchema $table the table metadata
|
||||
* @return bool whether the table exists in the database
|
||||
* @throws \Exception if DB query fails
|
||||
*/
|
||||
protected function findColumns($table)
|
||||
{
|
||||
$sql = 'SHOW FULL COLUMNS FROM ' . $this->quoteTableName($table->fullName);
|
||||
try {
|
||||
$columns = $this->db->createCommand($sql)->queryAll();
|
||||
} catch (\Exception $e) {
|
||||
$previous = $e->getPrevious();
|
||||
if ($previous instanceof \PDOException && strpos($previous->getMessage(), 'SQLSTATE[42S02') !== false) {
|
||||
// table does not exist
|
||||
// https://dev.mysql.com/doc/refman/5.5/en/error-messages-server.html#error_er_bad_table_error
|
||||
return false;
|
||||
}
|
||||
throw $e;
|
||||
}
|
||||
foreach ($columns as $info) {
|
||||
if ($this->db->slavePdo->getAttribute(\PDO::ATTR_CASE) !== \PDO::CASE_LOWER) {
|
||||
$info = array_change_key_case($info, CASE_LOWER);
|
||||
}
|
||||
$column = $this->loadColumnSchema($info);
|
||||
$table->columns[$column->name] = $column;
|
||||
if ($column->isPrimaryKey) {
|
||||
$table->primaryKey[] = $column->name;
|
||||
if ($column->autoIncrement) {
|
||||
$table->sequenceName = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the CREATE TABLE sql string.
|
||||
* @param TableSchema $table the table metadata
|
||||
* @return string $sql the result of 'SHOW CREATE TABLE'
|
||||
*/
|
||||
protected function getCreateTableSql($table)
|
||||
{
|
||||
$row = $this->db->createCommand('SHOW CREATE TABLE ' . $this->quoteTableName($table->fullName))->queryOne();
|
||||
if (isset($row['Create Table'])) {
|
||||
$sql = $row['Create Table'];
|
||||
} else {
|
||||
$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
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function findConstraints($table)
|
||||
{
|
||||
$sql = <<<'SQL'
|
||||
SELECT
|
||||
kcu.constraint_name,
|
||||
kcu.column_name,
|
||||
kcu.referenced_table_name,
|
||||
kcu.referenced_column_name
|
||||
FROM information_schema.referential_constraints AS rc
|
||||
JOIN information_schema.key_column_usage AS kcu ON
|
||||
(
|
||||
kcu.constraint_catalog = rc.constraint_catalog OR
|
||||
(kcu.constraint_catalog IS NULL AND rc.constraint_catalog IS NULL)
|
||||
) AND
|
||||
kcu.constraint_schema = rc.constraint_schema AND
|
||||
kcu.constraint_name = rc.constraint_name
|
||||
WHERE rc.constraint_schema = database() AND kcu.table_schema = database()
|
||||
AND rc.table_name = :tableName AND kcu.table_name = :tableName1
|
||||
SQL;
|
||||
|
||||
try {
|
||||
$rows = $this->db->createCommand($sql, [':tableName' => $table->name, ':tableName1' => $table->name])->queryAll();
|
||||
$constraints = [];
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$constraints[$row['constraint_name']]['referenced_table_name'] = $row['referenced_table_name'];
|
||||
$constraints[$row['constraint_name']]['columns'][$row['column_name']] = $row['referenced_column_name'];
|
||||
}
|
||||
|
||||
$table->foreignKeys = [];
|
||||
foreach ($constraints as $name => $constraint) {
|
||||
$table->foreignKeys[$name] = array_merge(
|
||||
[$constraint['referenced_table_name']],
|
||||
$constraint['columns']
|
||||
);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$previous = $e->getPrevious();
|
||||
if (!$previous instanceof \PDOException || strpos($previous->getMessage(), 'SQLSTATE[42S02') === false) {
|
||||
throw $e;
|
||||
}
|
||||
|
||||
// table does not exist, try to determine the foreign keys using the table creation sql
|
||||
$sql = $this->getCreateTableSql($table);
|
||||
$regexp = '/FOREIGN KEY\s+\(([^\)]+)\)\s+REFERENCES\s+([^\(^\s]+)\s*\(([^\)]+)\)/mi';
|
||||
if (preg_match_all($regexp, $sql, $matches, PREG_SET_ORDER)) {
|
||||
foreach ($matches as $match) {
|
||||
$fks = array_map('trim', explode(',', str_replace('`', '', $match[1])));
|
||||
$pks = array_map('trim', explode(',', str_replace('`', '', $match[3])));
|
||||
$constraint = [str_replace('`', '', $match[2])];
|
||||
foreach ($fks as $k => $name) {
|
||||
$constraint[$name] = $pks[$k];
|
||||
}
|
||||
$table->foreignKeys[md5(serialize($constraint))] = $constraint;
|
||||
}
|
||||
$table->foreignKeys = array_values($table->foreignKeys);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all unique indexes for the given table.
|
||||
*
|
||||
* Each array element is of the following structure:
|
||||
*
|
||||
* ```php
|
||||
* [
|
||||
* '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*\((\`.+\`)+\)/mi';
|
||||
if (preg_match_all($regexp, $sql, $matches, PREG_SET_ORDER)) {
|
||||
foreach ($matches as $match) {
|
||||
$indexName = $match[1];
|
||||
$indexColumns = array_map('trim', explode('`,`', trim($match[2], '`')));
|
||||
$uniqueIndexes[$indexName] = $indexColumns;
|
||||
}
|
||||
}
|
||||
|
||||
return $uniqueIndexes;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function createColumnSchemaBuilder($type, $length = null)
|
||||
{
|
||||
return new ColumnSchemaBuilder($type, $length, $this->db);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool whether the version of the MySQL being used is older than 5.1.
|
||||
* @throws InvalidConfigException
|
||||
* @throws Exception
|
||||
* @since 2.0.13
|
||||
*/
|
||||
protected function isOldMysql()
|
||||
{
|
||||
if ($this->_oldMysql === null) {
|
||||
$version = $this->db->getSlavePdo()->getAttribute(\PDO::ATTR_SERVER_VERSION);
|
||||
$this->_oldMysql = version_compare($version, '5.1', '<=');
|
||||
}
|
||||
|
||||
return $this->_oldMysql;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads multiple types of constraints and returns the specified ones.
|
||||
* @param string $tableName table name.
|
||||
* @param string $returnType return type:
|
||||
* - primaryKey
|
||||
* - foreignKeys
|
||||
* - uniques
|
||||
* @return mixed constraints.
|
||||
*/
|
||||
private function loadTableConstraints($tableName, $returnType)
|
||||
{
|
||||
static $sql = <<<'SQL'
|
||||
SELECT
|
||||
`kcu`.`CONSTRAINT_NAME` AS `name`,
|
||||
`kcu`.`COLUMN_NAME` AS `column_name`,
|
||||
`tc`.`CONSTRAINT_TYPE` AS `type`,
|
||||
CASE
|
||||
WHEN :schemaName IS NULL AND `kcu`.`REFERENCED_TABLE_SCHEMA` = DATABASE() THEN NULL
|
||||
ELSE `kcu`.`REFERENCED_TABLE_SCHEMA`
|
||||
END AS `foreign_table_schema`,
|
||||
`kcu`.`REFERENCED_TABLE_NAME` AS `foreign_table_name`,
|
||||
`kcu`.`REFERENCED_COLUMN_NAME` AS `foreign_column_name`,
|
||||
`rc`.`UPDATE_RULE` AS `on_update`,
|
||||
`rc`.`DELETE_RULE` AS `on_delete`,
|
||||
`kcu`.`ORDINAL_POSITION` AS `position`
|
||||
FROM
|
||||
`information_schema`.`KEY_COLUMN_USAGE` AS `kcu`,
|
||||
`information_schema`.`REFERENTIAL_CONSTRAINTS` AS `rc`,
|
||||
`information_schema`.`TABLE_CONSTRAINTS` AS `tc`
|
||||
WHERE
|
||||
`kcu`.`TABLE_SCHEMA` = COALESCE(:schemaName, DATABASE()) AND `kcu`.`CONSTRAINT_SCHEMA` = `kcu`.`TABLE_SCHEMA` AND `kcu`.`TABLE_NAME` = :tableName
|
||||
AND `rc`.`CONSTRAINT_SCHEMA` = `kcu`.`TABLE_SCHEMA` AND `rc`.`TABLE_NAME` = :tableName AND `rc`.`CONSTRAINT_NAME` = `kcu`.`CONSTRAINT_NAME`
|
||||
AND `tc`.`TABLE_SCHEMA` = `kcu`.`TABLE_SCHEMA` AND `tc`.`TABLE_NAME` = :tableName AND `tc`.`CONSTRAINT_NAME` = `kcu`.`CONSTRAINT_NAME` AND `tc`.`CONSTRAINT_TYPE` = 'FOREIGN KEY'
|
||||
UNION
|
||||
SELECT
|
||||
`kcu`.`CONSTRAINT_NAME` AS `name`,
|
||||
`kcu`.`COLUMN_NAME` AS `column_name`,
|
||||
`tc`.`CONSTRAINT_TYPE` AS `type`,
|
||||
NULL AS `foreign_table_schema`,
|
||||
NULL AS `foreign_table_name`,
|
||||
NULL AS `foreign_column_name`,
|
||||
NULL AS `on_update`,
|
||||
NULL AS `on_delete`,
|
||||
`kcu`.`ORDINAL_POSITION` AS `position`
|
||||
FROM
|
||||
`information_schema`.`KEY_COLUMN_USAGE` AS `kcu`,
|
||||
`information_schema`.`TABLE_CONSTRAINTS` AS `tc`
|
||||
WHERE
|
||||
`kcu`.`TABLE_SCHEMA` = COALESCE(:schemaName, DATABASE()) AND `kcu`.`TABLE_NAME` = :tableName
|
||||
AND `tc`.`TABLE_SCHEMA` = `kcu`.`TABLE_SCHEMA` AND `tc`.`TABLE_NAME` = :tableName AND `tc`.`CONSTRAINT_NAME` = `kcu`.`CONSTRAINT_NAME` AND `tc`.`CONSTRAINT_TYPE` IN ('PRIMARY KEY', 'UNIQUE')
|
||||
ORDER BY `position` ASC
|
||||
SQL;
|
||||
|
||||
$resolvedName = $this->resolveTableName($tableName);
|
||||
$constraints = $this->db->createCommand($sql, [
|
||||
':schemaName' => $resolvedName->schemaName,
|
||||
':tableName' => $resolvedName->name,
|
||||
])->queryAll();
|
||||
$constraints = $this->normalizePdoRowKeyCase($constraints, true);
|
||||
$constraints = ArrayHelper::index($constraints, null, ['type', 'name']);
|
||||
$result = [
|
||||
'primaryKey' => null,
|
||||
'foreignKeys' => [],
|
||||
'uniques' => [],
|
||||
];
|
||||
foreach ($constraints as $type => $names) {
|
||||
foreach ($names as $name => $constraint) {
|
||||
switch ($type) {
|
||||
case 'PRIMARY KEY':
|
||||
$result['primaryKey'] = new Constraint([
|
||||
'columnNames' => ArrayHelper::getColumn($constraint, 'column_name'),
|
||||
]);
|
||||
break;
|
||||
case 'FOREIGN KEY':
|
||||
$result['foreignKeys'][] = new ForeignKeyConstraint([
|
||||
'name' => $name,
|
||||
'columnNames' => ArrayHelper::getColumn($constraint, 'column_name'),
|
||||
'foreignSchemaName' => $constraint[0]['foreign_table_schema'],
|
||||
'foreignTableName' => $constraint[0]['foreign_table_name'],
|
||||
'foreignColumnNames' => ArrayHelper::getColumn($constraint, 'foreign_column_name'),
|
||||
'onDelete' => $constraint[0]['on_delete'],
|
||||
'onUpdate' => $constraint[0]['on_update'],
|
||||
]);
|
||||
break;
|
||||
case 'UNIQUE':
|
||||
$result['uniques'][] = new Constraint([
|
||||
'name' => $name,
|
||||
'columnNames' => ArrayHelper::getColumn($constraint, 'column_name'),
|
||||
]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($result as $type => $data) {
|
||||
$this->setTableMetadata($tableName, $type, $data);
|
||||
}
|
||||
|
||||
return $result[$returnType];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user