Skip to content

Instantly share code, notes, and snippets.

@radzserg
Created July 3, 2013 06:13
Show Gist options
  • Save radzserg/5915803 to your computer and use it in GitHub Desktop.
Save radzserg/5915803 to your computer and use it in GitHub Desktop.
yii migration with cahnge command
<?php
namespace yii\db;
class Migration extends \yii\db\MigrationBase
{
const DIRECTION_UP = 'up';
const DIRECTION_DOWN = 'down';
/**
* Specify direction for change function
* @var up|down
*/
private $_change;
/**
* Queue of change actions
* @var type
*/
private $_changeDownQueue = array();
/**
* This method contains the logic to be executed when applying this migration.
* Child classes may overwrite this method to provide actual migration logic.
* @return boolean return a false value to indicate the migration fails
* and should not proceed further. All other return values mean the migration succeeds.
*/
public function up()
{
$transaction = $this->db->beginTransaction();
try {
if (method_exists($this, 'change')) {
$this->_change = self::DIRECTION_UP;
$this->change();
} else {
if ($this->safeUp() === false) {
$transaction->rollback();
return false;
}
}
$transaction->commit();
} catch (\Exception $e) {
echo "Exception: " . $e->getMessage() . ' (' . $e->getFile() . ':' . $e->getLine() . ")\n";
echo $e->getTraceAsString() . "\n";
$transaction->rollback();
return false;
}
return null;
}
/**
* This method contains the logic to be executed when removing this migration.
* The default implementation throws an exception indicating the migration cannot be removed.
* Child classes may override this method if the corresponding migrations can be removed.
* @return boolean return a false value to indicate the migration fails
* and should not proceed further. All other return values mean the migration succeeds.
*/
public function down()
{
$transaction = $this->db->beginTransaction();
try {
if (method_exists($this, 'change')) {
$this->_change = self::DIRECTION_DOWN;
$this->change();
$this->_afterChangeDown();
} else {
if ($this->safeDown() === false) {
$transaction->rollback();
return false;
}
}
$transaction->commit();
} catch (\Exception $e) {
echo "Exception: " . $e->getMessage() . ' (' . $e->getFile() . ':' . $e->getLine() . ")\n";
echo $e->getTraceAsString() . "\n";
$transaction->rollback();
return false;
}
return null;
}
/**
* Call function in reverse order
*/
private function _afterChangeDown()
{
foreach (array_reverse($this->_changeDownQueue) as $function) {
/* @var $function \Closure */
$function();
}
}
public function execute($sql, $params = array())
{
if ($this->_change) {
$this->_notSupportedInChange(__FUNCTION__);
}
return parent::execute($sql, $params);
}
public function insert($table, $columns)
{
if ($this->_change) {
$this->_notSupportedInChange(__FUNCTION__);
}
return parent::insert($table, $columns);
}
public function update($table, $columns, $condition = '', $params = array())
{
if ($this->_change) {
$this->_notSupportedInChange(__FUNCTION__);
}
return parent::update($table, $columns, $condition, $params);
}
public function delete($table, $condition = '', $params = array())
{
if ($this->_change) {
$this->_notSupportedInChange(__FUNCTION__);
}
return parent::delete($table, $condition, $params);
}
public function createTable($table, $columns, $options = null)
{
if (!$this->_change || $this->_change == self::DIRECTION_UP) {
parent::createTable($table, $columns, $options);
} else {
$this->_changeDownQueue[] = function() use($table) {
return parent::dropTable($table);
};
}
}
public function renameTable($table, $newName)
{
if (!$this->_change || $this->_change == self::DIRECTION_UP) {
return parent::renameTable($table, $newName);
} else {
$this->_changeDownQueue[] = function() use($newName, $table) {
return parent::renameTable($newName, $table);
};
}
}
public function dropTable($table)
{
if ($this->_change) {
$this->_notSupportedInChange(__FUNCTION__);
}
return parent::dropTable($table);
}
public function truncateTable($table)
{
if ($this->_change) {
$this->_notSupportedInChange(__FUNCTION__);
}
return parent::truncateTable($table);
}
public function addColumn($table, $column, $type)
{
if (!$this->_change || $this->_change == self::DIRECTION_UP) {
return parent::addColumn($table, $column, $type);
} else {
$this->_changeDownQueue[] = function() use($table, $column) {
return parent::dropColumn($table, $column);
};
}
}
public function dropColumn($table, $column)
{
if ($this->_change) {
$this->_notSupportedInChange(__FUNCTION__);
}
return parent::dropColumn($table, $column);
}
public function renameColumn($table, $name, $newName)
{
if (!$this->_change || $this->_change == self::DIRECTION_UP) {
return parent::renameColumn($table, $name, $newName);
} else {
$this->_changeDownQueue[] = function() use($table, $newName, $name) {
return parent::renameColumn($table, $newName, $name);
};
}
}
public function alterColumn($table, $column, $type)
{
if ($this->_change) {
$this->_notSupportedInChange(__FUNCTION__);
}
return parent::alterColumn($table, $column, $type);
}
public function addPrimaryKey($name, $table, $columns)
{
if (!$this->_change || $this->_change == self::DIRECTION_UP) {
return parent::addPrimaryKey($name, $table, $columns);
} else {
$this->_changeDownQueue[] = function() use($name, $table) {
return parent::dropPrimaryKey($name, $table);
};
}
}
public function dropPrimaryKey($name, $table)
{
if ($this->_change) {
$this->_notSupportedInChange(__FUNCTION__);
}
return parent::dropPrimaryKey($name, $table);
}
public function addForeignKey($name, $table, $columns, $refTable, $refColumns, $delete = null, $update = null)
{
if (!$this->_change || $this->_change == self::DIRECTION_UP) {
return parent::addForeignKey($name, $table, $columns, $refTable, $refColumns, $delete, $update);
} else {
$this->_changeDownQueue[] = function() use($name, $table) {
return parent::dropForeignKey($name, $table);
};
}
}
public function dropForeignKey($name, $table)
{
if ($this->_change) {
$this->_notSupportedInChange(__FUNCTION__);
}
return parent::dropPrimaryKey($name, $table);
}
public function createIndex($name, $table, $column, $unique = false)
{
if (!$this->_change || $this->_change == self::DIRECTION_UP) {
return parent::createIndex($name, $table, $column, $unique);
} else {
$this->_changeDownQueue[] = function() use($name, $table) {
return parent::dropIndex($name, $table);
};
}
}
public function dropIndex($name, $table)
{
if ($this->_change) {
$this->_notSupportedInChange(__FUNCTION__);
}
return parent::dropIndex($name, $table);
}
private function _notSupportedInChange($name)
{
throw new \Exception("Method {$name} is not supported in change migration");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment