/** * Attempts to revert a step of the given migration or one of its dependencies * * @param string $name The class name of the migration * @return bool Whether any update step was successfully run */ protected function try_revert($name) { if (!class_exists($name)) { return false; } $migration = $this->get_migration($name); $state = $this->migration_state[$name]; $this->last_run_migration = array('name' => $name, 'class' => $migration, 'task' => ''); if ($state['migration_data_done']) { if ($state['migration_data_state'] !== 'revert_data') { $result = $this->process_data_step($migration->update_data(), $state['migration_data_state'], true); $state['migration_data_state'] = $result === true ? 'revert_data' : $result; } else { $result = $this->process_data_step($migration->revert_data(), '', false); $state['migration_data_state'] = $result === true ? '' : $result; $state['migration_data_done'] = $result === true ? false : true; } $this->set_migration_state($name, $state); } else { if ($state['migration_schema_done']) { $steps = $this->helper->get_schema_steps($migration->revert_schema()); $result = $this->process_data_step($steps, $state['migration_data_state']); $state['migration_data_state'] = $result === true ? '' : $result; $state['migration_schema_done'] = $result === true ? false : true; if (!$state['migration_schema_done']) { $sql = 'DELETE FROM ' . $this->migrations_table . "\n\t\t\t\t\tWHERE migration_name = '" . $this->db->sql_escape($name) . "'"; $this->db->sql_query($sql); unset($this->migration_state[$name]); } } } return true; }
/** * Attempts to revert a step of the given migration or one of its dependencies * * @param string $name The class name of the migration * @return bool Whether any update step was successfully run */ protected function try_revert($name) { if (!class_exists($name)) { return false; } $migration = $this->get_migration($name); $state = $this->migration_state[$name]; $this->last_run_migration = array('name' => $name, 'class' => $migration, 'task' => ''); if ($state['migration_data_done']) { $verbosity = empty($state['migration_data_state']) ? migrator_output_handler_interface::VERBOSITY_VERBOSE : migrator_output_handler_interface::VERBOSITY_DEBUG; $this->output_handler->write(array('MIGRATION_REVERT_DATA_RUNNING', $name), $verbosity); $total_time = is_array($state['migration_data_state']) && isset($state['migration_data_state']['_total_time']) ? $state['migration_data_state']['_total_time'] : 0.0; $elapsed_time = microtime(true); $steps = array_merge($this->helper->reverse_update_data($migration->update_data()), $migration->revert_data()); $result = $this->process_data_step($steps, $state['migration_data_state']); $elapsed_time = microtime(true) - $elapsed_time; $total_time += $elapsed_time; if (is_array($result)) { $result['_total_time'] = $total_time; } $state['migration_data_state'] = $result === true ? '' : $result; $state['migration_data_done'] = $result === true ? false : true; $this->set_migration_state($name, $state); if (!$state['migration_data_done']) { $this->output_handler->write(array('MIGRATION_REVERT_DATA_DONE', $name, $total_time), migrator_output_handler_interface::VERBOSITY_NORMAL); } else { $this->output_handler->write(array('MIGRATION_REVERT_DATA_IN_PROGRESS', $name, $elapsed_time), migrator_output_handler_interface::VERBOSITY_VERY_VERBOSE); } } else { if ($state['migration_schema_done']) { $verbosity = empty($state['migration_data_state']) ? migrator_output_handler_interface::VERBOSITY_VERBOSE : migrator_output_handler_interface::VERBOSITY_DEBUG; $this->output_handler->write(array('MIGRATION_REVERT_SCHEMA_RUNNING', $name), $verbosity); $total_time = is_array($state['migration_data_state']) && isset($state['migration_data_state']['_total_time']) ? $state['migration_data_state']['_total_time'] : 0.0; $elapsed_time = microtime(true); $steps = $this->helper->get_schema_steps($migration->revert_schema()); $result = $this->process_data_step($steps, $state['migration_data_state']); $elapsed_time = microtime(true) - $elapsed_time; $total_time += $elapsed_time; if (is_array($result)) { $result['_total_time'] = $total_time; } $state['migration_data_state'] = $result === true ? '' : $result; $state['migration_schema_done'] = $result === true ? false : true; if (!$state['migration_schema_done']) { $sql = 'DELETE FROM ' . $this->migrations_table . "\n\t\t\t\t\tWHERE migration_name = '" . $this->db->sql_escape($name) . "'"; $this->db->sql_query($sql); $this->last_run_migration = false; unset($this->migration_state[$name]); $this->output_handler->write(array('MIGRATION_REVERT_SCHEMA_DONE', $name, $total_time), migrator_output_handler_interface::VERBOSITY_NORMAL); } else { $this->set_migration_state($name, $state); $this->output_handler->write(array('MIGRATION_REVERT_SCHEMA_IN_PROGRESS', $name, $elapsed_time), migrator_output_handler_interface::VERBOSITY_VERY_VERBOSE); } } } return true; }
/** * @dataProvider update_data_provider */ public function test_get_schema_steps($data_changes, $expected) { $this->assertEquals($expected, $this->helper->reverse_update_data($data_changes)); }
/** * Attempts to revert a step of the given migration or one of its dependencies * * @param string $name The class name of the migration * @return bool Whether any update step was successfully run */ protected function try_revert($name) { if (!class_exists($name)) { return false; } $migration = $this->get_migration($name); $state = $this->migration_state[$name]; $this->last_run_migration = array( 'name' => $name, 'class' => $migration, 'task' => '', ); if ($state['migration_data_done']) { $this->output_handler->write(array('MIGRATION_REVERT_DATA_RUNNING', $name), migrator_output_handler_interface::VERBOSITY_VERBOSE); $elapsed_time = microtime(true); if ($state['migration_data_state'] !== 'revert_data') { $result = $this->process_data_step($migration->update_data(), $state['migration_data_state'], true); $state['migration_data_state'] = ($result === true) ? 'revert_data' : $result; } else { $result = $this->process_data_step($migration->revert_data(), '', false); $state['migration_data_state'] = ($result === true) ? '' : $result; $state['migration_data_done'] = ($result === true) ? false : true; } $this->set_migration_state($name, $state); $elapsed_time = microtime(true) - $elapsed_time; if ($state['migration_data_done']) { $this->output_handler->write(array('MIGRATION_REVERT_DATA_DONE', $name, $elapsed_time), migrator_output_handler_interface::VERBOSITY_NORMAL); } else { $this->output_handler->write(array('MIGRATION_REVERT_DATA_IN_PROGRESS', $name, $elapsed_time), migrator_output_handler_interface::VERBOSITY_VERY_VERBOSE); } } else if ($state['migration_schema_done']) { $this->output_handler->write(array('MIGRATION_REVERT_SCHEMA_RUNNING', $name), migrator_output_handler_interface::VERBOSITY_VERBOSE); $elapsed_time = microtime(true); $steps = $this->helper->get_schema_steps($migration->revert_schema()); $result = $this->process_data_step($steps, $state['migration_data_state']); $state['migration_data_state'] = ($result === true) ? '' : $result; $state['migration_schema_done'] = ($result === true) ? false : true; if (!$state['migration_schema_done']) { $sql = 'DELETE FROM ' . $this->migrations_table . " WHERE migration_name = '" . $this->db->sql_escape($name) . "'"; $this->db->sql_query($sql); unset($this->migration_state[$name]); } $elapsed_time = microtime(true) - $elapsed_time; $this->output_handler->write(array('MIGRATION_REVERT_SCHEMA_DONE', $name, $elapsed_time), migrator_output_handler_interface::VERBOSITY_NORMAL); } return true; }