Skip to content

Commit

Permalink
Merge pull request #273 from pmoraes/issue/272
Browse files Browse the repository at this point in the history
"jump-to" feature
  • Loading branch information
steinkel authored Aug 3, 2016
2 parents 6ea20e6 + 1cb39bc commit 26347a6
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 22 deletions.
9 changes: 6 additions & 3 deletions Console/Command/MigrationShell.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ public function startup() {
'precheck' => $this->params['precheck'],
'autoinit' => !$this->params['no-auto-init'],
'dry' => $this->params['dry'],
'skip' => isset($this->params['skip']) ? $this->params['skip'] : null);
'skip' => isset($this->params['skip']) ? $this->params['skip'] : null,
'jumpTo' => isset($this->params['jump-to']) ? $this->params['jump-to'] : null);

if (!empty($this->connection)) {
$options['connection'] = $this->connection;
Expand Down Expand Up @@ -179,7 +180,10 @@ public function getOptionParser() {
'boolean' => true,
'help' => __d('migrations', 'Force \'generate\' to compare all tables.')))
->addOption('skip', array(
'help' => __('Skip to a certain migration.')))
'help' => __('Skip certain migration.')))
->addOption('jump-to', array(
'short' => 'j',
'help' => __('Jump to a certain migration and mark the preceding migrations as executed.')))
->addOption('compare', array(
'short' => 'm',
'boolean' => true,
Expand Down Expand Up @@ -453,7 +457,6 @@ public function generate() {
$response = $this->in(__d('migrations', 'Do you want to compare the schema.php file to the database?'), array('y', 'n'), 'y');
}

$response = $this->in(__d('migrations', 'Do you want to compare the schema.php file to the database?'), array('y', 'n'), 'y');
if (strtolower($response) === 'y') {
$this->_generateFromComparison($migration, $oldSchema, $comparison);
$this->_migrationChanges($migration);
Expand Down
13 changes: 12 additions & 1 deletion Docs/Documentation/Examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,4 +94,15 @@ You can skip many migrations using comma to separate, for example.
cake Migrations.migration run all --skip 1458963215_articles_table,1457412585_users_table
```

Remember this migrations will be set as executed.
Remember this migrations will be set as executed.

Jumping to certain migrations
--------------------------------------------------

If you want to jump to a certain migration, you can use ```--jump-to``` or ```-j``` + migration name as in the example below.

```
cake Migrations.migration run all -j 1458963215_articles_table
```

Remember all migrations before this will be set as executed.
58 changes: 52 additions & 6 deletions Lib/MigrationVersion.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@ class MigrationVersion {
*/
public $skip = array();

/**
* Jump to a certain migration.
*
* @var null|string
*/
public $jumpTo = null;

/**
* Log of SQL queries generated
*
Expand Down Expand Up @@ -106,6 +113,10 @@ public function __construct($options = array()) {
$this->skip = $options['skip'];
}

if (!empty($options['jumpTo'])) {
$this->jumpTo = $options['jumpTo'];
}

if (!isset($options['dry'])) {
$options['dry'] = false;
}
Expand Down Expand Up @@ -174,7 +185,6 @@ public function setVersion($version, $type, $migrated = true) {
$bc = ($this->Version->schema('class') === null);
$field = $bc ? 'version' : 'class';
$value = $bc ? $version : $mapping[$version]['class'];

if ($migrated) {
$this->Version->create();
$result = $this->Version->save(array(
Expand Down Expand Up @@ -309,6 +319,7 @@ public function getMigration($name, $class, $type, $options = array()) {
public function run($options) {
$targetVersion = $latestVersion = $this->getVersion($options['type']);
$mapping = $this->getMapping($options['type'], false);

$direction = 'up';
if (!empty($options['direction'])) {
$direction = $options['direction'];
Expand Down Expand Up @@ -337,19 +348,27 @@ public function run($options) {
krsort($mapping);
}


foreach ($mapping as $version => $info) {
if (($direction === 'up' && $version > $targetVersion)
|| ($direction === 'down' && $version < $targetVersion)) {
break;
} elseif (($direction === 'up' && $info['migrated'] === null)
} elseif (($direction === 'up' && $info['migrated'] === null)
|| ($direction === 'down' && $info['migrated'] !== null)) {
$type = $info['type'];

$jumpVersion = $this->getVersionByName($mapping);
if ($version < $jumpVersion) {
$this->jump($version, $type);
continue;
}

if (in_array($mapping[$version]['name'], $this->skip)) {
$this->setVersion($version, $info['type']);
$this->setVersion($version, $type);
continue;
}

$migration = $this->getMigration($info['name'], $info['class'], $info['type'], $options);
$migration = $this->getMigration($info['name'], $info['class'], $type, $options);
$migration->Version = $this;
$migration->info = $info;

Expand All @@ -371,7 +390,7 @@ public function run($options) {
return $errorMessage;
}

$this->setVersion($version, $info['type'], ($direction === 'up'));
$this->setVersion($version, $type, ($direction === 'up'));
}
}

Expand All @@ -381,6 +400,34 @@ public function run($options) {
return true;
}

/**
* Jump to a certain migration and mark the preceding migrations as executed.
*
* @param array $version Version of a migration to jump to.
* @param array $type migration type
* @return void
*/
public function jump($version, $type) {
$this->setVersion($version, $type);
}

/**
* Will return a version based in the migration name
*
* @param array $mapping mapping of all migrations.
* @return bool|string
*/
public function getVersionByName($mapping) {
$version = false;
foreach ($mapping as $key => $info) {
if ($mapping[$key]['name'] == $this->jumpTo) {
$version = $key;
}
}

return $version;
}

/**
* Initialize the migrations schema and keep it up-to-date
*
Expand Down Expand Up @@ -504,7 +551,6 @@ protected function _enumerateOldMigrations($type) {
}
return $mapping;
}

}

/**
Expand Down
17 changes: 11 additions & 6 deletions Test/Case/Console/Command/MigrationShellTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,9 @@ public function testRun() {
'direction' => 'up',
'version' => 1,
'dry' => false,
'precheck' => null)));
'precheck' => null,
'skip' => array()))
);
$this->Shell->args = array('up');
$this->assertTrue($this->Shell->run());

Expand All @@ -227,7 +229,9 @@ public function testRun() {
'direction' => 'down',
'version' => 1,
'dry' => false,
'precheck' => null)));
'precheck' => null,
'skip' => array()))
);
$this->Shell->args = array('down');
$this->assertTrue($this->Shell->run());

Expand All @@ -239,7 +243,8 @@ public function testRun() {
'version' => 10,
'direction' => 'up',
'dry' => false,
'precheck' => null)));
'precheck' => null,
'skip' => array())));
$this->Shell->args = array('all');
$this->assertTrue($this->Shell->run());

Expand All @@ -251,7 +256,8 @@ public function testRun() {
'version' => 0,
'direction' => 'down',
'dry' => false,
'precheck' => null)));
'precheck' => null,
'skip' => array())));
$this->Shell->args = array('reset');
$this->assertTrue($this->Shell->run());

Expand Down Expand Up @@ -1081,5 +1087,4 @@ protected function _unlink($files) {
}
}

}

}
79 changes: 73 additions & 6 deletions Test/Case/Lib/MigrationVersionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,11 @@ public function testGetMapping() {
'migrated' => '2011-11-18 13:53:32'
),
3 => array(
'version' => 3,
'name' => '003_increase_class_name_length',
'class' => 'IncreaseClassNameLength',
'type' => 'Migrations',
'migrated' => null
'version' => 3,
'name' => '003_increase_class_name_length',
'class' => 'IncreaseClassNameLength',
'type' => 'Migrations',
'migrated' => null
)
);
$this->assertEquals($result, $expected);
Expand Down Expand Up @@ -308,6 +308,71 @@ public function testRun() {
$this->assertTrue($Version->run(array('version' => 0, 'type' => 'mocks')));
}

/**
* TestRunWithJump method
*
* @return void
*/
public function testRunWithJump() {
$options = array(
'connection' => 'test',
'autoinit' => false,
'jumpTo' => '003_schema_dump'
);

$Version = $this->getMock('MigrationVersion',
array('getMapping', 'getMigration', 'getVersion', 'jump'),
array($options),
'TestMigrationVersionMockMigrationVersions'
);

$CakeMigration = new CakeMigration($options);

$Version->expects($this->any())
->method('getMigration')
->will($this->returnValue($CakeMigration));

$Version->Version = ClassRegistry::init(array(
'class' => 'schema_migrations',
'ds' => 'test'
));

$Version->expects($this->at(0))->method('getVersion')->will($this->returnValue(9));
$Version->expects($this->exactly(2))->method('jump');
$Version->expects($this->any())->method('getMapping')->will($this->returnValue($this->_mapping()));

$this->assertTrue($Version->run(array('direction' => 'up', 'type' => 'mocks')));

$migrations = $Version->Version->find('count', array(
'conditions' => array(
'type' => 'mocks'
)
));

$this->assertEquals(8, $migrations);
}

/**
* TestGetVersionByName method
*
* @return void
*/
public function testGetVersionByName() {
$Version = new MigrationVersion(array(
'jumpTo' => '007_schema_dump'
));

$result = $Version->getVersionByName($this->_mapping());
$this->assertEquals(7, $result);

$Version = new MigrationVersion(array(
'jumpTo' => '00_schema_dump'
));

$result = $Version->getVersionByName($this->_mapping());
$this->assertFalse($result);
}

/**
* _mapping method
*
Expand All @@ -319,14 +384,16 @@ protected function _mapping($start = 0, $end = 0) {
$mapping = array();
for ($i = 1; $i <= 10; $i++) {
$mapping[$i] = array(
'version' => $i, 'name' => '001_schema_dump',
'version' => $i,
'name' => "00{$i}_schema_dump",
'class' => 'M4af9d151e1484b74ad9d007058157726',
'type' => 'mocks', 'migrated' => null
);
if ($i >= $start && $i <= $end) {
$mapping[$i]['migrated'] = CakeTime::nice();
}
}

return $mapping;
}
}

0 comments on commit 26347a6

Please sign in to comment.