diff --git a/code/Migration.php b/code/Migration.php index 6e47e93..1a0b8e9 100644 --- a/code/Migration.php +++ b/code/Migration.php @@ -79,6 +79,28 @@ public static function getTableColumns($table) { return DB::fieldList($table); } + /** + * Allows to you fetch the specific table (and thus DataObject) that a particular field exists on, since they're + * merged at runtime. This will actually iterate through the class ancestry in order to determine the table in which + * a field actually exists. + * + * @param string $className + * @param string $field + * @return string + */ + public static function getTableForField($className, $field) { + // Let's get our hands dirty on this ancestry filth and reference the database because the private static ::$db isn't reliable (seriously). + $ancestors = ClassInfo::ancestry($className, true); + foreach($ancestors as $ancestor) { + if (DataObject::has_own_table($ancestor)) { + if (DB::get_schema()->hasField($ancestor, $field)) return $ancestor; + } + } + + // Still not found. + return ''; + } + /** * Drops columns from a database table. * Returns array of columns that were dropped @@ -98,7 +120,7 @@ public static function dropColumnsFromTable($table, array $columns) { } return $droppedColumns; } - + /** * Add columns to a database table if they don't exist. * Returns array of columns that were added @@ -123,7 +145,7 @@ public static function addColumnsToTable($table, array $columns) { } return $addedColumns; } - + /** * Gets the value for a single column in a row from the database by the ID column. * Useful when a field has been removed from the class' `$db` property, @@ -181,7 +203,7 @@ public static function getRowValuesFromTable($table, array $fields, $id) { } return $values; } - + /** * Sets the values for multiple rows on a database table by the ID column. * Useful when fields have been removed from the class' `$db` property, @@ -230,7 +252,7 @@ public static function setRowValuesOnTable($table, array $values, $id = null, $i // Nothing was done. return false; } - + /** * Simplifies publishing of an actual page instance (since migrations are run from command line). * diff --git a/tests/MigrateTaskTest.php b/tests/MigrateTaskTest.php index 4d8afdc..110c1ef 100644 --- a/tests/MigrateTaskTest.php +++ b/tests/MigrateTaskTest.php @@ -4,6 +4,12 @@ class MigrateTaskTest extends SapphireTest { protected static $fixture_file = 'MigrateTaskTest.yml'; + protected $extraDataObjects = [ + Migration_TestParent::class, + Migration_TestChild::class, + Migration_TestGrandchild::class, + ]; + /** * @var MigrateTask */ @@ -30,7 +36,6 @@ public function testLatestBatch() { $this->assertEquals(1, MigrateTask::getLatestBatch()); } - public function testTransactionRollback() { // TODO: Ensure changes are rolled back in case there is an exception. } @@ -55,8 +60,13 @@ public function testTransitionField() { // TODO: Make sure values are properly transformed from old -> new } -} + public function testGetTableForField() { + $this->assertEquals(Migration_TestParent::class, Migration::getTableForField(Migration_TestGrandchild::class, 'ParentField')); + $this->assertEquals(Migration_TestChild::class, Migration::getTableForField(Migration_TestGrandchild::class, 'ChildField')); + $this->assertEquals(Migration_TestGrandchild::class, Migration::getTableForField(Migration_TestGrandchild::class, 'Grandchild')); + } +} class Migration_UnitTestOnly extends Migration implements TestOnly, MigrationInterface { @@ -83,3 +93,27 @@ protected static function exceptionator() { } } + +class Migration_TestParent extends DataObject implements TestOnly { + + private static $db = [ + 'ParentField' => 'Varchar(255)', + ]; + +} + +class Migration_TestChild extends Migration_TestParent implements TestOnly { + + private static $db = [ + 'ChildField' => 'Varchar(255)', + ]; + +} + +class Migration_TestGrandchild extends Migration_TestChild implements TestOnly { + + private static $db = [ + 'Grandchild' => 'Varchar(255)', + ]; + +}