Commit b1d34fca authored by romanb's avatar romanb

[2.0] Work on SchemaTool and DBAL.

parent 0612e6b0
......@@ -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" >
......@@ -123,6 +124,39 @@
<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" />
</xs:complexType>
......@@ -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,7 +205,7 @@
<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>
......@@ -179,8 +213,8 @@
<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>
......
......@@ -362,14 +362,6 @@ abstract class AbstractPlatform
* 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 @@ abstract class AbstractPlatform
/**
* 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 @@ abstract class AbstractPlatform
/**
* 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 @@ abstract class AbstractPlatform
* 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 @@ abstract class AbstractPlatform
}
/**
* 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']))) . ')';
}
......
......@@ -227,7 +227,7 @@ class MySqlPlatform extends AbstractPlatform
$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 @@ class MySqlPlatform extends AbstractPlatform
$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 @@ class MySqlPlatform extends AbstractPlatform
$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 @@ class MySqlPlatform extends AbstractPlatform
// 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 @@ class MySqlPlatform extends AbstractPlatform
if ( ! $name) {
throw DoctrineException::updateMe('no valid table name specified');
}
foreach ($changes as $changeName => $change) {
switch ($changeName) {
case 'add':
......@@ -670,61 +675,6 @@ class MySqlPlatform extends AbstractPlatform
return 'ALTER TABLE ' . $name . ' ' . $query;
}
/**
* 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.
......@@ -818,7 +768,6 @@ class MySqlPlatform extends AbstractPlatform
}
/**
* 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 @@ class MySqlPlatform extends AbstractPlatform
}
/**
* Get the platform name for this instance
* Get the platform name for this instance.
*
* @return string
*/
......
......@@ -241,7 +241,7 @@ class OraclePlatform extends AbstractPlatform
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,7 +258,7 @@ class OraclePlatform extends AbstractPlatform
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')) {
$sql[] = $this->getCreateIndexSql($table, $indexName, $definition);
......
......@@ -616,13 +616,10 @@ class PostgreSqlPlatform extends AbstractPlatform
}
if (isset($options['foreignKeys'])) {
foreach ((array) $options['foreignKeys'] as $k => $definition) {
if (is_array($definition)) {
$sql[] = $this->getCreateForeignKeySql($name, $definition);
}
}
}
return $sql;
}
......
......@@ -166,10 +166,10 @@ abstract class AbstractSchemaManager
}
/**
* 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)
{
......
......@@ -233,11 +233,6 @@ final class ClassMetadata
* 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 @@ final class ClassMetadata
*
* name => <tableName>
* schema => <schemaName>
* indexes => array
* uniqueConstraints => array
*
* @var array
*/
......
......@@ -73,10 +73,21 @@ class AnnotationDriver implements Driver
// 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 @@ class AnnotationDriver implements Driver
);
} 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,
......
......@@ -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 ElementCollection extends Annotation {
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;
......
......@@ -56,6 +56,21 @@ class XmlDriver extends AbstractFileDriver
$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)) {
foreach ($xmlRoot->field as $fieldMapping) {
......@@ -69,6 +84,12 @@ class XmlDriver extends AbstractFileDriver
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 @@ class XmlDriver extends AbstractFileDriver
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 @@ class XmlDriver extends AbstractFileDriver
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 @@ class XmlDriver extends AbstractFileDriver
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 @@ class XmlDriver extends AbstractFileDriver
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 @@ class XmlDriver extends AbstractFileDriver
{
$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 @@ class XmlDriver extends AbstractFileDriver
$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;
......
This diff is collapsed.
......@@ -25,9 +25,7 @@ use Doctrine\Common\Collections\ArrayCollection,
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 @@ class UnitOfWork implements PropertyChangedListener
{
$this->_em = $em;
$this->_evm = $em->getEventManager();
$this->_commitOrderCalculator = new CommitOrderCalculator();
$this->_commitOrderCalculator = new Internal\CommitOrderCalculator();
$this->_useCExtension = $this->_em->getConfiguration()->getUseCExtension();
}
......
......@@ -126,7 +126,7 @@ class MySqlPlatformTest extends \Doctrine\Tests\DbalTestCase
'Variable string declaration is not correct'
);
$this->assertEquals(
'TEXT',
'VARCHAR(255)',
$this->_platform->getVarcharTypeDeclarationSql(array()),
'Long string declaration is not correct'
);
......
......@@ -26,7 +26,6 @@ class AllTests
$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());
......
......@@ -42,6 +42,7 @@ class AllTests
$suite->addTestSuite('Doctrine\Tests\ORM\Functional\EntityRepositoryTest');
$suite->addTest(Locking\AllTests::suite());
$suite->addTest(SchemaTool\AllTests::suite());
return $suite;
}
......
<?php
namespace Doctrine\Tests\ORM\Tools;
namespace Doctrine\Tests\ORM\Functional\SchemaTool;
if (!defined('PHPUnit_MAIN_METHOD')) {
define('PHPUnit_MAIN_METHOD', 'Orm_Tools_AllTests::main');
define('PHPUnit_MAIN_METHOD', 'Orm_Functional_Tools_AllTests::main');
}
require_once __DIR__ . '/../../TestInit.php';
require_once __DIR__ . '/../../../TestInit.php';
class AllTests
{
......@@ -17,14 +17,14 @@ class AllTests
public static function suite()
{
$suite = new \Doctrine\Tests\DoctrineTestSuite('Doctrine Orm Tools');
$suite = new \Doctrine\Tests\DoctrineTestSuite('Doctrine Orm Functional Tools');
$suite->addTestSuite('Doctrine\Tests\ORM\Tools\SchemaToolTest');
$suite->addTestSuite('Doctrine\Tests\ORM\Functional\SchemaTool\MySqlSchemaToolTest');
return $suite;
}
}
if (PHPUnit_MAIN_METHOD == 'Orm_Tools_AllTests::main') {
if (PHPUnit_MAIN_METHOD == 'Orm_Functional_Tools_AllTests::main') {
AllTests::main();
}
\ No newline at end of file
<?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;
}
......@@ -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>
......
<?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);
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment