1
0
mirror of synced 2025-01-19 06:51:40 +03:00

Merge branch 'master' of github.com:doctrine/doctrine2

This commit is contained in:
Benjamin Eberlei 2010-08-27 21:28:46 +02:00
commit 797d9f1be5
4 changed files with 129 additions and 76 deletions

View File

@ -680,9 +680,11 @@ class ClassMetadataInfo
} }
/** /**
* Validates & completes the mapping. Mapping defaults are applied here. * Validates & completes the basic mapping information that is common to all
* association mappings (one-to-one, many-ot-one, one-to-many, many-to-many).
* *
* @param array $mapping * @param array $mapping The mapping.
* @return array The updated mapping.
* @throws MappingException If something is wrong with the mapping. * @throws MappingException If something is wrong with the mapping.
*/ */
protected function _validateAndCompleteAssociationMapping(array $mapping) protected function _validateAndCompleteAssociationMapping(array $mapping)
@ -693,31 +695,28 @@ class ClassMetadataInfo
if ( ! isset($mapping['inversedBy'])) { if ( ! isset($mapping['inversedBy'])) {
$mapping['inversedBy'] = null; $mapping['inversedBy'] = null;
} }
$mapping['isOwningSide'] = true; $mapping['isOwningSide'] = true; // assume owning side until we hit mappedBy
// If targetEntity is unqualified, assume it is in the same namespace as
// the sourceEntity.
$mapping['sourceEntity'] = $this->name; $mapping['sourceEntity'] = $this->name;
if (isset($mapping['targetEntity']) && strpos($mapping['targetEntity'], '\\') === false && strlen($this->namespace) > 0) { if (isset($mapping['targetEntity']) && strpos($mapping['targetEntity'], '\\') === false
&& strlen($this->namespace) > 0) {
$mapping['targetEntity'] = $this->namespace . '\\' . $mapping['targetEntity']; $mapping['targetEntity'] = $this->namespace . '\\' . $mapping['targetEntity'];
} }
// Mandatory attributes for both sides // Mandatory: fieldName, targetEntity
if ( ! isset($mapping['fieldName'])) { if ( ! isset($mapping['fieldName'])) {
throw MappingException::missingFieldName(); throw MappingException::missingFieldName();
} }
if ( ! isset($mapping['sourceEntity'])) {
throw MappingException::missingSourceEntity($mapping['fieldName']);
}
if ( ! isset($mapping['targetEntity'])) { if ( ! isset($mapping['targetEntity'])) {
throw MappingException::missingTargetEntity($mapping['fieldName']); throw MappingException::missingTargetEntity($mapping['fieldName']);
} }
// Mandatory and optional attributes for either side // Mandatory and optional attributes for either side
if ( ! isset($mapping['mappedBy'])) { if ( ! $mapping['mappedBy']) {
// Optional
if (isset($mapping['joinTable']) && $mapping['joinTable']) { if (isset($mapping['joinTable']) && $mapping['joinTable']) {
if ($mapping['joinTable']['name'][0] == '`') { if (isset($mapping['joinTable']['name']) && $mapping['joinTable']['name'][0] == '`') {
$mapping['joinTable']['name'] = trim($mapping['joinTable']['name'], '`'); $mapping['joinTable']['name'] = trim($mapping['joinTable']['name'], '`');
$mapping['joinTable']['quoted'] = true; $mapping['joinTable']['quoted'] = true;
} }
@ -726,12 +725,13 @@ class ClassMetadataInfo
$mapping['isOwningSide'] = false; $mapping['isOwningSide'] = false;
} }
// Optional attributes for both sides // Fetch mode. Default fetch mode to LAZY, if not set.
if ( ! isset($mapping['fetch'])) { if ( ! isset($mapping['fetch'])) {
$mapping['fetch'] = self::FETCH_LAZY; $mapping['fetch'] = self::FETCH_LAZY;
} }
$cascades = isset($mapping['cascade']) ? $mapping['cascade'] : array();
// Cascades
$cascades = isset($mapping['cascade']) ? $mapping['cascade'] : array();
if (in_array('all', $cascades)) { if (in_array('all', $cascades)) {
$cascades = array( $cascades = array(
'remove', 'remove',
@ -752,7 +752,7 @@ class ClassMetadataInfo
} }
/** /**
* {@inheritdoc} * Validates & completes a one-to-one association mapping.
* *
* @param array $mapping The mapping to validate & complete. * @param array $mapping The mapping to validate & complete.
* @return array The validated & completed mapping. * @return array The validated & completed mapping.
@ -774,11 +774,16 @@ class ClassMetadataInfo
'referencedColumnName' => 'id' 'referencedColumnName' => 'id'
)); ));
} }
foreach ($mapping['joinColumns'] AS $key => $joinColumn) { foreach ($mapping['joinColumns'] as $key => &$joinColumn) {
if ($mapping['type'] == self::ONE_TO_ONE) { if ($mapping['type'] === self::ONE_TO_ONE) {
$mapping['joinColumns'][$key]['unique'] = true; $joinColumn['unique'] = true;
}
if (empty($joinColumn['name'])) {
$joinColumn['name'] = $mapping['fieldName'] . '_id';
}
if (empty($joinColumn['referencedColumnName'])) {
$joinColumn['referencedColumnName'] = 'id';
} }
$mapping['sourceToTargetKeyColumns'][$joinColumn['name']] = $joinColumn['referencedColumnName']; $mapping['sourceToTargetKeyColumns'][$joinColumn['name']] = $joinColumn['referencedColumnName'];
$mapping['joinColumnFieldNames'][$joinColumn['name']] = isset($joinColumn['fieldName']) $mapping['joinColumnFieldNames'][$joinColumn['name']] = isset($joinColumn['fieldName'])
? $joinColumn['fieldName'] : $joinColumn['name']; ? $joinColumn['fieldName'] : $joinColumn['name'];
@ -826,58 +831,49 @@ class ClassMetadataInfo
{ {
$mapping = $this->_validateAndCompleteAssociationMapping($mapping); $mapping = $this->_validateAndCompleteAssociationMapping($mapping);
if ($mapping['isOwningSide']) { if ($mapping['isOwningSide']) {
$sourceShortName = strtolower(substr($mapping['sourceEntity'], strrpos($mapping['sourceEntity'], '\\') + 1));
$targetShortName = strtolower(substr($mapping['targetEntity'], strrpos($mapping['targetEntity'], '\\') + 1));
// owning side MUST have a join table // owning side MUST have a join table
if ( ! isset($mapping['joinTable']) || ! $mapping['joinTable']) { if ( ! isset($mapping['joinTable']['name'])) {
// Apply default join table $mapping['joinTable']['name'] = $sourceShortName .'_' . $targetShortName;
$sourceShortName = substr($mapping['sourceEntity'], strrpos($mapping['sourceEntity'], '\\') + 1); }
$targetShortName = substr($mapping['targetEntity'], strrpos($mapping['targetEntity'], '\\') + 1); if ( ! isset($mapping['joinTable']['joinColumns'])) {
$mapping['joinTable'] = array( $mapping['joinTable']['joinColumns'] = array(array(
'name' => $sourceShortName .'_' . $targetShortName,
'joinColumns' => array(
array(
'name' => $sourceShortName . '_id', 'name' => $sourceShortName . '_id',
'referencedColumnName' => 'id', 'referencedColumnName' => 'id',
'onDelete' => 'CASCADE' 'onDelete' => 'CASCADE'));
) }
), if ( ! isset($mapping['joinTable']['inverseJoinColumns'])) {
'inverseJoinColumns' => array( $mapping['joinTable']['inverseJoinColumns'] = array(array(
array(
'name' => $targetShortName . '_id', 'name' => $targetShortName . '_id',
'referencedColumnName' => 'id', 'referencedColumnName' => 'id',
'onDelete' => 'CASCADE' 'onDelete' => 'CASCADE'));
)
)
);
}
// owning side MUST specify joinColumns
else if ( ! isset($mapping['joinTable']['joinColumns'])) {
throw MappingException::missingRequiredOption(
$mapping['fieldName'], 'joinColumns',
'Did you think of case sensitivity / plural s?'
);
}
// owning side MUST specify inverseJoinColumns
else if ( ! isset($mapping['joinTable']['inverseJoinColumns'])) {
throw MappingException::missingRequiredOption(
$mapping['fieldName'], 'inverseJoinColumns',
'Did you think of case sensitivity / plural s?'
);
} }
foreach ($mapping['joinTable']['joinColumns'] as $joinColumn) { foreach ($mapping['joinTable']['joinColumns'] as &$joinColumn) {
if (empty($joinColumn['name'])) {
$joinColumn['name'] = $sourceShortName . '_id';
}
if (empty($joinColumn['referencedColumnName'])) {
$joinColumn['referencedColumnName'] = 'id';
}
if (isset($joinColumn['onDelete']) && strtolower($joinColumn['onDelete']) == 'cascade') { if (isset($joinColumn['onDelete']) && strtolower($joinColumn['onDelete']) == 'cascade') {
$mapping['isOnDeleteCascade'] = true; $mapping['isOnDeleteCascade'] = true;
} }
$mapping['relationToSourceKeyColumns'][$joinColumn['name']] = $joinColumn['referencedColumnName']; $mapping['relationToSourceKeyColumns'][$joinColumn['name']] = $joinColumn['referencedColumnName'];
$mapping['joinTableColumns'][] = $joinColumn['name']; $mapping['joinTableColumns'][] = $joinColumn['name'];
} }
foreach ($mapping['joinTable']['inverseJoinColumns'] as $inverseJoinColumn) { foreach ($mapping['joinTable']['inverseJoinColumns'] as &$inverseJoinColumn) {
if (empty($inverseJoinColumn['name'])) {
$inverseJoinColumn['name'] = $targetShortName . '_id';
}
if (empty($inverseJoinColumn['referencedColumnName'])) {
$inverseJoinColumn['referencedColumnName'] = 'id';
}
if (isset($inverseJoinColumn['onDelete']) && strtolower($inverseJoinColumn['onDelete']) == 'cascade') { if (isset($inverseJoinColumn['onDelete']) && strtolower($inverseJoinColumn['onDelete']) == 'cascade') {
$mapping['isOnDeleteCascade'] = true; $mapping['isOnDeleteCascade'] = true;
} }
$mapping['relationToTargetKeyColumns'][$inverseJoinColumn['name']] = $inverseJoinColumn['referencedColumnName']; $mapping['relationToTargetKeyColumns'][$inverseJoinColumn['name']] = $inverseJoinColumn['referencedColumnName'];
$mapping['joinTableColumns'][] = $inverseJoinColumn['name']; $mapping['joinTableColumns'][] = $inverseJoinColumn['name'];
} }
@ -1211,22 +1207,33 @@ class ClassMetadataInfo
* indexes => array of indexes (optional) * indexes => array of indexes (optional)
* uniqueConstraints => array of constraints (optional) * uniqueConstraints => array of constraints (optional)
* *
* @param array $table * If a key is omitted, the current value is kept.
*
* @param array $table The table description.
*/ */
public function setPrimaryTable(array $table) public function setPrimaryTable(array $table)
{ {
if (isset($table['name']) && $table['name'][0] == '`') { if (isset($table['name'])) {
$table['name'] = trim($table['name'], '`'); if ($table['name'][0] == '`') {
$table['quoted'] = true; $this->table['name'] = trim($table['name'], '`');
$this->table['quoted'] = true;
} else {
$this->table['name'] = $table['name'];
}
}
if (isset($table['indexes'])) {
$this->table['indexes'] = $table['indexes'];
}
if (isset($table['uniqueConstraints'])) {
$this->table['uniqueConstraints'] = $table['uniqueConstraints'];
} }
$this->table = $table;
} }
/** /**
* Checks whether the given type identifies an inheritance type. * Checks whether the given type identifies an inheritance type.
* *
* @param string $type * @param integer $type
* @return boolean * @return boolean TRUE if the given type identifies an inheritance type, FALSe otherwise.
*/ */
private function _isInheritanceType($type) private function _isInheritanceType($type)
{ {

View File

@ -39,6 +39,7 @@ class CmsAddress
/** /**
* @OneToOne(targetEntity="CmsUser", inversedBy="address") * @OneToOne(targetEntity="CmsUser", inversedBy="address")
* @JoinColumn(referencedColumnName="id")
*/ */
public $user; public $user;

View File

@ -19,7 +19,7 @@ class PostgreSqlSchemaToolTest extends \Doctrine\Tests\OrmFunctionalTestCase
public function testPostgresMetadataSequenceIncrementedBy10() public function testPostgresMetadataSequenceIncrementedBy10()
{ {
$address = $this->_em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsAddress'); $address = $this->_em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsAddress');
$this->assertEquals(10, $address->sequenceGeneratorDefinition['allocationSize']); $this->assertEquals(1, $address->sequenceGeneratorDefinition['allocationSize']);
} }
public function testGetCreateSchemaSql() public function testGetCreateSchemaSql()
@ -39,8 +39,8 @@ class PostgreSqlSchemaToolTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertEquals("CREATE UNIQUE INDEX cms_users_username_uniq ON cms_users (username)", $sql[3]); $this->assertEquals("CREATE UNIQUE INDEX cms_users_username_uniq ON cms_users (username)", $sql[3]);
$this->assertEquals("CREATE TABLE cms_users_groups (user_id INT NOT NULL, group_id INT NOT NULL, PRIMARY KEY(user_id, group_id))", $sql[4]); $this->assertEquals("CREATE TABLE cms_users_groups (user_id INT NOT NULL, group_id INT NOT NULL, PRIMARY KEY(user_id, group_id))", $sql[4]);
$this->assertEquals("CREATE TABLE cms_phonenumbers (phonenumber VARCHAR(50) NOT NULL, user_id INT DEFAULT NULL, PRIMARY KEY(phonenumber))", $sql[5]); $this->assertEquals("CREATE TABLE cms_phonenumbers (phonenumber VARCHAR(50) NOT NULL, user_id INT DEFAULT NULL, PRIMARY KEY(phonenumber))", $sql[5]);
$this->assertEquals("CREATE SEQUENCE cms_addresses_id_seq INCREMENT BY 10 MINVALUE 1 START 1", $sql[6]); $this->assertEquals("CREATE SEQUENCE cms_addresses_id_seq INCREMENT BY 1 MINVALUE 1 START 1", $sql[6]);
$this->assertEquals("CREATE SEQUENCE cms_users_id_seq INCREMENT BY 10 MINVALUE 1 START 1", $sql[7]); $this->assertEquals("CREATE SEQUENCE cms_users_id_seq INCREMENT BY 1 MINVALUE 1 START 1", $sql[7]);
$this->assertEquals("ALTER TABLE cms_addresses ADD FOREIGN KEY (user_id) REFERENCES cms_users(id) NOT DEFERRABLE INITIALLY IMMEDIATE", $sql[8]); $this->assertEquals("ALTER TABLE cms_addresses ADD FOREIGN KEY (user_id) REFERENCES cms_users(id) NOT DEFERRABLE INITIALLY IMMEDIATE", $sql[8]);
$this->assertEquals("ALTER TABLE cms_users_groups ADD FOREIGN KEY (user_id) REFERENCES cms_users(id) NOT DEFERRABLE INITIALLY IMMEDIATE", $sql[9]); $this->assertEquals("ALTER TABLE cms_users_groups ADD FOREIGN KEY (user_id) REFERENCES cms_users(id) NOT DEFERRABLE INITIALLY IMMEDIATE", $sql[9]);
$this->assertEquals("ALTER TABLE cms_users_groups ADD FOREIGN KEY (group_id) REFERENCES cms_groups(id) NOT DEFERRABLE INITIALLY IMMEDIATE", $sql[10]); $this->assertEquals("ALTER TABLE cms_users_groups ADD FOREIGN KEY (group_id) REFERENCES cms_groups(id) NOT DEFERRABLE INITIALLY IMMEDIATE", $sql[10]);
@ -61,7 +61,7 @@ class PostgreSqlSchemaToolTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertEquals(2, count($sql)); $this->assertEquals(2, count($sql));
$this->assertEquals('CREATE TABLE decimal_model (id INT NOT NULL, "decimal" NUMERIC(5, 2) NOT NULL, "high_scale" NUMERIC(14, 4) NOT NULL, PRIMARY KEY(id))', $sql[0]); $this->assertEquals('CREATE TABLE decimal_model (id INT NOT NULL, "decimal" NUMERIC(5, 2) NOT NULL, "high_scale" NUMERIC(14, 4) NOT NULL, PRIMARY KEY(id))', $sql[0]);
$this->assertEquals("CREATE SEQUENCE decimal_model_id_seq INCREMENT BY 10 MINVALUE 1 START 1", $sql[1]); $this->assertEquals("CREATE SEQUENCE decimal_model_id_seq INCREMENT BY 1 MINVALUE 1 START 1", $sql[1]);
} }
public function testGetCreateSchemaSql3() public function testGetCreateSchemaSql3()
@ -75,6 +75,6 @@ class PostgreSqlSchemaToolTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertEquals(2, count($sql)); $this->assertEquals(2, count($sql));
$this->assertEquals("CREATE TABLE boolean_model (id INT NOT NULL, booleanField BOOLEAN NOT NULL, PRIMARY KEY(id))", $sql[0]); $this->assertEquals("CREATE TABLE boolean_model (id INT NOT NULL, booleanField BOOLEAN NOT NULL, PRIMARY KEY(id))", $sql[0]);
$this->assertEquals("CREATE SEQUENCE boolean_model_id_seq INCREMENT BY 10 MINVALUE 1 START 1", $sql[1]); $this->assertEquals("CREATE SEQUENCE boolean_model_id_seq INCREMENT BY 1 MINVALUE 1 START 1", $sql[1]);
} }
} }

View File

@ -102,9 +102,9 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
$assoc = $cm->associationMappings['groups']; $assoc = $cm->associationMappings['groups'];
//$this->assertTrue($assoc instanceof \Doctrine\ORM\Mapping\ManyToManyMapping); //$this->assertTrue($assoc instanceof \Doctrine\ORM\Mapping\ManyToManyMapping);
$this->assertEquals(array( $this->assertEquals(array(
'name' => 'CmsUser_CmsGroup', 'name' => 'cmsuser_cmsgroup',
'joinColumns' => array(array('name' => 'CmsUser_id', 'referencedColumnName' => 'id', 'onDelete' => 'CASCADE')), 'joinColumns' => array(array('name' => 'cmsuser_id', 'referencedColumnName' => 'id', 'onDelete' => 'CASCADE')),
'inverseJoinColumns' => array(array('name' => 'CmsGroup_id', 'referencedColumnName' => 'id', 'onDelete' => 'CASCADE')) 'inverseJoinColumns' => array(array('name' => 'cmsgroup_id', 'referencedColumnName' => 'id', 'onDelete' => 'CASCADE'))
), $assoc['joinTable']); ), $assoc['joinTable']);
$this->assertTrue($assoc['isOnDeleteCascade']); $this->assertTrue($assoc['isOnDeleteCascade']);
} }
@ -231,4 +231,49 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
$this->setExpectedException('Doctrine\ORM\Mapping\MappingException'); $this->setExpectedException('Doctrine\ORM\Mapping\MappingException');
$cm->mapField(array('fieldName' => 'name', 'columnName' => 'name')); $cm->mapField(array('fieldName' => 'name', 'columnName' => 'name'));
} }
public function testDefaultTableName()
{
$cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
// When table's name is not given
$primaryTable = array();
$cm->setPrimaryTable($primaryTable);
$this->assertEquals('CmsUser', $cm->getTableName());
$this->assertEquals('CmsUser', $cm->table['name']);
$cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsAddress');
// When joinTable's name is not given
$cm->mapManyToMany(array(
'fieldName' => 'user',
'targetEntity' => 'CmsUser',
'inversedBy' => 'users',
'joinTable' => array('joinColumns' => array(array('referencedColumnName' => 'id')),
'inverseJoinColumns' => array(array('referencedColumnName' => 'id')))));
$this->assertEquals('cmsaddress_cmsuser', $cm->associationMappings['user']['joinTable']['name']);
}
public function testDefaultJoinColumnName()
{
$cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsAddress');
// this is really dirty, but it's the simpliest way to test whether
// joinColumn's name will be automatically set to user_id
$cm->mapOneToOne(array(
'fieldName' => 'user',
'targetEntity' => 'CmsUser',
'joinColumns' => array(array('referencedColumnName' => 'id'))));
$this->assertEquals('user_id', $cm->associationMappings['user']['joinColumns'][0]['name']);
$cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsAddress');
$cm->mapManyToMany(array(
'fieldName' => 'user',
'targetEntity' => 'CmsUser',
'inversedBy' => 'users',
'joinTable' => array('name' => 'user_CmsUser',
'joinColumns' => array(array('referencedColumnName' => 'id')),
'inverseJoinColumns' => array(array('referencedColumnName' => 'id')))));
$this->assertEquals('cmsaddress_id', $cm->associationMappings['user']['joinTable']['joinColumns'][0]['name']);
$this->assertEquals('cmsuser_id', $cm->associationMappings['user']['joinTable']['inverseJoinColumns'][0]['name']);
}
} }