From ac4c33c371805b08b2757b6dd3ff1322e3512541 Mon Sep 17 00:00:00 2001 From: beberlei Date: Sun, 7 Feb 2010 12:36:30 +0000 Subject: [PATCH] [2.0] DDC-214, DDC-303, DDC-304 - Fix several errors with Schema Inference from Database and Metadata and Comparisons, aswell as related bugs in DatabaseDriver. DDC-305 - Abstracted TRUNCATE command for all platforms. --- .../DBAL/Platforms/AbstractPlatform.php | 21 ++++- lib/Doctrine/DBAL/Platforms/MsSqlPlatform.php | 8 ++ lib/Doctrine/DBAL/Platforms/MySqlPlatform.php | 8 +- .../DBAL/Platforms/OraclePlatform.php | 59 +++++++++++--- .../DBAL/Platforms/PostgreSqlPlatform.php | 8 ++ .../DBAL/Platforms/SqlitePlatform.php | 8 ++ .../DBAL/Schema/AbstractSchemaManager.php | 20 +++-- lib/Doctrine/DBAL/Schema/Comparator.php | 4 +- .../DBAL/Schema/MySqlSchemaManager.php | 12 ++- .../DBAL/Schema/OracleSchemaManager.php | 9 ++- lib/Doctrine/DBAL/Schema/Table.php | 26 +++++- .../Visitor/CreateSchemaSqlCollector.php | 2 +- .../Schema/Visitor/DropSchemaSqlCollector.php | 2 +- .../DBAL/Schema/Visitor/FixSchema.php | 9 ++- lib/Doctrine/DBAL/Schema/Visitor/Visitor.php | 2 +- .../ORM/Mapping/Driver/DatabaseDriver.php | 2 +- lib/Doctrine/ORM/Tools/SchemaTool.php | 25 ++++-- .../ORM/Functional/DatabaseDriverTest.php | 6 +- .../ORM/Functional/Ticket/DDC214Test.php | 79 +++++++++++++++++++ 19 files changed, 267 insertions(+), 43 deletions(-) create mode 100644 tests/Doctrine/Tests/ORM/Functional/Ticket/DDC214Test.php diff --git a/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php b/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php index 370566660..8a5e7b968 100644 --- a/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php @@ -810,12 +810,12 @@ abstract class AbstractPlatform $sql = array(); if ($this->supportsForeignKeyConstraints()) { - foreach ($diff->addedForeignKeys AS $foreignKey) { - $sql[] = $this->getCreateForeignKeySql($foreignKey, $tableName); - } foreach ($diff->removedForeignKeys AS $foreignKey) { $sql[] = $this->getDropForeignKeySql($foreignKey, $tableName); } + foreach ($diff->addedForeignKeys AS $foreignKey) { + $sql[] = $this->getCreateForeignKeySql($foreignKey, $tableName); + } foreach ($diff->changedForeignKeys AS $foreignKey) { $sql[] = $this->getDropForeignKeySql($foreignKey, $tableName); $sql[] = $this->getCreateForeignKeySql($foreignKey, $tableName); @@ -1831,4 +1831,19 @@ abstract class AbstractPlatform { return 'INSERT INTO ' . $tableName . ' (' . $identifierColumnName . ') VALUES (null)'; } + + /** + * Generate a Truncate Table SQL statement for a given table. + * + * Cascade is not supported on many platforms but would optionally cascade the truncate by + * following the foreign keys. + * + * @param string $tableName + * @param bool $cascade + * @return string + */ + public function getTruncateTableSql($tableName, $cascade = false) + { + return 'TRUNCATE '.$tableName; + } } diff --git a/lib/Doctrine/DBAL/Platforms/MsSqlPlatform.php b/lib/Doctrine/DBAL/Platforms/MsSqlPlatform.php index 470d1c11b..4ed49c782 100644 --- a/lib/Doctrine/DBAL/Platforms/MsSqlPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/MsSqlPlatform.php @@ -505,4 +505,12 @@ class MsSqlPlatform extends AbstractPlatform { return 'INSERT INTO ' . $quotedTableName . ' DEFAULT VALUES'; } + + /** + * @inheritdoc + */ + public function getTruncateTableSql($tableName, $cascade = false) + { + return 'TRUNCATE TABLE '.$tableName; + } } diff --git a/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php b/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php index ed8b59601..5be107264 100644 --- a/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php @@ -203,8 +203,12 @@ class MySqlPlatform extends AbstractPlatform public function getListTableForeignKeysSql($table, $database = null) { - $sql = "SELECT `CONSTRAINT_NAME`, `COLUMN_NAME`, `REFERENCED_TABLE_NAME`, ". - "`REFERENCED_COLUMN_NAME` FROM information_schema.key_column_usage WHERE table_name = '" . $table . "'"; + $sql = "SELECT DISTINCT k.`CONSTRAINT_NAME`, k.`COLUMN_NAME`, k.`REFERENCED_TABLE_NAME`, ". + "k.`REFERENCED_COLUMN_NAME` /*!50116 , c.update_rule, c.delete_rule */ ". + "FROM information_schema.key_column_usage k /*!50116 ". + "INNER JOIN information_schema.referential_constraints c ON k.`CONSTRAINT_NAME` = c.constraint_name AND ". + " c.constraint_name = k.constraint_name AND ". + " c.table_name = k.table_name */ WHERE k.table_name = '$table'"; if ( ! is_null($database)) { $sql .= " AND table_schema = '$database'"; diff --git a/lib/Doctrine/DBAL/Platforms/OraclePlatform.php b/lib/Doctrine/DBAL/Platforms/OraclePlatform.php index 1453d30eb..78bd48df7 100644 --- a/lib/Doctrine/DBAL/Platforms/OraclePlatform.php +++ b/lib/Doctrine/DBAL/Platforms/OraclePlatform.php @@ -418,18 +418,27 @@ END;'; { $table = strtoupper($table); - return "SELECT rel.constraint_name, rel.position, col.column_name AS local_column, ". - " rel.table_name, rel.column_name AS foreign_column, cc.delete_rule ". - "FROM (user_tab_columns col ". - "JOIN user_cons_columns con ". - " ON col.table_name = con.table_name ". - " AND col.column_name = con.column_name ". - "JOIN user_constraints cc ". - " ON con.constraint_name = cc.constraint_name ". - "JOIN user_cons_columns rel ". - " ON cc.r_constraint_name = rel.constraint_name ". - " AND con.position = rel.position) ". - "WHERE cc.constraint_type = 'R' AND col.table_name = '".$table."'"; + return "SELECT alc.constraint_name, + alc.DELETE_RULE, + alc.search_condition, + cols.column_name \"local_column\", + cols.position, + r_alc.table_name \"references_table\", + r_cols.column_name \"foreign_column\" + FROM all_cons_columns cols +LEFT JOIN all_constraints alc + ON alc.constraint_name = cols.constraint_name + AND alc.owner = cols.owner +LEFT JOIN all_constraints r_alc + ON alc.r_constraint_name = r_alc.constraint_name + AND alc.r_owner = r_alc.owner +LEFT JOIN all_cons_columns r_cols + ON r_alc.constraint_name = r_cols.constraint_name + AND r_alc.owner = r_cols.owner + AND cols.position = r_cols.position + WHERE alc.constraint_name = cols.constraint_name + AND alc.constraint_type = 'R' + AND alc.table_name = '".$table."'"; } public function getListTableConstraintsSql($table) @@ -458,6 +467,24 @@ END;'; return 'DROP SEQUENCE ' . $sequence; } + /** + * @param ForeignKeyConstraint|string $foreignKey + * @param Table|string $table + * @return string + */ + public function getDropForeignKeySql($foreignKey, $table) + { + if ($foreignKey instanceof \Doctrine\DBAL\Schema\ForeignKeyConstraint) { + $foreignKey = $foreignKey->getName(); + } + + if ($table instanceof \Doctrine\DBAL\Schema\Table) { + $table = $table->getName(); + } + + return 'ALTER TABLE ' . $table . ' DROP CONSTRAINT ' . $foreignKey; + } + public function getDropDatabaseSql($database) { return 'DROP USER ' . $database . ' CASCADE'; @@ -627,4 +654,12 @@ END;'; { return false; } + + /** + * @inheritdoc + */ + public function getTruncateTableSql($tableName, $cascade = false) + { + return 'TRUNCATE TABLE '.$tableName; + } } diff --git a/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php b/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php index 0c8528c5a..bfd6ae362 100644 --- a/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php @@ -784,4 +784,12 @@ class PostgreSqlPlatform extends AbstractPlatform { return 'INSERT INTO ' . $quotedTableName . ' (' . $quotedIdentifierColumnName . ') VALUES (DEFAULT)'; } + + /** + * @inheritdoc + */ + public function getTruncateTableSql($tableName, $cascade = false) + { + return 'TRUNCATE '.$tableName.' '.($cascade)?'CASCADE':''; + } } diff --git a/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php b/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php index a5c35fb97..2c8b15ae3 100644 --- a/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php +++ b/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php @@ -456,4 +456,12 @@ class SqlitePlatform extends AbstractPlatform { return 'sqlite'; } + + /** + * @inheritdoc + */ + public function getTruncateTableSql($tableName, $cascade = false) + { + return 'DELETE FROM '.$tableName; + } } diff --git a/lib/Doctrine/DBAL/Schema/AbstractSchemaManager.php b/lib/Doctrine/DBAL/Schema/AbstractSchemaManager.php index b91b23b83..e6dbbab27 100644 --- a/lib/Doctrine/DBAL/Schema/AbstractSchemaManager.php +++ b/lib/Doctrine/DBAL/Schema/AbstractSchemaManager.php @@ -238,6 +238,20 @@ abstract class AbstractSchemaManager return $this->_getPortableTableIndexesList($tableIndexes, $table); } + /** + * Return a list of all tables in the current database + * + * @return array + */ + public function listTableNames() + { + $sql = $this->_platform->getListTablesSql(); + + $tables = $this->_conn->fetchAll($sql); + + return $this->_getPortableTablesList($tables); + } + /** * List the tables for this connection * @@ -245,13 +259,9 @@ abstract class AbstractSchemaManager */ public function listTables() { - $sql = $this->_platform->getListTablesSql(); + $tableNames = $this->listTableNames(); - $tables = $this->_conn->fetchAll($sql); - - $tableNames = $this->_getPortableTablesList($tables); $tables = array(); - foreach ($tableNames AS $tableName) { $columns = $this->listTableColumns($tableName); $foreignKeys = array(); diff --git a/lib/Doctrine/DBAL/Schema/Comparator.php b/lib/Doctrine/DBAL/Schema/Comparator.php index 21aa43ad8..b60b97e75 100644 --- a/lib/Doctrine/DBAL/Schema/Comparator.php +++ b/lib/Doctrine/DBAL/Schema/Comparator.php @@ -272,11 +272,11 @@ class Comparator */ public function diffForeignKey(ForeignKeyConstraint $key1, ForeignKeyConstraint $key2) { - if ($key1->getLocalColumns() != $key2->getLocalColumns()) { + if (array_map('strtolower', $key1->getLocalColumns()) != array_map('strtolower', $key2->getLocalColumns())) { return true; } - if ($key1->getForeignColumns() != $key2->getForeignColumns()) { + if (array_map('strtolower', $key1->getForeignColumns()) != array_map('strtolower', $key2->getForeignColumns())) { return true; } diff --git a/lib/Doctrine/DBAL/Schema/MySqlSchemaManager.php b/lib/Doctrine/DBAL/Schema/MySqlSchemaManager.php index e52cd1260..ac60c0c1d 100644 --- a/lib/Doctrine/DBAL/Schema/MySqlSchemaManager.php +++ b/lib/Doctrine/DBAL/Schema/MySqlSchemaManager.php @@ -265,13 +265,23 @@ class MySqlSchemaManager extends AbstractSchemaManager public function _getPortableTableForeignKeyDefinition($tableForeignKey) { $tableForeignKey = array_change_key_case($tableForeignKey, CASE_LOWER); + + if ($tableForeignKey['delete_rule'] == "RESTRICT") { + $tableForeignKey['delete_rule'] = null; + } + if ($tableForeignKey['update_rule'] == "RESTRICT") { + $tableForeignKey['update_rule'] = null; + } return new ForeignKeyConstraint( (array)$tableForeignKey['column_name'], $tableForeignKey['referenced_table_name'], (array)$tableForeignKey['referenced_column_name'], $tableForeignKey['constraint_name'], - array() + array( + 'onUpdate' => $tableForeignKey['update_rule'], + 'onDelete' => $tableForeignKey['delete_rule'], + ) ); } } \ No newline at end of file diff --git a/lib/Doctrine/DBAL/Schema/OracleSchemaManager.php b/lib/Doctrine/DBAL/Schema/OracleSchemaManager.php index f5d0dca9c..7c70ea938 100644 --- a/lib/Doctrine/DBAL/Schema/OracleSchemaManager.php +++ b/lib/Doctrine/DBAL/Schema/OracleSchemaManager.php @@ -22,11 +22,12 @@ namespace Doctrine\DBAL\Schema; /** - * xxx + * Oracle Schema Manager * * @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @author Konsta Vesterinen * @author Lukas Smith (PEAR MDB2 library) + * @author Benjamin Eberlei * @version $Revision$ * @since 2.0 */ @@ -198,11 +199,15 @@ class OracleSchemaManager extends AbstractSchemaManager foreach ($tableForeignKeys as $key => $value) { $value = \array_change_key_case($value, CASE_LOWER); if (!isset($list[$value['constraint_name']])) { + if ($value['delete_rule'] == "NO ACTION") { + $value['delete_rule'] = null; + } + $list[$value['constraint_name']] = array( 'name' => $value['constraint_name'], 'local' => array(), 'foreign' => array(), - 'foreignTable' => $value['table_name'], + 'foreignTable' => $value['references_table'], 'onDelete' => $value['delete_rule'], ); } diff --git a/lib/Doctrine/DBAL/Schema/Table.php b/lib/Doctrine/DBAL/Schema/Table.php index 44edc9cad..c6e7eb5ca 100644 --- a/lib/Doctrine/DBAL/Schema/Table.php +++ b/lib/Doctrine/DBAL/Schema/Table.php @@ -201,6 +201,30 @@ class Table extends AbstractAsset return $this->_createIndex($columnNames, $indexName, true, false); } + /** + * Check if an index begins in the order of the given columns. + * + * @param array $columnsNames + * @return bool + */ + public function columnsAreIndexed(array $columnsNames) + { + foreach ($this->getIndexes() AS $index) { + $indexColumns = $index->getColumns(); + $areIndexed = true; + for ($i = 0; $i < count($columnsNames); $i++) { + if ($columnsNames[$i] != $indexColumns[$i]) { + $areIndexed = false; + } + } + + if ($areIndexed) { + return true; + } + } + return false; + } + /** * * @param array $columnNames @@ -585,7 +609,7 @@ class Table extends AbstractAsset $visitor->acceptTable($this); foreach ($this->getColumns() AS $column) { - $visitor->acceptColunn($this, $column); + $visitor->acceptColumn($this, $column); } foreach ($this->getIndexes() AS $index) { diff --git a/lib/Doctrine/DBAL/Schema/Visitor/CreateSchemaSqlCollector.php b/lib/Doctrine/DBAL/Schema/Visitor/CreateSchemaSqlCollector.php index 2ad288a2d..94804ef5e 100644 --- a/lib/Doctrine/DBAL/Schema/Visitor/CreateSchemaSqlCollector.php +++ b/lib/Doctrine/DBAL/Schema/Visitor/CreateSchemaSqlCollector.php @@ -81,7 +81,7 @@ class CreateSchemaSqlCollector implements Visitor ); } - public function acceptColunn(Table $table, Column $column) + public function acceptColumn(Table $table, Column $column) { } diff --git a/lib/Doctrine/DBAL/Schema/Visitor/DropSchemaSqlCollector.php b/lib/Doctrine/DBAL/Schema/Visitor/DropSchemaSqlCollector.php index c2809cd12..013d6fe9e 100644 --- a/lib/Doctrine/DBAL/Schema/Visitor/DropSchemaSqlCollector.php +++ b/lib/Doctrine/DBAL/Schema/Visitor/DropSchemaSqlCollector.php @@ -89,7 +89,7 @@ class DropSchemaSqlCollector implements Visitor /** * @param Column $column */ - public function acceptColunn(Table $table, Column $column) + public function acceptColumn(Table $table, Column $column) { } diff --git a/lib/Doctrine/DBAL/Schema/Visitor/FixSchema.php b/lib/Doctrine/DBAL/Schema/Visitor/FixSchema.php index 4e3e0458b..1a13a6e27 100644 --- a/lib/Doctrine/DBAL/Schema/Visitor/FixSchema.php +++ b/lib/Doctrine/DBAL/Schema/Visitor/FixSchema.php @@ -42,7 +42,7 @@ class FixSchema implements Visitor /** * @param Column $column */ - public function acceptColunn(Table $table, Column $column) + public function acceptColumn(Table $table, Column $column) { } @@ -54,7 +54,12 @@ class FixSchema implements Visitor public function acceptForeignKey(Table $localTable, ForeignKeyConstraint $fkConstraint) { if ($this->_addExplicitIndexForForeignKey) { - $localTable->addIndex($fkConstraint->getColumns()); + $columns = $fkConstraint->getColumns(); + if ($localTable->columnsAreIndexed($columns)) { + return; + } + + $localTable->addIndex($columns); } } diff --git a/lib/Doctrine/DBAL/Schema/Visitor/Visitor.php b/lib/Doctrine/DBAL/Schema/Visitor/Visitor.php index b0a732f6a..2dad80deb 100644 --- a/lib/Doctrine/DBAL/Schema/Visitor/Visitor.php +++ b/lib/Doctrine/DBAL/Schema/Visitor/Visitor.php @@ -54,7 +54,7 @@ interface Visitor /** * @param Column $column */ - public function acceptColunn(Table $table, Column $column); + public function acceptColumn(Table $table, Column $column); /** * @param Table $localTable diff --git a/lib/Doctrine/ORM/Mapping/Driver/DatabaseDriver.php b/lib/Doctrine/ORM/Mapping/Driver/DatabaseDriver.php index 464b14638..5b237e2c0 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/DatabaseDriver.php +++ b/lib/Doctrine/ORM/Mapping/Driver/DatabaseDriver.php @@ -90,7 +90,7 @@ class DatabaseDriver implements Driver $fieldMapping['id'] = true; } - $fieldMapping['fieldName'] = Inflector::camelize($column->getName()); + $fieldMapping['fieldName'] = Inflector::camelize(strtolower($column->getName())); $fieldMapping['columnName'] = $column->getName(); $fieldMapping['type'] = strtolower((string) $column->getType()); diff --git a/lib/Doctrine/ORM/Tools/SchemaTool.php b/lib/Doctrine/ORM/Tools/SchemaTool.php index d9f606c4a..91c5a12ff 100644 --- a/lib/Doctrine/ORM/Tools/SchemaTool.php +++ b/lib/Doctrine/ORM/Tools/SchemaTool.php @@ -109,8 +109,12 @@ class SchemaTool { $processedClasses = array(); // Reminder for processed classes, used for hierarchies + $metadataSchemaConfig = new \Doctrine\DBAL\Schema\SchemaConfig(); + $metadataSchemaConfig->setExplicitForeignKeyIndexes(false); + $metadataSchemaConfig->setMaxIdentifierLength(63); + $sm = $this->_em->getConnection()->getSchemaManager(); - $schema = new \Doctrine\DBAL\Schema\Schema(array(), array(), $sm->createSchemaConfig()); + $schema = new \Doctrine\DBAL\Schema\Schema(array(), array(), $metadataSchemaConfig); foreach ($classes as $class) { if (isset($processedClasses[$class->name]) || $class->isMappedSuperclass) { @@ -235,6 +239,11 @@ class SchemaTool { $discrColumn = $class->discriminatorColumn; + if (!isset($discrColumn['type']) || (strtolower($discrColumn['type']) == 'string' && $discrColumn['length'] === null)) { + $discrColumn['type'] = 'string'; + $discrColumn['length'] = 255; + } + $table->createColumn( $class->getQuotedDiscriminatorColumnName($this->_platform), $discrColumn['type'], @@ -329,11 +338,8 @@ class SchemaTool * This includes the SQL for foreign key constraints and join tables. * * @param ClassMetadata $class - * @param array $sql The sequence of SQL statements where any new statements should be appended. - * @param array $columns The list of columns in the class's primary table where any additional - * columns required by relations should be appended. - * @param array $constraints The constraints of the table where any additional constraints - * required by relations should be appended. + * @param \Doctrine\DBAL\Schema\Table $table + * @param \Doctrine\DBAL\Schema\Schema $schema * @return void */ private function _gatherRelationsSql($class, $table, $schema) @@ -344,10 +350,10 @@ class SchemaTool } $foreignClass = $this->_em->getClassMetadata($mapping->targetEntityName); - + if ($mapping->isOneToOne() && $mapping->isOwningSide) { $primaryKeyColumns = $uniqueConstraints = array(); // unnecessary for this relation-type - + $this->_gatherRelationJoinColumns($mapping->getJoinColumns(), $table, $foreignClass, $mapping, $primaryKeyColumns, $uniqueConstraints); } else if ($mapping->isOneToMany() && $mapping->isOwningSide) { //... create join table, one-many through join table supported later @@ -423,6 +429,9 @@ class SchemaTool $columnDef = $fieldMapping['columnDefinition']; } $columnOptions = array('notnull' => false, 'columnDefinition' => $columnDef); + if (isset($joinColumn['nullable'])) { + $columnOptions['notnull'] = !$joinColumn['nullable']; + } $theJoinTable->createColumn( $columnName, $class->getTypeOfColumn($joinColumn['referencedColumnName']), $columnOptions diff --git a/tests/Doctrine/Tests/ORM/Functional/DatabaseDriverTest.php b/tests/Doctrine/Tests/ORM/Functional/DatabaseDriverTest.php index 02d13c7ac..3368d5abe 100644 --- a/tests/Doctrine/Tests/ORM/Functional/DatabaseDriverTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/DatabaseDriverTest.php @@ -22,6 +22,10 @@ class DatabaseDriverTest extends \Doctrine\Tests\OrmFunctionalTestCase public function testCreateSimpleYamlFromDatabase() { + if (!$this->_em->getConnection()->getDatabasePlatform()->supportsForeignKeyConstraints()) { + $this->markTestSkipped('Platform does not support foreign keys.'); + } + $table = new \Doctrine\DBAL\Schema\Table("dbdriver_foo"); $table->createColumn('id', 'integer'); $table->setPrimaryKey(array('id')); @@ -92,7 +96,7 @@ class DatabaseDriverTest extends \Doctrine\Tests\OrmFunctionalTestCase $output = false; foreach ($metadatas AS $metadata) { - if ($metadata->name == $className) { + if (strtolower($metadata->name) == strtolower($className)) { return $metadata; } } diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC214Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC214Test.php new file mode 100644 index 000000000..7f3df9b15 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC214Test.php @@ -0,0 +1,79 @@ +_em->getConnection(); + + if (strpos($conn->getDriver()->getName(), "sqlite") !== false) { + $this->markTestSkipped('SQLite does not support ALTER TABLE statements.'); + } + } + + /** + * @group DDC-214 + */ + public function testCmsAddressModel() + { + $classes = array( + 'Doctrine\Tests\Models\CMS\CmsUser', + 'Doctrine\Tests\Models\CMS\CmsPhonenumber', + 'Doctrine\Tests\Models\CMS\CmsAddress', + 'Doctrine\Tests\Models\CMS\CmsGroup', + 'Doctrine\Tests\Models\CMS\CmsArticle' + ); + + $this->assertCreatedSchemaNeedsNoUpdates($classes); + } + + /** + * @group DDC-214 + */ + public function testCompanyModel() + { + $classes = array( + 'Doctrine\Tests\Models\Company\CompanyPerson', + 'Doctrine\Tests\Models\Company\CompanyEmployee', + 'Doctrine\Tests\Models\Company\CompanyManager', + 'Doctrine\Tests\Models\Company\CompanyOrganization', + 'Doctrine\Tests\Models\Company\CompanyEvent', + 'Doctrine\Tests\Models\Company\CompanyAuction', + 'Doctrine\Tests\Models\Company\CompanyRaffle', + 'Doctrine\Tests\Models\Company\CompanyCar' + ); + + $this->assertCreatedSchemaNeedsNoUpdates($classes); + } + + public function assertCreatedSchemaNeedsNoUpdates($classes) + { + $classMetadata = array(); + foreach ($classes AS $class) { + $classMetadata[] = $this->_em->getClassMetadata($class); + } + + $schemaTool = new Tools\SchemaTool($this->_em); + $schemaTool->dropSchema($classMetadata); + $schemaTool->createSchema($classMetadata); + + $sm = $this->_em->getConnection()->getSchemaManager(); + + $fromSchema = $sm->createSchema(); + $toSchema = $schemaTool->getSchemaFromMetadata($classMetadata); + + $comparator = new \Doctrine\DBAL\Schema\Comparator(); + $schemaDiff = $comparator->compare($fromSchema, $toSchema); + + $sql = $schemaDiff->toSql($this->_em->getConnection()->getDatabasePlatform()); + $this->assertEquals(0, count($sql)); + } +} \ No newline at end of file