From d68fcd8bd20511f55f9ebdfe24d589db7cfc464b Mon Sep 17 00:00:00 2001 From: Jan Sorgalla Date: Thu, 26 Jan 2012 14:36:56 +0100 Subject: [PATCH 1/2] Implement custom options on table level --- doctrine-mapping.xsd | 18 ++++++++++ .../ORM/Mapping/ClassMetadataInfo.php | 4 +++ .../ORM/Mapping/Driver/AnnotationDriver.php | 4 +++ lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php | 33 +++++++++++++++++++ .../ORM/Mapping/Driver/YamlDriver.php | 4 +++ lib/Doctrine/ORM/Mapping/Table.php | 2 ++ lib/Doctrine/ORM/Tools/SchemaTool.php | 6 ++++ .../ORM/Mapping/AbstractMappingDriverTest.php | 19 ++++++++++- .../php/Doctrine.Tests.ORM.Mapping.User.php | 4 +++ .../Doctrine.Tests.ORM.Mapping.User.dcm.xml | 8 ++++- .../Doctrine.Tests.ORM.Mapping.User.dcm.yml | 4 +++ .../Tests/ORM/Tools/SchemaToolTest.php | 11 ++++--- 12 files changed, 111 insertions(+), 6 deletions(-) diff --git a/doctrine-mapping.xsd b/doctrine-mapping.xsd index e8e21f193..5dd510ff1 100644 --- a/doctrine-mapping.xsd +++ b/doctrine-mapping.xsd @@ -86,6 +86,7 @@ + @@ -110,6 +111,23 @@ + + + + + + + + + + + + + + + + + diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php index 328d7bc35..253ab6003 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php @@ -1705,6 +1705,10 @@ class ClassMetadataInfo implements ClassMetadata if (isset($table['uniqueConstraints'])) { $this->table['uniqueConstraints'] = $table['uniqueConstraints']; } + + if (isset($table['options'])) { + $this->table['options'] = $table['options']; + } } /** diff --git a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php index f11331ffa..e95d32e94 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php +++ b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php @@ -190,6 +190,10 @@ class AnnotationDriver implements Driver } } + if ($tableAnnot->options !== null) { + $primaryTable['options'] = $tableAnnot->options; + } + $metadata->setPrimaryTable($primaryTable); } diff --git a/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php b/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php index 7308a23e3..e8e2a80a6 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php +++ b/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php @@ -161,6 +161,10 @@ class XmlDriver extends AbstractFileDriver } } + if (isset($xmlRoot->options)) { + $metadata->table['options'] = $this->_parseOptions($xmlRoot->options->children()); + } + // Evaluate mappings if (isset($xmlRoot->field)) { foreach ($xmlRoot->field as $fieldMapping) { @@ -454,6 +458,35 @@ class XmlDriver extends AbstractFileDriver } } + /** + * Parses (nested) option elements. + * + * @param $options The XML element. + * @return array The options array. + */ + private function _parseOptions(SimpleXMLElement $options) + { + $array = array(); + + foreach ($options as $option) { + if ($option->count()) { + $value = $this->_parseOptions($option->children()); + } else { + $value = (string) $option; + } + + $attr = $option->attributes(); + + if (isset($attr->name)) { + $array[(string) $attr->name] = $value; + } else { + $array[] = $value; + } + } + + return $array; + } + /** * Constructs a joinColumn mapping array based on the information * found in the given SimpleXMLElement. diff --git a/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php b/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php index a65b6fb2f..0106f3aba 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php +++ b/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php @@ -156,6 +156,10 @@ class YamlDriver extends AbstractFileDriver } } + if (isset($element['options'])) { + $metadata->table['options'] = $element['options']; + } + $associationIds = array(); if (isset($element['id'])) { // Evaluate identifier settings diff --git a/lib/Doctrine/ORM/Mapping/Table.php b/lib/Doctrine/ORM/Mapping/Table.php index 41db294de..25e8e82b2 100644 --- a/lib/Doctrine/ORM/Mapping/Table.php +++ b/lib/Doctrine/ORM/Mapping/Table.php @@ -33,4 +33,6 @@ final class Table implements Annotation public $indexes; /** @var array<\Doctrine\ORM\Mapping\UniqueConstraint> */ public $uniqueConstraints; + /** @var array */ + public $options = array(); } diff --git a/lib/Doctrine/ORM/Tools/SchemaTool.php b/lib/Doctrine/ORM/Tools/SchemaTool.php index efe7f7b7c..85e50b2b0 100644 --- a/lib/Doctrine/ORM/Tools/SchemaTool.php +++ b/lib/Doctrine/ORM/Tools/SchemaTool.php @@ -235,6 +235,12 @@ class SchemaTool } } + if (isset($class->table['options'])) { + foreach ($class->table['options'] AS $key => $val) { + $table->addOption($key, $val); + } + } + $processedClasses[$class->name] = true; if ($class->isIdGeneratorSequence() && $class->name == $class->rootEntityName) { diff --git a/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php b/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php index 40ff74342..6e440a457 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php @@ -77,6 +77,21 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase * @depends testEntityTableNameAndInheritance * @param ClassMetadata $class */ + public function testEntityOptions($class) + { + $this->assertArrayHasKey('options', $class->table, 'ClassMetadata should have options key in table property.'); + + $this->assertEquals(array( + 'foo' => 'bar', 'baz' => array('key' => 'val') + ), $class->table['options']); + + return $class; + } + + /** + * @depends testEntityOptions + * @param ClassMetadata $class + */ public function testEntitySequence($class) { $this->assertInternalType('array', $class->sequenceGeneratorDefinition, 'No Sequence Definition set on this driver.'); @@ -424,7 +439,8 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase * @Table( * name="cms_users", * uniqueConstraints={@UniqueConstraint(name="search_idx", columns={"name", "user_email"})}, - * indexes={@Index(name="name_idx", columns={"name"}), @Index(name="0", columns={"user_email"})} + * indexes={@Index(name="name_idx", columns={"name"}), @Index(name="0", columns={"user_email"})}, + * options={"foo": "bar", "baz": {"key": "val"}} * ) */ class User @@ -495,6 +511,7 @@ class User $metadata->setInheritanceType(ClassMetadataInfo::INHERITANCE_TYPE_NONE); $metadata->setPrimaryTable(array( 'name' => 'cms_users', + 'options' => array('foo' => 'bar', 'baz' => array('key' => 'val')), )); $metadata->setChangeTrackingPolicy(ClassMetadataInfo::CHANGETRACKING_DEFERRED_IMPLICIT); $metadata->addLifecycleCallback('doStuffOnPrePersist', 'prePersist'); diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.ORM.Mapping.User.php b/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.ORM.Mapping.User.php index 33020aa6b..b9ce24ccd 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.ORM.Mapping.User.php +++ b/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.ORM.Mapping.User.php @@ -106,6 +106,10 @@ $metadata->mapManyToMany(array( ), 'orderBy' => NULL, )); +$metadata->table['options'] = array( + 'foo' => 'bar', + 'baz' => array('key' => 'val') +); $metadata->table['uniqueConstraints'] = array( 'search_idx' => array('columns' => array('name', 'user_email')), ); diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.User.dcm.xml b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.User.dcm.xml index f116fb0fe..44521e827 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.User.dcm.xml +++ b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.User.dcm.xml @@ -6,6 +6,12 @@ http://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd"> + + + + + @@ -15,7 +21,7 @@ - + diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.User.dcm.yml b/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.User.dcm.yml index 333474981..7a39a874a 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.User.dcm.yml +++ b/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.User.dcm.yml @@ -1,6 +1,10 @@ Doctrine\Tests\ORM\Mapping\User: type: entity table: cms_users + options: + foo: bar + baz: + key: val namedQueries: all: SELECT u FROM __CLASS__ u id: diff --git a/tests/Doctrine/Tests/ORM/Tools/SchemaToolTest.php b/tests/Doctrine/Tests/ORM/Tools/SchemaToolTest.php index 6e4b62efe..66093a38d 100644 --- a/tests/Doctrine/Tests/ORM/Tools/SchemaToolTest.php +++ b/tests/Doctrine/Tests/ORM/Tools/SchemaToolTest.php @@ -32,19 +32,21 @@ class SchemaToolTest extends \Doctrine\Tests\OrmTestCase $this->assertTrue($schema->getTable('cms_users')->columnsAreIndexed(array('username')), "username column should be indexed."); } - public function testColumnAnnotationOptionsAttribute() + public function testAnnotationOptionsAttribute() { $em = $this->_getTestEntityManager(); $schemaTool = new SchemaTool($em); $classes = array( - $em->getClassMetadata(__NAMESPACE__ . '\\TestEntityWithColumnAnnotationOptionsAttribute'), + $em->getClassMetadata(__NAMESPACE__ . '\\TestEntityWithAnnotationOptionsAttribute'), ); $schema = $schemaTool->getSchemaFromMetadata($classes); $expected = array('foo' => 'bar', 'baz' => array('key' => 'val')); - $this->assertEquals($expected, $schema->getTable('TestEntityWithColumnAnnotationOptionsAttribute')->getColumn('test')->getCustomSchemaOptions(), "options annotation are passed to the columns customSchemaOptions"); + + $this->assertEquals($expected, $schema->getTable('TestEntityWithAnnotationOptionsAttribute')->getOptions(), "options annotation are passed to the tables optionss"); + $this->assertEquals($expected, $schema->getTable('TestEntityWithAnnotationOptionsAttribute')->getColumn('test')->getCustomSchemaOptions(), "options annotation are passed to the columns customSchemaOptions"); } /** @@ -103,8 +105,9 @@ class SchemaToolTest extends \Doctrine\Tests\OrmTestCase /** * @Entity + * @Table(options={"foo": "bar", "baz": {"key": "val"}}) */ -class TestEntityWithColumnAnnotationOptionsAttribute +class TestEntityWithAnnotationOptionsAttribute { /** @Id @Column */ private $id; From fac820f0e29d3dbfb185d27bd9816066b0a2dc10 Mon Sep 17 00:00:00 2001 From: jsor Date: Fri, 27 Jan 2012 11:05:47 +0100 Subject: [PATCH 2/2] Complete custom column option implementation - Support for xml driver - Tests --- doctrine-mapping.xsd | 1 + lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php | 8 ++++---- .../Tests/ORM/Mapping/AbstractMappingDriverTest.php | 6 +++++- .../ORM/Mapping/php/Doctrine.Tests.ORM.Mapping.User.php | 1 + .../Mapping/xml/Doctrine.Tests.ORM.Mapping.User.dcm.xml | 9 ++++++++- .../Mapping/yaml/Doctrine.Tests.ORM.Mapping.User.dcm.yml | 4 ++++ 6 files changed, 23 insertions(+), 6 deletions(-) diff --git a/doctrine-mapping.xsd b/doctrine-mapping.xsd index 5dd510ff1..227af4403 100644 --- a/doctrine-mapping.xsd +++ b/doctrine-mapping.xsd @@ -182,6 +182,7 @@ + diff --git a/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php b/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php index e8e2a80a6..a528346e6 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php +++ b/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php @@ -196,10 +196,6 @@ class XmlDriver extends AbstractFileDriver $mapping['unique'] = ((string)$fieldMapping['unique'] == "false") ? false : true; } - if (isset($fieldMapping['options'])) { - $mapping['options'] = (array)$fieldMapping['options']; - } - if (isset($fieldMapping['nullable'])) { $mapping['nullable'] = ((string)$fieldMapping['nullable'] == "false") ? false : true; } @@ -212,6 +208,10 @@ class XmlDriver extends AbstractFileDriver $mapping['columnDefinition'] = (string)$fieldMapping['column-definition']; } + if (isset($fieldMapping->options)) { + $mapping['options'] = $this->_parseOptions($fieldMapping->options->children()); + } + $metadata->mapField($mapping); } } diff --git a/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php b/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php index 6e440a457..369c8fdeb 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php @@ -144,6 +144,9 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase $this->assertTrue($class->fieldMappings['name']['nullable']); $this->assertTrue($class->fieldMappings['name']['unique']); + $expected = array('foo' => 'bar', 'baz' => array('key' => 'val')); + $this->assertEquals($expected, $class->fieldMappings['name']['options']); + return $class; } @@ -454,7 +457,7 @@ class User public $id; /** - * @Column(length=50, nullable=true, unique=true) + * @Column(length=50, nullable=true, unique=true, options={"foo": "bar", "baz": {"key": "val"}}) */ public $name; @@ -530,6 +533,7 @@ class User 'unique' => true, 'nullable' => true, 'columnName' => 'name', + 'options' => array('foo' => 'bar', 'baz' => array('key' => 'val')), )); $metadata->mapField(array( 'fieldName' => 'email', diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.ORM.Mapping.User.php b/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.ORM.Mapping.User.php index b9ce24ccd..df4dedda5 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.ORM.Mapping.User.php +++ b/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.ORM.Mapping.User.php @@ -27,6 +27,7 @@ $metadata->mapField(array( 'unique' => true, 'nullable' => true, 'columnName' => 'name', + 'options' => array('foo' => 'bar', 'baz' => array('key' => 'val')), )); $metadata->mapField(array( 'fieldName' => 'email', diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.User.dcm.xml b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.User.dcm.xml index 44521e827..18f4d5819 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.User.dcm.xml +++ b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.User.dcm.xml @@ -37,7 +37,14 @@ - + + + + + + + diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.User.dcm.yml b/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.User.dcm.yml index 7a39a874a..5c1018560 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.User.dcm.yml +++ b/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.User.dcm.yml @@ -22,6 +22,10 @@ Doctrine\Tests\ORM\Mapping\User: length: 50 nullable: true unique: true + options: + foo: bar + baz: + key: val email: type: string column: user_email