282 lines
7.3 KiB
PHP
Executable File
282 lines
7.3 KiB
PHP
Executable File
<?php
|
|
|
|
namespace common\components\Migration;
|
|
|
|
use Yii;
|
|
use yii\db\MigrationInterface;
|
|
use yii\db\TableSchema;
|
|
use yii\helpers\Console;
|
|
|
|
class SafeMigration extends MigrationWithDefaultOptions implements MigrationInterface
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
public function createTable($table, $columns, $options = null)
|
|
{
|
|
if ($this->db->getTableSchema($table, true) !== null) {
|
|
SafeMigration::renderSuccess(
|
|
Yii::t('console', "Таблица «{TABLE}» уже существует"),
|
|
['TABLE' => SafeMigration::normalizeFormattedName($table)]
|
|
);
|
|
|
|
return;
|
|
}
|
|
|
|
parent::createTable($table, $columns, $options);
|
|
}
|
|
|
|
|
|
|
|
|
|
public function dropTable($table)
|
|
{
|
|
if ($this->getTableSchema($table) !== null) {
|
|
parent::dropTable($table);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function addColumn($table, $column, $type)
|
|
{
|
|
if (($tableSchema = $this->getTableSchema($table)) === null) {
|
|
return;
|
|
}
|
|
$column = SafeMigration::normalizeFormattedName($column);
|
|
$columns = array_keys($tableSchema->columns);
|
|
if (in_array($column, $columns)) {
|
|
SafeMigration::renderSuccess(
|
|
Yii::t('console', "Колонка - «{COLUMN}» уже существует в таблице - «{TABLE}»"),
|
|
[
|
|
'COLUMN' => $column,
|
|
'TABLE' => SafeMigration::normalizeFormattedName($table),
|
|
]
|
|
);
|
|
return;
|
|
}
|
|
|
|
parent::addColumn($table, $column, $type);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public function dropColumn($table, $column)
|
|
{
|
|
if (($tableSchema = $this->getTableSchema($table)) === null) {
|
|
return;
|
|
}
|
|
$column = SafeMigration::normalizeFormattedName($column);
|
|
$columns = array_keys($tableSchema->columns);
|
|
if (!in_array($column, $columns)) {
|
|
SafeMigration::renderWarning(
|
|
Yii::t('console', "Колонка - «{COLUMN}» не найдена в таблице - «{TABLE}»"),
|
|
[
|
|
'COLUMN' => $column,
|
|
'TABLE' => SafeMigration::normalizeFormattedName($table),
|
|
]
|
|
);
|
|
return;
|
|
}
|
|
|
|
parent::dropColumn($table, $column);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function createIndex($name, $table, $columns, $unique = false)
|
|
{
|
|
if ($this->getTableSchema($table) === null) {
|
|
return;
|
|
}
|
|
if ($this->checkIfIndexExist($name, $table)) {
|
|
SafeMigration::renderSuccess(
|
|
Yii::t('console', "Индекс - «{IDX}» уже существует в таблице «{TABLE}»"),
|
|
[
|
|
'IDX' => SafeMigration::normalizeFormattedName($name),
|
|
'TABLE' => SafeMigration::normalizeFormattedName($table),
|
|
]
|
|
);
|
|
|
|
return;
|
|
}
|
|
|
|
parent::createIndex($name, $table, $columns, $unique);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public function dropIndex($name, $table)
|
|
{
|
|
if ($this->getTableSchema($table) === null) {
|
|
return;
|
|
}
|
|
if (!$this->checkIfIndexExist($name, $table)) {
|
|
SafeMigration::renderWarning(
|
|
Yii::t('console', "Индекс - «{IDX}» не существует в таблице «{TABLE}»"),
|
|
[
|
|
'IDX' => SafeMigration::normalizeFormattedName($name),
|
|
'TABLE' => SafeMigration::normalizeFormattedName($table),
|
|
]
|
|
);
|
|
|
|
return;
|
|
}
|
|
|
|
parent::dropIndex($name, $table);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function renameColumn($table, $name, $newName)
|
|
{
|
|
if (($tableSchema = $this->getTableSchema($table)) === null) {
|
|
return;
|
|
}
|
|
|
|
$hasTrouble = false;
|
|
$normalName = SafeMigration::normalizeFormattedName($name);
|
|
$normalNewName = SafeMigration::normalizeFormattedName($newName);
|
|
$columns = array_keys($tableSchema->columns);
|
|
if (!in_array($normalName, $columns)) {
|
|
SafeMigration::renderWarning(
|
|
Yii::t('console', "Старое наименование колонки - «{OLD_COLUMN}» не найдено в таблице - «{TABLE}»"),
|
|
[
|
|
'OLD_COLUMN' => $normalName,
|
|
'TABLE' => SafeMigration::normalizeFormattedName($table),
|
|
]
|
|
);
|
|
|
|
$hasTrouble = true;
|
|
}
|
|
|
|
if (in_array($normalNewName, $columns)) {
|
|
SafeMigration::renderSuccess(
|
|
Yii::t('console', "Новое наименование колонки - «{NEW_COLUMN}» уже существует в таблице - «{TABLE}»"),
|
|
[
|
|
'NEW_COLUMN' => $normalNewName,
|
|
'TABLE' => SafeMigration::normalizeFormattedName($table),
|
|
]
|
|
);
|
|
|
|
$hasTrouble = true;
|
|
}
|
|
|
|
if (!$hasTrouble) {
|
|
parent::renameColumn($table, $name, $newName);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function getTableSchema(string $table): ?TableSchema
|
|
{
|
|
$tableSchema = $this->db->getTableSchema($table, true);
|
|
if ($tableSchema === null) {
|
|
SafeMigration::renderWarning(
|
|
Yii::t('console', "Таблица «{TABLE}» не существует"),
|
|
['TABLE' => SafeMigration::normalizeFormattedName($table)]
|
|
);
|
|
}
|
|
|
|
return $tableSchema;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static function renderWarning(string $messageTemplate, array $params)
|
|
{
|
|
SafeMigration::renderMessage(
|
|
Yii::t(
|
|
'console',
|
|
$messageTemplate,
|
|
$params
|
|
),
|
|
Console::FG_YELLOW
|
|
);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static function renderSuccess(string $messageTemplate, array $params)
|
|
{
|
|
SafeMigration::renderMessage(
|
|
Yii::t(
|
|
'console',
|
|
$messageTemplate,
|
|
$params
|
|
),
|
|
Console::FG_GREEN
|
|
);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static function renderMessage(string $message, int $type)
|
|
{
|
|
$message = Console::ansiFormat($message, [$type]);
|
|
echo $message . PHP_EOL;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private function checkIfIndexExist(string $name, string $table): bool
|
|
{
|
|
$connection = $this->db;
|
|
$normalName = SafeMigration::normalizeFormattedName($name);
|
|
$normalTable = SafeMigration::normalizeFormattedName($table);
|
|
if ($connection->driverName === 'pgsql') {
|
|
return (bool) $connection->createCommand("
|
|
SELECT
|
|
COUNT(*)
|
|
FROM
|
|
pg_stat_user_indexes
|
|
WHERE
|
|
schemaname = current_schema()
|
|
AND indexrelname = '$normalName'
|
|
AND relname = '$normalTable'
|
|
")->queryScalar();
|
|
}
|
|
|
|
return (bool) $connection->createCommand("
|
|
SELECT
|
|
COUNT(*)
|
|
FROM
|
|
INFORMATION_SCHEMA.STATISTICS
|
|
WHERE
|
|
table_schema = DATABASE()
|
|
AND index_name = '$normalName'
|
|
AND table_name = '$normalTable'
|
|
")->queryScalar();
|
|
}
|
|
}
|