/** * @see sfTask */ protected function execute($arguments = array(), $options = array()) { $databaseManager = new sfDatabaseManager($this->configuration); $connections = $this->getConnections($databaseManager); $manager = new PropelMigrationManager(); $manager->setConnections($connections); $manager->setMigrationTable($options['migration-table']); $migrationDirectory = sfConfig::get('sf_root_dir') . DIRECTORY_SEPARATOR . $options['migration-dir']; $manager->setMigrationDir($migrationDirectory); if (!($nextMigrationTimestamp = $manager->getFirstUpMigrationTimestamp())) { $this->logSection('propel', 'All migrations were already executed - nothing to migrate.'); return false; } $this->logSection('propel', sprintf('Executing migration %s up', $manager->getMigrationClassName($nextMigrationTimestamp))); $migration = $manager->getMigrationObject($nextMigrationTimestamp); if (false === $migration->preUp($manager)) { $this->logSection('propel', 'preUp() returned false. Aborting migration.', null, 'ERROR'); return false; } foreach ($migration->getUpSQL() as $datasource => $sql) { $connection = $manager->getConnection($datasource); if ($options['verbose']) { $this->logSection('propel', sprintf(' Connecting to database "%s" using DSN "%s"', $datasource, $connection['dsn']), null, 'COMMENT'); } $pdo = $manager->getPdoConnection($datasource); $res = 0; $statements = PropelSQLParser::parseString($sql); foreach ($statements as $statement) { try { if ($options['verbose']) { $this->logSection('propel', sprintf(' Executing statement "%s"', $statement), null, 'COMMENT'); } $stmt = $pdo->prepare($statement); $stmt->execute(); $res++; } catch (PDOException $e) { $this->logSection(sprintf('Failed to execute SQL "%s". Aborting migration.', $statement), null, 'ERROR'); return false; // continue } } if (!$res) { $this->logSection('propel', 'No statement was executed. The version was not updated.'); $this->logSection('propel', sprintf('Please review the code in "%s"', $manager->getMigrationDir() . DIRECTORY_SEPARATOR . $manager->getMigrationClassName($nextMigrationTimestamp))); $this->logSection('propel', 'Migration aborted', null, 'ERROR'); return false; } $this->logSection('propel', sprintf('%d of %d SQL statements executed successfully on datasource "%s"', $res, count($statements), $datasource)); $manager->updateLatestMigrationTimestamp($datasource, $nextMigrationTimestamp); if ($options['verbose']) { $this->logSection('propel', sprintf(' Updated latest migration date to %d for datasource "%s"', $nextMigrationTimestamp, $datasource), null, 'COMMENT'); } } $migration->postUp($manager); if ($timestamps = $manager->getValidMigrationTimestamps()) { $this->logSection('propel', sprintf('Migration complete. %d migrations left to execute.', count($timestamps))); } else { $this->logSection('propel', 'Migration complete. No further migration to execute.'); } }
/** * Main method builds all the targets for a typical propel project. */ public function main() { $manager = new PropelMigrationManager(); $manager->setConnections($this->getGeneratorConfig()->getBuildConnections()); $manager->setMigrationTable($this->getMigrationTable()); $manager->setMigrationDir($this->getOutputDirectory()); $previousTimestamps = $manager->getAlreadyExecutedMigrationTimestamps(); if (!($nextMigrationTimestamp = array_pop($previousTimestamps))) { $this->log('No migration were ever executed on this database - nothing to reverse.'); return false; } $this->log(sprintf('Executing migration %s down', $manager->getMigrationClassName($nextMigrationTimestamp))); if ($nbPreviousTimestamps = count($previousTimestamps)) { $previousTimestamp = array_pop($previousTimestamps); } else { $previousTimestamp = 0; } $migration = $manager->getMigrationObject($nextMigrationTimestamp); if (false === $migration->preDown($manager)) { $this->log('preDown() returned false. Aborting migration.', Project::MSG_ERR); return false; } foreach ($migration->getDownSQL() as $datasource => $sql) { $connection = $manager->getConnection($datasource); $this->log(sprintf('Connecting to database "%s" using DSN "%s"', $datasource, $connection['dsn']), Project::MSG_VERBOSE); $pdo = $manager->getPdoConnection($datasource); $res = 0; $statements = PropelSQLParser::parseString($sql); foreach ($statements as $statement) { try { $this->log(sprintf('Executing statement "%s"', $statement), Project::MSG_VERBOSE); $stmt = $pdo->prepare($statement); $stmt->execute(); $res++; } catch (PDOException $e) { $this->log(sprintf('Failed to execute SQL "%s"', $statement), Project::MSG_ERR); // continue } } if (!$res) { $this->log('No statement was executed. The version was not updated.'); $this->log(sprintf('Please review the code in "%s"', $manager->getMigrationDir() . DIRECTORY_SEPARATOR . $manager->getMigrationClassName($nextMigrationTimestamp))); $this->log('Migration aborted', Project::MSG_ERR); return false; } $this->log(sprintf('%d of %d SQL statements executed successfully on datasource "%s"', $res, count($statements), $datasource)); $manager->updateLatestMigrationTimestamp($datasource, $previousTimestamp); $this->log(sprintf('Downgraded migration date to %d for datasource "%s"', $previousTimestamp, $datasource), Project::MSG_VERBOSE); } $migration->postDown($manager); if ($nbPreviousTimestamps) { $this->log(sprintf('Reverse migration complete. %d more migrations available for reverse.', $nbPreviousTimestamps)); } else { $this->log('Reverse migration complete. No more migration available for reverse'); } }
/** * Main method builds all the targets for a typical propel project. */ public function main() { $manager = new PropelMigrationManager(); $manager->setConnections($this->getGeneratorConfig()->getBuildConnections()); $manager->setMigrationTable($this->getMigrationTable()); $manager->setMigrationDir($this->getOutputDirectory()); if (!($nextMigrationTimestamp = $manager->getFirstUpMigrationTimestamp())) { $this->log('All migrations were already executed - nothing to migrate.'); return false; } $timestamps = $manager->getValidMigrationTimestamps(); if (count($timestamps) > 1) { $this->log(sprintf('%d migrations to execute', count($timestamps))); } foreach ($timestamps as $timestamp) { $this->log(sprintf('Executing migration %s up', $manager->getMigrationClassName($timestamp))); $migration = $manager->getMigrationObject($timestamp); if (false === $migration->preUp($manager)) { $this->log('preUp() returned false. Aborting migration.', Project::MSG_ERR); return false; } foreach ($migration->getUpSQL() as $datasource => $sql) { $connection = $manager->getConnection($datasource); $this->log(sprintf('Connecting to database "%s" using DSN "%s"', $datasource, $connection['dsn']), Project::MSG_VERBOSE); $pdo = $manager->getPdoConnection($datasource); $res = 0; $statements = PropelSQLParser::parseString($sql); foreach ($statements as $statement) { try { $this->log(sprintf('Executing statement "%s"', $statement), Project::MSG_VERBOSE); $stmt = $pdo->prepare($statement); $stmt->execute(); $res++; } catch (PDOException $e) { $this->log(sprintf('Failed to execute SQL "%s"', $statement), Project::MSG_ERR); // continue } } if (!$res) { $this->log('No statement was executed. The version was not updated.'); $this->log(sprintf('Please review the code in "%s"', $manager->getMigrationDir() . DIRECTORY_SEPARATOR . $manager->getMigrationClassName($timestamp))); $this->log('Migration aborted', Project::MSG_ERR); return false; } $this->log(sprintf('%d of %d SQL statements executed successfully on datasource "%s"', $res, count($statements), $datasource)); } // migrations for datasources have passed - update the timestamp // for all datasources foreach ($manager->getConnections() as $datasource => $connection) { $manager->updateLatestMigrationTimestamp($datasource, $timestamp); $this->log(sprintf('Updated latest migration date to %d for datasource "%s"', $timestamp, $datasource), Project::MSG_VERBOSE); } $migration->postUp($manager); } $this->log('Migration complete. No further migration to execute.'); }
/** * Detects the differences between current connected database and $pDatabase * and updates the schema. This does not DROP tables. * * @param Database $pDatabase */ public function updateSchema($pDatabase) { $diff = PropelDatabaseComparator::computeDiff($this->database, $pDatabase); $sql = $this->database->getPlatform()->getModifyDatabaseDDL($diff); $statements = PropelSQLParser::parseString($sql); foreach ($statements as $statement) { if (strpos($statement, 'DROP') === 0) { // drop statements cause errors since the table doesn't exist continue; } $stmt = $this->con->prepare($statement); if ($stmt instanceof PDOStatement) { // only execute if has no error $stmt->execute(); } } }
/** * * @param string $module * @param string $action */ public static function update($module, $action = 'create') { $targetDbName = 'centreon'; ini_set('memory_limit', '-1'); $di = Di::getDefault(); $config = $di->get('config'); $targetDb = 'db_centreon'; $db = $di->get($targetDb); // Configuration for Propel $configParams = array('propel.project' => 'centreon', 'propel.database' => 'mysql', 'propel.database.url' => $config->get($targetDb, 'dsn'), 'propel.database.user' => $config->get($targetDb, 'username'), 'propel.database.password' => $config->get($targetDb, 'password')); // Set the Current Platform and DB Connection $platform = new CentreonMysqlPlatform($db); // Initilize Schema Parser $propelDb = new \MysqlSchemaParser($db); $propelDb->setGeneratorConfig(new \GeneratorConfig($configParams)); $propelDb->setPlatform($platform); // get Current Db State $currentDbAppData = new \AppData($platform); $currentDbAppData->setGeneratorConfig(new \GeneratorConfig($configParams)); $currentDb = $currentDbAppData->addDatabase(array('name' => $targetDbName)); $propelDb->parse($currentDb); // Retreive target DB State $updatedAppData = new \AppData($platform); self::getDbFromXml($updatedAppData, 'centreon'); // Get diff between current db state and target db state $diff = \PropelDatabaseComparator::computeDiff($currentDb, $updatedAppData->getDatabase('centreon'), false); if ($diff !== false) { $strDiff = $platform->getModifyDatabaseDDL($diff); $sqlToBeExecuted = \PropelSQLParser::parseString($strDiff); $finalSql = "\nSET FOREIGN_KEY_CHECKS = 0;\n\n"; if ($action == 'create') { $finalSql .= implode(";\n\n", static::keepCreateStatement($sqlToBeExecuted, $module)); } elseif ($action == 'delete') { $finalSql .= implode(";\n\n", static::keepDeleteStatement($sqlToBeExecuted, $module)); } $finalSql .= ";\n\nSET FOREIGN_KEY_CHECKS = 1;\n\n"; \PropelSQLParser::executeString($finalSql, $db); } // Empty Target DB self::deleteTargetDbSchema($targetDbName); }
/** * @param string $datasource A datasource name. */ public function insertSql($datasource = null) { $statementsToInsert = array(); foreach ($this->getProperties($this->getSqlDbMapFilename()) as $sqlFile => $database) { if (null !== $datasource && $database !== $datasource) { // skip break; } if (!isset($statementsToInsert[$database])) { $statementsToInsert[$database] = array(); } if (null === $database || null !== $database && $database === $datasource) { $filename = $this->getWorkingDirectory() . DIRECTORY_SEPARATOR . $sqlFile; if (file_exists($filename)) { foreach (PropelSQLParser::parseFile($filename) as $sql) { $statementsToInsert[$database][] = $sql; } } } } foreach ($statementsToInsert as $database => $sqls) { if (!$this->hasConnection($database)) { continue; } $pdo = $this->getPdoConnection($database); $pdo->beginTransaction(); try { foreach ($sqls as $sql) { $stmt = $pdo->prepare($sql); $stmt->execute(); } $pdo->commit(); } catch (PDOException $e) { $pdo->rollback(); throw $e; } } return true; }
/** * @dataProvider explodeIntoStatementsDataProvider */ public function testExplodeIntoStatements($input, $output) { $parser = new PropelSQLParser(); $parser->setSQL($input); $this->assertEquals($output, $parser->explodeIntoStatements()); }
public function buildSQL(PDO $con) { $statements = PropelSQLParser::parseString($this->getSQL()); foreach ($statements as $statement) { if (strpos($statement, 'DROP') === 0) { // drop statements cause errors since the table doesn't exist continue; } $stmt = $con->prepare($statement); if ($stmt instanceof PDOStatement) { // only execute if has no error $stmt->execute(); } } return count($statements); }
/** * Load the sql file and then execute it * * @throws BuildException */ public function main() { $conf = new GeneratorConfig(); $conf->setBuildProperties($this->getProject()->getProperties()); $this->setBuildConnections($conf->getBuildConnections()); if ($this->sqldbmap === null || $this->getSqlDbMap()->exists() === false) { throw new BuildException("You haven't provided an sqldbmap, or " . "the one you specified doesn't exist: " . $this->sqldbmap->getPath()); } if ($this->url === null) { throw new BuildException("DSN url attribute must be set!"); } // get an ordered list of SQL files to execute $databases = $this->getFilesToExecute(); $this->log(sprintf('Reading SQL files...')); foreach ($databases as $database => $files) { $statements[$database] = array(); foreach ($files as $fileName) { $fullFileName = $this->srcDir ? $this->srcDir . DIRECTORY_SEPARATOR . $fileName : $fileName; if (file_exists($fullFileName)) { $this->log(sprintf(' Loading statements from "%s"', $fullFileName)); $fileStatements = PropelSQLParser::parseFile($fullFileName); $this->log(sprintf(' %d statements to execute', count($fileStatements)), Project::MSG_VERBOSE); $statements[$database] = array_merge($statements[$database], $fileStatements); } else { $this->log(sprintf('File "%s" in sqldbmap does not exist, skipping it.', $fullFileName)); } } } $successfullStatements = 0; $this->log(sprintf('Executing SQL statements...')); foreach ($statements as $database => $statementList) { $successfullStatements += $this->insertDatabaseSqlFiles($database, $statementList); } $this->log(sprintf('SQL execution complete. %d statements successfully executed.', $successfullStatements)); }
public function createMigrationTable($datasource) { $platform = $this->getPlatform($datasource); // modelize the table $database = new Database($datasource); $database->setPlatform($platform); $table = new Table($this->getMigrationTable()); $database->addTable($table); $column = new Column('version'); $column->getDomain()->copy($platform->getDomainForType('INTEGER')); $column->setDefaultValue(0); $table->addColumn($column); // insert the table into the database $statements = $platform->getAddTableDDL($table); $pdo = $this->getPdoConnection($datasource); $res = PropelSQLParser::executeString($statements, $pdo); if (!$res) { throw new Exception(sprintf('Unable to create migration table in datasource "%s"', $datasource)); } }
/** * Execute SQL statements, and apply callback to result. * * @param string $sql * @param bool $abortOnError * @param callback|null $stmtCallback */ public static function runStatements($sql, $abortOnError = true, $stmtCallback = null) { $connection = Propel::getConnection(); $parser = new PropelSQLParser(); $parser->setSQL($sql); $parser->convertLineFeedsToUnixStyle(); $parser->stripSQLCommentLines(); $statements = $parser->explodeIntoStatements(); foreach ($statements as $statement) { try { $stmt = $connection->prepare($statement); if (!$stmt) { throw new Exception('Failed to create statement'); } $stmt->execute(); if ($stmtCallback) { call_user_func($stmtCallback, $stmt, $statement); } } catch (Exception $e) { if ($abortOnError) { throw new Curry_Exception('Unable to execute statement: ' . $statement); } else { if ($stmtCallback) { call_user_func($stmtCallback, null, $statement); } } } } }
protected function dropTables() { $db = Di::getDefault()->get('db_centreon'); $platform = new CentreonMysqlPlatform($db); // Get current DB State $currentDb = self::initializeCurrentSchema($platform); // Retreive target DB State $updatedAppData = new \AppData($platform); $appDataObject = new \XmlToAppData(new CentreonMysqlPlatform($db), null, 'utf-8'); $updatedAppData->joinAppDatas(array($appDataObject->parseFile(__DIR__ . '/data/empty.xml'))); unset($appDataObject); /* @todo Fatorize */ $diff = \PropelDatabaseComparator::computeDiff($currentDb, $updatedAppData->getDatabase('centreon'), false); if (false !== $diff) { $strDiff = $platform->getModifyDatabaseDDL($diff); $sqlToBeExecuted = \PropelSQLParser::parseString($strDiff); \PropelSQLParser::executeString($strDiff, $db); } }