public function run($options = array()) { Yentu::greet(); $db = DatabaseManipulator::create(); DatabaseItem::setDriver($db); ChangeReverser::setDriver($db); $previousMigration = ''; if (isset($options['default-schema'])) { $this->schemaCondition = "default_schema = ?"; $this->schemaConditionData[] = $options['default-schema']; } if (empty($options)) { $session = $db->getLastSession(); $operations = $db->query("SELECT id, method, arguments, migration, default_schema FROM yentu_history WHERE {$this->schemaCondition} session = ? ORDER BY id DESC", $this->schemaConditionData + [$session]); } else { $operations = []; foreach ($options['stand_alones'] as $set) { $operations += $this->getOperations($db, $set); } } foreach ($operations as $operation) { if ($previousMigration !== $operation['migration']) { ClearIce::output("Rolling back '{$operation['migration']}' migration" . ($operation['default_schema'] != '' ? " on `{$operation['default_schema']}` schema." : ".") . "\n"); $previousMigration = $operation['migration']; } ChangeReverser::call($operation['method'], json_decode($operation['arguments'], true)); $db->query('DELETE FROM yentu_history WHERE id = ?', array($operation['id'])); } }
public function run($options = array()) { Yentu::greet(); $this->db = DatabaseManipulator::create(); $this->initializeCodeWriter(); $files = scandir(Yentu::getPath("migrations")); if (count($files) > 2) { throw new \yentu\exceptions\CommandException("Cannot run imports. Your migrations directory is not empty"); } $description = $this->db->getDescription(); $this->code->add('begin()'); if (isset($description['schemata'])) { $this->importSchemata($description['schemata']); } if (isset($description['tables'])) { $this->importTables($description['tables']); } if (isset($description['views'])) { $this->importViews($description['views']); } $this->importForeignKeys(); $this->code->add('->end();'); $this->newVersion = date('YmdHis', time()); $path = Yentu::getPath("migrations/{$this->newVersion}_import.php"); file_put_contents($path, $this->code); \clearice\ClearIce::output("Created `{$path}`\n"); if (!$this->db->getAssertor()->doesTableExist('yentu_history')) { $this->db->createHistory(); } $this->db->setVersion($this->newVersion); $this->db->disconnect(); return $description; }
public function setUp() { $this->testDatabase = 'yentu_rollback_test'; parent::setup(); $this->createDb($GLOBALS['DB_NAME']); $this->initDb($GLOBALS['DB_FULL_DSN'], file_get_contents("tests/sql/{$GLOBALS['DRIVER']}/pre_rollback.sql")); $this->connect($GLOBALS['DB_FULL_DSN']); $this->setupStreams(); $init = new \yentu\commands\Init(); $init->createConfigFile(array('driver' => $GLOBALS['DRIVER'], 'host' => $GLOBALS['DB_HOST'], 'dbname' => $GLOBALS["DB_NAME"], 'user' => $GLOBALS['DB_USER'], 'password' => $GLOBALS['DB_PASSWORD'], 'file' => $GLOBALS['DB_FILE'])); Config::readPath(\yentu\Yentu::getPath('config'), 'yentu'); }
public function __construct($message) { parent::__construct($message); foreach ($this->getTrace() as $item) { if (!isset($item['file'])) { continue; } if (realpath(Yentu::getPath('migrations')) === dirname($item['file'])) { $this->message .= ". Exception was thrown by action on line {$item['line']} of {$item['file']}"; break; } } }
public function createFile($name) { $this->checkExisting($name); $this->checkName($name); $this->checkPermission(); $timestamp = date('YmdHis', time()); $code = new \yentu\CodeWriter(); $code->add(''); $code->add('begin()'); $code->add(''); $code->add('->end();'); $path = Yentu::getPath("migrations/{$timestamp}_{$name}.php"); file_put_contents($path, $code); \clearice\ClearIce::output("Added {$path} for new migration.\n"); }
private function getMigrationInfo() { $runMigrations = Yentu::getRunMirations(); $migrations = Yentu::getAllMigrations(); $counter['previous'] = count($runMigrations); end($runMigrations); $current = "{$runMigrations[key($runMigrations)]['timestamp']} {$runMigrations[key($runMigrations)]['migration']}"; $run = array('previous' => array(), 'yet' => array()); foreach ($runMigrations as $timestamp => $migration) { unset($migrations[$timestamp]); $run['previous'][] = "{$timestamp} {$migration['migration']} " . ($migration['default_schema'] == '' ? '' : "on `{$migration['default_schema']}` schema"); } foreach ($migrations as $timestamp => $migration) { $run['yet'][] = "{$timestamp} {$migration['migration']}"; } $counter['yet'] = count($run['yet']); return array('counter' => $counter, 'current' => $current, 'run' => $run); }
private function performOperation($method, $matches, $arguments) { try { $return = $this->driver->{$method}($arguments[0]); Yentu::announce($matches['command'], $matches['item_type'], $arguments[0]); $this->driver->setDumpQuery(false); ClearIce::pushOutputLevel(ClearIce::OUTPUT_LEVEL_0); $this->driver->query('INSERT INTO yentu_history(session, version, method, arguments, migration, default_schema) VALUES (?,?,?,?,?,?)', array($this->session, $this->version, $method, json_encode($arguments), $this->migration, self::$defaultSchema)); ClearIce::popOutputLevel(); $this->changes++; $this->driver->setDisableQuery(false); } catch (\yentu\exceptions\DatabaseManipulatorException $e) { if ($this->skipOnErrors) { ClearIce::output("E"); ClearIce::output("rror " . preg_replace("/([a-z])([A-Z])/", "\$1 \$2", $matches['item_type']) . " '" . $arguments[0]['name'] . "'\n", ClearIce::OUTPUT_LEVEL_2); } else { throw $e; } } return $return; }
/** * Display the greeting for the CLI user interface. */ public static function greet() { $version = Yentu::getVersion(); $welcome = <<<WELCOME Yentu Database Migration Tool Version {$version} WELCOME; ClearIce::output($welcome); }
public function run($options = array()) { global $migrateCommand; global $migrateVariables; self::fillOptions($options); $migrateCommand = $this; if ($options['dump-queries'] !== true) { Yentu::greet(); } $this->driver = ChangeLogger::wrap(DatabaseManipulator::create()); $this->driver->setDumpQueriesOnly($options['dump-queries']); $this->driver->setDryRun($options['dry']); $totalOperations = 0; $filter = self::FILTER_UNRUN; $this->setupOptions($options, $filter); DatabaseItem::setDriver($this->driver); \yentu\Timer::start(); $migrationPaths = Yentu::getMigrationPathsInfo(); foreach ($migrationPaths as $path) { $this->setDefaultSchema($path); $migrateVariables = $path['variables']; $migrations = $this->filter(Yentu::getMigrations($path['home']), $filter); $this->announceMigration($migrations, $path); $this->currentPath = $path; foreach ($migrations as $migration) { $this->countOperations("{$path['home']}/{$migration['file']}"); $this->driver->setVersion($migration['timestamp']); $this->driver->setMigration($migration['migration']); ClearIce::output("\nApplying '{$migration['migration']}' migration\n"); require "{$path['home']}/{$migration['file']}"; DatabaseItem::purge(); ClearIce::output("\n"); $totalOperations += $this->driver->resetOperations(); } } if ($this->driver->getChanges()) { $elapsed = \yentu\Timer::stop(); ClearIce::output("\nMigration took " . \yentu\Timer::pretty($elapsed) . "\n"); ClearIce::output($this->driver->getChanges() . " operations performed\n"); ClearIce::output($totalOperations - $this->driver->getChanges() . " operations skipped\n"); } $this->driver->disconnect(); }
protected function setupStreams() { vfsStream::setup('home'); \yentu\Yentu::setDefaultHome(vfsStream::url('home/yentu')); \clearice\ClearIce::setStreamUrl('output', vfsStream::url('home/output.txt')); }
$class = "\\yentu\\commands\\" . ucfirst($options['__command__']); unset($options['__command__']); Config::readPath(Yentu::getPath('config'), 'yentu'); $command = new $class(); $command->run($options); } else { ClearIce::output(ClearIce::getHelpMessage()); } } catch (\yentu\exceptions\CommandException $e) { ClearIce::resetOutputLevel(); ClearIce::error("Error! " . $e->getMessage() . "\n"); } catch (\ntentan\atiaa\exceptions\DatabaseDriverException $e) { ClearIce::resetOutputLevel(); ClearIce::error("Database driver failed: " . $e->getMessage() . "\n"); Yentu::reverseCommand($command); } catch (\yentu\exceptions\DatabaseManipulatorException $e) { ClearIce::resetOutputLevel(); ClearIce::error("Failed to perform database action: " . $e->getMessage() . "\n"); Yentu::reverseCommand($command); } catch (\ntentan\atiaa\DescriptionException $e) { ClearIce::resetOutputLevel(); ClearIce::error("Failed to perform database action: " . $e->getMessage() . "\n"); Yentu::reverseCommand($command); } catch (\yentu\exceptions\SyntaxErrorException $e) { ClearIce::resetOutputLevel(); ClearIce::error("Error found in syntax: {$e->getMessage()}\n"); Yentu::reverseCommand($command); } catch (\PDOException $e) { ClearIce::resetOutputLevel(); ClearIce::error("Failed to connect to database: {$e->getMessage()}\n"); }
/** * @expectedException \yentu\exceptions\CommandException */ public function testExistingDb() { $this->pdo->query('CREATE TABLE yentu_history(dummy INTEGER)'); $initCommand = new \yentu\commands\Init(); \yentu\Yentu::setDefaultHome(vfsStream::url("home/yentu")); $initCommand->run(array('driver' => $GLOBALS['DRIVER'], 'host' => $GLOBALS['DB_HOST'], 'dbname' => $GLOBALS['DB_NAME'], 'user' => $GLOBALS['DB_USER'], 'password' => $GLOBALS['DB_PASSWORD'], 'file' => $GLOBALS['DB_FILE'])); }
public function run($options = array()) { Yentu::greet(); if (file_exists(Yentu::getPath(''))) { throw new CommandException("Could not initialize yentu. Your project has already been initialized with yentu."); } else { if (!is_writable(dirname(Yentu::getPath('')))) { throw new CommandException("Your current directory is not writable."); } } $params = $this->getParams($options); if (count($params) == 0 && defined('STDOUT')) { global $argv; throw new CommandException("You didn't provide any parameters for initialization. Please execute " . "`{$argv[0]} init -i` to initialize yentu interractively. " . "You can also try `{$argv[0]} init --help` for more information."); } $this->createConfigFile($params); Config::readPath(Yentu::getPath('config'), 'yentu'); $db = \yentu\DatabaseManipulator::create($params); if ($db->getAssertor()->doesTableExist('yentu_history')) { throw new CommandException("Could not initialize yentu. Your database has already been initialized with yentu."); } $db->createHistory(); $db->disconnect(); ClearIce::output("Yentu successfully initialized.\n"); }