/**
  * 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();
         }
     }
 }
    public function providerForTestGetModifyDatabaseDDL()
    {
        $schema1 = <<<EOF
<database name="test">
\t<table name="foo1">
\t\t<column name="id" primaryKey="true" type="INTEGER" autoIncrement="true" />
\t\t<column name="blooopoo" type="INTEGER" />
\t</table>
\t<table name="foo2">
\t\t<column name="id" primaryKey="true" type="INTEGER" autoIncrement="true" />
\t\t<column name="bar" type="INTEGER" />
\t\t<column name="baz" type="VARCHAR" size="12" required="true" />
\t</table>
\t<table name="foo3">
\t\t<column name="id" primaryKey="true" type="INTEGER" autoIncrement="true" />
\t\t<column name="yipee" type="INTEGER" />
\t</table>
</database>
EOF;
        $schema2 = <<<EOF
<database name="test">
\t<table name="foo2">
\t\t<column name="id" primaryKey="true" type="INTEGER" autoIncrement="true" />
\t\t<column name="bar1" type="INTEGER" />
\t\t<column name="baz" type="VARCHAR" size="12" required="false" />
\t\t<column name="baz3" type="LONGVARCHAR" />
\t</table>
\t<table name="foo4">
\t\t<column name="id" primaryKey="true" type="INTEGER" autoIncrement="true" />
\t\t<column name="yipee" type="INTEGER" />
\t</table>
\t<table name="foo5">
\t\t<column name="id" primaryKey="true" type="INTEGER" autoIncrement="true" />
\t\t<column name="lkdjfsh" type="INTEGER" />
\t\t<column name="dfgdsgf" type="LONGVARCHAR" />
\t</table>
</database>
EOF;
        $d1 = $this->getDatabaseFromSchema($schema1);
        $d2 = $this->getDatabaseFromSchema($schema2);
        return array(array(PropelDatabaseComparator::computeDiff($d1, $d2)));
    }
Exemple #3
0
 /**
  * 
  * @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);
 }
 public function testCompareSeveralRenamedSameTables()
 {
     $d1 = new Database();
     $t1 = new Table('table1');
     $c1 = new Column('col1');
     $c1->getDomain()->copy($this->platform->getDomainForType('INTEGER'));
     $t1->addColumn($c1);
     $d1->addTable($t1);
     $t2 = new Table('table2');
     $c2 = new Column('col1');
     $c2->getDomain()->copy($this->platform->getDomainForType('INTEGER'));
     $t2->addColumn($c2);
     $d1->addTable($t2);
     $t3 = new Table('table3');
     $c3 = new Column('col1');
     $c3->getDomain()->copy($this->platform->getDomainForType('INTEGER'));
     $t3->addColumn($c3);
     $d1->addTable($t3);
     $d2 = new Database();
     $t4 = new Table('table4');
     $c4 = new Column('col1');
     $c4->getDomain()->copy($this->platform->getDomainForType('INTEGER'));
     $t4->addColumn($c4);
     $d2->addTable($t4);
     $t5 = new Table('table5');
     $c5 = new Column('col1');
     $c5->getDomain()->copy($this->platform->getDomainForType('INTEGER'));
     $t5->addColumn($c5);
     $d2->addTable($t5);
     $t6 = new Table('table3');
     $c6 = new Column('col1');
     $c6->getDomain()->copy($this->platform->getDomainForType('INTEGER'));
     $t6->addColumn($c6);
     $d2->addTable($t6);
     $dc = new PropelDatabaseComparator();
     $dc->setFromDatabase($d1);
     $dc->setToDatabase($d2);
     $nbDiffs = $dc->compareTables();
     $databaseDiff = $dc->getDatabaseDiff();
     $this->assertEquals(2, $nbDiffs);
     $this->assertEquals(2, count($databaseDiff->getRenamedTables()));
     $this->assertEquals(array('table1' => 'table4', 'table2' => 'table5'), $databaseDiff->getRenamedTables());
     $this->assertEquals(array(), $databaseDiff->getAddedTables());
     $this->assertEquals(array(), $databaseDiff->getRemovedTables());
 }
Exemple #5
0
 /**
  * Main method builds all the targets for a typical propel project.
  */
 public function main()
 {
     // check to make sure task received all correct params
     $this->validate();
     $generatorConfig = $this->getGeneratorConfig();
     // loading model from database
     $this->log('Reading databases structure...');
     $connections = $generatorConfig->getBuildConnections();
     if (!$connections) {
         throw new Exception('You must define database connection settings in a buildtime-conf.xml file to use diff');
     }
     $totalNbTables = 0;
     $ad = new AppData();
     foreach ($connections as $name => $params) {
         $this->log(sprintf('Connecting to database "%s" using DSN "%s"', $name, $params['dsn']), Project::MSG_VERBOSE);
         $pdo = $generatorConfig->getBuildPDO($name);
         $database = new Database($name);
         $platform = $generatorConfig->getConfiguredPlatform($pdo);
         $database->setPlatform($platform);
         $database->setDefaultIdMethod(IDMethod::NATIVE);
         $parser = $generatorConfig->getConfiguredSchemaParser($pdo);
         $nbTables = $parser->parse($database, $this);
         $ad->addDatabase($database);
         $totalNbTables += $nbTables;
         $this->log(sprintf('%d tables imported from database "%s"', $nbTables, $name), Project::MSG_VERBOSE);
     }
     if ($totalNbTables) {
         $this->log(sprintf('%d tables imported from databases.', $totalNbTables));
     } else {
         $this->log('Database is empty');
     }
     // loading model from XML
     $this->packageObjectModel = true;
     $appDatasFromXml = $this->getDataModels();
     $appDataFromXml = array_pop($appDatasFromXml);
     // comparing models
     $this->log('Comparing models...');
     $manager = new PropelMigrationManager();
     $manager->setConnections($connections);
     $manager->setMigrationDir($this->getOutputDirectory());
     $migrationsUp = array();
     $migrationsDown = array();
     foreach ($ad->getDatabases() as $database) {
         $name = $database->getName();
         $this->log(sprintf('Comparing database "%s"', $name), Project::MSG_VERBOSE);
         if (!$appDataFromXml->hasDatabase($name)) {
             // FIXME: tables present in database but not in XML
             continue;
         }
         $databaseDiff = PropelDatabaseComparator::computeDiff($database, $appDataFromXml->getDatabase($name), $this->isCaseInsensitive());
         if (!$databaseDiff) {
             $this->log(sprintf('Same XML and database structures for datasource "%s" - no diff to generate', $name), Project::MSG_VERBOSE);
             continue;
         }
         $this->log(sprintf('Structure of database was modified in datasource "%s": %s', $name, $databaseDiff->getDescription()));
         $platform = $generatorConfig->getConfiguredPlatform(null, $name);
         $migrationsUp[$name] = $platform->getModifyDatabaseDDL($databaseDiff);
         $migrationsDown[$name] = $platform->getModifyDatabaseDDL($databaseDiff->getReverseDiff());
     }
     if (!$migrationsUp) {
         $this->log('Same XML and database structures for all datasource - no diff to generate');
         return;
     }
     $timestamp = time();
     $migrationFileName = $manager->getMigrationFileName($timestamp);
     $migrationClassBody = $manager->getMigrationClassBody($migrationsUp, $migrationsDown, $timestamp);
     $_f = new PhingFile($this->getOutputDirectory(), $migrationFileName);
     file_put_contents($_f->getAbsolutePath(), $migrationClassBody);
     $this->log(sprintf('"%s" file successfully created in %s', $_f->getName(), $_f->getParent()));
     if ($editorCmd = $this->getEditorCmd()) {
         $this->log(sprintf('Using "%s" as text editor', $editorCmd));
         shell_exec($editorCmd . ' ' . escapeshellarg($_f->getAbsolutePath()));
     } else {
         $this->log('  Please review the generated SQL statements, and add data migration code if necessary.');
         $this->log('  Once the migration class is valid, call the "migrate" task to execute it.');
     }
 }
 public function testCompareSeveralTableDifferences()
 {
     $d1 = new Database();
     $t1 = new Table('Foo_Table');
     $c1 = new Column('Foo');
     $c1->getDomain()->copy($this->platform->getDomainForType('DOUBLE'));
     $c1->getDomain()->replaceScale(2);
     $c1->getDomain()->replaceSize(3);
     $c1->setNotNull(true);
     $c1->getDomain()->setDefaultValue(new ColumnDefaultValue(123, ColumnDefaultValue::TYPE_VALUE));
     $t1->addColumn($c1);
     $d1->addTable($t1);
     $t2 = new Table('Bar');
     $c2 = new Column('Bar_Column');
     $c2->getDomain()->copy($this->platform->getDomainForType('DOUBLE'));
     $t2->addColumn($c2);
     $d1->addTable($t2);
     $t11 = new Table('Baz');
     $d1->addTable($t11);
     $d2 = new Database();
     $t3 = new Table('Foo_Table');
     $c3 = new Column('Foo1');
     $c3->getDomain()->copy($this->platform->getDomainForType('DOUBLE'));
     $c3->getDomain()->replaceScale(2);
     $c3->getDomain()->replaceSize(3);
     $c3->setNotNull(true);
     $c3->getDomain()->setDefaultValue(new ColumnDefaultValue(123, ColumnDefaultValue::TYPE_VALUE));
     $t3->addColumn($c3);
     $d2->addTable($t3);
     $t4 = new Table('Bar2');
     $c4 = new Column('Bar_Column');
     $c4->getDomain()->copy($this->platform->getDomainForType('DOUBLE'));
     $t4->addColumn($c4);
     $d2->addTable($t4);
     $t5 = new Table('Biz');
     $c5 = new Column('Biz_Column');
     $c5->getDomain()->copy($this->platform->getDomainForType('INTEGER'));
     $t5->addColumn($c5);
     $d2->addTable($t5);
     // Foo_Table was modified, Bar was renamed, Baz was removed, Biz was added
     $dc = new PropelDatabaseComparator();
     $dc->setFromDatabase($d1);
     $dc->setToDatabase($d2);
     $nbDiffs = $dc->compareTables();
     $databaseDiff = $dc->getDatabaseDiff();
     $this->assertEquals(4, $nbDiffs);
     $this->assertEquals(array('Bar' => 'Bar2'), $databaseDiff->getRenamedTables());
     $this->assertEquals(array('Biz' => $t5), $databaseDiff->getAddedTables());
     $this->assertEquals(array('Baz' => $t11), $databaseDiff->getRemovedTables());
     $tableDiff = PropelTableComparator::computeDiff($t1, $t3);
     $this->assertEquals(array('Foo_Table' => $tableDiff), $databaseDiff->getModifiedTables());
 }
 /**
  * @see sfTask
  */
 protected function execute($arguments = array(), $options = array())
 {
     $databaseManager = new sfDatabaseManager($this->configuration);
     $connections = $this->getConnections($databaseManager);
     //$connection = $databaseManager->getDatabase($options['connection'] ? $options['connection'] : null)->getConnection();
     $i = new afsDbInfo();
     $this->logSection('propel', 'Reading databases structure...');
     $ad = new AppData();
     $totalNbTables = 0;
     foreach ($connections as $name => $params) {
         $pdo = $databaseManager->getDatabase($name)->getConnection();
         $database = new Database($name);
         $platform = $this->getPlatform($databaseManager, $name);
         $database->setPlatform($platform);
         $database->setDefaultIdMethod(IDMethod::NATIVE);
         $parser = $this->getParser($databaseManager, $name, $pdo);
         //$parser->setMigrationTable($options['migration-table']);
         $parser->setPlatform($platform);
         $nbTables = $parser->parse($database);
         $ad->addDatabase($database);
         $totalNbTables += $nbTables;
         $this->logSection('propel', sprintf('  %d tables imported from database "%s"', $nbTables, $name), null, 'COMMENT');
     }
     if ($totalNbTables) {
         $this->logSection('propel', sprintf('%d tables imported from databases.', $totalNbTables));
     } else {
         $this->logSection('propel', 'Database is empty');
     }
     $this->logSection('propel', 'Loading XML schema files...');
     Phing::startup();
     // required to locate behavior classes...
     $this->schemaToXML(self::DO_NOT_CHECK_SCHEMA, 'generated-');
     $this->copyXmlSchemaFromPlugins('generated-');
     $appData = $this->getModels($databaseManager, true);
     $this->logSection('propel', sprintf('%d tables defined in the schema files.', $appData->countTables()));
     $this->cleanup(true);
     $this->logSection('sql-diff', 'Comparing databases and schemas...');
     $manager = new PropelMigrationManager();
     $manager->setConnections($connections);
     foreach ($ad->getDatabases() as $database) {
         $name = $database->getName();
         $filenameDiff = sfConfig::get('sf_data_dir') . "/sql/{$name}." . time() . ".diff.sql";
         $this->logSection('sql-diff', sprintf('  Comparing database "%s"', $name), null, 'COMMENT');
         if (!$appData->hasDatabase($name)) {
             // FIXME: tables present in database but not in XML
             continue;
         }
         $databaseDiff = PropelDatabaseComparator::computeDiff($database, $appData->getDatabase($name));
         if (!$databaseDiff) {
             //no diff
         }
         $this->logSection('sql-diff', sprintf('Structure of database was modified in datasource "%s": %s', $name, $databaseDiff->getDescription()));
         $platform = $this->getPlatform($databaseManager, $name);
         //up sql
         $upDiff = $platform->getModifyDatabaseDDL($databaseDiff);
         //down sql
         $downDiff = $platform->getModifyDatabaseDDL($databaseDiff->getReverseDiff());
         if ($databaseDiff) {
             $this->logSection('sql-diff', "Writing file {$filenameDiff}");
             afStudioUtil::writeFile($filenameDiff, $upDiff);
             if ($options['insert'] === true || $options['insert'] === 'true') {
                 $this->logSection('sql-diff', "Inserting sql diff");
                 $i->executeSql($upDiff, Propel::getConnection($name));
             }
             if ($options['build'] === true || $options['build'] === 'true') {
                 $this->logSection('sql-diff', 'Creating models from current schema');
                 $this->createTask('propel:build-model')->run();
                 $this->logSection('sql-diff', 'Creating forms from current schema');
                 $this->createTask('propel:build-forms')->run();
                 $this->logSection('sql-diff', 'Setting AppFlower project permissions');
                 $this->createTask('afs:fix-perms')->run();
                 $this->logSection('sql-diff', 'Creating AppFlower validator cache');
                 $this->createTask('appflower:validator-cache')->run(array('frontend', 'cache', 'yes'));
                 $this->logSection('sql-diff', 'Clearing Symfony cache');
                 $this->createTask('cc')->run();
             }
         }
     }
 }
    public function testGetModifyDatabaseWithBlockStorageDDL()
    {
        $schema1 = <<<EOF
<database name="test">
    <table name="foo1">
        <column name="id" primaryKey="true" type="INTEGER" autoIncrement="true" />
        <column name="blooopoo" type="INTEGER" />
    </table>
    <table name="foo2">
        <column name="id" primaryKey="true" type="INTEGER" autoIncrement="true" />
        <column name="bar" type="INTEGER" />
        <column name="baz" type="VARCHAR" size="12" required="true" />
    </table>
    <table name="foo3">
        <column name="id" primaryKey="true" type="INTEGER" autoIncrement="true" />
        <column name="yipee" type="INTEGER" />
    </table>
</database>
EOF;
        $schema2 = <<<EOF
<database name="test">
    <table name="foo2">
        <column name="id" primaryKey="true" type="INTEGER" autoIncrement="true" />
        <column name="bar1" type="INTEGER" />
        <column name="baz" type="VARCHAR" size="12" required="false" />
        <column name="baz3" type="CLOB" />
        <vendor type="oracle">
            <parameter name="PCTFree" value="20"/>
            <parameter name="InitTrans" value="4"/>
            <parameter name="MinExtents" value="1"/>
            <parameter name="MaxExtents" value="99"/>
            <parameter name="PCTIncrease" value="0"/>
            <parameter name="Tablespace" value="L_128K"/>
            <parameter name="PKPCTFree" value="20"/>
            <parameter name="PKInitTrans" value="4"/>
            <parameter name="PKMinExtents" value="1"/>
            <parameter name="PKMaxExtents" value="99"/>
            <parameter name="PKPCTIncrease" value="0"/>
            <parameter name="PKTablespace" value="IL_128K"/>
        </vendor>
    </table>
    <table name="foo4">
        <column name="id" primaryKey="true" type="INTEGER" autoIncrement="true" />
        <column name="yipee" type="INTEGER" />
        <vendor type="oracle">
            <parameter name="PCTFree" value="20"/>
            <parameter name="InitTrans" value="4"/>
            <parameter name="MinExtents" value="1"/>
            <parameter name="MaxExtents" value="99"/>
            <parameter name="PCTIncrease" value="0"/>
            <parameter name="Tablespace" value="L_128K"/>
            <parameter name="PKPCTFree" value="20"/>
            <parameter name="PKInitTrans" value="4"/>
            <parameter name="PKMinExtents" value="1"/>
            <parameter name="PKMaxExtents" value="99"/>
            <parameter name="PKPCTIncrease" value="0"/>
            <parameter name="PKTablespace" value="IL_128K"/>
        </vendor>
    </table>
    <table name="foo5">
        <column name="id" primaryKey="true" type="INTEGER" autoIncrement="true" />
        <column name="lkdjfsh" type="INTEGER" />
        <column name="dfgdsgf" type="CLOB" />
        <index name="lkdjfsh_IDX">
            <index-column name="lkdjfsh"/>
            <vendor type="oracle">
                <parameter name="PCTFree" value="20"/>
                <parameter name="InitTrans" value="4"/>
                <parameter name="MinExtents" value="1"/>
                <parameter name="MaxExtents" value="99"/>
                <parameter name="PCTIncrease" value="0"/>
                <parameter name="Tablespace" value="L_128K"/>
            </vendor>
        </index>
        <vendor type="oracle">
            <parameter name="PCTFree" value="20"/>
            <parameter name="InitTrans" value="4"/>
            <parameter name="MinExtents" value="1"/>
            <parameter name="MaxExtents" value="99"/>
            <parameter name="PCTIncrease" value="0"/>
            <parameter name="Tablespace" value="L_128K"/>
            <parameter name="PKPCTFree" value="20"/>
            <parameter name="PKInitTrans" value="4"/>
            <parameter name="PKMinExtents" value="1"/>
            <parameter name="PKMaxExtents" value="99"/>
            <parameter name="PKPCTIncrease" value="0"/>
            <parameter name="PKTablespace" value="IL_128K"/>
        </vendor>
    </table>
</database>
EOF;
        $d1 = $this->getDatabaseFromSchema($schema1);
        $d2 = $this->getDatabaseFromSchema($schema2);
        $databaseDiff = PropelDatabaseComparator::computeDiff($d1, $d2);
        $expected = "\nALTER SESSION SET NLS_DATE_FORMAT='YYYY-MM-DD';\nALTER SESSION SET NLS_TIMESTAMP_FORMAT='YYYY-MM-DD HH24:MI:SS';\n\nDROP TABLE foo1 CASCADE CONSTRAINTS;\n\nDROP SEQUENCE foo1_SEQ;\n\nALTER TABLE foo3 RENAME TO foo4;\n\nCREATE TABLE foo5\n(\n    id NUMBER NOT NULL,\n    lkdjfsh NUMBER,\n    dfgdsgf CLOB\n)\nPCTFREE 20\nINITRANS 4\nSTORAGE\n(\n    MINEXTENTS 1\n    MAXEXTENTS 99\n    PCTINCREASE 0\n)\nTABLESPACE L_128K;\n\nALTER TABLE foo5 ADD CONSTRAINT foo5_PK PRIMARY KEY (id)\nUSING INDEX\nPCTFREE 20\nINITRANS 4\nSTORAGE\n(\n    MINEXTENTS 1\n    MAXEXTENTS 99\n    PCTINCREASE 0\n)\nTABLESPACE IL_128K;\n\nCREATE SEQUENCE foo5_SEQ\n    INCREMENT BY 1 START WITH 1 NOMAXVALUE NOCYCLE NOCACHE ORDER;\n\nCREATE INDEX lkdjfsh_IDX ON foo5 (lkdjfsh)\nPCTFREE 20\nINITRANS 4\nSTORAGE\n(\n    MINEXTENTS 1\n    MAXEXTENTS 99\n    PCTINCREASE 0\n)\nTABLESPACE L_128K;\n\nALTER TABLE foo2 RENAME COLUMN bar TO bar1;\n\nALTER TABLE foo2 MODIFY\n(\n    baz NVARCHAR2(12)\n);\n\nALTER TABLE foo2 ADD\n(\n    baz3 CLOB\n);\n";
        // ignore tab/space indentation comparison
        $this->assertEquals($expected, str_replace("\t", '    ', $this->getPlatform()->getModifyDatabaseDDL($databaseDiff)));
    }
 /**
  * @see sfTask
  */
 protected function execute($arguments = array(), $options = array())
 {
     $databaseManager = new sfDatabaseManager($this->configuration);
     $connections = $this->getConnections($databaseManager);
     $this->logSection('propel', 'Reading databases structure...');
     $ad = new AppData();
     $totalNbTables = 0;
     foreach ($connections as $name => $params) {
         if ($options['verbose']) {
             $this->logSection('propel', sprintf('  Connecting to database "%s" using DSN "%s"', $name, $params['dsn']), null, 'COMMENT');
         }
         $pdo = $databaseManager->getDatabase($name)->getConnection();
         $database = new Database($name);
         $platform = $this->getPlatform($databaseManager, $name);
         $database->setPlatform($platform);
         $database->setDefaultIdMethod(IDMethod::NATIVE);
         $parser = $this->getParser($databaseManager, $name, $pdo);
         $parser->setMigrationTable($options['migration-table']);
         $parser->setPlatform($platform);
         $nbTables = $parser->parse($database);
         $ad->addDatabase($database);
         $totalNbTables += $nbTables;
         if ($options['verbose']) {
             $this->logSection('propel', sprintf('  %d tables imported from database "%s"', $nbTables, $name), null, 'COMMENT');
         }
     }
     if ($totalNbTables) {
         $this->logSection('propel', sprintf('%d tables imported from databases.', $totalNbTables));
     } else {
         $this->logSection('propel', 'Database is empty');
     }
     $this->logSection('propel', 'Loading XML schema files...');
     Phing::startup();
     // required to locate behavior classes...
     $this->schemaToXML(self::DO_NOT_CHECK_SCHEMA, 'generated-');
     $this->copyXmlSchemaFromPlugins('generated-');
     $appData = $this->getModels($databaseManager, $options['verbose']);
     $this->logSection('propel', sprintf('%d tables defined in the schema files.', $appData->countTables()));
     $this->cleanup($options['verbose']);
     $this->logSection('propel', 'Comparing databases and schemas...');
     $manager = new PropelMigrationManager();
     $manager->setConnections($connections);
     $migrationsUp = array();
     $migrationsDown = array();
     foreach ($ad->getDatabases() as $database) {
         $name = $database->getName();
         if ($options['verbose']) {
             $this->logSection('propel', sprintf('  Comparing database "%s"', $name), null, 'COMMENT');
         }
         if (!$appData->hasDatabase($name)) {
             // FIXME: tables present in database but not in XML
             continue;
         }
         $databaseDiff = PropelDatabaseComparator::computeDiff($database, $appData->getDatabase($name));
         if (!$databaseDiff) {
             if ($options['verbose']) {
                 $this->logSection('propel', sprintf('  Same XML and database structures for datasource "%s" - no diff to generate', $name), null, 'COMMENT');
             }
             continue;
         }
         $this->logSection('propel', sprintf('Structure of database was modified in datasource "%s": %s', $name, $databaseDiff->getDescription()));
         if ($options['verbose']) {
             $this->logBlock($databaseDiff, 'COMMENT');
         }
         $platform = $this->getPlatform($databaseManager, $name);
         $migrationsUp[$name] = $platform->getModifyDatabaseDDL($databaseDiff);
         $migrationsDown[$name] = $platform->getModifyDatabaseDDL($databaseDiff->getReverseDiff());
     }
     if (!$migrationsUp) {
         $this->logSection('propel', 'Same XML and database structures for all datasources - no diff to generate');
         return;
     }
     $timestamp = time();
     $migrationDirectory = sfConfig::get('sf_root_dir') . DIRECTORY_SEPARATOR . $options['migration-dir'];
     $migrationFileName = $manager->getMigrationFileName($timestamp);
     $migrationFilePath = $migrationDirectory . DIRECTORY_SEPARATOR . $migrationFileName;
     if ($options['ask-confirmation'] && !$this->askConfirmation(array(sprintf('Migration class will be generated in %s', $migrationFilePath), 'Are you sure you want to proceed? (Y/n)'), 'QUESTION_LARGE', true)) {
         $this->logSection('propel', 'Task aborted.');
         return 1;
     }
     $this->getFilesystem()->mkdirs($migrationDirectory);
     $migrationClassBody = $manager->getMigrationClassBody($migrationsUp, $migrationsDown, $timestamp);
     file_put_contents($migrationFilePath, $migrationClassBody);
     $this->logSection('propel', sprintf('"%s" file successfully created in %s', $migrationFileName, $migrationDirectory));
     if ($editorCmd = $options['editor-cmd']) {
         $this->logSection('propel', sprintf('Using "%s" as text editor', $editorCmd));
         shell_exec($editorCmd . ' ' . escapeshellarg($migrationFilePath));
     } else {
         $this->logSection('propel', '  Please review the generated SQL statements, and add data migration code if necessary.');
         $this->logSection('propel', '  Once the migration class is valid, call the "propel:migrate" task to execute it.');
     }
 }
    public function providerForTestGetModifyTableForeignKeysSkipSql4DDL()
    {
        $schema1 = <<<EOF
<database name="test">
    <table name="test">
        <column name="test" type="INTEGER" primaryKey="true" autoIncrement="true" required="true" />
        <column name="ref_test" type="INTEGER"/>
        <foreign-key foreignTable="test2" onDelete="CASCADE" onUpdate="CASCADE" skipSql="true">
            <reference local="ref_test" foreign="test" />
        </foreign-key>
    </table>
    <table name="test2">
        <column name="test" type="integer" primaryKey="true" />
    </table>
</database>
EOF;
        $schema2 = <<<EOF
<database name="test">
  <table name="test">
    <column name="test" type="INTEGER" primaryKey="true" autoIncrement="true" required="true" />
    <column name="ref_test" type="INTEGER"/>
  </table>
  <table name="test2">
    <column name="test" type="integer" primaryKey="true" />
  </table>
</database>
EOF;
        $d1 = $this->getDatabaseFromSchema($schema1);
        $d2 = $this->getDatabaseFromSchema($schema2);
        $diff = PropelDatabaseComparator::computeDiff($d2, $d1);
        return array(array($diff));
    }
    private function checkDeletedFk()
    {
        $this->readDatabase();
        $diff = PropelDatabaseComparator::computeDiff($this->database, $this->updatedBuilder->getDatabase());
        $sql = $this->database->getPlatform()->getModifyDatabaseDDL($diff);
        $expected = '
# This is a fix for InnoDB in MySQL >= 4.1.x
# It "suspends judgement" for fkey relationships until are tables are set.
SET FOREIGN_KEY_CHECKS = 0;

DROP TABLE IF EXISTS `book`;

DROP TABLE IF EXISTS `foo`;

# This restores the fkey checks, after having unset them earlier
SET FOREIGN_KEY_CHECKS = 1;
';
        $this->assertEquals($expected, $sql);
    }
 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);
     }
 }