1
0
Fork 0
mirror of https://github.com/Oreolek/kohana-migrations.git synced 2024-06-26 03:40:54 +03:00

Adding tests for/fixing fetch_required_migrations() / resolve_target()

This commit is contained in:
Matt Button 2011-02-17 23:53:15 +00:00
parent 63ad3348f2
commit 42001496eb
2 changed files with 225 additions and 39 deletions

View file

@ -286,11 +286,22 @@ class Model_Minion_Migration extends Model
public function fetch_required_migrations($group = NULL, $target = TRUE)
{
$migrations = array();
$current_groups = $this->fetch_groups(TRUE);
foreach ( (array) $group as $group_name)
{
if ( ! isset($current_groups[$group_name]))
{
throw new Kohana_Exception("Migration group :group does not exist", array(':group' => $group_name));
}
}
$query = $this->_select();
if (is_bool($target))
{
$up = $target;
// If we want to limit this migration to certain groups
if ($group !== NULL)
{
@ -303,9 +314,25 @@ class Model_Minion_Migration extends Model
$query->where('group', '=', $group);
}
}
}
else
{
list($target, $up) = $this->resolve_target($group, $target);
$query->where('group', '=', $group);
if ($up)
{
$query->where('timestamp', '<=', $target);
}
else
{
$query->where('timestamp', '>', $target);
}
}
// If we're migrating up
if ($target === TRUE)
if ($up)
{
$query
->where('applied', '=', 0)
@ -318,28 +345,111 @@ class Model_Minion_Migration extends Model
->where('applied', '>', 0)
->order_by('timestamp', 'DESC');
}
}
else
{
list($target, $up) = $this->resolve_target($group, $target);
$query->where('group', '=', $group);
if ($up)
{
$query
->where('timestamp', '<=', $target)
->where('applied', '=', 0)
->order_by('timestamp', 'ASC');
}
else
{
$query
->where('timestamp', '>', $target)
->order_by('timestamp', 'DESC');
}
}
return $query->execute($this->_db)->as_array();
}
/**
* Resolve a (potentially relative) target for a group to a definite timestamp
*
* @param string Group name
* @param string|int Target
* @return array First element timestamp, second is boolean (TRUE if up, FALSE if down)
*/
public function resolve_target($group, $target)
{
if (empty($group))
{
throw new Kohana_Exception("No group specified");
}
if (is_array($group))
{
if (count($group) > 1)
{
throw new Kohana_Exception("A target can only be expressed for a single group");
}
$group = $group[0];
}
$amount = NULL;
$query = $this->_select();
$statuses = $this->fetch_current_versions();
$target = (string) $target;
$group_applied = isset($statuses[$group]);
$up = NULL;
$timestamp = $group_applied ? $statuses[$group]['timestamp'] : NULL;
// If this target is relative to the current state of the group
if ($target[0] === '+' OR $target[0] === '-')
{
$amount = substr($target, 1);
$up = $target[0] === '+';
if ($up)
{
if ($group_applied)
{
$query->where('timestamp', '>', $timestamp);
}
}
else
{
if ( ! $group_applied)
{
throw new Kohana_Exception(
"Cannot migrate group :group down as none of its migrations have been applied",
array(':group' => $group)
);
}
$query->where('timestamp', '<=', $timestamp);
}
$query->limit($amount);
}
// Else this is an absolute target
else
{
if ($group_applied)
{
$up = ( (int) $timestamp < (int) $target);
$query->where('timestamp', ($up ? '>' : '<='), $timestamp);
}
else
{
$up = TRUE;
}
if ($up)
{
$query->where('timestamp', '<=', $target);
}
else
{
$query->where('timestamp', '>', $target);
}
}
if ( ! $up)
{
$query->where('applied', '>', 0);
}
$query->where('group', '=', $group);
$query->order_by('timestamp', ($up ? 'ASC' : 'DESC'));
$results = $query->execute($this->_db);
if ($amount !== NULL AND count($results) != $amount)
{
return array(NULL, $up);
}
return array((float) $query->execute($this->_db)->get('timestamp'), $up);
}
}

View file

@ -201,7 +201,27 @@ class Minion_Migration_ModelTest extends Kohana_Unittest_Database_TestCase
),
NULL,
FALSE
)
),
array(
array(
array(
'timestamp' => '20101216080000',
'description' => 'remove-password-salt-column',
'group' => 'app',
'applied' => '1',
'id' => 'app:20101216080000',
),
array(
'timestamp' => '20101215164400',
'description' => 'create-tables',
'group' => 'app',
'applied' => '1',
'id' => 'app:20101215164400',
),
),
'app',
20101216080000
),
);
}
@ -355,4 +375,60 @@ class Minion_Migration_ModelTest extends Kohana_Unittest_Database_TestCase
$model->get_migration($migration['group'], $migration['timestamp'])
);
}
/**
* Provides test data for test_resolve_target()
*
* @return array
*/
public function provider_resolve_target()
{
return array(
array(
array(20101216080000, FALSE),
'app',
'-1'
),
array(
array(NULL, FALSE),
'dblogger',
'-10'
),
array(
array(20101226112100, TRUE),
'dblogger',
'+1',
),
array(
array(NULL, TRUE),
'app',
'+10'
),
array(
array(NULL, TRUE),
'dblogger',
'+100'
),
);
}
/**
* Test that we can resolve a target version for a group.
*
* Target version can be relative (+migrations_up / -migrations_down) or absolute (i.e. timestamp)
*
* @test
* @dataProvider provider_resolve_target
* @covers Model_Minion_Migration::resolve_target
* @param array Expected output
* @param string Group name
* @param string Target version
*/
public function test_resolve_target($expected, $group, $target)
{
$this->assertSame(
$expected,
$this->getModel()->resolve_target($group, $target)
);
}
}