public function testCompareCaseInsensitive() { $d1 = new Database(); $t1 = new Table('Foo'); $d1->addTable($t1); $d2 = new Database(); $t2 = new Table('fOO'); $d2->addTable($t2); $this->assertFalse(PropelDatabaseComparator::computeDiff($d1, $d2, true)); }
public function providerForTestGetModifyTableForeignKeysSkipSql4DDL() { $schema1 = <<<EOF <database name="test"> \t<table name="test"> \t\t<column name="test" type="INTEGER" primaryKey="true" autoIncrement="true" required="true" /> \t\t<column name="ref_test" type="INTEGER"/> \t\t<foreign-key foreignTable="test2" onDelete="CASCADE" onUpdate="CASCADE" skipSql="true"> \t\t <reference local="ref_test" foreign="test" /> \t </foreign-key> \t</table> \t<table name="test2"> \t\t<column name="test" type="integer" primaryKey="true" /> \t</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)); }
/** * 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); if (!$platform->supportsMigrations()) { $this->log(sprintf('Skipping database "%s" since vendor "%s" does not support migrations', $name, $platform->getDatabaseType())); continue; } $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 found in database "%s"', $nbTables, $name), Project::MSG_VERBOSE); } if ($totalNbTables) { $this->log(sprintf('%d tables found in all databases.', $totalNbTables)); } else { $this->log('No table found in all databases'); } // 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 testGetModifyDatabaseWithBlockStorageDDL() { $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="CLOB" /> \t\t<vendor type="oracle"> \t\t\t<parameter name="PCTFree" value="20"/> \t\t\t<parameter name="InitTrans" value="4"/> \t\t\t<parameter name="MinExtents" value="1"/> \t\t\t<parameter name="MaxExtents" value="99"/> \t\t\t<parameter name="PCTIncrease" value="0"/> \t\t\t<parameter name="Tablespace" value="L_128K"/> \t\t\t<parameter name="PKPCTFree" value="20"/> \t\t\t<parameter name="PKInitTrans" value="4"/> \t\t\t<parameter name="PKMinExtents" value="1"/> \t\t\t<parameter name="PKMaxExtents" value="99"/> \t\t\t<parameter name="PKPCTIncrease" value="0"/> \t\t\t<parameter name="PKTablespace" value="IL_128K"/> \t\t</vendor> \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\t<vendor type="oracle"> \t\t\t<parameter name="PCTFree" value="20"/> \t\t\t<parameter name="InitTrans" value="4"/> \t\t\t<parameter name="MinExtents" value="1"/> \t\t\t<parameter name="MaxExtents" value="99"/> \t\t\t<parameter name="PCTIncrease" value="0"/> \t\t\t<parameter name="Tablespace" value="L_128K"/> \t\t\t<parameter name="PKPCTFree" value="20"/> \t\t\t<parameter name="PKInitTrans" value="4"/> \t\t\t<parameter name="PKMinExtents" value="1"/> \t\t\t<parameter name="PKMaxExtents" value="99"/> \t\t\t<parameter name="PKPCTIncrease" value="0"/> \t\t\t<parameter name="PKTablespace" value="IL_128K"/> \t\t</vendor> \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="CLOB" /> \t\t<index name="lkdjfsh_IDX"> \t\t\t<index-column name="lkdjfsh"/> \t\t\t<vendor type="oracle"> \t\t\t\t<parameter name="PCTFree" value="20"/> \t\t\t\t<parameter name="InitTrans" value="4"/> \t\t\t\t<parameter name="MinExtents" value="1"/> \t\t\t\t<parameter name="MaxExtents" value="99"/> \t\t\t\t<parameter name="PCTIncrease" value="0"/> \t\t\t\t<parameter name="Tablespace" value="L_128K"/> \t\t\t</vendor> \t\t</index> \t\t<vendor type="oracle"> \t\t\t<parameter name="PCTFree" value="20"/> \t\t\t<parameter name="InitTrans" value="4"/> \t\t\t<parameter name="MinExtents" value="1"/> \t\t\t<parameter name="MaxExtents" value="99"/> \t\t\t<parameter name="PCTIncrease" value="0"/> \t\t\t<parameter name="Tablespace" value="L_128K"/> \t\t\t<parameter name="PKPCTFree" value="20"/> \t\t\t<parameter name="PKInitTrans" value="4"/> \t\t\t<parameter name="PKMinExtents" value="1"/> \t\t\t<parameter name="PKMaxExtents" value="99"/> \t\t\t<parameter name="PKPCTIncrease" value="0"/> \t\t\t<parameter name="PKTablespace" value="IL_128K"/> \t\t</vendor> \t</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\tid NUMBER NOT NULL,\n\tlkdjfsh NUMBER,\n\tdfgdsgf CLOB\n)\nPCTFREE 20\nINITRANS 4\nSTORAGE\n(\n\tMINEXTENTS 1\n\tMAXEXTENTS 99\n\tPCTINCREASE 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\tMINEXTENTS 1\n\tMAXEXTENTS 99\n\tPCTINCREASE 0\n)\nTABLESPACE IL_128K;\n\nCREATE SEQUENCE foo5_SEQ\n\tINCREMENT BY 1 START WITH 1 NOMAXVALUE NOCYCLE NOCACHE ORDER;\n\nCREATE INDEX lkdjfsh_IDX ON foo5 (lkdjfsh)\nPCTFREE 20\nINITRANS 4\nSTORAGE\n(\n\tMINEXTENTS 1\n\tMAXEXTENTS 99\n\tPCTINCREASE 0\n)\nTABLESPACE L_128K;\n\nALTER TABLE foo2 RENAME COLUMN bar TO bar1;\n\nALTER TABLE foo2 MODIFY\n(\n\tbaz NVARCHAR2(12)\n);\n\nALTER TABLE foo2 ADD\n(\n\tbaz3 CLOB\n);\n"; $this->assertEquals($expected, $this->getPlatform()->getModifyDatabaseDDL($databaseDiff)); }