Skip to content

Commit

Permalink
Allow for parsing of migration names
Browse files Browse the repository at this point in the history
  • Loading branch information
JeffreyWay committed Mar 3, 2014
1 parent 96a9ea7 commit 6191b8b
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 0 deletions.
36 changes: 36 additions & 0 deletions spec/Way/Generators/MigrationNameParserSpec.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

namespace spec\Way\Generators;

use PhpSpec\ObjectBehavior;
use Prophecy\Argument;

class MigrationNameParserSpec extends ObjectBehavior
{
function it_is_initializable()
{
$this->shouldHaveType('Way\Generators\MigrationNameParser');
}

function it_parses_a_basic_migration_name()
{
$this->parse('create_orders_table')->shouldBe([
'action' => 'create',
'tableName' => 'orders'
]);
}

function it_parses_a_complex_migration_name()
{
$this->parse('add_first_name_and_last_name_to_recent_orders_table')->shouldBe([
'action' => 'add',
'tableName' => 'recent_orders'
]);
}

function it_requires_a_valid_crud_action_name()
{
$this->shouldThrow('Way\Generators\InvalidActionType')->duringParse('foo_orders_table');
}

}
3 changes: 3 additions & 0 deletions src/Way/Generators/InvalidActionType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<?php namespace Way\Generators;

class InvalidActionType extends \Exception {}
78 changes: 78 additions & 0 deletions src/Way/Generators/MigrationNameParser.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php namespace Way\Generators;

class MigrationNameParser {

/**
* Recognized CRUD types
*
* @var array
*/
public static $acceptableTypes = [
'create', 'add', 'update', 'delete', 'destroy'
];

/**
* Parse a migration name, like:
* create_orders_table
* add_last_name_to_recent_orders_table
*
* @param $migrationName
* @throws InvalidActionType
* @return array
*/
public function parse($migrationName)
{
// Split the migration name into pieces
// create_orders_table => ['create', 'orders', 'table']
$pieces = explode('_', $migrationName);

// We'll start by fetching the CRUD action type
$action = array_shift($pieces);

// This action type must be something we understand
if ( ! in_array($action, self::$acceptableTypes))
{
throw new InvalidActionType;
}

// Next, we can remove any "table" string at
// the end of the migration name, like:
// create_orders_table
if (end($pieces) == 'table') array_pop($pieces);

// Now, we need to figure out the table name
$tableName = $this->getTableName($pieces);

return compact('action', 'tableName');
}

/**
* Determine what the table name should be
*
* @param array $pieces
* @return string
*/
protected function getTableName(array $pieces)
{
$tableName = [];

// This is deceptively complex, because
// there are a number of ways to write
// these migration names. We'll work backwards
// to figure out the name.
foreach(array_reverse($pieces) as $piece)
{
// Once we get to a connecting word (if any), this
// will signal the end of our search. So, for
// add_name_to_archived_lessons, "archived_lessons"
// would be the table name
if (in_array($piece, ['to', 'for', 'on'])) break;

$tableName[] = $piece;
}

// We can't forget to reverse it back again!
return implode('_', array_reverse($tableName));
}

}

0 comments on commit 6191b8b

Please sign in to comment.