public function execute($args) { echo "Started: " . date('Y-m-d g:ia T') . "\n\n"; echo "[db:status]: \n"; $util = new Ruckusing_MigratorUtil($this->get_adapter()); $migrations = $util->get_executed_migrations(); $files = $util->get_migration_files($this->get_framework()->migrations_directory(), 'up'); $applied = array(); $not_applied = array(); foreach ($files as $file) { if (in_array($file['version'], $migrations)) { $applied[] = $file['class'] . ' [ ' . $file['version'] . ' ]'; } else { $not_applied[] = $file['class'] . ' [ ' . $file['version'] . ' ]'; } } echo "\n\n===================== APPLIED ======================= \n"; foreach ($applied as $a) { echo "\t" . $a . "\n"; } echo "\n\n===================== NOT APPLIED ======================= \n"; foreach ($not_applied as $na) { echo "\t" . $na . "\n"; } echo "\n\nFinished: " . date('Y-m-d g:ia T') . "\n\n"; }
function main($args) { //input sanity check if (!is_array($args) || is_array($args) && !array_key_exists('name', $args)) { print_help(true); } $migration_name = $args['name']; //clear any filesystem stats cache clearstatcache(); //check to make sure our migration directory exists if (!is_dir(RUCKUSING_MIGRATION_DIR)) { die_with_error("ERROR: migration directory '" . RUCKUSING_MIGRATION_DIR . "' does not exist. Specify MIGRATION_DIR in config/config.inc.php and try again."); } //generate a complete migration file $next_version = Ruckusing_MigratorUtil::generate_timestamp(); $klass = Ruckusing_NamingUtil::camelcase($migration_name); $file_name = $next_version . '_' . $klass . '.php'; $full_path = realpath(RUCKUSING_MIGRATION_DIR) . '/' . $file_name; $template_str = get_template($klass); //check to make sure our destination directory is writable if (!is_writable(RUCKUSING_MIGRATION_DIR . '/')) { die_with_error("ERROR: migration directory '" . RUCKUSING_MIGRATION_DIR . "' is not writable by the current user. Check permissions and try again."); } //write it out! $file_result = file_put_contents($full_path, $template_str); if ($file_result === FALSE) { die_with_error("Error writing to migrations directory/file. Do you have sufficient privileges?"); } else { echo "\nCreated migration: {$file_name}\n\n"; } }
public function test_get_relevant_migration_files_down() { $down_files = Ruckusing_MigratorUtil::get_migration_files('down', RUCKUSING_MIGRATION_DIR, true); $actual_down_files = Ruckusing_MigratorUtil::get_relevant_files('down', $down_files, 3, 0); $expect_down_files = array(array('version' => 3, 'class' => 'AddIndexToBlogs', 'file' => '003_AddIndexToBlogs.php'), array('version' => 1, 'class' => 'CreateUsers', 'file' => '001_CreateUsers.php')); $this->assertEquals($expect_down_files, $actual_down_files); $actual_down_files = Ruckusing_MigratorUtil::get_relevant_files('down', $down_files, 2, 0); $expect_down_files = array(array('version' => 1, 'class' => 'CreateUsers', 'file' => '001_CreateUsers.php')); $this->assertEquals($expect_down_files, $actual_down_files); $actual_down_files = Ruckusing_MigratorUtil::get_relevant_files('down', $down_files, 3, 2); $expect_down_files = array(array('version' => 3, 'class' => 'AddIndexToBlogs', 'file' => '003_AddIndexToBlogs.php')); $this->assertEquals($expect_down_files, $actual_down_files); }
public function test_get_runnable_migrations_going_down_with_target_version_no_current() { $migrator_util = new Ruckusing_MigratorUtil($this->adapter); $this->insert_dummy_version_data(array(3, '20090122193325')); $actual_down_files = $migrator_util->get_runnable_migrations($this->migrations_dir, 'down', 1, false); $expect_down_files = array(array('version' => '20090122193325', 'class' => 'AddNewTable', 'file' => '20090122193325_AddNewTable.php'), array('version' => 3, 'class' => 'AddIndexToBlogs', 'file' => '003_AddIndexToBlogs.php')); $this->assertEquals($expect_down_files, $actual_down_files); $this->clear_dummy_data(); $this->insert_dummy_version_data(array(3)); $actual_down_files = $migrator_util->get_runnable_migrations($this->migrations_dir, 'down', 1, false); $expect_down_files = array(array('version' => 3, 'class' => 'AddIndexToBlogs', 'file' => '003_AddIndexToBlogs.php')); $this->assertEquals($expect_down_files, $actual_down_files); //go all the way down! $this->clear_dummy_data(); $this->insert_dummy_version_data(array(1, 3, '20090122193325')); $actual_down_files = $migrator_util->get_runnable_migrations($this->migrations_dir, 'down', 0, false); $expect_down_files = array(array('version' => '20090122193325', 'class' => 'AddNewTable', 'file' => '20090122193325_AddNewTable.php'), array('version' => 3, 'class' => 'AddIndexToBlogs', 'file' => '003_AddIndexToBlogs.php'), array('version' => 1, 'class' => 'CreateUsers', 'file' => '001_CreateUsers.php')); $this->assertEquals($expect_down_files, $actual_down_files); }
public function update_schema_for_timestamps() { //only create the table if it doesnt already exist $this->adapter->create_schema_version_table(); //insert all existing records into our new table $migrator_util = new Ruckusing_MigratorUtil($this->adapter); $files = $migrator_util->get_migration_files(RUCKUSING_MIGRATION_DIR, 'up'); foreach ($files as $file) { if ((int) $file['version'] >= PHP_INT_MAX) { //its new style like '20081010170207' so its not a candidate continue; } //query old table, if it less than or equal to our max version, then its a candidate for insertion $query_sql = sprintf("SELECT version FROM %s WHERE version >= %d", RUCKUSING_SCHEMA_TBL_NAME, $file['version']); $existing_version_old_style = $this->adapter->select_one($query_sql); if (count($existing_version_old_style) > 0) { //make sure it doesnt exist in our new table, who knows how it got inserted? $new_vers_sql = sprintf("SELECT version FROM %s WHERE version = %d", RUCKUSING_TS_SCHEMA_TBL_NAME, $file['version']); $existing_version_new_style = $this->adapter->select_one($new_vers_sql); if (empty($existing_version_new_style)) { // use printf & %d to force it to be stripped of any leading zeros, we *know* this represents an old version style // so we dont have to worry about PHP and integer overflow $insert_sql = sprintf("INSERT INTO %s (version) VALUES (%d)", RUCKUSING_TS_SCHEMA_TBL_NAME, $file['version']); $this->adapter->query($insert_sql); } } } //foreach }
private function migrate_down($destination, $current) { try { echo "\tMigrating DOWN to: {$destination} (current version: {$current})\n"; $migrations = Ruckusing_MigratorUtil::migration_files(RUCKUSING_MIGRATION_DIR, 'down', $current, $destination); $result = $this->run_migrations($migrations, 'down', $destination); if (count($migrations) == 0) { return "\nNo relevant migrations to run. Exiting...\n"; } } catch (Exception $ex) { throw $ex; } }
require RUCKUSING_BASE . '/config/database.inc.php'; require RUCKUSING_BASE . '/lib/classes/util/class.Ruckusing_Logger.php'; require RUCKUSING_BASE . '/lib/classes/util/class.Ruckusing_NamingUtil.php'; require RUCKUSING_BASE . '/lib/classes/util/class.Ruckusing_MigratorUtil.php'; require RUCKUSING_BASE . '/lib/classes/class.Ruckusing_FrameworkRunner.php'; $args = parse_args($argv); $framework = new Ruckusing_FrameworkRunner($ruckusing_db_config, null); //input sanity check if (!is_array($args) || is_array($args) && !array_key_exists('name', $args)) { print_help(true); } $migration_name = $args['name']; //clear any filesystem stats cache clearstatcache(); //generate a complete migration file $next_version = Ruckusing_MigratorUtil::generate_timestamp(); $klass = Ruckusing_NamingUtil::camelcase($migration_name); $file_name = $next_version . '_' . $klass . '.php'; $migrations_dir = $framework->migrations_directory(); $template_str = get_template($klass); if (!is_dir($migrations_dir)) { printf("\n\tMigrations directory (%s doesn't exist, attempting to create.", $migrations_dir); if (mkdir($migrations_dir) === FALSE) { printf("\n\tUnable to create migrations directory at %s, check permissions?", $migrations_dir); } else { printf("\n\tCreated OK"); } } //check to make sure our destination directory is writable if (!is_writable($migrations_dir)) { die_with_error("ERROR: migration directory '" . $migrations_dir . "' is not writable by the current user. Check permissions and try again.");