-
-
Save nerdsrescueme/9b579608422e7442e3d9 to your computer and use it in GitHub Desktop.
Migrations
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
private static function _fieldify($field = array(), $include_name = true) | |
{ | |
if ($include_name) | |
{ | |
$name = array_shift($field); | |
} | |
$field_opts = array(); | |
foreach($field as $option => $val) | |
{ | |
if($val === true) | |
{ | |
$field_opts[] = "'$option' => true"; | |
} | |
else | |
{ | |
if(is_int($val)) | |
{ | |
$field_opts[] = "'$option' => $val"; | |
} | |
else | |
{ | |
$field_opts[] = "'$option' => '$val'"; | |
} | |
} | |
} | |
$field_opts = implode(', ', $field_opts); | |
if ($include_name) | |
{ | |
return "'$name' => array({$field_opts})"; | |
} | |
return "array({$field_opts})"; | |
} | |
// create_{tablename} | |
public static function create($subjects, $fields) | |
{ | |
$field_str = ''; | |
foreach($fields as $field) | |
{ | |
$field_str .= "\t\t\t" . static::_fieldify($field) . PHP_EOL; | |
} | |
// ID Field | |
$field_str = "\t\t\t'id' => array('constraint' => 11, 'type' => 'int', 'auto_increment' => true),".PHP_EOL . $field_str; | |
$up = <<<UP | |
\DBUtil::create_table('{$subjects[1]}', array( | |
$field_str | |
), array('id')); | |
UP; | |
$down = <<<DOWN | |
\DBUtil::drop_table('{$subjects[1]}'); | |
DOWN; | |
return array($up, $down); | |
} | |
// add_{thing}_to_{tablename} | |
public static function add($subjects, $fields) | |
{ | |
$up, $down = ''; | |
// Adds multiple if given. | |
foreach ($fields as $field) | |
{ | |
$name = array_shift($field); | |
$opts = static::_fieldify($field, false); | |
$up .= "\t\t\\DBUtil::add_column('{$subjects[1]}', '{$name}', '{$opts}')" . PHP_EOL; | |
$down .= "\t\t\\DBUtil::remove_column('{$subjects[1]}', '{$name}')" . PHP_EOL; | |
} | |
return array($up, $down); | |
} | |
// rename_{fieldname}_to_{newfieldname}_on_{table} | |
public static function rename_field($subjects, $fields) | |
{ | |
return array( | |
"\t\t" . \DBUtil::rename_column('{$subjects[2]}', '{$subjects[0]}', '{$subjects[1]}'), | |
"\t\t" . \DBUtil::rename_column('{$subjects[2]}', '{$subjects[1]}', '{$subjects[0]}'), | |
); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
public function add_column($table, $name, $options = array()) | |
{ | |
$sql = 'ALTER TABLE ' . DB::quote_identifier(DB::table_prefix($table)) . ' ' | |
. 'ADD COLUMN (' . DB::quote_identifier($name) . ' ' | |
. static::process_fields(array($options)) . ')'; | |
return DB::query($sql, \DB::UPDATE)->execute(); | |
} | |
public function remove_column($table, $name) | |
{ | |
$sql = 'ALTER TABLE ' . DB::quote_identifier(DB::table_prefix($table) . ' ' | |
. 'DROP COLUMN ' . DB::quote_identifier($name); | |
return DB::query($sql, \DB::UPDATE)->execute(); | |
} | |
public function rename_column($table, $old_name, $new_name) | |
{ | |
$sql = 'ALTER TABLE ' . DB::quote_identifier(DB::table_prefix($table) . ' ' | |
. 'CHANGE COLUMN ' . DB::quote_identifier($old_name) . ' ' | |
. DB::quote_identifier($new_name); | |
return DB::query($sql, \DB::UPDATE)->execute(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
public static function migration($args, $build = true) | |
{ | |
// Get the migration name | |
$migration_name = strtolower(str_replace('-', '_', array_shift($args))); | |
// Check if a migration with this name already exists | |
if (count($duplicates = glob(APPPATH."migrations/*_{$migration_name}*")) > 0) | |
{ | |
// Don't override a file | |
if (\Cli::option('s', \Cli::option('skip')) === true) | |
{ | |
return; | |
} | |
// Tear up the file path and name to get the last duplicate | |
$file_name = pathinfo(end($duplicates), PATHINFO_FILENAME); | |
// Override the (most recent) migration with the same name by using its number | |
if (\Cli::option('f', \Cli::option('force')) === true) | |
{ | |
list($number) = explode('_', $file_name); | |
} | |
// Name clashes but this is done by hand. Assume they know what they're doing and just increment the file | |
elseif (static::$scaffolding === false) | |
{ | |
// Increment the name of this | |
$migration_name = \Str::increment(substr($file_name, 4), 2); | |
} | |
} | |
// See if the action exists | |
$methods = get_class_methods(__NAMESPACE__ . '\Generate_Migration_Actions'); | |
// For empty migrations that dont have actions | |
$migration = array('', ''); | |
// Loop through the actions and act on a matching action appropriately | |
foreach ($methods as $method_name) | |
{ | |
// If the miration name starts with the name of the action method | |
if (substr($migration_name, 0, strlen($method_name)) === $method_name) | |
{ | |
/** | |
* Create an array of the subject the migration is about | |
* | |
* - In a migration named 'create_users' the subject is 'users' since thats what we want to create | |
* So it would be the second object in the array | |
* array(false, 'users') | |
* | |
* - In a migration named 'add_name_to_users' the object is 'name' and the subject is 'users'. | |
* So again 'users' would be the second object, but 'name' would be the first | |
* array('name', 'users') | |
* | |
*/ | |
$subjects = array(false, false); | |
$matches = explode('_', str_replace($method_name . '_', '', $migration_name)); | |
// create_{table} | |
if (count($matches) == 1) | |
{ | |
$subjects = array(false, $matches[0]); | |
} | |
// add_{field}_to_{table} | |
else if (count($matches) == 3 && $matches[1] == 'to') | |
{ | |
$subjects = array($matches[0], $matches[2]); | |
} | |
// rename_table_{tablename}_to_{newtablename} | |
else if (count($matches) == 5 && $matches[1] == 'rename' && $matches[2] == 'table') | |
{ | |
$subjects = array($matches[3], $matches[5]); | |
} | |
// rename_{tablename}_to_{newtablename}_on_{table} | |
else if (count($matches) == 6 && $matches[1] == 'rename' && $matches[3] == 'to') | |
{ | |
$subjects = array($matches[2], $matches[4], $matches[6]); | |
} | |
// create_{table} (with underscores in table name) | |
else if (count($matches) !== 0) | |
{ | |
$subjects = array(false, implode('_', $matches)); | |
} | |
// There is no subject here so just carry on with a normal empty migration | |
else | |
{ | |
break; | |
} | |
// We always pass in fields to a migration, so lets sort them out here. | |
$fields = array(); | |
foreach ($args as $field) | |
{ | |
$field_array = array(); | |
// Each paramater for a field is seperated by the : character | |
$parts = explode(":", $field); | |
// We must have the 'name:type' if nothing else! | |
if (count($parts) >= 2) | |
{ | |
$field_array['name'] = array_shift($parts); | |
foreach ($parts as $part_i => $part) | |
{ | |
preg_match('/([a-z0-9_-]+)(?:\[([a-z0-9]+)\])?/i', $part, $part_matches); | |
array_shift($part_matches); | |
if (count($part_matches) < 1) | |
{ | |
// Move onto the next part, something is wrong here... | |
continue; | |
} | |
$option_name = ''; // This is the name of the option to be passed to the action in a field | |
$option = $part_matches; | |
// The first option always has to be the field type | |
if ($part_i == 0) | |
{ | |
$option_name = 'type'; | |
$type = $option[0]; | |
if ($type === 'string') | |
{ | |
$type = 'varchar'; | |
} | |
else if ($type === 'integer') | |
{ | |
$type = 'int'; | |
} | |
if ( ! in_array($type, array('text', 'blob', 'datetime', 'date', 'timestamp', 'time'))) | |
{ | |
if ( ! isset($option[1]) || $option[1] == NULL) | |
{ | |
if (isset(self::$_default_constraints[$type])) | |
{ | |
$field_array['constraint'] = self::$_default_constraints[$type]; | |
} | |
} | |
else | |
{ | |
$field_array['constraint'] = (int) $option[1]; | |
} | |
} | |
$option = $type; | |
} | |
else | |
{ | |
// This allows you to put any number of :option or :option[val] into your field and these will... | |
// ... always be passed through to the action making it really easy to add extra options for a field | |
$option_name = array_shift($option); | |
if (count($option) > 0) | |
{ | |
$option = $option[0]; | |
} | |
else | |
{ | |
$option = true; | |
} | |
} | |
$field_array[$option_name] = $option; | |
} | |
$fields[] = $field_array; | |
} | |
else | |
{ | |
// Invalid field passed in | |
continue; | |
} | |
} | |
// Call the magic action which returns an array($up, $down) for the migration | |
$migration = call_user_func(__NAMESPACE__ . "\Generate_Migration_Actions::{$method_name}", $subjects, $fields); | |
} | |
} | |
// Build the migration | |
list($up, $down)=$migration; | |
$migration_name = ucfirst(strtolower($migration_name)); | |
$migration = <<<MIGRATION | |
<?php | |
namespace Fuel\Migrations; | |
class {$migration_name} { | |
public function up() | |
{ | |
{$up} | |
} | |
public function down() | |
{ | |
{$down} | |
} | |
} | |
MIGRATION; | |
$number = isset($number) ? $number : static::_find_migration_number(); | |
$filepath = APPPATH . 'migrations/'.$number.'_' . strtolower($migration_name) . '.php'; | |
static::create($filepath, $migration, 'migration'); | |
$build and static::build(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment