diff --git a/lib/Doctrine/ORM/Configuration.php b/lib/Doctrine/ORM/Configuration.php index 83b4dc5dd..7a3f7fdec 100644 --- a/lib/Doctrine/ORM/Configuration.php +++ b/lib/Doctrine/ORM/Configuration.php @@ -24,7 +24,9 @@ use Doctrine\Common\Cache\Cache, Doctrine\Common\Annotations\AnnotationRegistry, Doctrine\Common\Annotations\AnnotationReader, Doctrine\ORM\Mapping\Driver\Driver, - Doctrine\ORM\Mapping\Driver\AnnotationDriver; + Doctrine\ORM\Mapping\Driver\AnnotationDriver, + Doctrine\ORM\Mapping\NamingStrategy, + Doctrine\ORM\Mapping\DefaultNamingStrategy; /** * Configuration container for all configuration options of Doctrine. @@ -548,4 +550,29 @@ class Configuration extends \Doctrine\DBAL\Configuration return isset($this->_attributes['defaultRepositoryClassName']) ? $this->_attributes['defaultRepositoryClassName'] : 'Doctrine\ORM\EntityRepository'; } + + /** + * Set naming strategy. + * + * @since 2.3 + * @param NamingStrategy $namingStrategy + */ + public function setNamingStrategy(NamingStrategy $namingStrategy) + { + $this->_attributes['namingStrategy'] = $namingStrategy; + } + + /** + * Get naming strategy.. + * + * @since 2.3 + * @return NamingStrategy + */ + public function getNamingStrategy() + { + if (!isset($this->_attributes['namingStrategy'])) { + $this->_attributes['namingStrategy'] = new DefaultNamingStrategy(); + } + return $this->_attributes['namingStrategy']; + } } diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadata.php b/lib/Doctrine/ORM/Mapping/ClassMetadata.php index a5b983fbb..a5410c748 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadata.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadata.php @@ -61,13 +61,15 @@ class ClassMetadata extends ClassMetadataInfo implements IClassMetadata * metadata of the class with the given name. * * @param string $entityName The name of the entity class the new instance is used for. + * @param NamingStrategy $namingStrategy */ - public function __construct($entityName) + public function __construct($entityName, NamingStrategy $namingStrategy = null) { + $namingStrategy = $namingStrategy ?: new DefaultNamingStrategy(); $this->reflClass = new ReflectionClass($entityName); $this->namespace = $this->reflClass->getNamespaceName(); - $this->table['name'] = $this->reflClass->getShortName(); - parent::__construct($this->reflClass->getName()); // do not use $entityName, possible case-problems + $this->table['name'] = $namingStrategy->classToTableName($this->reflClass->getShortName()); + parent::__construct($this->reflClass->getName(),$namingStrategy); // do not use $entityName, possible case-problems } /** diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php b/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php index bf802ecf9..9fd537d6a 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php @@ -385,7 +385,7 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface */ protected function newClassMetadataInstance($className) { - return new ClassMetadata($className); + return new ClassMetadata($className, $this->em->getConfiguration()->getNamingStrategy()); } /** diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php index 6fbf8b3c6..50b2fdb4b 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php @@ -494,16 +494,25 @@ class ClassMetadataInfo */ public $isReadOnly = false; + /** + * NamingStrategy determining the default column and table names + * + * @var \Doctrine\ORM\NamingStrategy + */ + protected $namingStrategy; + /** * Initializes a new ClassMetadata instance that will hold the object-relational mapping * metadata of the class with the given name. * * @param string $entityName The name of the entity class the new instance is used for. + * @param NamingStrategy $namingStrategy */ - public function __construct($entityName) + public function __construct($entityName, NamingStrategy $namingStrategy = null) { $this->name = $entityName; $this->rootEntityName = $entityName; + $this->namingStrategy = $namingStrategy ?: new DefaultNamingStrategy(); } /** @@ -717,7 +726,7 @@ class ClassMetadataInfo // Complete fieldName and columnName mapping if ( ! isset($mapping['columnName'])) { - $mapping['columnName'] = $mapping['fieldName']; + $mapping['columnName'] = $this->namingStrategy->propertyToColumnName($mapping['fieldName']); } else { if ($mapping['columnName'][0] == '`') { $mapping['columnName'] = trim($mapping['columnName'], '`'); @@ -886,8 +895,8 @@ class ClassMetadataInfo if ( ! isset($mapping['joinColumns']) || ! $mapping['joinColumns']) { // Apply default join column $mapping['joinColumns'] = array(array( - 'name' => $mapping['fieldName'] . '_id', - 'referencedColumnName' => 'id' + 'name' => $this->namingStrategy->joinColumnName($mapping['fieldName']), + 'referencedColumnName' => $this->namingStrategy->referenceColumnName() )); } @@ -901,10 +910,10 @@ class ClassMetadataInfo } } if (empty($joinColumn['name'])) { - $joinColumn['name'] = $mapping['fieldName'] . '_id'; + $joinColumn['name'] = $this->namingStrategy->joinColumnName($mapping['fieldName']); } if (empty($joinColumn['referencedColumnName'])) { - $joinColumn['referencedColumnName'] = 'id'; + $joinColumn['referencedColumnName'] = $this->namingStrategy->referenceColumnName(); } $mapping['sourceToTargetKeyColumns'][$joinColumn['name']] = $joinColumn['referencedColumnName']; $mapping['joinColumnFieldNames'][$joinColumn['name']] = isset($joinColumn['fieldName']) @@ -965,40 +974,29 @@ class ClassMetadataInfo { $mapping = $this->_validateAndCompleteAssociationMapping($mapping); if ($mapping['isOwningSide']) { - if (strpos($mapping['sourceEntity'], '\\') !== false) { - $sourceShortName = strtolower(substr($mapping['sourceEntity'], strrpos($mapping['sourceEntity'], '\\') + 1)); - } else { - $sourceShortName = strtolower($mapping['sourceEntity']); - } - if (strpos($mapping['targetEntity'], '\\') !== false) { - $targetShortName = strtolower(substr($mapping['targetEntity'], strrpos($mapping['targetEntity'], '\\') + 1)); - } else { - $targetShortName = strtolower($mapping['targetEntity']); - } - // owning side MUST have a join table if ( ! isset($mapping['joinTable']['name'])) { - $mapping['joinTable']['name'] = $sourceShortName .'_' . $targetShortName; + $mapping['joinTable']['name'] = $this->namingStrategy->joinTableName($mapping['sourceEntity'], $mapping['targetEntity'], $mapping['fieldName']); } if ( ! isset($mapping['joinTable']['joinColumns'])) { $mapping['joinTable']['joinColumns'] = array(array( - 'name' => $sourceShortName . '_id', - 'referencedColumnName' => 'id', + 'name' => $this->namingStrategy->joinKeyColumnName($mapping['sourceEntity']), + 'referencedColumnName' => $this->namingStrategy->referenceColumnName(), 'onDelete' => 'CASCADE')); } if ( ! isset($mapping['joinTable']['inverseJoinColumns'])) { $mapping['joinTable']['inverseJoinColumns'] = array(array( - 'name' => $targetShortName . '_id', - 'referencedColumnName' => 'id', + 'name' => $this->namingStrategy->joinKeyColumnName($mapping['targetEntity']), + 'referencedColumnName' => $this->namingStrategy->referenceColumnName(), 'onDelete' => 'CASCADE')); } foreach ($mapping['joinTable']['joinColumns'] as &$joinColumn) { if (empty($joinColumn['name'])) { - $joinColumn['name'] = $sourceShortName . '_id'; + $joinColumn['name'] = $this->namingStrategy->joinKeyColumnName($mapping['sourceEntity'], $joinColumn['referencedColumnName']); } if (empty($joinColumn['referencedColumnName'])) { - $joinColumn['referencedColumnName'] = 'id'; + $joinColumn['referencedColumnName'] = $this->namingStrategy->referenceColumnName(); } if (isset($joinColumn['onDelete']) && strtolower($joinColumn['onDelete']) == 'cascade') { $mapping['isOnDeleteCascade'] = true; @@ -1009,10 +1007,10 @@ class ClassMetadataInfo foreach ($mapping['joinTable']['inverseJoinColumns'] as &$inverseJoinColumn) { if (empty($inverseJoinColumn['name'])) { - $inverseJoinColumn['name'] = $targetShortName . '_id'; + $inverseJoinColumn['name'] = $this->namingStrategy->joinKeyColumnName($mapping['targetEntity'], $inverseJoinColumn['referencedColumnName']); } if (empty($inverseJoinColumn['referencedColumnName'])) { - $inverseJoinColumn['referencedColumnName'] = 'id'; + $inverseJoinColumn['referencedColumnName'] = $this->namingStrategy->referenceColumnName(); } if (isset($inverseJoinColumn['onDelete']) && strtolower($inverseJoinColumn['onDelete']) == 'cascade') { $mapping['isOnDeleteCascade'] = true; diff --git a/lib/Doctrine/ORM/Mapping/DefaultNamingStrategy.php b/lib/Doctrine/ORM/Mapping/DefaultNamingStrategy.php new file mode 100644 index 000000000..5bfe31577 --- /dev/null +++ b/lib/Doctrine/ORM/Mapping/DefaultNamingStrategy.php @@ -0,0 +1,86 @@ +. + */ + +namespace Doctrine\ORM\Mapping; + +/** + * The default NamingStrategy + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.3 + * @author Fabio B. Silva + */ +class DefaultNamingStrategy implements NamingStrategy +{ + /** + * {@inheritdoc} + */ + public function classToTableName($className) + { + if (strpos($className, '\\') !== false) { + return substr($className, strrpos($className, '\\') + 1); + } + + return $className; + } + + /** + * {@inheritdoc} + */ + public function propertyToColumnName($propertyName) + { + return $propertyName; + } + + /** + * {@inheritdoc} + */ + public function referenceColumnName() + { + return 'id'; + } + + /** + * {@inheritdoc} + */ + public function joinColumnName($propertyName) + { + return $propertyName . '_' . $this->referenceColumnName(); + } + + /** + * {@inheritdoc} + */ + public function joinTableName($sourceEntity, $targetEntity, $propertyName = null) + { + return strtolower($this->classToTableName($sourceEntity) . '_' . + $this->classToTableName($targetEntity)); + } + + /** + * {@inheritdoc} + */ + public function joinKeyColumnName($entityName, $referencedColumnName = null) + { + return strtolower($this->classToTableName($entityName) . '_' . + ($referencedColumnName ?: $this->referenceColumnName())); + } +} \ No newline at end of file diff --git a/lib/Doctrine/ORM/Mapping/NamingStrategy.php b/lib/Doctrine/ORM/Mapping/NamingStrategy.php new file mode 100644 index 000000000..8a7cbb335 --- /dev/null +++ b/lib/Doctrine/ORM/Mapping/NamingStrategy.php @@ -0,0 +1,82 @@ +. + */ + +namespace Doctrine\ORM\Mapping; + +/** + * A set of rules for determining the physical column and table names + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.3 + * @author Fabio B. Silva + */ +interface NamingStrategy +{ + /** + * Return a table name for an entity class + * + * @param string $className The fully-qualified class name + * @return string A table name + */ + function classToTableName($className); + + /** + * Return a column name for a property + * + * @param string $propertyName A property + * @return string A column name + */ + function propertyToColumnName($propertyName); + + /** + * Return the default reference column name + * + * @return string A column name + */ + function referenceColumnName(); + + /** + * Return a join column name for a property + * + * @param string $propertyName A property + * @return string A join column name + */ + function joinColumnName($propertyName); + + /** + * Return a join table name + * + * @param string $sourceEntity The source entity + * @param string $targetEntity The target entity + * @param string $propertyName A property + * @return string A join table name + */ + function joinTableName($sourceEntity, $targetEntity, $propertyName = null); + + /** + * Return the foreign key column name for the given parameters + * + * @param string $entityName A entity + * @param string $referencedColumnName A property + * @return string A join column name + */ + function joinKeyColumnName($entityName, $referencedColumnName = null); +} \ No newline at end of file diff --git a/lib/Doctrine/ORM/Mapping/UnderscoreNamingStrategy.php b/lib/Doctrine/ORM/Mapping/UnderscoreNamingStrategy.php new file mode 100644 index 000000000..4b2a9a9da --- /dev/null +++ b/lib/Doctrine/ORM/Mapping/UnderscoreNamingStrategy.php @@ -0,0 +1,134 @@ +. + */ + +namespace Doctrine\ORM\Mapping; + +/** + * The default NamingStrategy + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.3 + * @author Fabio B. Silva + */ +class UnderscoreNamingStrategy implements NamingStrategy +{ + /** + * @var string + */ + private $case; + + /** + * Underscore naming strategy construct + * + * @param integer $case CASE_LOWER | CASE_UPPER + */ + public function __construct($case = CASE_LOWER) + { + $this->case = $case; + } + + /** + * @return integer + */ + public function getCase() + { + return $this->case; + } + + /** + * Sets string case CASE_LOWER | CASE_UPPER + * Alphabetic characters converted to lowercase or uppercase + * + * @param integer $case + */ + public function setCase($case) + { + $this->case = $case; + } + + /** + * {@inheritdoc} + */ + public function classToTableName($className) + { + if (strpos($className, '\\') !== false) { + $className = substr($className, strrpos($className, '\\') + 1); + } + + return $this->underscore($className); + } + + /** + * {@inheritdoc} + */ + public function propertyToColumnName($propertyName) + { + return $this->underscore($propertyName); + } + + /** + * {@inheritdoc} + */ + public function referenceColumnName() + { + return $this->case === CASE_UPPER ? 'ID' : 'id'; + } + + /** + * {@inheritdoc} + */ + public function joinColumnName($propertyName) + { + return $this->underscore($propertyName) . '_' . $this->referenceColumnName(); + } + + /** + * {@inheritdoc} + */ + public function joinTableName($sourceEntity, $targetEntity, $propertyName = null) + { + return $this->classToTableName($sourceEntity) . '_' . $this->classToTableName($targetEntity); + } + + /** + * {@inheritdoc} + */ + public function joinKeyColumnName($entityName, $referencedColumnName = null) + { + return $this->classToTableName($entityName) . '_' . + ($referencedColumnName ?: $this->referenceColumnName()); + } + + /** + * @param string $string + * @return string + */ + private function underscore($string) + { + $string = preg_replace('/(?<=[a-z])([A-Z])/', '_$1', $string); + + if ($this->case === CASE_UPPER) { + return strtoupper($string); + } + + return strtolower($string); + } +} \ No newline at end of file diff --git a/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php b/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php index 0042259e1..5ad1b65d2 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php @@ -392,6 +392,29 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase $this->assertEquals("INT unsigned NOT NULL", $class->fieldMappings['id']['columnDefinition']); $this->assertEquals("VARCHAR(255) NOT NULL", $class->fieldMappings['value']['columnDefinition']); } + + /** + * @group DDC-559 + */ + public function testNamingStrategy() + { + $driver = $this->_loadDriver(); + $em = $this->_getTestEntityManager(); + $factory = new \Doctrine\ORM\Mapping\ClassMetadataFactory(); + $em->getConfiguration()->setMetadataDriverImpl($driver); + $factory->setEntityManager($em); + + + $this->assertInstanceOf('Doctrine\ORM\Mapping\DefaultNamingStrategy', $em->getConfiguration()->getNamingStrategy()); + $em->getConfiguration()->setNamingStrategy(new \Doctrine\ORM\Mapping\UnderscoreNamingStrategy(CASE_UPPER)); + $this->assertInstanceOf('Doctrine\ORM\Mapping\UnderscoreNamingStrategy', $em->getConfiguration()->getNamingStrategy()); + + $class = $factory->getMetadataFor('Doctrine\Tests\Models\DDC1476\DDC1476EntityWithDefaultFieldType'); + + $this->assertEquals('ID', $class->columnNames['id']); + $this->assertEquals('NAME', $class->columnNames['name']); + $this->assertEquals('DDC1476ENTITY_WITH_DEFAULT_FIELD_TYPE', $class->table['name']); + } } /** diff --git a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php b/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php index 7a4de4ca4..8b8392efb 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php @@ -293,6 +293,51 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase $this->assertEquals('cmsuser_id', $cm->associationMappings['user']['joinTable']['inverseJoinColumns'][0]['name']); } + /** + * @group DDC-559 + */ + public function testUnderscoreNamingStrategyDefaults() + { + $namingStrategy = new \Doctrine\ORM\Mapping\UnderscoreNamingStrategy(CASE_UPPER); + $oneToOneMetadata = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsAddress', $namingStrategy); + $manyToManyMetadata = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsAddress', $namingStrategy); + + $oneToOneMetadata->mapOneToOne(array( + 'fieldName' => 'user', + 'targetEntity' => 'CmsUser' + )); + + $manyToManyMetadata->mapManyToMany(array( + 'fieldName' => 'user', + 'targetEntity' => 'CmsUser' + )); + + $this->assertEquals(array('USER_ID'=>'ID'), $oneToOneMetadata->associationMappings['user']['sourceToTargetKeyColumns']); + $this->assertEquals(array('USER_ID'=>'USER_ID'), $oneToOneMetadata->associationMappings['user']['joinColumnFieldNames']); + $this->assertEquals(array('ID'=>'USER_ID'), $oneToOneMetadata->associationMappings['user']['targetToSourceKeyColumns']); + + $this->assertEquals('USER_ID', $oneToOneMetadata->associationMappings['user']['joinColumns'][0]['name']); + $this->assertEquals('ID', $oneToOneMetadata->associationMappings['user']['joinColumns'][0]['referencedColumnName']); + + + $this->assertEquals('CMS_ADDRESS_CMS_USER', $manyToManyMetadata->associationMappings['user']['joinTable']['name']); + + $this->assertEquals(array('CMS_ADDRESS_ID','CMS_USER_ID'), $manyToManyMetadata->associationMappings['user']['joinTableColumns']); + $this->assertEquals(array('CMS_ADDRESS_ID'=>'ID'), $manyToManyMetadata->associationMappings['user']['relationToSourceKeyColumns']); + $this->assertEquals(array('CMS_USER_ID'=>'ID'), $manyToManyMetadata->associationMappings['user']['relationToTargetKeyColumns']); + + $this->assertEquals('CMS_ADDRESS_ID', $manyToManyMetadata->associationMappings['user']['joinTable']['joinColumns'][0]['name']); + $this->assertEquals('CMS_USER_ID', $manyToManyMetadata->associationMappings['user']['joinTable']['inverseJoinColumns'][0]['name']); + + $this->assertEquals('ID', $manyToManyMetadata->associationMappings['user']['joinTable']['joinColumns'][0]['referencedColumnName']); + $this->assertEquals('ID', $manyToManyMetadata->associationMappings['user']['joinTable']['inverseJoinColumns'][0]['referencedColumnName']); + + + $cm = new ClassMetadata('DoctrineGlobal_Article', $namingStrategy); + $cm->mapManyToMany(array('fieldName' => 'author', 'targetEntity' => 'Doctrine\Tests\Models\CMS\CmsUser')); + $this->assertEquals('DOCTRINE_GLOBAL_ARTICLE_CMS_USER', $cm->associationMappings['author']['joinTable']['name']); + } + /** * @group DDC-886 */ diff --git a/tests/Doctrine/Tests/ORM/Mapping/NamingStrategyTest.php b/tests/Doctrine/Tests/ORM/Mapping/NamingStrategyTest.php new file mode 100644 index 000000000..0c56aa810 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Mapping/NamingStrategyTest.php @@ -0,0 +1,298 @@ +assertEquals($expected, $strategy->classToTableName($className)); + } + + /** + * Data Provider for NamingStrategy#propertyToColumnName + * + * @return array + */ + static public function dataPropertyToColumnName() + { + return array( + // DefaultNamingStrategy + array(self::defaultNaming(), 'someProperty', + 'someProperty' + ), + array(self::defaultNaming(), 'SOME_PROPERTY', + 'SOME_PROPERTY' + ), + array(self::defaultNaming(), 'some_property', + 'some_property' + ), + + // UnderscoreNamingStrategy + array(self::underscoreNamingLower(), 'some_property', + 'someProperty' + ), + array(self::underscoreNamingUpper(), 'SOME_PROPERTY', + 'someProperty' + ), + array(self::underscoreNamingUpper(), 'SOME_PROPERTY', + 'some_property' + ), + array(self::underscoreNamingUpper(), 'SOME_PROPERTY', + 'SOME_PROPERTY' + ), + ); + } + + /** + * @dataProvider dataPropertyToColumnName + * + * @param NamingStrategy $strategy + * @param string $expected + * @param string $propertyName + */ + public function testPropertyToColumnName(NamingStrategy $strategy, $expected, $propertyName) + { + $this->assertEquals($expected, $strategy->propertyToColumnName($propertyName)); + } + + /** + * Data Provider for NamingStrategy#referenceColumnName + * + * @return array + */ + static public function dataReferenceColumnName() + { + return array( + // DefaultNamingStrategy + array(self::defaultNaming(), 'id'), + + // UnderscoreNamingStrategy + array(self::underscoreNamingLower(), 'id'), + array(self::underscoreNamingUpper(), 'ID'), + ); + } + + /** + * @dataProvider dataReferenceColumnName + * + * @param NamingStrategy $strategy + * @param string $expected + */ + public function testReferenceColumnName(NamingStrategy $strategy, $expected) + { + $this->assertEquals($expected, $strategy->referenceColumnName()); + } + + /** + * Data Provider for NamingStrategy#joinColumnName + * + * @return array + */ + static public function dataJoinColumnName() + { + return array( + // DefaultNamingStrategy + array(self::defaultNaming(), 'someColumn_id', + 'someColumn', null, + ), + array(self::defaultNaming(), 'some_column_id', + 'some_column', null, + ), + + // UnderscoreNamingStrategy + array(self::underscoreNamingLower(), 'some_column_id', + 'someColumn', null, + ), + array(self::underscoreNamingUpper(), 'SOME_COLUMN_ID', + 'someColumn', null, + ), + ); + } + + /** + * @dataProvider dataJoinColumnName + * + * @param NamingStrategy $strategy + * @param string $expected + * @param string $propertyName + */ + public function testJoinColumnName(NamingStrategy $strategy, $expected, $propertyName) + { + $this->assertEquals($expected, $strategy->joinColumnName($propertyName)); + } + + /** + * Data Provider for NamingStrategy#joinTableName + * + * @return array + */ + static public function dataJoinTableName() + { + return array( + // DefaultNamingStrategy + array(self::defaultNaming(), 'someclassname_classname', + 'SomeClassName', 'Some\ClassName', null, + ), + array(self::defaultNaming(), 'someclassname_classname', + '\SomeClassName', 'ClassName', null, + ), + array(self::defaultNaming(), 'name_classname', + '\Some\Class\Name', 'ClassName', null, + ), + + // UnderscoreNamingStrategy + array(self::underscoreNamingLower(), 'some_class_name_class_name', + 'SomeClassName', 'Some\ClassName', null, + ), + array(self::underscoreNamingLower(), 'some_class_name_class_name', + '\SomeClassName', 'ClassName', null, + ), + array(self::underscoreNamingLower(), 'name_class_name', + '\Some\Class\Name', 'ClassName', null, + ), + + array(self::underscoreNamingUpper(), 'SOME_CLASS_NAME_CLASS_NAME', + 'SomeClassName', 'Some\ClassName', null, + ), + array(self::underscoreNamingUpper(), 'SOME_CLASS_NAME_CLASS_NAME', + '\SomeClassName', 'ClassName', null, + ), + array(self::underscoreNamingUpper(), 'NAME_CLASS_NAME', + '\Some\Class\Name', 'ClassName', null, + ), + ); + } + + /** + * @dataProvider dataJoinTableName + * + * @param NamingStrategy $strategy + * @param string $expected + * @param string $ownerEntity + * @param string $associatedEntity + * @param string $propertyName + */ + public function testJoinTableName(NamingStrategy $strategy, $expected, $ownerEntity, $associatedEntity, $propertyName = null) + { + $this->assertEquals($expected, $strategy->joinTableName($ownerEntity, $associatedEntity, $propertyName)); + } + + /** + * Data Provider for NamingStrategy#joinKeyColumnName + * + * @return array + */ + static public function dataJoinKeyColumnName() + { + return array( + // DefaultNamingStrategy + array(self::defaultNaming(), 'someclassname_id', + 'SomeClassName', null, null, + ), + array(self::defaultNaming(), 'name_identifier', + '\Some\Class\Name', 'identifier', null, + ), + + // UnderscoreNamingStrategy + array(self::underscoreNamingLower(), 'some_class_name_id', + 'SomeClassName', null, null, + ), + array(self::underscoreNamingLower(), 'class_name_identifier', + '\Some\Class\ClassName', 'identifier', null, + ), + + array(self::underscoreNamingUpper(), 'SOME_CLASS_NAME_ID', + 'SomeClassName', null, null, + ), + array(self::underscoreNamingUpper(), 'CLASS_NAME_IDENTIFIER', + '\Some\Class\ClassName', 'IDENTIFIER', null, + ), + ); + } + + /** + * @dataProvider dataJoinKeyColumnName + * + * @param NamingStrategy $strategy + * @param string $expected + * @param string $propertyEntityName + * @param string $referencedColumnName + * @param string $propertyName + */ + public function testJoinKeyColumnName(NamingStrategy $strategy, $expected, $propertyEntityName, $referencedColumnName = null, $propertyName = null) + { + $this->assertEquals($expected, $strategy->joinKeyColumnName($propertyEntityName, $referencedColumnName, $propertyName)); + } +} \ No newline at end of file