Browse files

[2.0] Work on SchemaTool and DBAL.

  • Loading branch information...
1 parent 0612e6b commit b1d34fca1c0ea1aeb30c7dbf9fa0a934acd916e8 romanb committed Aug 21, 2009
View
70 doctrine-mapping.xsd
@@ -8,15 +8,15 @@
<xs:annotation>
<xs:documentation><![CDATA[
This is the XML Schema for the object/relational
- mapping file used by Doctrine.
+ mapping file used by the Doctrine ORM.
]]></xs:documentation>
</xs:annotation>
<xs:element name="doctrine-mapping">
<xs:complexType>
<xs:sequence>
- <xs:element name="mapped-superclass" type="orm:mapped-superclass" minOccurs="0" />
- <xs:element name="entity" type="orm:entity" minOccurs="0" />
+ <xs:element name="mapped-superclass" type="orm:mapped-superclass" minOccurs="0" maxOccurs="unbounded" />
+ <xs:element name="entity" type="orm:entity" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:element>
@@ -52,27 +52,28 @@
<xs:complexType name="lifecycle-callbacks">
<xs:sequence>
- <xs:element name="lifecycle-callback" type="orm:lifecycle-callback" minOccurs="1" />
+ <xs:element name="lifecycle-callback" type="orm:lifecycle-callback" minOccurs="1" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="entity">
<xs:sequence>
+ <xs:element name="indexes" type="orm:indexes" minOccurs="0"/>
+ <xs:element name="unique-constraints" type="orm:unique-constraints" minOccurs="0"/>
<xs:element name="discriminator-column" type="orm:discriminator-column" minOccurs="0"/>
- <xs:element name="subclasses" type="xs:NMTOKENS" minOccurs="0"/>
+ <xs:element name="discriminator-map" type="orm:discriminator-map" minOccurs="0"/>
<xs:element name="lifecycle-callbacks" type="orm:lifecycle-callbacks" minOccurs="0" maxOccurs="1" />
<xs:element name="id" type="orm:id" />
- <xs:element name="field" type="orm:field" minOccurs="0" />
- <xs:element name="one-to-one" type="orm:one-to-one" minOccurs="0"/>
- <xs:element name="one-to-many" type="orm:one-to-many" minOccurs="0" />
- <xs:element name="many-to-many" type="orm:many-to-many" minOccurs="0" />
+ <xs:element name="field" type="orm:field" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="one-to-one" type="orm:one-to-one" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="one-to-many" type="orm:one-to-many" minOccurs="0" maxOccurs="unbounded" />
+ <xs:element name="many-to-many" type="orm:many-to-many" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required" />
<xs:attribute name="table" type="xs:NMTOKEN" />
<xs:attribute name="schema" type="xs:NMTOKEN" />
<xs:attribute name="repository-class" type="xs:NMTOKEN"/>
<xs:attribute name="inheritance-type" type="orm:inheritance-type"/>
- <xs:attribute name="discriminator-value" type="xs:NMTOKEN"/>
</xs:complexType>
<xs:complexType name="mapped-superclass" >
@@ -122,6 +123,39 @@
<xs:attribute name="field-name" type="xs:NMTOKEN" />
<xs:attribute name="length" type="xs:NMTOKEN" />
</xs:complexType>
+
+ <xs:complexType name="unique-constraint">
+ <xs:attribute name="name" type="xs:NMTOKEN" use="optional"/>
+ <xs:attribute name="columns" type="xs:NMTOKENS" use="required"/>
+ </xs:complexType>
+
+ <xs:complexType name="unique-constraints">
+ <xs:sequence>
+ <xs:element name="unique-constraint" type="orm:unique-constraint" minOccurs="1" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="index">
+ <xs:attribute name="name" type="xs:NMTOKEN" use="optional"/>
+ <xs:attribute name="columns" type="xs:NMTOKENS" use="required"/>
+ </xs:complexType>
+
+ <xs:complexType name="indexes">
+ <xs:sequence>
+ <xs:element name="index" type="orm:index" minOccurs="1" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="discriminator-mapping">
+ <xs:attribute name="value" type="xs:NMTOKEN" use="required"/>
+ <xs:attribute name="class" type="xs:NMTOKEN" use="required"/>
+ </xs:complexType>
+
+ <xs:complexType name="discriminator-map">
+ <xs:sequence>
+ <xs:element name="discriminator-mapping" type="orm:discriminator-mapping" minOccurs="1" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
<xs:complexType name="generator">
<xs:attribute name="strategy" type="orm:generator-strategy" use="required" />
@@ -138,13 +172,13 @@
<xs:complexType name="inverse-join-columns">
<xs:sequence>
- <xs:element name="join-column" type="orm:join-column" />
+ <xs:element name="join-column" type="orm:join-column" minOccurs="1" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="join-column">
<xs:attribute name="name" type="xs:NMTOKEN" use="required" />
- <xs:attribute name="referencedColumnName" type="xs:NMTOKEN" use="required" />
+ <xs:attribute name="referenced-column-name" type="xs:NMTOKEN" use="required" />
<xs:attribute name="unique" type="xs:boolean" default="false" />
<xs:attribute name="nullable" type="xs:boolean" default="true" />
<xs:attribute name="on-delete" type="orm:fk-action" />
@@ -153,7 +187,7 @@
<xs:complexType name="join-columns">
<xs:sequence>
- <xs:element name="join-column" type="orm:join-column" />
+ <xs:element name="join-column" type="orm:join-column" minOccurs="1" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
@@ -171,16 +205,16 @@
<xs:element name="cascade" type="orm:cascade-type" minOccurs="0" />
<xs:element name="join-table" type="orm:join-table" />
</xs:sequence>
- <xs:attribute name="targetEntity" type="xs:NMTOKEN" use="required" />
+ <xs:attribute name="target-entity" type="xs:NMTOKEN" use="required" />
<xs:attribute name="field" type="xs:NMTOKEN" use="required" />
</xs:complexType>
<xs:complexType name="one-to-many">
<xs:sequence>
<xs:element name="cascade" type="orm:cascade-type" minOccurs="0" />
</xs:sequence>
- <xs:attribute name="targetEntity" type="xs:NMTOKEN" use="required" />
- <xs:attribute name="mappedBy" type="xs:NMTOKEN" />
+ <xs:attribute name="target-entity" type="xs:NMTOKEN" use="required" />
+ <xs:attribute name="mapped-by" type="xs:NMTOKEN" />
<xs:attribute name="field" type="xs:NMTOKEN" use="required" />
<xs:attribute name="orphan-removal" type="xs:boolean" default="false" />
</xs:complexType>
@@ -193,8 +227,8 @@
<xs:element name="join-columns" type="orm:join-columns"/>
</xs:choice>
</xs:sequence>
- <xs:attribute name="targetEntity" type="xs:NMTOKEN" use="required" />
- <xs:attribute name="mappedBy" type="xs:NMTOKEN" />
+ <xs:attribute name="target-entity" type="xs:NMTOKEN" use="required" />
+ <xs:attribute name="mapped-by" type="xs:NMTOKEN" />
<xs:attribute name="field" type="xs:NMTOKEN" use="required" />
<xs:attribute name="orphan-removal" type="xs:boolean" default="false" />
</xs:complexType>
View
48 lib/Doctrine/DBAL/Platforms/AbstractPlatform.php
@@ -362,14 +362,6 @@ public function getNotExpression($expression)
* must contain a logical expression or an array with logical expressions.
* These expressions will be matched against the first parameter.
*
- * Example:
- * <code>
- * $q = new Doctrine_Query();
- * $q->select('u.*')
- * ->from('User u')
- * ->where($q->expr->in( 'id', array(1,2,3)));
- * </code>
- *
* @param string $column the value that should be matched against
* @param string|array(string) values that will be matched against $column
* @return string logical expression
@@ -390,14 +382,6 @@ public function getInExpression($column, $values)
/**
* Returns SQL that checks if a expression is null.
*
- * Example:
- * <code>
- * $q = new Doctrine_Query();
- * $q->select('u.*')
- * ->from('User u')
- * ->where($q->expr->isNull('id'));
- * </code>
- *
* @param string $expression the expression that should be compared to null
* @return string logical expression
*/
@@ -409,14 +393,6 @@ public function getIsNullExpression($expression)
/**
* Returns SQL that checks if a expression is not null.
*
- * Example:
- * <code>
- * $q = new Doctrine_Query();
- * $q->select('u.*')
- * ->from('User u')
- * ->where($q->expr->isNotNull('id'));
- * </code>
- *
* @param string $expression the expression that should be compared to null
* @return string logical expression
*/
@@ -435,14 +411,6 @@ public function getIsNotNullExpression($expression)
* http://www.w3schools.com/sql/sql_between.asp. If you want complete database
* independence you should avoid using between().
*
- * Example:
- * <code>
- * $q = new Doctrine_Query();
- * $q->select('u.*')
- * ->from('User u')
- * ->where($q->expr->between('id', 1, 5));
- * </code>
- *
* @param string $expression the value to compare to
* @param string $value1 the lower value to compare with
* @param string $value2 the higher value to compare with
@@ -504,18 +472,24 @@ public function getDropForeignKeySql($table, $name)
}
/**
- * Gets the SQL statement(s) to create a table with the specified name, columns and options
+ * Gets the SQL statement(s) to create a table with the specified name, columns and constraints
* on this platform.
*
- * @param string $table
- * @param array $columns
- * @param array $options
- * @return array
+ * @param string $table The name of the table.
+ * @param array $columns The column definitions for the table.
+ * @param array $options The table constraints.
+ * @return array The sequence of SQL statements.
*/
public function getCreateTableSql($table, array $columns, array $options = array())
{
$columnListSql = $this->getColumnDeclarationListSql($columns);
+ if (isset($options['uniqueConstraints']) && ! empty($options['uniqueConstraints'])) {
+ foreach ($options['uniqueConstraints'] as $uniqueConstraint) {
+ $columnListSql .= ', UNIQUE(' . implode(', ', array_values($uniqueConstraint)) . ')';
+ }
+ }
+
if (isset($options['primary']) && ! empty($options['primary'])) {
$columnListSql .= ', PRIMARY KEY(' . implode(', ', array_unique(array_values($options['primary']))) . ')';
}
View
75 lib/Doctrine/DBAL/Platforms/MySqlPlatform.php
@@ -227,7 +227,7 @@ public function getVarcharTypeDeclarationSql(array $field)
$fixed = (isset($field['fixed'])) ? $field['fixed'] : false;
return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(255)')
- : ($length ? 'VARCHAR(' . $length . ')' : 'TEXT');
+ : ($length ? 'VARCHAR(' . $length . ')' : 'VARCHAR(255)');
}
public function getClobDeclarationSql(array $field)
@@ -408,7 +408,7 @@ public function getCreateTableSql($name, array $fields, array $options = array()
$queryFields = $this->getColumnDeclarationListSql($fields);
// build indexes for all foreign key fields (needed in MySQL!!)
- if (isset($options['foreignKeys'])) {
+ /*if (isset($options['foreignKeys'])) {
foreach ($options['foreignKeys'] as $fk) {
$local = $fk['local'];
$found = false;
@@ -433,6 +433,12 @@ public function getCreateTableSql($name, array $fields, array $options = array()
$options['indexes'][$local] = array('fields' => array($local => array()));
}
}
+ }*/
+
+ if (isset($options['uniqueConstraints']) && ! empty($options['uniqueConstraints'])) {
+ foreach ($options['uniqueConstraints'] as $uniqueConstraint) {
+ $queryFields .= ', UNIQUE(' . implode(', ', array_values($uniqueConstraint)) . ')';
+ }
}
// add all indexes
@@ -471,9 +477,7 @@ public function getCreateTableSql($name, array $fields, array $options = array()
// get the type of the table
if (isset($options['type'])) {
$type = $options['type'];
- }/* else {
- $type = $this->getAttribute(Doctrine::ATTR_DEFAULT_TABLE_TYPE);
- }*/
+ }
if ($type) {
$optionStrings[] = 'ENGINE = ' . $type;
@@ -589,6 +593,7 @@ public function getAlterTableSql($name, array $changes, $check = false)
if ( ! $name) {
throw DoctrineException::updateMe('no valid table name specified');
}
+
foreach ($changes as $changeName => $change) {
switch ($changeName) {
case 'add':
@@ -671,61 +676,6 @@ public function getAlterTableSql($name, array $changes, $check = false)
}
/**
- * Get the stucture of a field into an array
- *
- * @author Leoncx
- * @param string $table name of the table on which the index is to be created
- * @param string $name name of the index to be created
- * @param array $definition associative array that defines properties of the index to be created.
- * Currently, only one property named FIELDS is supported. This property
- * is also an associative with the names of the index fields as array
- * indexes. Each entry of this array is set to another type of associative
- * array that specifies properties of the index that are specific to
- * each field.
- *
- * Currently, only the sorting property is supported. It should be used
- * to define the sorting direction of the index. It may be set to either
- * ascending or descending.
- *
- * Not all DBMS support index sorting direction configuration. The DBMS
- * drivers of those that do not support it ignore this property. Use the
- * function supports() to determine whether the DBMS driver can manage indexes.
- *
- * Example
- * array(
- * 'fields' => array(
- * 'user_name' => array(
- * 'sorting' => 'ASC'
- * 'length' => 10
- * ),
- * 'last_login' => array()
- * )
- * )
- * @throws PDOException
- * @return void
- * @override
- */
- public function getCreateIndexSql($table, $name, array $definition)
- {
- $table = $table;
- $type = '';
- if (isset($definition['type'])) {
- switch (strtolower($definition['type'])) {
- case 'fulltext':
- case 'unique':
- $type = strtoupper($definition['type']) . ' ';
- break;
- default:
- throw DoctrineException::updateMe('Unknown index type ' . $definition['type']);
- }
- }
- $query = 'CREATE ' . $type . 'INDEX ' . $name . ' ON ' . $table;
- $query .= ' (' . $this->getIndexFieldDeclarationListSql($definition['fields']) . ')';
-
- return $query;
- }
-
- /**
* Obtain DBMS specific SQL code portion needed to declare an integer type
* field to be used in statements like CREATE TABLE.
*
@@ -791,7 +741,7 @@ protected function _getCommonIntegerTypeDeclarationSql(array $columnDef)
*/
public function getIndexDeclarationSql($name, array $definition)
{
- $type = '';
+ $type = '';
if (isset($definition['type'])) {
switch (strtolower($definition['type'])) {
case 'fulltext':
@@ -818,7 +768,6 @@ public function getIndexDeclarationSql($name, array $definition)
}
/**
- * getIndexFieldDeclarationList
* Obtain DBMS specific SQL code portion needed to set an index
* declaration to be used in statements like CREATE TABLE.
*
@@ -908,7 +857,7 @@ public function getSetTransactionIsolationSql($level)
}
/**
- * Get the platform name for this instance
+ * Get the platform name for this instance.
*
* @return string
*/
View
6 lib/Doctrine/DBAL/Platforms/OraclePlatform.php
@@ -241,7 +241,7 @@ public function getListSequencesSql($database)
public function getCreateTableSql($table, array $columns, array $options = array())
{
- $indexes = isset($options['indexes']) ? $options['indexes']:array();
+ $indexes = isset($options['indexes']) ? $options['indexes'] : array();
$options['indexes'] = array();
$sql = parent::getCreateTableSql($table, $columns, $options);
@@ -258,9 +258,9 @@ public function getCreateTableSql($table, array $columns, array $options = array
if (isset($indexes) && ! empty($indexes)) {
foreach ($indexes as $indexName => $definition) {
- // create nonunique indexes, as they are a part od CREATE TABLE DDL
+ // create nonunique indexes, as they are a part of CREATE TABLE DDL
if ( ! isset($definition['type']) ||
- (isset($definition['type']) && strtolower($definition['type']) != 'unique')) {
+ (isset($definition['type']) && strtolower($definition['type']) != 'unique')) {
$sql[] = $this->getCreateIndexSql($table, $indexName, $definition);
}
}
View
5 lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php
@@ -616,11 +616,8 @@ public function getCreateTableSql($name, array $fields, array $options = array()
}
if (isset($options['foreignKeys'])) {
-
foreach ((array) $options['foreignKeys'] as $k => $definition) {
- if (is_array($definition)) {
- $sql[] = $this->getCreateForeignKeySql($name, $definition);
- }
+ $sql[] = $this->getCreateForeignKeySql($name, $definition);
}
}
View
6 lib/Doctrine/DBAL/Schema/AbstractSchemaManager.php
@@ -166,10 +166,10 @@ public function listTableConstraints($table)
}
/**
- * List the columns for a given table
+ * List the columns for a given table.
*
- * @param string $table The name of the table
- * @return array $tableColumns
+ * @param string $table The name of the table.
+ * @return array $tableColumns The column descriptions.
*/
public function listTableColumns($table)
{
View
7 lib/Doctrine/ORM/Mapping/ClassMetadata.php
@@ -233,11 +233,6 @@
* The value specifies the name of the index. To create a multi-column index,
* just use the same name for several mappings.
*
- * - <b>unique (string, optional, schema-only)</b>
- * Whether a unique constraint should be generated for the column.
- * The value specifies the name of the unique constraint. To create a multi-column
- * unique constraint, just use the same name for several mappings.
- *
* - <b>foreignKey (string, optional, schema-only)</b>
*
* @var array
@@ -316,6 +311,8 @@
*
* name => <tableName>
* schema => <schemaName>
+ * indexes => array
+ * uniqueConstraints => array
*
* @var array
*/
View
16 lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php
@@ -73,10 +73,21 @@ public function loadMetadataForClass($className, ClassMetadata $metadata)
// Evaluate DoctrineTable annotation
if (isset($classAnnotations['Doctrine\ORM\Mapping\Table'])) {
$tableAnnot = $classAnnotations['Doctrine\ORM\Mapping\Table'];
- $metadata->setPrimaryTable(array(
+ $primaryTable = array(
'name' => $tableAnnot->name,
'schema' => $tableAnnot->schema
- ));
+ );
+ if ($tableAnnot->indexes !== null) {
+ foreach ($tableAnnot->indexes as $indexAnnot) {
+ $primaryTable['indexes'][$indexAnnot->name] = array('fields' => $indexAnnot->columns);
+ }
+ }
+ if ($tableAnnot->uniqueConstraints !== null) {
+ foreach ($tableAnnot->uniqueConstraints as $uniqueConstraint) {
+ $primaryTable['uniqueConstraints'][] = $uniqueConstraint->columns;
+ }
+ }
+ $metadata->setPrimaryTable($primaryTable);
}
// Evaluate InheritanceType annotation
@@ -135,7 +146,6 @@ public function loadMetadataForClass($className, ClassMetadata $metadata)
);
} else if ($joinColumnsAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\JoinColumns')) {
foreach ($joinColumnsAnnot->value as $joinColumn) {
- //$joinColumns = $joinColumnsAnnot->value;
$joinColumns[] = array(
'name' => $joinColumn->name,
'referencedColumnName' => $joinColumn->referencedColumnName,
View
12 lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php
@@ -21,7 +21,7 @@
namespace Doctrine\ORM\Mapping;
-use \Doctrine\Common\Annotations\Annotation;
+use Doctrine\Common\Annotations\Annotation;
/* Annotations */
@@ -94,6 +94,16 @@
final class Table extends Annotation {
public $name;
public $schema;
+ public $indexes;
+ public $uniqueConstraints;
+}
+final class UniqueConstraint extends Annotation {
+ public $name;
+ public $columns;
+}
+final class Index extends Annotation {
+ public $name;
+ public $columns;
}
final class JoinTable extends Annotation {
public $name;
View
43 lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php
@@ -55,6 +55,21 @@ public function loadMetadataForClass($className, ClassMetadata $metadata)
if (isset($xmlRoot['inheritance-type'])) {
$metadata->setInheritanceType((string)$xmlRoot['inheritance-type']);
}
+
+ // Evaluate <indexes...>
+ if (isset($xmlRoot->indexes)) {
+ foreach ($xmlRoot->indexes->index as $index) {
+ $metadata->primaryTable['indexes'][$index['name']] = array('fields' =>
+ explode(',', $index['columns']));
+ }
+ }
+
+ // Evaluate <unique-constraints..>
+ if (isset($xmlRoot->{'unique-constraints'})) {
+ foreach ($xmlRoot->{'unique-constraints'}->{'unique-constraint'} as $unique) {
+ $metadata->primaryTable['uniqueConstraints'][] = explode(',', $index['columns']);
+ }
+ }
// Evaluate <field ...> mappings
if (isset($xmlRoot->field)) {
@@ -69,6 +84,12 @@ public function loadMetadataForClass($className, ClassMetadata $metadata)
if (isset($fieldMapping['length'])) {
$mapping['length'] = (int)$fieldMapping['length'];
}
+ if (isset($fieldMapping['precision'])) {
+ $mapping['precision'] = (int)$fieldMapping['precision'];
+ }
+ if (isset($fieldMapping['scale'])) {
+ $mapping['scale'] = (int)$fieldMapping['scale'];
+ }
$metadata->mapField($mapping);
}
}
@@ -96,10 +117,10 @@ public function loadMetadataForClass($className, ClassMetadata $metadata)
foreach ($xmlRoot->{'one-to-one'} as $oneToOneElement) {
$mapping = array(
'fieldName' => (string)$oneToOneElement['field'],
- 'targetEntity' => (string)$oneToOneElement['targetEntity']
+ 'targetEntity' => (string)$oneToOneElement['target-entity']
);
- if (isset($oneToOneElement['mappedBy'])) {
- $mapping['mappedBy'] = (string)$oneToOneElement['mappedBy'];
+ if (isset($oneToOneElement['mapped-by'])) {
+ $mapping['mappedBy'] = (string)$oneToOneElement['mapped-by'];
} else {
$joinColumns = array();
if (isset($oneToOneElement->{'join-column'})) {
@@ -127,8 +148,8 @@ public function loadMetadataForClass($className, ClassMetadata $metadata)
foreach ($xmlRoot->{'one-to-many'} as $oneToManyElement) {
$mapping = array(
'fieldName' => (string)$oneToManyElement['field'],
- 'targetEntity' => (string)$oneToManyElement['targetEntity'],
- 'mappedBy' => (string)$oneToManyElement['mappedBy']
+ 'targetEntity' => (string)$oneToManyElement['target-entity'],
+ 'mappedBy' => (string)$oneToManyElement['mapped-by']
);
if (isset($oneToManyElement->cascade)) {
$mapping['cascade'] = $this->_getCascadeMappings($oneToManyElement->cascade);
@@ -142,7 +163,7 @@ public function loadMetadataForClass($className, ClassMetadata $metadata)
foreach ($xmlRoot->{'many-to-one'} as $manyToOneElement) {
$mapping = array(
'fieldName' => (string)$manyToOneElement['field'],
- 'targetEntity' => (string)$manyToOneElement['targetEntity']
+ 'targetEntity' => (string)$manyToOneElement['target-entity']
);
$joinColumns = array();
if (isset($manyToOneElement->{'join-column'})) {
@@ -167,11 +188,11 @@ public function loadMetadataForClass($className, ClassMetadata $metadata)
foreach ($xmlRoot->{'many-to-many'} as $manyToManyElement) {
$mapping = array(
'fieldName' => (string)$manyToManyElement['field'],
- 'targetEntity' => (string)$manyToManyElement['targetEntity']
+ 'targetEntity' => (string)$manyToManyElement['target-entity']
);
if (isset($manyToManyElement['mappedBy'])) {
- $mapping['mappedBy'] = (string)$manyToManyElement['mappedBy'];
+ $mapping['mappedBy'] = (string)$manyToManyElement['mapped-by'];
} else if (isset($manyToManyElement->{'join-table'})) {
$joinTableElement = $manyToManyElement->{'join-table'};
$joinTable = array(
@@ -242,7 +263,7 @@ private function _getJoinColumnMapping(\SimpleXMLElement $joinColumnElement)
{
$joinColumn = array(
'name' => (string)$joinColumnElement['name'],
- 'referencedColumnName' => (string)$joinColumnElement['referencedColumnName']
+ 'referencedColumnName' => (string)$joinColumnElement['referenced-column-name']
);
if (isset($joinColumnElement['unique'])) {
$joinColumn['unique'] = (bool)$joinColumnElement['unique'];
@@ -251,10 +272,10 @@ private function _getJoinColumnMapping(\SimpleXMLElement $joinColumnElement)
$joinColumn['nullable'] = (bool)$joinColumnElement['nullable'];
}
if (isset($joinColumnElement['onDelete'])) {
- $joinColumn['onDelete'] = (string)$joinColumnElement['onDelete'];
+ $joinColumn['onDelete'] = (string)$joinColumnElement['on-delete'];
}
if (isset($joinColumnElement['onUpdate'])) {
- $joinColumn['onUpdate'] = (string)$joinColumnElement['onUpdate'];
+ $joinColumn['onUpdate'] = (string)$joinColumnElement['on-update'];
}
return $joinColumn;
View
251 lib/Doctrine/ORM/Tools/SchemaTool.php
@@ -28,8 +28,6 @@
* The SchemaTool is a tool to create and/or drop database schemas based on
* <tt>ClassMetadata</tt> class descriptors.
*
- * @author Konsta Vesterinen <kvesteri@cc.hut.fi>
- * @author Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library)
* @author Roman Borschel <roman@code-factory.org>
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.org
@@ -70,10 +68,11 @@ public function createSchema(array $classes)
}
/**
- * Gets an array of DDL statements for the specified array of ClassMetadata instances.
+ * Gets the list of DDL statements that are required to create the database schema for
+ * the given list of ClassMetadata instances.
*
* @param array $classes
- * @return array $sql
+ * @return array $sql The SQL statements needed to create the schema for the classes.
*/
public function getCreateSchemaSql(array $classes)
{
@@ -140,11 +139,18 @@ public function getCreateSchemaSql(array $classes)
$foreignKeyConstraints[] = $constraint;
}
} else if ($class->isInheritanceTypeTablePerClass()) {
- //TODO
+ throw DoctrineException::notSupported();
} else {
$columns = $this->_gatherColumns($class, $options);
$this->_gatherRelationsSql($class, $sql, $columns, $foreignKeyConstraints);
}
+
+ if (isset($class->primaryTable['indexes'])) {
+ $options['indexes'] = $class->primaryTable['indexes'];
+ }
+ if (isset($class->primaryTable['uniqueConstraints'])) {
+ $options['uniqueConstraints'] = $class->primaryTable['uniqueConstraints'];
+ }
$sql = array_merge($sql, $this->_platform->getCreateTableSql(
$class->getQuotedTableName($this->_platform), $columns, $options));
@@ -175,6 +181,14 @@ public function getCreateSchemaSql(array $classes)
return $sql;
}
+ /**
+ * Gets a portable column definition as required by the DBAL for the discriminator
+ * column of a class.
+ *
+ * @param ClassMetadata $class
+ * @return array The portable column definition of the discriminator column as required by
+ * the DBAL.
+ */
private function _getDiscriminatorColumnDefinition($class)
{
$discrColumn = $class->discriminatorColumn;
@@ -187,11 +201,13 @@ private function _getDiscriminatorColumnDefinition($class)
}
/**
- * Gathers the column definitions of all field mappings found in the given class.
+ * Gathers the column definitions as required by the DBAL of all field mappings
+ * found in the given class.
*
* @param ClassMetadata $class
- * @param array $options
- * @return array
+ * @param array $options The table options/constraints where any additional options/constraints
+ * that are required by columns should be appended.
+ * @return array The list of portable column definitions as required by the DBAL.
*/
private function _gatherColumns($class, array &$options)
{
@@ -203,14 +219,23 @@ private function _gatherColumns($class, array &$options)
return $columns;
}
-
+
+ /**
+ * Creates a column definition as required by the DBAL from an ORM field mapping definition.
+ *
+ * @param ClassMetadata $class The class that owns the field mapping.
+ * @param array $mapping The field mapping.
+ * @param array $options The table options/constraints where any additional options/constraints
+ * required by the column should be appended.
+ * @return array The portable column definition as required by the DBAL.
+ */
private function _gatherColumn($class, array $mapping, array &$options)
{
$column = array();
$column['name'] = $class->getQuotedColumnName($mapping['fieldName'], $this->_platform);
$column['type'] = Type::getType($mapping['type']);
- $column['length'] = $mapping['length'];
- $column['notnull'] = ! $mapping['nullable'];
+ $column['length'] = isset($mapping['length']) ? $mapping['length'] : null;
+ $column['notnull'] = isset($mapping['nullable']) ? ! $mapping['nullable'] : false;
if (isset($mapping['default'])) {
$column['default'] = $mapping['default'];
}
@@ -225,6 +250,18 @@ private function _gatherColumn($class, array $mapping, array &$options)
return $column;
}
+ /**
+ * Gathers the SQL for properly setting up the relations of the given class.
+ * 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.
+ * @return void
+ */
private function _gatherRelationsSql($class, array &$sql, array &$columns, array &$constraints)
{
foreach ($class->associationMappings as $fieldName => $mapping) {
@@ -246,16 +283,24 @@ private function _gatherRelationsSql($class, array &$sql, array &$columns, array
$columns[$column['name']] = $column;
$constraint['local'][] = $column['name'];
$constraint['foreign'][] = $joinColumn['referencedColumnName'];
+ if (isset($joinColumn['onUpdate'])) {
+ $constraint['onUpdate'] = $joinColumn['onUpdate'];
+ }
+ if (isset($joinColumn['onDelete'])) {
+ $constraint['onDelete'] = $joinColumn['onDelete'];
+ }
}
$constraints[] = $constraint;
} else if ($mapping->isOneToMany() && $mapping->isOwningSide) {
//... create join table, one-many through join table supported later
- throw DoctrineException::updateMe("Not yet implemented.");
+ throw DoctrineException::notSupported();
} else if ($mapping->isManyToMany() && $mapping->isOwningSide) {
// create join table
$joinTableColumns = array();
$joinTableOptions = array();
$joinTable = $mapping->getJoinTable();
+
+ // Build first FK constraint (relation table => source table)
$constraint1 = array(
'tableName' => $mapping->getQuotedJoinTableName($this->_platform),
'foreignTable' => $class->getQuotedTableName($this->_platform),
@@ -271,9 +316,16 @@ private function _gatherRelationsSql($class, array &$sql, array &$columns, array
$joinTableColumns[$column['name']] = $column;
$constraint1['local'][] = $column['name'];
$constraint1['foreign'][] = $joinColumn['referencedColumnName'];
+ if (isset($joinColumn['onUpdate'])) {
+ $constraint1['onUpdate'] = $joinColumn['onUpdate'];
+ }
+ if (isset($joinColumn['onDelete'])) {
+ $constraint1['onDelete'] = $joinColumn['onDelete'];
+ }
}
$constraints[] = $constraint1;
-
+
+ // Build second FK constraint (relation table => target table)
$constraint2 = array();
$constraint2['tableName'] = $mapping->getQuotedJoinTableName($this->_platform);
$constraint2['foreignTable'] = $foreignClass->getQuotedTableName($this->_platform);
@@ -289,33 +341,192 @@ private function _gatherRelationsSql($class, array &$sql, array &$columns, array
$joinTableColumns[$inverseJoinColumn['name']] = $column;
$constraint2['local'][] = $inverseJoinColumn['name'];
$constraint2['foreign'][] = $inverseJoinColumn['referencedColumnName'];
+ if (isset($inverseJoinColumn['onUpdate'])) {
+ $constraint2['onUpdate'] = $inverseJoinColumn['onUpdate'];
+ }
+ if (isset($joinColumn['onDelete'])) {
+ $constraint2['onDelete'] = $inverseJoinColumn['onDelete'];
+ }
}
$constraints[] = $constraint2;
-
+
+ // Get the SQL for creating the join table and merge it with the others
$sql = array_merge($sql, $this->_platform->getCreateTableSql(
$mapping->getQuotedJoinTableName($this->_platform), $joinTableColumns, $joinTableOptions)
);
}
}
}
-
+
+ /**
+ * Drops the database schema for the given classes.
+ *
+ * @param array $classes
+ * @return void
+ */
public function dropSchema(array $classes)
{
- //TODO
+ $dropSchemaSql = $this->getDropSchemaSql($classes);
+ $conn = $this->_em->getConnection();
+ foreach ($dropSchemaSql as $sql) {
+ $conn->execute($sql);
+ }
}
-
+
+ /**
+ * Gets the SQL needed to drop the database schema for the given classes.
+ *
+ * @param array $classes
+ * @return array
+ */
public function getDropSchemaSql(array $classes)
{
- //TODO
+ $sql = array();
+ $commitOrder = $classes; //FIXME: get real commit order!!
+
+ // Drop tables in reverse commit order
+ for ($i = count($commitOrder) - 1; $i >= 0; --$i) {
+ $class = $commitOrder[$i];
+ if ($class->isInheritanceTypeSingleTable() && $class->name != $class->rootEntityName) {
+ continue;
+ }
+ $sql[] = $this->_platform->getDropTableSql($class->getTableName());
+ }
+
+ return $sql;
}
+ /**
+ * Updates the database schema of the given classes by comparing the ClassMetadata
+ * instances to the current database schema that is inspected.
+ *
+ * @param array $classes
+ * @return void
+ */
public function updateSchema(array $classes)
{
- //TODO
+ $updateSchemaSql = $this->getUpdateSchemaSql($classes);
+ $conn = $this->_em->getConnection();
+ foreach ($updateSchemaSql as $sql) {
+ $conn->execute($sql);
+ }
}
+ /**
+ * Gets the sequence of SQL statements that need to be performed in order
+ * to bring the given class mappings in-synch with the relational schema.
+ *
+ * @param array $classes The classes to consider.
+ * @return array The sequence of SQL statements.
+ */
public function getUpdateSchemaSql(array $classes)
{
- //TODO
+ $sql = array();
+ $conn = $this->_em->getConnection();
+ $sm = $conn->getSchemaManager();
+
+ $tables = $sm->listTables();
+ $newClasses = array();
+
+ foreach ($classes as $class) {
+ $tableName = $class->getTableName();
+ $tableExists = false;
+ foreach ($tables as $index => $table) {
+ if ($tableName == $table) {
+ $tableExists = true;
+ unset($tables[$index]);
+ break;
+ }
+ }
+ if ( ! $tableExists) {
+ $newClasses[] = $class;
+ } else {
+ $newFields = array();
+ $newJoinColumns = array();
+ $currentColumns = $sm->listTableColumns($tableName);
+
+ foreach ($class->fieldMappings as $fieldMapping) {
+ $exists = false;
+ foreach ($currentColumns as $index => $column) {
+ if ($column['name'] == $fieldMapping['columnName']) {
+ // Column exists, check for changes
+
+ // 1. check for nullability change
+ // 2. check for uniqueness change
+ // 3. check for length change if type string
+ // 4. check for type change
+
+ unset($currentColumns[$index]);
+ $exists = true;
+ break;
+ }
+ }
+ if ( ! $exists) {
+ $newFields[] = $fieldMapping;
+ }
+ }
+
+ foreach ($class->associationMappings as $assoc) {
+ if ($assoc->isOwningSide && $assoc->isOneToOne()) {
+ foreach ($assoc->targetToSourceKeyColumns as $targetColumn => $sourceColumn) {
+ $exists = false;
+ foreach ($currentColumns as $index => $column) {
+ if ($column['name'] == $sourceColumn) {
+ // Column exists, check for changes
+
+ // 1. check for nullability change
+
+ unset($currentColumns[$index]);
+ $exists = true;
+ break;
+ }
+ }
+ if ( ! $exists) {
+ $newJoinColumns[$sourceColumn] = array(
+ 'name' => $sourceColumn,
+ 'type' => 'integer' //FIXME!!!
+ );
+ }
+ }
+ }
+ }
+
+ if ($newFields || $newJoinColumns) {
+ $changes = array();
+ foreach ($newFields as $newField) {
+ $options = array();
+ $changes['add'][$newField['columnName']] = $this->_gatherColumn($class, $newField, $options);
+ }
+ foreach ($newJoinColumns as $name => $joinColumn) {
+ $changes['add'][$name] = $joinColumn;
+ }
+ $sql[] = $this->_platform->getAlterTableSql($tableName, $changes);
+ }
+
+ // Drop any remaining columns
+ if ($currentColumns) {
+ $changes = array();
+ foreach ($currentColumns as $column) {
+ $options = array();
+ $changes['remove'][$column['name']] = $column;
+ }
+ $sql[] = $this->_platform->getAlterTableSql($tableName, $changes);
+ }
+ }
+ }
+
+ if ($newClasses) {
+ $sql = array_merge($this->getCreateSchemaSql($newClasses), $sql);
+ }
+
+ // Drop any remaining tables (Probably not a good idea, because the given class list
+ // may not be complete!)
+ /*if ($tables) {
+ foreach ($tables as $table) {
+ $sql[] = $this->_platform->getDropTableSql($table);
+ }
+ }*/
+
+ return $sql;
}
}
View
6 lib/Doctrine/ORM/UnitOfWork.php
@@ -25,9 +25,7 @@
Doctrine\Common\Collections\Collection,
Doctrine\Common\DoctrineException,
Doctrine\Common\PropertyChangedListener,
- Doctrine\ORM\Event\LifecycleEventArgs,
- Doctrine\ORM\Internal\CommitOrderCalculator,
- Doctrine\ORM\Internal\CommitOrderNode;
+ Doctrine\ORM\Event\LifecycleEventArgs;
/**
* The UnitOfWork is responsible for tracking changes to objects during an
@@ -233,7 +231,7 @@ public function __construct(EntityManager $em)
{
$this->_em = $em;
$this->_evm = $em->getEventManager();
- $this->_commitOrderCalculator = new CommitOrderCalculator();
+ $this->_commitOrderCalculator = new Internal\CommitOrderCalculator();
$this->_useCExtension = $this->_em->getConfiguration()->getUseCExtension();
}
View
2 tests/Doctrine/Tests/DBAL/Platforms/MySqlPlatformTest.php
@@ -126,7 +126,7 @@ public function testGeneratesTypeDeclarationForStrings()
'Variable string declaration is not correct'
);
$this->assertEquals(
- 'TEXT',
+ 'VARCHAR(255)',
$this->_platform->getVarcharTypeDeclarationSql(array()),
'Long string declaration is not correct'
);
View
1 tests/Doctrine/Tests/ORM/AllTests.php
@@ -26,7 +26,6 @@ public static function suite()
$suite->addTest(Query\AllTests::suite());
$suite->addTest(Hydration\AllTests::suite());
$suite->addTest(Entity\AllTests::suite());
- $suite->addTest(Tools\AllTests::suite());
$suite->addTest(Associations\AllTests::suite());
$suite->addTest(Mapping\AllTests::suite());
$suite->addTest(Functional\AllTests::suite());
View
1 tests/Doctrine/Tests/ORM/Functional/AllTests.php
@@ -42,6 +42,7 @@ public static function suite()
$suite->addTestSuite('Doctrine\Tests\ORM\Functional\EntityRepositoryTest');
$suite->addTest(Locking\AllTests::suite());
+ $suite->addTest(SchemaTool\AllTests::suite());
return $suite;
}
View
30 tests/Doctrine/Tests/ORM/Functional/SchemaTool/AllTests.php
@@ -0,0 +1,30 @@
+<?php
+
+namespace Doctrine\Tests\ORM\Functional\SchemaTool;
+
+if (!defined('PHPUnit_MAIN_METHOD')) {
+ define('PHPUnit_MAIN_METHOD', 'Orm_Functional_Tools_AllTests::main');
+}
+
+require_once __DIR__ . '/../../../TestInit.php';
+
+class AllTests
+{
+ public static function main()
+ {
+ \PHPUnit_TextUI_TestRunner::run(self::suite());
+ }
+
+ public static function suite()
+ {
+ $suite = new \Doctrine\Tests\DoctrineTestSuite('Doctrine Orm Functional Tools');
+
+ $suite->addTestSuite('Doctrine\Tests\ORM\Functional\SchemaTool\MySqlSchemaToolTest');
+
+ return $suite;
+ }
+}
+
+if (PHPUnit_MAIN_METHOD == 'Orm_Functional_Tools_AllTests::main') {
+ AllTests::main();
+}
View
98 tests/Doctrine/Tests/ORM/Functional/SchemaTool/MySqlSchemaToolTest.php
@@ -0,0 +1,98 @@
+<?php
+
+namespace Doctrine\Tests\ORM\Functional\SchemaTool;
+
+use Doctrine\ORM\Tools\SchemaTool,
+ Doctrine\ORM\Mapping\ClassMetadata;
+
+require_once __DIR__ . '/../../../TestInit.php';
+
+class MySqlSchemaToolTest extends \Doctrine\Tests\OrmFunctionalTestCase
+{
+ protected function setUp() {
+ parent::setUp();
+ if ($this->_em->getConnection()->getDatabasePlatform()->getName() !== 'mysql') {
+ $this->markTestSkipped('The ' . __CLASS__ .' requires the use of mysql.');
+ }
+ }
+
+ public function testGetCreateSchemaSql()
+ {
+ $classes = array(
+ $this->_em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsAddress'),
+ $this->_em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsUser'),
+ $this->_em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsPhonenumber'),
+ );
+
+ $tool = new SchemaTool($this->_em);
+ $sql = $tool->getCreateSchemaSql($classes);
+ $this->assertEquals(count($sql), 8);
+ $this->assertEquals("CREATE TABLE cms_addresses (id INT AUTO_INCREMENT NOT NULL, country VARCHAR(50) NOT NULL, zip VARCHAR(50) NOT NULL, city VARCHAR(50) NOT NULL, user_id INT DEFAULT NULL, PRIMARY KEY(id))", $sql[0]);
+ $this->assertEquals("CREATE TABLE cms_users_groups (user_id INT DEFAULT NULL, group_id INT DEFAULT NULL, PRIMARY KEY(user_id, group_id))", $sql[1]);
+ $this->assertEquals("CREATE TABLE cms_users (id INT AUTO_INCREMENT NOT NULL, status VARCHAR(50) NOT NULL, username VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, PRIMARY KEY(id))", $sql[2]);
+ $this->assertEquals("CREATE TABLE cms_phonenumbers (phonenumber VARCHAR(50) NOT NULL, user_id INT DEFAULT NULL, PRIMARY KEY(phonenumber))", $sql[3]);
+ $this->assertEquals("ALTER TABLE cms_addresses ADD FOREIGN KEY (user_id) REFERENCES cms_users(id)", $sql[4]);
+ $this->assertEquals("ALTER TABLE cms_users_groups ADD FOREIGN KEY (user_id) REFERENCES cms_users(id)", $sql[5]);
+ $this->assertEquals("ALTER TABLE cms_users_groups ADD FOREIGN KEY (group_id) REFERENCES cms_groups(id)", $sql[6]);
+ $this->assertEquals("ALTER TABLE cms_phonenumbers ADD FOREIGN KEY (user_id) REFERENCES cms_users(id)", $sql[7]);
+ }
+
+ public function testGetUpdateSchemaSql()
+ {
+ $classes = array(
+ $this->_em->getClassMetadata(__NAMESPACE__ . '\SchemaToolEntityA')
+ );
+
+ $tool = new SchemaTool($this->_em);
+
+ $tool->createSchema($classes);
+
+ // Add field to SchemaToolEntityA
+ $classA = $classes[0];
+ $classA->mapField(array(
+ 'fieldName' => 'newField',
+ 'columnName' => 'new_field',
+ 'type' => 'string',
+ 'length' => 50,
+ 'nullable' => false
+ ));
+
+ // Introduce SchemaToolEntityB
+ $classB = new ClassMetadata(__NAMESPACE__ . '\SchemaToolEntityB');
+ $classB->setTableName('schematool_entity_b');
+ $classB->mapField(array(
+ 'fieldName' => 'id',
+ 'columnName' => 'id',
+ 'type' => 'integer',
+ 'nullable' => false,
+ 'id' => true
+ ));
+ $classB->mapField(array(
+ 'fieldName' => 'field',
+ 'columnName' => 'field',
+ 'type' => 'string',
+ 'nullable' => false
+ ));
+ $classes[] = $classB;
+
+ $sql = $tool->getUpdateSchemaSql($classes);
+
+ $this->assertEquals(2, count($sql));
+ $this->assertEquals("CREATE TABLE schematool_entity_b (id INT NOT NULL, field VARCHAR(255) NOT NULL, PRIMARY KEY(id))", $sql[0]);
+ $this->assertEquals("ALTER TABLE schematool_entity_a ADD new_field VARCHAR(50) NOT NULL", $sql[1]);
+
+ }
+}
+
+/** @Entity @Table(name="schematool_entity_a") */
+class SchemaToolEntityA {
+ /** @Id @Column(type="integer") */
+ private $id;
+ private $newField;
+}
+
+class SchemaToolEntityB {
+ private $id;
+ private $field;
+}
+
View
1 tests/Doctrine/Tests/ORM/Functional/SchemaTool/PostgreSqlSchemaToolTest.php
@@ -0,0 +1 @@
+<?php
View
12 tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.User.dcm.xml
@@ -17,23 +17,23 @@
<field name="name" column="name" type="string" length="50"/>
- <one-to-one field="address" targetEntity="Address">
- <join-column name="address_id" referencedColumnName="id"/>
+ <one-to-one field="address" target-entity="Address">
+ <join-column name="address_id" referenced-column-name="id"/>
</one-to-one>
- <one-to-many field="phonenumbers" targetEntity="Phonenumber" mappedBy="user">
+ <one-to-many field="phonenumbers" target-entity="Phonenumber" mapped-by="user">
<cascade>
<cascade-persist/>
</cascade>
</one-to-many>
- <many-to-many field="groups" targetEntity="Group">
+ <many-to-many field="groups" target-entity="Group">
<join-table name="cms_users_groups">
<join-columns>
- <join-column name="user_id" referencedColumnName="id"/>
+ <join-column name="user_id" referenced-column-name="id"/>
</join-columns>
<inverse-join-columns>
- <join-column name="group_id" referencedColumnName="id"/>
+ <join-column name="group_id" referenced-column-name="id"/>
</inverse-join-columns>
</join-table>
</many-to-many>
View
30 tests/Doctrine/Tests/ORM/Tools/AllTests.php
@@ -1,30 +0,0 @@
-<?php
-
-namespace Doctrine\Tests\ORM\Tools;
-
-if (!defined('PHPUnit_MAIN_METHOD')) {
- define('PHPUnit_MAIN_METHOD', 'Orm_Tools_AllTests::main');
-}
-
-require_once __DIR__ . '/../../TestInit.php';
-
-class AllTests
-{
- public static function main()
- {
- \PHPUnit_TextUI_TestRunner::run(self::suite());
- }
-
- public static function suite()
- {
- $suite = new \Doctrine\Tests\DoctrineTestSuite('Doctrine Orm Tools');
-
- $suite->addTestSuite('Doctrine\Tests\ORM\Tools\SchemaToolTest');
-
- return $suite;
- }
-}
-
-if (PHPUnit_MAIN_METHOD == 'Orm_Tools_AllTests::main') {
- AllTests::main();
-}
View
29 tests/Doctrine/Tests/ORM/Tools/SchemaToolTest.php
@@ -1,29 +0,0 @@
-<?php
-
-namespace Doctrine\Tests\ORM\Tools;
-
-use Doctrine\ORM\Tools\SchemaTool;
-
-require_once __DIR__ . '/../../TestInit.php';
-
-class SchemaToolTest extends \Doctrine\Tests\OrmTestCase
-{
- public function testGetCreateSchemaSql()
- {
- $driver = new \Doctrine\Tests\Mocks\DriverMock;
- $conn = new \Doctrine\Tests\Mocks\ConnectionMock(array(), $driver);
- $conn->setDatabasePlatform(new \Doctrine\DBAL\Platforms\MySqlPlatform());
-
- $em = $this->_getTestEntityManager($conn);
-
- $classes = array(
- $em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsAddress'),
- $em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsUser'),
- $em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsPhonenumber'),
- );
-
- $exporter = new SchemaTool($em);
- $sql = $exporter->getCreateSchemaSql($classes);
- $this->assertEquals(count($sql), 8);
- }
-}

0 comments on commit b1d34fc

Please sign in to comment.