Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
To get the current state of a database into a migration for Yii 2
<?php
namespace app\commands;
use yii;
class MigrationReverserController extends \yii\console\Controller
{
public function actionRun($schema = null)
{
if (null == $schema) {
echo "Please provide a schema as the only argument.\n";
return 1;
}
$schema = Yii::$app->db->schema;
$tables = $schema->getTableNames();
$addForeignKeys = '';
$dropForeignKeys = '';
$result = "public function up()\n{\n";
foreach ($tables as $table) {
$compositePrimaryKeyCols = array();
// Create table
$result .= ' $this->createTable(\'' . $table . '\', array(' . "\n";
foreach ($schema->getTableSchema($table)->columns as $col) {
$result .= ' \'' . $col->name . '\'=>\'' . $this->getColType($col) . '\',' . "\n";
if ($col->isPrimaryKey && !$col->autoIncrement) {
// Add column to composite primary key array
$compositePrimaryKeyCols[] = $col->name;
}
}
$result .= ' ), \'\');' . "\n\n";
// Add foreign key(s) and create indexes
foreach ($schema->getTableSchema($table)->foreignKeys as $fkName => $relation) {
// Foreign key naming convention: fk_table_foreignTable_col (max 64 characters)
$fkName = substr($fkName, 0 , 64);
$refTable = $relation[0];
$refTableColumn = array_keys($relation)[1];
$col = $relation[$refTableColumn];
$addForeignKeys .= ' $this->addForeignKey(' . "'$fkName', '$table', '$col', '$refTable', '$refTableColumn', 'NO ACTION', 'NO ACTION');\n\n";
$dropForeignKeys .= ' $this->dropForeignKey(' . "'$fkName', '$table');\n\n";
// Index naming convention: idx_col
$result .= ' $this->createIndex(\'idx_' . $col . "', '$table', '$col', FALSE);\n\n";
}
// Add composite primary key for join tables
if ($compositePrimaryKeyCols) {
$result .= ' $this->addPrimaryKey(\'pk_' . $table . "', '$table', '" . implode(',', $compositePrimaryKeyCols) . "');\n\n";
}
}
// After all the tables have been created ...
$result .= $addForeignKeys;
$result .= "}\n\n\n";
// down function
$result .= "public function down()\n{\n";
$result .= $dropForeignKeys; // This needs to come before the tables are dropped.
foreach ($tables as $table) {
$result .= ' $this->dropTable(\'' . $table . '\');' . "\n";
}
$result .= "}\n";
echo $result;
}
public function getColType($col) {
if ($col->isPrimaryKey && $col->autoIncrement) {
return "pk";
}
$result = $col->dbType;
if (!$col->allowNull) {
$result .= ' NOT NULL';
}
if ($col->defaultValue != null) {
$result .= " DEFAULT '{$col->defaultValue}'";
} elseif ($col->allowNull) {
$result .= ' DEFAULT NULL';
}
return $result;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.