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

Merge branch 'hotfix/#1178-correct-association-links-dbal-types-conversion'

Close #1178
This commit is contained in:
Marco Pivetta 2015-01-17 08:03:00 +01:00
commit dad3a6bae1
42 changed files with 2876 additions and 126 deletions

View File

@ -1998,7 +1998,10 @@ class ClassMetadataInfo implements ClassMetadata
*
* @param string $columnName
*
* @return \Doctrine\DBAL\Types\Type
* @return \Doctrine\DBAL\Types\Type|string|null
*
* @deprecated this method is bogous and unreliable, since it cannot resolve the type of a column that is
* derived by a referenced field on a different entity.
*/
public function getTypeOfColumn($columnName)
{

View File

@ -25,6 +25,7 @@ use Doctrine\ORM\Persisters\SqlExpressionVisitor;
use Doctrine\ORM\Persisters\SqlValueVisitor;
use Doctrine\ORM\PersistentCollection;
use Doctrine\ORM\Query;
use Doctrine\ORM\Utility\PersisterHelper;
/**
* Persister for many-to-many collections.
@ -61,15 +62,23 @@ class ManyToManyPersister extends AbstractCollectionPersister
return; // ignore inverse side
}
$insertSql = $this->getInsertRowSQL($collection);
$deleteSql = $this->getDeleteRowSQL($collection);
list($deleteSql, $deleteTypes) = $this->getDeleteRowSQL($collection);
list($insertSql, $insertTypes) = $this->getInsertRowSQL($collection);
foreach ($collection->getDeleteDiff() as $element) {
$this->conn->executeUpdate($deleteSql, $this->getDeleteRowSQLParameters($collection, $element));
$this->conn->executeUpdate(
$deleteSql,
$this->getDeleteRowSQLParameters($collection, $element),
$deleteTypes
);
}
foreach ($collection->getInsertDiff() as $element) {
$this->conn->executeUpdate($insertSql, $this->getInsertRowSQLParameters($collection, $element));
$this->conn->executeUpdate(
$insertSql,
$this->getInsertRowSQLParameters($collection, $element),
$insertTypes
);
}
}
@ -99,6 +108,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
{
$conditions = array();
$params = array();
$types = array();
$mapping = $collection->getMapping();
$id = $this->uow->getEntityIdentifier($collection->getOwner());
$sourceClass = $this->em->getClassMetadata($mapping['sourceEntity']);
@ -117,6 +127,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
$referencedName = $joinColumn['referencedColumnName'];
$conditions[] = 't.' . $columnName . ' = ?';
$params[] = $id[$sourceClass->getFieldForColumn($referencedName)];
$types[] = PersisterHelper::getTypeOfColumn($referencedName, $sourceClass, $this->em);
}
list($joinTargetEntitySQL, $filterSql) = $this->getFilterSql($mapping);
@ -147,7 +158,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
. $joinTargetEntitySQL
. ' WHERE ' . implode(' AND ', $conditions);
return $this->conn->fetchColumn($sql, $params);
return $this->conn->fetchColumn($sql, $params, 0, $types);
}
/**
@ -171,11 +182,11 @@ class ManyToManyPersister extends AbstractCollectionPersister
throw new \BadMethodCallException("Selecting a collection by index is only supported on indexed collections.");
}
list($quotedJoinTable, $whereClauses, $params) = $this->getJoinTableRestrictionsWithKey($collection, $key, true);
list($quotedJoinTable, $whereClauses, $params, $types) = $this->getJoinTableRestrictionsWithKey($collection, $key, true);
$sql = 'SELECT 1 FROM ' . $quotedJoinTable . ' WHERE ' . implode(' AND ', $whereClauses);
return (bool) $this->conn->fetchColumn($sql, $params);
return (bool) $this->conn->fetchColumn($sql, $params, 0, $types);
}
/**
@ -187,11 +198,11 @@ class ManyToManyPersister extends AbstractCollectionPersister
return false;
}
list($quotedJoinTable, $whereClauses, $params) = $this->getJoinTableRestrictions($collection, $element, true);
list($quotedJoinTable, $whereClauses, $params, $types) = $this->getJoinTableRestrictions($collection, $element, true);
$sql = 'SELECT 1 FROM ' . $quotedJoinTable . ' WHERE ' . implode(' AND ', $whereClauses);
return (bool) $this->conn->fetchColumn($sql, $params);
return (bool) $this->conn->fetchColumn($sql, $params, 0, $types);
}
/**
@ -203,11 +214,11 @@ class ManyToManyPersister extends AbstractCollectionPersister
return false;
}
list($quotedJoinTable, $whereClauses, $params) = $this->getJoinTableRestrictions($collection, $element, false);
list($quotedJoinTable, $whereClauses, $params, $types) = $this->getJoinTableRestrictions($collection, $element, false);
$sql = 'DELETE FROM ' . $quotedJoinTable . ' WHERE ' . implode(' AND ', $whereClauses);
return (bool) $this->conn->executeUpdate($sql, $params);
return (bool) $this->conn->executeUpdate($sql, $params, $types);
}
/**
@ -397,24 +408,32 @@ class ManyToManyPersister extends AbstractCollectionPersister
*
* @param \Doctrine\ORM\PersistentCollection $collection
*
* @return string
* @return string[]|string[][] ordered tuple containing the SQL to be executed and an array
* of types for bound parameters
*/
protected function getDeleteRowSQL(PersistentCollection $collection)
{
$mapping = $collection->getMapping();
$class = $this->em->getClassMetadata($mapping['sourceEntity']);
$columns = array();
$mapping = $collection->getMapping();
$class = $this->em->getClassMetadata($mapping['sourceEntity']);
$targetClass = $this->em->getClassMetadata($mapping['targetEntity']);
$columns = array();
$types = array();
foreach ($mapping['joinTable']['joinColumns'] as $joinColumn) {
$columns[] = $this->quoteStrategy->getJoinColumnName($joinColumn, $class, $this->platform);
$types[] = PersisterHelper::getTypeOfColumn($joinColumn['referencedColumnName'], $class, $this->em);
}
foreach ($mapping['joinTable']['inverseJoinColumns'] as $joinColumn) {
$columns[] = $this->quoteStrategy->getJoinColumnName($joinColumn, $class, $this->platform);
$columns[] = $this->quoteStrategy->getJoinColumnName($joinColumn, $targetClass, $this->platform);
$types[] = PersisterHelper::getTypeOfColumn($joinColumn['referencedColumnName'], $targetClass, $this->em);
}
return 'DELETE FROM ' . $this->quoteStrategy->getJoinTableName($mapping, $class, $this->platform)
. ' WHERE ' . implode(' = ? AND ', $columns) . ' = ?';
return array(
'DELETE FROM ' . $this->quoteStrategy->getJoinTableName($mapping, $class, $this->platform)
. ' WHERE ' . implode(' = ? AND ', $columns) . ' = ?',
$types,
);
}
/**
@ -438,26 +457,34 @@ class ManyToManyPersister extends AbstractCollectionPersister
*
* @param \Doctrine\ORM\PersistentCollection $collection
*
* @return string
* @return string[]|string[][] ordered tuple containing the SQL to be executed and an array
* of types for bound parameters
*/
protected function getInsertRowSQL(PersistentCollection $collection)
{
$columns = array();
$mapping = $collection->getMapping();
$class = $this->em->getClassMetadata($mapping['sourceEntity']);
$columns = array();
$types = array();
$mapping = $collection->getMapping();
$class = $this->em->getClassMetadata($mapping['sourceEntity']);
$targetClass = $this->em->getClassMetadata($mapping['targetEntity']);
foreach ($mapping['joinTable']['joinColumns'] as $joinColumn) {
$columns[] = $this->quoteStrategy->getJoinColumnName($joinColumn, $class, $this->platform);
$columns[] = $this->quoteStrategy->getJoinColumnName($joinColumn, $targetClass, $this->platform);
$types[] = PersisterHelper::getTypeOfColumn($joinColumn['referencedColumnName'], $class, $this->em);
}
foreach ($mapping['joinTable']['inverseJoinColumns'] as $joinColumn) {
$columns[] = $this->quoteStrategy->getJoinColumnName($joinColumn, $class, $this->platform);
$columns[] = $this->quoteStrategy->getJoinColumnName($joinColumn, $targetClass, $this->platform);
$types[] = PersisterHelper::getTypeOfColumn($joinColumn['referencedColumnName'], $targetClass, $this->em);
}
return 'INSERT INTO ' . $this->quoteStrategy->getJoinTableName($mapping, $class, $this->platform)
return array(
'INSERT INTO ' . $this->quoteStrategy->getJoinTableName($mapping, $class, $this->platform)
. ' (' . implode(', ', $columns) . ')'
. ' VALUES'
. ' (' . implode(', ', array_fill(0, count($columns), '?')) . ')';
. ' (' . implode(', ', array_fill(0, count($columns), '?')) . ')',
$types,
);
}
/**
@ -525,33 +552,40 @@ class ManyToManyPersister extends AbstractCollectionPersister
* @param string $key
* @param boolean $addFilters Whether the filter SQL should be included or not.
*
* @return array
* @return array ordered vector:
* - quoted join table name
* - where clauses to be added for filtering
* - parameters to be bound for filtering
* - types of the parameters to be bound for filtering
*/
private function getJoinTableRestrictionsWithKey(PersistentCollection $collection, $key, $addFilters)
{
$filterMapping = $collection->getMapping();
$mapping = $filterMapping;
$indexBy = $mapping['indexBy'];
$id = $this->uow->getEntityIdentifier($collection->getOwner());
$targetEntity = $this->em->getClassMetadata($mapping['targetEntity']);
$filterMapping = $collection->getMapping();
$mapping = $filterMapping;
$indexBy = $mapping['indexBy'];
$id = $this->uow->getEntityIdentifier($collection->getOwner());
$sourceClass = $this->em->getClassMetadata($mapping['sourceEntity']);
$targetClass = $this->em->getClassMetadata($mapping['targetEntity']);
if (! $mapping['isOwningSide']) {
$associationSourceClass = $this->em->getClassMetadata($mapping['targetEntity']);
$mapping = $associationSourceClass->associationMappings[$mapping['mappedBy']];
$joinColumns = $mapping['joinTable']['joinColumns'];
$relationMode = 'relationToTargetKeyColumns';
$mapping = $associationSourceClass->associationMappings[$mapping['mappedBy']];
$joinColumns = $mapping['joinTable']['joinColumns'];
$sourceRelationMode = 'relationToTargetKeyColumns';
$targetRelationMode = 'relationToSourceKeyColumns';
} else {
$joinColumns = $mapping['joinTable']['inverseJoinColumns'];
$associationSourceClass = $this->em->getClassMetadata($mapping['sourceEntity']);
$relationMode = 'relationToSourceKeyColumns';
$joinColumns = $mapping['joinTable']['inverseJoinColumns'];
$sourceRelationMode = 'relationToSourceKeyColumns';
$targetRelationMode = 'relationToTargetKeyColumns';
}
$quotedJoinTable = $this->quoteStrategy->getJoinTableName($mapping, $associationSourceClass, $this->platform). ' t';
$whereClauses = array();
$params = array();
$types = array();
$joinNeeded = !in_array($indexBy, $targetEntity->identifier);
$joinNeeded = ! in_array($indexBy, $targetClass->identifier);
if ($joinNeeded) { // extra join needed if indexBy is not a @id
$joinConditions = array();
@ -559,21 +593,30 @@ class ManyToManyPersister extends AbstractCollectionPersister
foreach ($joinColumns as $joinTableColumn) {
$joinConditions[] = 't.' . $joinTableColumn['name'] . ' = tr.' . $joinTableColumn['referencedColumnName'];
}
$tableName = $this->quoteStrategy->getTableName($targetEntity, $this->platform);
$tableName = $this->quoteStrategy->getTableName($targetClass, $this->platform);
$quotedJoinTable .= ' JOIN ' . $tableName . ' tr ON ' . implode(' AND ', $joinConditions);
$columnName = $targetClass->getColumnName($indexBy);
$whereClauses[] = 'tr.' . $targetEntity->getColumnName($indexBy) . ' = ?';
$params[] = $key;
$whereClauses[] = 'tr.' . $columnName . ' = ?';
$params[] = $key;
$types[] = PersisterHelper::getTypeOfColumn($columnName, $targetClass, $this->em);
}
foreach ($mapping['joinTableColumns'] as $joinTableColumn) {
if (isset($mapping[$relationMode][$joinTableColumn])) {
if (isset($mapping[$sourceRelationMode][$joinTableColumn])) {
$column = $mapping[$sourceRelationMode][$joinTableColumn];
$whereClauses[] = 't.' . $joinTableColumn . ' = ?';
$params[] = $id[$targetEntity->getFieldForColumn($mapping[$relationMode][$joinTableColumn])];
} elseif (!$joinNeeded) {
$params[] = $sourceClass->containsForeignIdentifier
? $id[$sourceClass->getFieldForColumn($column)]
: $id[$sourceClass->fieldNames[$column]];
$types[] = PersisterHelper::getTypeOfColumn($column, $sourceClass, $this->em);
} elseif ( ! $joinNeeded) {
$column = $mapping[$targetRelationMode][$joinTableColumn];
$whereClauses[] = 't.' . $joinTableColumn . ' = ?';
$params[] = $key;
$params[] = $key;
$types[] = PersisterHelper::getTypeOfColumn($column, $targetClass, $this->em);
}
}
@ -586,7 +629,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
}
}
return array($quotedJoinTable, $whereClauses, $params);
return array($quotedJoinTable, $whereClauses, $params, $types);
}
/**
@ -594,7 +637,11 @@ class ManyToManyPersister extends AbstractCollectionPersister
* @param object $element
* @param boolean $addFilters Whether the filter SQL should be included or not.
*
* @return array
* @return array ordered vector:
* - quoted join table name
* - where clauses to be added for filtering
* - parameters to be bound for filtering
* - types of the parameters to be bound for filtering
*/
private function getJoinTableRestrictions(PersistentCollection $collection, $element, $addFilters)
{
@ -618,18 +665,23 @@ class ManyToManyPersister extends AbstractCollectionPersister
$quotedJoinTable = $this->quoteStrategy->getJoinTableName($mapping, $sourceClass, $this->platform);
$whereClauses = array();
$params = array();
$types = array();
foreach ($mapping['joinTableColumns'] as $joinTableColumn) {
$whereClauses[] = ($addFilters ? 't.' : '') . $joinTableColumn . ' = ?';
if (isset($mapping['relationToTargetKeyColumns'][$joinTableColumn])) {
$params[] = $targetId[$targetClass->getFieldForColumn($mapping['relationToTargetKeyColumns'][$joinTableColumn])];
$targetColumn = $mapping['relationToTargetKeyColumns'][$joinTableColumn];
$params[] = $targetId[$targetClass->getFieldForColumn($targetColumn)];
$types[] = PersisterHelper::getTypeOfColumn($targetColumn, $targetClass, $this->em);
continue;
}
// relationToSourceKeyColumns
$params[] = $sourceId[$sourceClass->getFieldForColumn($mapping['relationToSourceKeyColumns'][$joinTableColumn])];
$targetColumn = $mapping['relationToSourceKeyColumns'][$joinTableColumn];
$params[] = $sourceId[$sourceClass->getFieldForColumn($targetColumn)];
$types[] = PersisterHelper::getTypeOfColumn($targetColumn, $sourceClass, $this->em);
}
if ($addFilters) {
@ -643,7 +695,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
}
}
return array($quotedJoinTable, $whereClauses, $params);
return array($quotedJoinTable, $whereClauses, $params, $types);
}
/**

View File

@ -67,7 +67,17 @@ class OneToManyPersister extends AbstractCollectionPersister
$persister = $this->uow->getEntityPersister($mapping['targetEntity']);
return $persister->load(array($mapping['mappedBy'] => $collection->getOwner(), $mapping['indexBy'] => $index), null, $mapping, array(), null, 1);
return $persister->load(
array(
$mapping['mappedBy'] => $collection->getOwner(),
$mapping['indexBy'] => $index
),
null,
$mapping,
array(),
null,
1
);
}
/**

View File

@ -36,6 +36,7 @@ use Doctrine\ORM\Persisters\SqlValueVisitor;
use Doctrine\ORM\Query;
use Doctrine\ORM\UnitOfWork;
use Doctrine\ORM\Utility\IdentifierFlattener;
use Doctrine\ORM\Utility\PersisterHelper;
/**
* A BasicEntityPersister maps an entity to a single table in a relational database.
@ -610,15 +611,16 @@ class BasicEntityPersister implements EntityPersister
*/
protected function prepareUpdateData($entity)
{
$result = array();
$uow = $this->em->getUnitOfWork();
$versionField = null;
$result = array();
$uow = $this->em->getUnitOfWork();
if (($versioned = $this->class->isVersioned) != false) {
$versionField = $this->class->versionField;
}
foreach ($uow->getEntityChangeSet($entity) as $field => $change) {
if ($versioned && $versionField == $field) {
if (isset($versionField) && $versionField == $field) {
continue;
}
@ -668,7 +670,7 @@ class BasicEntityPersister implements EntityPersister
$quotedColumn = $this->quoteStrategy->getJoinColumnName($joinColumn, $this->class, $this->platform);
$this->quotedColumns[$sourceColumn] = $quotedColumn;
$this->columnTypes[$sourceColumn] = $targetClass->getTypeOfColumn($targetColumn);
$this->columnTypes[$sourceColumn] = PersisterHelper::getTypeOfColumn($targetColumn, $targetClass, $this->em);
$result[$owningTable][$sourceColumn] = $newValId
? $newValId[$targetClass->getFieldForColumn($targetColumn)]
: null;
@ -862,12 +864,12 @@ class BasicEntityPersister implements EntityPersister
list($params, $types) = $valueVisitor->getParamsAndTypes();
foreach ($params as $param) {
$sqlParams[] = $this->getValue($param);
$sqlParams[] = PersisterHelper::getIdentifierValues($param, $this->em);
}
foreach ($types as $type) {
list($field, $value) = $type;
$sqlTypes[] = $this->getType($field, $value);
$sqlTypes[] = $this->getType($field, $value, $this->class);
}
return array($sqlParams, $sqlTypes);
@ -969,7 +971,7 @@ class BasicEntityPersister implements EntityPersister
$class = $sourceClass;
$association = $assoc;
$criteria = array();
$parameters = array();
if ( ! $assoc['isOwningSide']) {
$class = $this->em->getClassMetadata($assoc['targetEntity']);
@ -1012,10 +1014,15 @@ class BasicEntityPersister implements EntityPersister
}
$criteria[$quotedJoinTable . '.' . $quotedKeyColumn] = $value;
$parameters[] = array(
'value' => $value,
'field' => $field,
'class' => $sourceClass,
);
}
$sql = $this->getSelectSQL($criteria, $assoc, null, $limit, $offset);
list($params, $types) = $this->expandParameters($criteria);
list($params, $types) = $this->expandToManyParameters($parameters);
return $this->conn->executeQuery($sql, $params, $types);
}
@ -1309,10 +1316,7 @@ class BasicEntityPersister implements EntityPersister
$resultColumnName = $this->getSQLColumnAlias($joinColumn['name']);
$columnList[] = $this->getSQLTableAlias($class->name, ($alias == 'r' ? '' : $alias) )
. '.' . $quotedColumn . ' AS ' . $resultColumnName;
if (isset($targetClass->fieldNames[$joinColumn['referencedColumnName']])) {
$type = $targetClass->fieldMappings[$targetClass->fieldNames[$joinColumn['referencedColumnName']]]['type'];
}
$type = PersisterHelper::getTypeOfColumn($joinColumn['referencedColumnName'], $targetClass, $this->em);
$this->rsm->addMetaResult($alias, $resultColumnName, $quotedColumn, $isIdentifier, $type);
}
@ -1426,7 +1430,7 @@ class BasicEntityPersister implements EntityPersister
}
if ($this->class->generatorType != ClassMetadata::GENERATOR_TYPE_IDENTITY || $this->class->identifier[0] != $name) {
$columns[] = $this->quoteStrategy->getColumnName($name, $this->class, $this->platform);
$columns[] = $this->quoteStrategy->getColumnName($name, $this->class, $this->platform);
$this->columnTypes[$name] = $this->class->fieldMappings[$name]['type'];
}
}
@ -1713,7 +1717,8 @@ class BasicEntityPersister implements EntityPersister
*/
private function getOneToManyStatement(array $assoc, $sourceEntity, $offset = null, $limit = null)
{
$criteria = array();
$criteria = array();
$parameters = array();
$owningAssoc = $this->class->associationMappings[$assoc['mappedBy']];
$sourceClass = $this->em->getClassMetadata($assoc['sourceEntity']);
@ -1730,15 +1735,29 @@ class BasicEntityPersister implements EntityPersister
}
$criteria[$tableAlias . "." . $targetKeyColumn] = $value;
$parameters[] = array(
'value' => $value,
'field' => $field,
'class' => $sourceClass,
);
continue;
}
$criteria[$tableAlias . "." . $targetKeyColumn] = $sourceClass->reflFields[$sourceClass->fieldNames[$sourceKeyColumn]]->getValue($sourceEntity);
$field = $sourceClass->fieldNames[$sourceKeyColumn];
$value = $sourceClass->reflFields[$field]->getValue($sourceEntity);
$criteria[$tableAlias . "." . $targetKeyColumn] = $value;
$parameters[] = array(
'value' => $value,
'field' => $field,
'class' => $sourceClass,
);
}
$sql = $this->getSelectSQL($criteria, $assoc, null, $limit, $offset);
list($params, $types) = $this->expandParameters($criteria);
$sql = $this->getSelectSQL($criteria, $assoc, null, $limit, $offset);
list($params, $types) = $this->expandToManyParameters($parameters);
return $this->conn->executeQuery($sql, $params, $types);
}
@ -1756,72 +1775,56 @@ class BasicEntityPersister implements EntityPersister
continue; // skip null values.
}
$types[] = $this->getType($field, $value);
$types[] = $this->getType($field, $value, $this->class);
$params[] = $this->getValue($value);
}
return array($params, $types);
}
/**
* Expands the parameters from the given criteria and use the correct binding types if found,
* specialized for OneToMany or ManyToMany associations.
*
* @param mixed[][] $criteria an array of arrays containing following:
* - field to which each criterion will be bound
* - value to be bound
* - class to which the field belongs to
*
*
* @return array
*/
private function expandToManyParameters($criteria)
{
$params = array();
$types = array();
foreach ($criteria as $criterion) {
if ($criterion['value'] === null) {
continue; // skip null values.
}
$types[] = $this->getType($criterion['field'], $criterion['value'], $criterion['class']);
$params[] = PersisterHelper::getIdentifierValues($criterion['value'], $this->em);
}
return array($params, $types);
}
/**
* Infers field type to be used by parameter type casting.
*
* @param string $field
* @param mixed $value
* @param string $fieldName
* @param mixed $value
* @param ClassMetadata $class
*
* @return integer
*
* @throws \Doctrine\ORM\Query\QueryException
*/
private function getType($field, $value)
private function getType($fieldName, $value, ClassMetadata $class)
{
switch (true) {
case (isset($this->class->fieldMappings[$field])):
$type = $this->class->fieldMappings[$field]['type'];
break;
case (isset($this->class->associationMappings[$field]) && $this->class->associationMappings[$field]['type'] === ClassMetadata::MANY_TO_MANY):
$assoc = $this->class->associationMappings[$field];
$targetClass = $this->em->getClassMetadata($assoc['targetEntity']);
if ( ! $assoc['isOwningSide']) {
$assoc = $targetClass->associationMappings[$assoc['mappedBy']];
}
if (count($assoc['relationToTargetKeyColumns']) > 1) {
throw Query\QueryException::associationPathCompositeKeyNotSupported();
}
$targetClass = $this->em->getClassMetadata($assoc['targetEntity']);
$targetColumn = $assoc['joinTable']['inverseJoinColumns'][0]['referencedColumnName'];
$type = null;
if (isset($targetClass->fieldNames[$targetColumn])) {
$type = $targetClass->fieldMappings[$targetClass->fieldNames[$targetColumn]]['type'];
}
break;
case (isset($this->class->associationMappings[$field])):
$assoc = $this->class->associationMappings[$field];
if (count($assoc['sourceToTargetKeyColumns']) > 1) {
throw Query\QueryException::associationPathCompositeKeyNotSupported();
}
$targetClass = $this->em->getClassMetadata($assoc['targetEntity']);
$targetColumn = $assoc['joinColumns'][0]['referencedColumnName'];
$type = null;
if (isset($targetClass->fieldNames[$targetColumn])) {
$type = $targetClass->fieldMappings[$targetClass->fieldNames[$targetColumn]]['type'];
}
break;
default:
$type = null;
}
$type = PersisterHelper::getTypeOfField($fieldName, $class, $this->em);
if (is_array($value)) {
$type = Type::getType($type)->getBindingType();
@ -1886,20 +1889,21 @@ class BasicEntityPersister implements EntityPersister
. $this->getLockTablesSql(null)
. ' WHERE ' . $this->getSelectConditionSQL($criteria);
list($params) = $this->expandParameters($criteria);
list($params, $types) = $this->expandParameters($criteria);
if (null !== $extraConditions) {
$sql .= ' AND ' . $this->getSelectConditionCriteriaSQL($extraConditions);
list($criteriaParams, $values) = $this->expandCriteriaParameters($extraConditions);
$sql .= ' AND ' . $this->getSelectConditionCriteriaSQL($extraConditions);
list($criteriaParams, $criteriaTypes) = $this->expandCriteriaParameters($extraConditions);
$params = array_merge($params, $criteriaParams);
$types = array_merge($types, $criteriaTypes);
}
if ($filterSql = $this->generateFilterConditionSQL($this->class, $alias)) {
$sql .= ' AND ' . $filterSql;
}
return (bool) $this->conn->fetchColumn($sql, $params);
return (bool) $this->conn->fetchColumn($sql, $params, 0, $types);
}
/**

View File

@ -0,0 +1,172 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Utility;
use Doctrine\Common\Util\ClassUtils;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\Query\QueryException;
/**
* The PersisterHelper contains logic to infer binding types which is used in
* several persisters.
*
* @link www.doctrine-project.org
* @since 2.5
* @author Jasper N. Brouwer <jasper@nerdsweide.nl>
*/
class PersisterHelper
{
/**
* @param string $fieldName
* @param ClassMetadata $class
* @param EntityManagerInterface $em
*
* @return string|null
*
* @throws QueryException
*/
public static function getTypeOfField($fieldName, ClassMetadata $class, EntityManagerInterface $em)
{
if (isset($class->fieldMappings[$fieldName])) {
return $class->fieldMappings[$fieldName]['type'];
}
if ( ! isset($class->associationMappings[$fieldName])) {
return null;
}
$assoc = $class->associationMappings[$fieldName];
if (! $assoc['isOwningSide']) {
return self::getTypeOfField($assoc['mappedBy'], $em->getClassMetadata($assoc['targetEntity']), $em);
}
if (($assoc['type'] & ClassMetadata::MANY_TO_MANY) > 0) {
$joinData = $assoc['joinTable'];
} else {
$joinData = $assoc;
}
if (count($joinData['joinColumns']) > 1) {
throw QueryException::associationPathCompositeKeyNotSupported();
}
$targetColumnName = $joinData['joinColumns'][0]['referencedColumnName'];
$targetClass = $em->getClassMetadata($assoc['targetEntity']);
return self::getTypeOfColumn($targetColumnName, $targetClass, $em);
}
/**
* @param string $columnName
* @param ClassMetadata $class
* @param EntityManagerInterface $em
*
* @return string
*
* @throws \RuntimeException
*/
public static function getTypeOfColumn($columnName, ClassMetadata $class, EntityManagerInterface $em)
{
if (isset($class->fieldNames[$columnName])) {
$fieldName = $class->fieldNames[$columnName];
if (isset($class->fieldMappings[$fieldName])) {
return $class->fieldMappings[$fieldName]['type'];
}
}
// iterate over to-one association mappings
foreach ($class->associationMappings as $assoc) {
if ( ! isset($assoc['joinColumns'])) {
continue;
}
foreach ($assoc['joinColumns'] as $joinColumn) {
if ($joinColumn['name'] == $columnName) {
$targetColumnName = $joinColumn['referencedColumnName'];
$targetClass = $em->getClassMetadata($assoc['targetEntity']);
return self::getTypeOfColumn($targetColumnName, $targetClass, $em);
}
}
}
// iterate over to-many association mappings
foreach ($class->associationMappings as $assoc) {
if ( ! (isset($assoc['joinTable']) && isset($assoc['joinTable']['joinColumns']))) {
continue;
}
foreach ($assoc['joinTable']['joinColumns'] as $joinColumn) {
if ($joinColumn['name'] == $columnName) {
$targetColumnName = $joinColumn['referencedColumnName'];
$targetClass = $em->getClassMetadata($assoc['targetEntity']);
return self::getTypeOfColumn($targetColumnName, $targetClass, $em);
}
}
}
throw new \RuntimeException(sprintf(
'Could not resolve type of column "%s" of class "%s"',
$columnName,
$class->getName()
));
}
/**
* @param mixed $value
* @param EntityManagerInterface $em
*
* @return mixed
*/
public static function getIdentifierValues($value, EntityManagerInterface $em)
{
if ( ! is_array($value)) {
return self::getIndividualValue($value, $em);
}
$newValue = array();
foreach ($value as $fieldName => $fieldValue) {
$newValue[$fieldName] = self::getIndividualValue($fieldValue, $em);
}
return $newValue;
}
/**
* @param mixed $value
* @param EntityManagerInterface $em
*
* @return mixed
*/
private static function getIndividualValue($value, EntityManagerInterface $em)
{
if ( ! is_object($value) || ! $em->getMetadataFactory()->hasMetadataFor(ClassUtils::getClass($value))) {
return $value;
}
return $em->getUnitOfWork()->getSingleIdentifierValue($value);
}
}

View File

@ -0,0 +1,81 @@
<?php
namespace Doctrine\Tests\DbalTypes;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Types\Type;
/**
* Shifts every letter by 13 places in the alphabet (ROT13 encoding).
*/
class Rot13Type extends Type
{
/**
* {@inheritdoc}
*
* @param string|null $value
* @param AbstractPlatform $platform
*
* @return string|null
*/
public function convertToDatabaseValue($value, AbstractPlatform $platform)
{
if ($value === null) {
return null;
}
return str_rot13($value);
}
/**
* {@inheritdoc}
*
* @param string|null $value
* @param AbstractPlatform $platform
*
* @return string|null
*/
public function convertToPHPValue($value, AbstractPlatform $platform)
{
if ($value === null) {
return null;
}
return str_rot13($value);
}
/**
* {@inheritdoc}
*
* @param array $fieldDeclaration
* @param AbstractPlatform $platform
*
* @return string
*/
public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
{
return $platform->getVarcharTypeDeclarationSQL($fieldDeclaration);
}
/**
* {@inheritdoc}
*
* @param AbstractPlatform $platform
*
* @return int|null
*/
public function getDefaultLength(AbstractPlatform $platform)
{
return $platform->getVarcharDefaultLength();
}
/**
* {@inheritdoc}
*
* @return string
*/
public function getName()
{
return 'rot13';
}
}

View File

@ -0,0 +1,16 @@
<?php
namespace Doctrine\Tests\Models\ValueConversionType;
/**
* @Entity
* @Table(name="vct_auxiliary")
*/
class AuxiliaryEntity
{
/**
* @Column(type="rot13")
* @Id
*/
public $id4;
}

View File

@ -0,0 +1,34 @@
<?php
namespace Doctrine\Tests\Models\ValueConversionType;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @Entity
* @Table(name="vct_inversed_manytomany_compositeid")
*/
class InversedManyToManyCompositeIdEntity
{
/**
* @Column(type="rot13")
* @Id
*/
public $id1;
/**
* @Column(type="rot13")
* @Id
*/
public $id2;
/**
* @ManyToMany(targetEntity="OwningManyToManyCompositeIdEntity", mappedBy="associatedEntities")
*/
public $associatedEntities;
public function __construct()
{
$this->associatedEntities = new ArrayCollection();
}
}

View File

@ -0,0 +1,35 @@
<?php
namespace Doctrine\Tests\Models\ValueConversionType;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @Entity
* @Table(name="vct_inversed_manytomany_compositeid_foreignkey")
*/
class InversedManyToManyCompositeIdForeignKeyEntity
{
/**
* @Column(type="rot13")
* @Id
*/
public $id1;
/**
* @ManyToOne(targetEntity="AuxiliaryEntity")
* @JoinColumn(name="foreign_id", referencedColumnName="id4")
* @Id
*/
public $foreignEntity;
/**
* @ManyToMany(targetEntity="OwningManyToManyCompositeIdForeignKeyEntity", mappedBy="associatedEntities")
*/
public $associatedEntities;
public function __construct()
{
$this->associatedEntities = new ArrayCollection();
}
}

View File

@ -0,0 +1,28 @@
<?php
namespace Doctrine\Tests\Models\ValueConversionType;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @Entity
* @Table(name="vct_inversed_manytomany")
*/
class InversedManyToManyEntity
{
/**
* @Column(type="rot13")
* @Id
*/
public $id1;
/**
* @ManyToMany(targetEntity="OwningManyToManyEntity", mappedBy="associatedEntities")
*/
public $associatedEntities;
public function __construct()
{
$this->associatedEntities = new ArrayCollection();
}
}

View File

@ -0,0 +1,33 @@
<?php
namespace Doctrine\Tests\Models\ValueConversionType;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @Entity
* @Table(name="vct_inversed_manytomany_extralazy")
*/
class InversedManyToManyExtraLazyEntity
{
/**
* @Column(type="rot13")
* @Id
*/
public $id1;
/**
* @ManyToMany(
* targetEntity="OwningManyToManyExtraLazyEntity",
* mappedBy="associatedEntities",
* fetch="EXTRA_LAZY",
* indexBy="id2"
* )
*/
public $associatedEntities;
public function __construct()
{
$this->associatedEntities = new ArrayCollection();
}
}

View File

@ -0,0 +1,39 @@
<?php
namespace Doctrine\Tests\Models\ValueConversionType;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @Entity
* @Table(name="vct_inversed_onetomany_compositeid")
*/
class InversedOneToManyCompositeIdEntity
{
/**
* @Column(type="rot13")
* @Id
*/
public $id1;
/**
* @Column(type="rot13")
* @Id
*/
public $id2;
/**
* @Column(type="string", name="some_property")
*/
public $someProperty;
/**
* @OneToMany(targetEntity="OwningManyToOneCompositeIdEntity", mappedBy="associatedEntity")
*/
public $associatedEntities;
public function __construct()
{
$this->associatedEntities = new ArrayCollection();
}
}

View File

@ -0,0 +1,40 @@
<?php
namespace Doctrine\Tests\Models\ValueConversionType;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @Entity
* @Table(name="vct_inversed_onetomany_compositeid_foreignkey")
*/
class InversedOneToManyCompositeIdForeignKeyEntity
{
/**
* @Column(type="rot13")
* @Id
*/
public $id1;
/**
* @ManyToOne(targetEntity="AuxiliaryEntity")
* @JoinColumn(name="foreign_id", referencedColumnName="id4")
* @Id
*/
public $foreignEntity;
/**
* @Column(type="string", name="some_property")
*/
public $someProperty;
/**
* @OneToMany(targetEntity="OwningManyToOneCompositeIdForeignKeyEntity", mappedBy="associatedEntity")
*/
public $associatedEntities;
public function __construct()
{
$this->associatedEntities = new ArrayCollection();
}
}

View File

@ -0,0 +1,33 @@
<?php
namespace Doctrine\Tests\Models\ValueConversionType;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @Entity
* @Table(name="vct_inversed_onetomany")
*/
class InversedOneToManyEntity
{
/**
* @Column(type="rot13")
* @Id
*/
public $id1;
/**
* @OneToMany(targetEntity="OwningManyToOneEntity", mappedBy="associatedEntity")
*/
public $associatedEntities;
/**
* @Column(type="string", name="some_property")
*/
public $someProperty;
public function __construct()
{
$this->associatedEntities = new ArrayCollection();
}
}

View File

@ -0,0 +1,33 @@
<?php
namespace Doctrine\Tests\Models\ValueConversionType;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @Entity
* @Table(name="vct_inversed_onetomany_extralazy")
*/
class InversedOneToManyExtraLazyEntity
{
/**
* @Column(type="rot13")
* @Id
*/
public $id1;
/**
* @OneToMany(
* targetEntity="OwningManyToOneExtraLazyEntity",
* mappedBy="associatedEntity",
* fetch="EXTRA_LAZY",
* indexBy="id2"
* )
*/
public $associatedEntities;
public function __construct()
{
$this->associatedEntities = new ArrayCollection();
}
}

View File

@ -0,0 +1,32 @@
<?php
namespace Doctrine\Tests\Models\ValueConversionType;
/**
* @Entity
* @Table(name="vct_inversed_onetoone_compositeid")
*/
class InversedOneToOneCompositeIdEntity
{
/**
* @Column(type="rot13")
* @Id
*/
public $id1;
/**
* @Column(type="rot13")
* @Id
*/
public $id2;
/**
* @Column(type="string", name="some_property")
*/
public $someProperty;
/**
* @OneToOne(targetEntity="OwningOneToOneCompositeIdEntity", mappedBy="associatedEntity")
*/
public $associatedEntity;
}

View File

@ -0,0 +1,33 @@
<?php
namespace Doctrine\Tests\Models\ValueConversionType;
/**
* @Entity
* @Table(name="vct_inversed_onetoone_compositeid_foreignkey")
*/
class InversedOneToOneCompositeIdForeignKeyEntity
{
/**
* @Column(type="rot13")
* @Id
*/
public $id1;
/**
* @ManyToOne(targetEntity="AuxiliaryEntity")
* @JoinColumn(name="foreign_id", referencedColumnName="id4")
* @Id
*/
public $foreignEntity;
/**
* @Column(type="string", name="some_property")
*/
public $someProperty;
/**
* @OneToOne(targetEntity="OwningOneToOneCompositeIdForeignKeyEntity", mappedBy="associatedEntity")
*/
public $associatedEntity;
}

View File

@ -0,0 +1,26 @@
<?php
namespace Doctrine\Tests\Models\ValueConversionType;
/**
* @Entity
* @Table(name="vct_inversed_onetoone")
*/
class InversedOneToOneEntity
{
/**
* @Column(type="rot13")
* @Id
*/
public $id1;
/**
* @Column(type="string", name="some_property")
*/
public $someProperty;
/**
* @OneToOne(targetEntity="OwningOneToOneEntity", mappedBy="associatedEntity")
*/
public $associatedEntity;
}

View File

@ -0,0 +1,36 @@
<?php
namespace Doctrine\Tests\Models\ValueConversionType;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @Entity
* @Table(name="vct_owning_manytomany_compositeid")
*/
class OwningManyToManyCompositeIdEntity
{
/**
* @Column(type="rot13")
* @Id
*/
public $id3;
/**
* @ManyToMany(targetEntity="InversedManyToManyCompositeIdEntity", inversedBy="associatedEntities")
* @JoinTable(
* name="vct_xref_manytomany_compositeid",
* joinColumns={@JoinColumn(name="owning_id", referencedColumnName="id3")},
* inverseJoinColumns={
* @JoinColumn(name="inversed_id1", referencedColumnName="id1"),
* @JoinColumn(name="inversed_id2", referencedColumnName="id2")
* }
* )
*/
public $associatedEntities;
public function __construct()
{
$this->associatedEntities = new ArrayCollection();
}
}

View File

@ -0,0 +1,36 @@
<?php
namespace Doctrine\Tests\Models\ValueConversionType;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @Entity
* @Table(name="vct_owning_manytomany_compositeid_foreignkey")
*/
class OwningManyToManyCompositeIdForeignKeyEntity
{
/**
* @Column(type="rot13")
* @Id
*/
public $id2;
/**
* @ManyToMany(targetEntity="InversedManyToManyCompositeIdForeignKeyEntity", inversedBy="associatedEntities")
* @JoinTable(
* name="vct_xref_manytomany_compositeid_foreignkey",
* joinColumns={@JoinColumn(name="owning_id", referencedColumnName="id2")},
* inverseJoinColumns={
* @JoinColumn(name="associated_id", referencedColumnName="id1"),
* @JoinColumn(name="associated_foreign_id", referencedColumnName="foreign_id")
* }
* )
*/
public $associatedEntities;
public function __construct()
{
$this->associatedEntities = new ArrayCollection();
}
}

View File

@ -0,0 +1,33 @@
<?php
namespace Doctrine\Tests\Models\ValueConversionType;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @Entity
* @Table(name="vct_owning_manytomany")
*/
class OwningManyToManyEntity
{
/**
* @Column(type="rot13")
* @Id
*/
public $id2;
/**
* @ManyToMany(targetEntity="InversedManyToManyEntity", inversedBy="associatedEntities")
* @JoinTable(
* name="vct_xref_manytomany",
* joinColumns={@JoinColumn(name="owning_id", referencedColumnName="id2")},
* inverseJoinColumns={@JoinColumn(name="inversed_id", referencedColumnName="id1")}
* )
*/
public $associatedEntities;
public function __construct()
{
$this->associatedEntities = new ArrayCollection();
}
}

View File

@ -0,0 +1,38 @@
<?php
namespace Doctrine\Tests\Models\ValueConversionType;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @Entity
* @Table(name="vct_owning_manytomany_extralazy")
*/
class OwningManyToManyExtraLazyEntity
{
/**
* @Column(type="rot13")
* @Id
*/
public $id2;
/**
* @ManyToMany(
* targetEntity="InversedManyToManyExtraLazyEntity",
* inversedBy="associatedEntities",
* fetch="EXTRA_LAZY",
* indexBy="id1"
* )
* @JoinTable(
* name="vct_xref_manytomany_extralazy",
* joinColumns={@JoinColumn(name="owning_id", referencedColumnName="id2")},
* inverseJoinColumns={@JoinColumn(name="inversed_id", referencedColumnName="id1")}
* )
*/
public $associatedEntities;
public function __construct()
{
$this->associatedEntities = new ArrayCollection();
}
}

View File

@ -0,0 +1,25 @@
<?php
namespace Doctrine\Tests\Models\ValueConversionType;
/**
* @Entity
* @Table(name="vct_owning_manytoone_compositeid")
*/
class OwningManyToOneCompositeIdEntity
{
/**
* @Column(type="rot13")
* @Id
*/
public $id3;
/**
* @ManyToOne(targetEntity="InversedOneToManyCompositeIdEntity", inversedBy="associatedEntities")
* @JoinColumns({
* @JoinColumn(name="associated_id1", referencedColumnName="id1"),
* @JoinColumn(name="associated_id2", referencedColumnName="id2")
* })
*/
public $associatedEntity;
}

View File

@ -0,0 +1,25 @@
<?php
namespace Doctrine\Tests\Models\ValueConversionType;
/**
* @Entity
* @Table(name="vct_owning_manytoone_compositeid_foreignkey")
*/
class OwningManyToOneCompositeIdForeignKeyEntity
{
/**
* @Column(type="rot13")
* @Id
*/
public $id2;
/**
* @ManyToOne(targetEntity="InversedOneToManyCompositeIdForeignKeyEntity", inversedBy="associatedEntities")
* @JoinColumns({
* @JoinColumn(name="associated_id", referencedColumnName="id1"),
* @JoinColumn(name="associated_foreign_id", referencedColumnName="foreign_id")
* })
*/
public $associatedEntity;
}

View File

@ -0,0 +1,22 @@
<?php
namespace Doctrine\Tests\Models\ValueConversionType;
/**
* @Entity
* @Table(name="vct_owning_manytoone")
*/
class OwningManyToOneEntity
{
/**
* @Column(type="rot13")
* @Id
*/
public $id2;
/**
* @ManyToOne(targetEntity="InversedOneToManyEntity", inversedBy="associatedEntities")
* @JoinColumn(name="associated_id", referencedColumnName="id1")
*/
public $associatedEntity;
}

View File

@ -0,0 +1,22 @@
<?php
namespace Doctrine\Tests\Models\ValueConversionType;
/**
* @Entity
* @Table(name="vct_owning_manytoone_extralazy")
*/
class OwningManyToOneExtraLazyEntity
{
/**
* @Column(type="rot13")
* @Id
*/
public $id2;
/**
* @ManyToOne(targetEntity="InversedOneToManyExtraLazyEntity", inversedBy="associatedEntities")
* @JoinColumn(name="associated_id", referencedColumnName="id1")
*/
public $associatedEntity;
}

View File

@ -0,0 +1,25 @@
<?php
namespace Doctrine\Tests\Models\ValueConversionType;
/**
* @Entity
* @Table(name="vct_owning_onetoone_compositeid")
*/
class OwningOneToOneCompositeIdEntity
{
/**
* @Column(type="rot13")
* @Id
*/
public $id3;
/**
* @OneToOne(targetEntity="InversedOneToOneCompositeIdEntity", inversedBy="associatedEntity")
* @JoinColumns({
* @JoinColumn(name="associated_id1", referencedColumnName="id1"),
* @JoinColumn(name="associated_id2", referencedColumnName="id2")
* })
*/
public $associatedEntity;
}

View File

@ -0,0 +1,30 @@
<?php
namespace Doctrine\Tests\Models\ValueConversionType;
/**
* @Entity
* @Table(
* name="vct_owning_onetoone_compositeid_foreignkey",
* uniqueConstraints={
* @UniqueConstraint(name="associated_entity_uniq", columns={"associated_id", "associated_foreign_id"})
* }
* )
*/
class OwningOneToOneCompositeIdForeignKeyEntity
{
/**
* @Column(type="rot13")
* @Id
*/
public $id2;
/**
* @OneToOne(targetEntity="InversedOneToOneCompositeIdForeignKeyEntity", inversedBy="associatedEntity")
* @JoinColumns({
* @JoinColumn(name="associated_id", referencedColumnName="id1"),
* @JoinColumn(name="associated_foreign_id", referencedColumnName="foreign_id")
* })
*/
public $associatedEntity;
}

View File

@ -0,0 +1,22 @@
<?php
namespace Doctrine\Tests\Models\ValueConversionType;
/**
* @Entity
* @Table(name="vct_owning_onetoone")
*/
class OwningOneToOneEntity
{
/**
* @Column(type="rot13")
* @Id
*/
public $id2;
/**
* @OneToOne(targetEntity="InversedOneToOneEntity", inversedBy="associatedEntity")
* @JoinColumn(name="associated_id", referencedColumnName="id1")
*/
public $associatedEntity;
}

View File

@ -2,6 +2,7 @@
namespace Doctrine\Tests\ORM\Functional;
use Doctrine\DBAL\Types\Type as DBALType;
use Doctrine\ORM\Tools\SchemaValidator;
/**

View File

@ -0,0 +1,195 @@
<?php
namespace Doctrine\Tests\ORM\Functional\ValueConversionType;
use Doctrine\DBAL\Types\Type as DBALType;
use Doctrine\Tests\Models\ValueConversionType as Entity;
use Doctrine\Tests\OrmFunctionalTestCase;
/**
* The entities all use a custom type that converst the value as identifier(s).
* {@see \Doctrine\Tests\DbalTypes\Rot13Type}
*
* Test that ManyToMany associations with composite id of which one is a
* association itself work correctly.
*
* @group DDC-3380
*/
class ManyToManyCompositeIdForeignKeyTest extends OrmFunctionalTestCase
{
public function setUp()
{
$this->useModelSet('vct_manytomany_compositeid_foreignkey');
parent::setUp();
$auxiliary = new Entity\AuxiliaryEntity();
$auxiliary->id4 = 'abc';
$inversed = new Entity\InversedManyToManyCompositeIdForeignKeyEntity();
$inversed->id1 = 'def';
$inversed->foreignEntity = $auxiliary;
$owning = new Entity\OwningManyToManyCompositeIdForeignKeyEntity();
$owning->id2 = 'ghi';
$inversed->associatedEntities->add($owning);
$owning->associatedEntities->add($inversed);
$this->_em->persist($auxiliary);
$this->_em->persist($inversed);
$this->_em->persist($owning);
$this->_em->flush();
$this->_em->clear();
}
public static function tearDownAfterClass()
{
$conn = static::$_sharedConn;
$conn->executeUpdate('DROP TABLE vct_xref_manytomany_compositeid_foreignkey');
$conn->executeUpdate('DROP TABLE vct_owning_manytomany_compositeid_foreignkey');
$conn->executeUpdate('DROP TABLE vct_inversed_manytomany_compositeid_foreignkey');
$conn->executeUpdate('DROP TABLE vct_auxiliary');
}
public function testThatTheValueOfIdentifiersAreConvertedInTheDatabase()
{
$conn = $this->_em->getConnection();
$this->assertEquals('nop', $conn->fetchColumn('SELECT id4 FROM vct_auxiliary LIMIT 1'));
$this->assertEquals('qrs', $conn->fetchColumn('SELECT id1 FROM vct_inversed_manytomany_compositeid_foreignkey LIMIT 1'));
$this->assertEquals('nop', $conn->fetchColumn('SELECT foreign_id FROM vct_inversed_manytomany_compositeid_foreignkey LIMIT 1'));
$this->assertEquals('tuv', $conn->fetchColumn('SELECT id2 FROM vct_owning_manytomany_compositeid_foreignkey LIMIT 1'));
$this->assertEquals('qrs', $conn->fetchColumn('SELECT associated_id FROM vct_xref_manytomany_compositeid_foreignkey LIMIT 1'));
$this->assertEquals('nop', $conn->fetchColumn('SELECT associated_foreign_id FROM vct_xref_manytomany_compositeid_foreignkey LIMIT 1'));
$this->assertEquals('tuv', $conn->fetchColumn('SELECT owning_id FROM vct_xref_manytomany_compositeid_foreignkey LIMIT 1'));
}
/**
* @depends testThatTheValueOfIdentifiersAreConvertedInTheDatabase
*/
public function testThatEntitiesAreFetchedFromTheDatabase()
{
$auxiliary = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\AuxiliaryEntity',
'abc'
);
$inversed = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\InversedManyToManyCompositeIdForeignKeyEntity',
array('id1' => 'def', 'foreignEntity' => 'abc')
);
$owning = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\OwningManyToManyCompositeIdForeignKeyEntity',
'ghi'
);
$this->assertInstanceOf('Doctrine\Tests\Models\ValueConversionType\AuxiliaryEntity', $auxiliary);
$this->assertInstanceOf('Doctrine\Tests\Models\ValueConversionType\InversedManyToManyCompositeIdForeignKeyEntity', $inversed);
$this->assertInstanceOf('Doctrine\Tests\Models\ValueConversionType\OwningManyToManyCompositeIdForeignKeyEntity', $owning);
}
/**
* @depends testThatEntitiesAreFetchedFromTheDatabase
*/
public function testThatTheValueOfIdentifiersAreConvertedBackAfterBeingFetchedFromTheDatabase()
{
$auxiliary = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\AuxiliaryEntity',
'abc'
);
$inversed = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\InversedManyToManyCompositeIdForeignKeyEntity',
array('id1' => 'def', 'foreignEntity' => 'abc')
);
$owning = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\OwningManyToManyCompositeIdForeignKeyEntity',
'ghi'
);
$this->assertEquals('abc', $auxiliary->id4);
$this->assertEquals('def', $inversed->id1);
$this->assertEquals('abc', $inversed->foreignEntity->id4);
$this->assertEquals('ghi', $owning->id2);
}
/**
* @depends testThatTheValueOfIdentifiersAreConvertedBackAfterBeingFetchedFromTheDatabase
*/
public function testThatInversedEntityIsFetchedFromTheDatabaseUsingAuxiliaryEntityAsId()
{
$auxiliary = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\AuxiliaryEntity',
'abc'
);
$inversed = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\InversedManyToManyCompositeIdForeignKeyEntity',
array('id1' => 'def', 'foreignEntity' => $auxiliary)
);
$this->assertInstanceOf('Doctrine\Tests\Models\ValueConversionType\InversedManyToManyCompositeIdForeignKeyEntity', $inversed);
}
/**
* @depends testThatEntitiesAreFetchedFromTheDatabase
*/
public function testThatTheCollectionFromOwningToInversedIsLoaded()
{
$owning = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\OwningManyToManyCompositeIdForeignKeyEntity',
'ghi'
);
$this->assertCount(1, $owning->associatedEntities);
}
/**
* @depends testThatEntitiesAreFetchedFromTheDatabase
*/
public function testThatTheCollectionFromInversedToOwningIsLoaded()
{
$inversed = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\InversedManyToManyCompositeIdForeignKeyEntity',
array('id1' => 'def', 'foreignEntity' => 'abc')
);
$this->assertCount(1, $inversed->associatedEntities);
}
/**
* @depends testThatTheCollectionFromOwningToInversedIsLoaded
* @depends testThatTheCollectionFromInversedToOwningIsLoaded
*/
public function testThatTheJoinTableRowsAreRemovedWhenRemovingTheAssociation()
{
$conn = $this->_em->getConnection();
// remove association
$inversed = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\InversedManyToManyCompositeIdForeignKeyEntity',
array('id1' => 'def', 'foreignEntity' => 'abc')
);
foreach ($inversed->associatedEntities as $owning) {
$inversed->associatedEntities->removeElement($owning);
$owning->associatedEntities->removeElement($inversed);
}
$this->_em->flush();
$this->_em->clear();
// test association is removed
$this->assertEquals(0, $conn->fetchColumn('SELECT COUNT(*) FROM vct_xref_manytomany_compositeid_foreignkey'));
}
}

View File

@ -0,0 +1,157 @@
<?php
namespace Doctrine\Tests\ORM\Functional\ValueConversionType;
use Doctrine\DBAL\Types\Type as DBALType;
use Doctrine\Tests\Models\ValueConversionType as Entity;
use Doctrine\Tests\OrmFunctionalTestCase;
/**
* The entities all use a custom type that converst the value as identifier(s).
* {@see \Doctrine\Tests\DbalTypes\Rot13Type}
*
* Test that ManyToMany associations with composite id work correctly.
*
* @group DDC-3380
*/
class ManyToManyCompositeIdTest extends OrmFunctionalTestCase
{
public function setUp()
{
$this->useModelSet('vct_manytomany_compositeid');
parent::setUp();
$inversed = new Entity\InversedManyToManyCompositeIdEntity();
$inversed->id1 = 'abc';
$inversed->id2 = 'def';
$owning = new Entity\OwningManyToManyCompositeIdEntity();
$owning->id3 = 'ghi';
$inversed->associatedEntities->add($owning);
$owning->associatedEntities->add($inversed);
$this->_em->persist($inversed);
$this->_em->persist($owning);
$this->_em->flush();
$this->_em->clear();
}
public static function tearDownAfterClass()
{
$conn = static::$_sharedConn;
$conn->executeUpdate('DROP TABLE vct_xref_manytomany_compositeid');
$conn->executeUpdate('DROP TABLE vct_owning_manytomany_compositeid');
$conn->executeUpdate('DROP TABLE vct_inversed_manytomany_compositeid');
}
public function testThatTheValueOfIdentifiersAreConvertedInTheDatabase()
{
$conn = $this->_em->getConnection();
$this->assertEquals('nop', $conn->fetchColumn('SELECT id1 FROM vct_inversed_manytomany_compositeid LIMIT 1'));
$this->assertEquals('qrs', $conn->fetchColumn('SELECT id2 FROM vct_inversed_manytomany_compositeid LIMIT 1'));
$this->assertEquals('tuv', $conn->fetchColumn('SELECT id3 FROM vct_owning_manytomany_compositeid LIMIT 1'));
$this->assertEquals('nop', $conn->fetchColumn('SELECT inversed_id1 FROM vct_xref_manytomany_compositeid LIMIT 1'));
$this->assertEquals('qrs', $conn->fetchColumn('SELECT inversed_id2 FROM vct_xref_manytomany_compositeid LIMIT 1'));
$this->assertEquals('tuv', $conn->fetchColumn('SELECT owning_id FROM vct_xref_manytomany_compositeid LIMIT 1'));
}
/**
* @depends testThatTheValueOfIdentifiersAreConvertedInTheDatabase
*/
public function testThatEntitiesAreFetchedFromTheDatabase()
{
$inversed = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\InversedManyToManyCompositeIdEntity',
array('id1' => 'abc', 'id2' => 'def')
);
$owning = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\OwningManyToManyCompositeIdEntity',
'ghi'
);
$this->assertInstanceOf('Doctrine\Tests\Models\ValueConversionType\InversedManyToManyCompositeIdEntity', $inversed);
$this->assertInstanceOf('Doctrine\Tests\Models\ValueConversionType\OwningManyToManyCompositeIdEntity', $owning);
}
/**
* @depends testThatEntitiesAreFetchedFromTheDatabase
*/
public function testThatTheValueOfIdentifiersAreConvertedBackAfterBeingFetchedFromTheDatabase()
{
$inversed = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\InversedManyToManyCompositeIdEntity',
array('id1' => 'abc', 'id2' => 'def')
);
$owning = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\OwningManyToManyCompositeIdEntity',
'ghi'
);
$this->assertEquals('abc', $inversed->id1);
$this->assertEquals('def', $inversed->id2);
$this->assertEquals('ghi', $owning->id3);
}
/**
* @depends testThatEntitiesAreFetchedFromTheDatabase
*/
public function testThatTheCollectionFromOwningToInversedIsLoaded()
{
$owning = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\OwningManyToManyCompositeIdEntity',
'ghi'
);
$this->assertCount(1, $owning->associatedEntities);
}
/**
* @depends testThatEntitiesAreFetchedFromTheDatabase
*/
public function testThatTheCollectionFromInversedToOwningIsLoaded()
{
$inversed = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\InversedManyToManyCompositeIdEntity',
array('id1' => 'abc', 'id2' => 'def')
);
$this->assertCount(1, $inversed->associatedEntities);
}
/**
* @depends testThatTheCollectionFromOwningToInversedIsLoaded
* @depends testThatTheCollectionFromInversedToOwningIsLoaded
*/
public function testThatTheJoinTableRowsAreRemovedWhenRemovingTheAssociation()
{
$conn = $this->_em->getConnection();
// remove association
$inversed = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\InversedManyToManyCompositeIdEntity',
array('id1' => 'abc', 'id2' => 'def')
);
foreach ($inversed->associatedEntities as $owning) {
$inversed->associatedEntities->removeElement($owning);
$owning->associatedEntities->removeElement($inversed);
}
$this->_em->flush();
$this->_em->clear();
// test association is removed
$this->assertEquals(0, $conn->fetchColumn('SELECT COUNT(*) FROM vct_xref_manytomany_compositeid'));
}
}

View File

@ -0,0 +1,154 @@
<?php
namespace Doctrine\Tests\ORM\Functional\ValueConversionType;
use Doctrine\DBAL\Types\Type as DBALType;
use Doctrine\Tests\Models\ValueConversionType as Entity;
use Doctrine\Tests\OrmFunctionalTestCase;
/**
* The entities all use a custom type that converst the value as identifier(s).
* {@see \Doctrine\Tests\DbalTypes\Rot13Type}
*
* Test that ManyToMany associations work correctly, focusing on EXTRA_LAZY
* functionality.
*
* @group DDC-3380
*/
class ManyToManyExtraLazyTest extends OrmFunctionalTestCase
{
public function setUp()
{
$this->useModelSet('vct_manytomany_extralazy');
parent::setUp();
$inversed1 = new Entity\InversedManyToManyExtraLazyEntity();
$inversed1->id1 = 'abc';
$inversed2 = new Entity\InversedManyToManyExtraLazyEntity();
$inversed2->id1 = 'def';
$owning1 = new Entity\OwningManyToManyExtraLazyEntity();
$owning1->id2 = 'ghi';
$owning2 = new Entity\OwningManyToManyExtraLazyEntity();
$owning2->id2 = 'jkl';
$inversed1->associatedEntities->add($owning1);
$owning1->associatedEntities->add($inversed1);
$inversed1->associatedEntities->add($owning2);
$owning2->associatedEntities->add($inversed1);
$inversed2->associatedEntities->add($owning1);
$owning1->associatedEntities->add($inversed2);
$inversed2->associatedEntities->add($owning2);
$owning2->associatedEntities->add($inversed2);
$this->_em->persist($inversed1);
$this->_em->persist($inversed2);
$this->_em->persist($owning1);
$this->_em->persist($owning2);
$this->_em->flush();
$this->_em->clear();
}
public static function tearDownAfterClass()
{
$conn = static::$_sharedConn;
$conn->executeUpdate('DROP TABLE vct_xref_manytomany_extralazy');
$conn->executeUpdate('DROP TABLE vct_owning_manytomany_extralazy');
$conn->executeUpdate('DROP TABLE vct_inversed_manytomany_extralazy');
}
public function testThatTheExtraLazyCollectionFromOwningToInversedIsCounted()
{
$owning = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\OwningManyToManyExtraLazyEntity',
'ghi'
);
$this->assertEquals(2, $owning->associatedEntities->count());
}
public function testThatTheExtraLazyCollectionFromInversedToOwningIsCounted()
{
$inversed = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\InversedManyToManyExtraLazyEntity',
'abc'
);
$this->assertEquals(2, $inversed->associatedEntities->count());
}
public function testThatTheExtraLazyCollectionFromOwningToInversedContainsAnEntity()
{
$owning = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\OwningManyToManyExtraLazyEntity',
'ghi'
);
$inversed = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\InversedManyToManyExtraLazyEntity',
'abc'
);
$this->assertTrue($owning->associatedEntities->contains($inversed));
}
public function testThatTheExtraLazyCollectionFromInversedToOwningContainsAnEntity()
{
$inversed = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\InversedManyToManyExtraLazyEntity',
'abc'
);
$owning = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\OwningManyToManyExtraLazyEntity',
'ghi'
);
$this->assertTrue($inversed->associatedEntities->contains($owning));
}
public function testThatTheExtraLazyCollectionFromOwningToInversedContainsAnIndexByKey()
{
$owning = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\OwningManyToManyExtraLazyEntity',
'ghi'
);
$this->assertTrue($owning->associatedEntities->containsKey('abc'));
}
public function testThatTheExtraLazyCollectionFromInversedToOwningContainsAnIndexByKey()
{
$inversed = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\InversedManyToManyExtraLazyEntity',
'abc'
);
$this->assertTrue($inversed->associatedEntities->containsKey('ghi'));
}
public function testThatASliceOfTheExtraLazyCollectionFromOwningToInversedIsLoaded()
{
$owning = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\OwningManyToManyExtraLazyEntity',
'ghi'
);
$this->assertCount(1, $owning->associatedEntities->slice(0, 1));
}
public function testThatASliceOfTheExtraLazyCollectionFromInversedToOwningIsLoaded()
{
$inversed = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\InversedManyToManyExtraLazyEntity',
'abc'
);
$this->assertCount(1, $inversed->associatedEntities->slice(1, 1));
}
}

View File

@ -0,0 +1,153 @@
<?php
namespace Doctrine\Tests\ORM\Functional\ValueConversionType;
use Doctrine\DBAL\Types\Type as DBALType;
use Doctrine\Tests\Models\ValueConversionType as Entity;
use Doctrine\Tests\OrmFunctionalTestCase;
/**
* The entities all use a custom type that converst the value as identifier(s).
* {@see \Doctrine\Tests\DbalTypes\Rot13Type}
*
* Test that ManyToMany associations work correctly.
*
* @group DDC-3380
*/
class ManyToManyTest extends OrmFunctionalTestCase
{
public function setUp()
{
$this->useModelSet('vct_manytomany');
parent::setUp();
$inversed = new Entity\InversedManyToManyEntity();
$inversed->id1 = 'abc';
$owning = new Entity\OwningManyToManyEntity();
$owning->id2 = 'def';
$inversed->associatedEntities->add($owning);
$owning->associatedEntities->add($inversed);
$this->_em->persist($inversed);
$this->_em->persist($owning);
$this->_em->flush();
$this->_em->clear();
}
public static function tearDownAfterClass()
{
$conn = static::$_sharedConn;
$conn->executeUpdate('DROP TABLE vct_xref_manytomany');
$conn->executeUpdate('DROP TABLE vct_owning_manytomany');
$conn->executeUpdate('DROP TABLE vct_inversed_manytomany');
}
public function testThatTheValueOfIdentifiersAreConvertedInTheDatabase()
{
$conn = $this->_em->getConnection();
$this->assertEquals('nop', $conn->fetchColumn('SELECT id1 FROM vct_inversed_manytomany LIMIT 1'));
$this->assertEquals('qrs', $conn->fetchColumn('SELECT id2 FROM vct_owning_manytomany LIMIT 1'));
$this->assertEquals('nop', $conn->fetchColumn('SELECT inversed_id FROM vct_xref_manytomany LIMIT 1'));
$this->assertEquals('qrs', $conn->fetchColumn('SELECT owning_id FROM vct_xref_manytomany LIMIT 1'));
}
/**
* @depends testThatTheValueOfIdentifiersAreConvertedInTheDatabase
*/
public function testThatEntitiesAreFetchedFromTheDatabase()
{
$inversed = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\InversedManyToManyEntity',
'abc'
);
$owning = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\OwningManyToManyEntity',
'def'
);
$this->assertInstanceOf('Doctrine\Tests\Models\ValueConversionType\InversedManyToManyEntity', $inversed);
$this->assertInstanceOf('Doctrine\Tests\Models\ValueConversionType\OwningManyToManyEntity', $owning);
}
/**
* @depends testThatEntitiesAreFetchedFromTheDatabase
*/
public function testThatTheValueOfIdentifiersAreConvertedBackAfterBeingFetchedFromTheDatabase()
{
$inversed = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\InversedManyToManyEntity',
'abc'
);
$owning = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\OwningManyToManyEntity',
'def'
);
$this->assertEquals('abc', $inversed->id1);
$this->assertEquals('def', $owning->id2);
}
/**
* @depends testThatEntitiesAreFetchedFromTheDatabase
*/
public function testThatTheCollectionFromOwningToInversedIsLoaded()
{
$owning = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\OwningManyToManyEntity',
'def'
);
$this->assertCount(1, $owning->associatedEntities);
}
/**
* @depends testThatEntitiesAreFetchedFromTheDatabase
*/
public function testThatTheCollectionFromInversedToOwningIsLoaded()
{
$inversed = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\InversedManyToManyEntity',
'abc'
);
$this->assertCount(1, $inversed->associatedEntities);
}
/**
* @depends testThatTheCollectionFromOwningToInversedIsLoaded
* @depends testThatTheCollectionFromInversedToOwningIsLoaded
*/
public function testThatTheJoinTableRowsAreRemovedWhenRemovingTheAssociation()
{
$conn = $this->_em->getConnection();
// remove association
$inversed = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\InversedManyToManyEntity',
'abc'
);
foreach ($inversed->associatedEntities as $owning) {
$inversed->associatedEntities->removeElement($owning);
$owning->associatedEntities->removeElement($inversed);
}
$this->_em->flush();
$this->_em->clear();
// test association is removed
$this->assertEquals(0, $conn->fetchColumn('SELECT COUNT(*) FROM vct_xref_manytomany'));
}
}

View File

@ -0,0 +1,169 @@
<?php
namespace Doctrine\Tests\ORM\Functional\ValueConversionType;
use Doctrine\DBAL\Types\Type as DBALType;
use Doctrine\Tests\Models\ValueConversionType as Entity;
use Doctrine\Tests\OrmFunctionalTestCase;
/**
* The entities all use a custom type that converst the value as identifier(s).
* {@see \Doctrine\Tests\DbalTypes\Rot13Type}
*
* Test that OneToMany associations with composite id of which one is a
* association itself work correctly.
*
* @group DDC-3380
*/
class OneToManyCompositeIdForeignKeyTest extends OrmFunctionalTestCase
{
public function setUp()
{
$this->useModelSet('vct_onetomany_compositeid_foreignkey');
parent::setUp();
$auxiliary = new Entity\AuxiliaryEntity();
$auxiliary->id4 = 'abc';
$inversed = new Entity\InversedOneToManyCompositeIdForeignKeyEntity();
$inversed->id1 = 'def';
$inversed->foreignEntity = $auxiliary;
$inversed->someProperty = 'some value to be loaded';
$owning = new Entity\OwningManyToOneCompositeIdForeignKeyEntity();
$owning->id2 = 'ghi';
$inversed->associatedEntities->add($owning);
$owning->associatedEntity = $inversed;
$this->_em->persist($auxiliary);
$this->_em->persist($inversed);
$this->_em->persist($owning);
$this->_em->flush();
$this->_em->clear();
}
public static function tearDownAfterClass()
{
$conn = static::$_sharedConn;
$conn->executeUpdate('DROP TABLE vct_owning_manytoone_compositeid_foreignkey');
$conn->executeUpdate('DROP TABLE vct_inversed_onetomany_compositeid_foreignkey');
$conn->executeUpdate('DROP TABLE vct_auxiliary');
}
public function testThatTheValueOfIdentifiersAreConvertedInTheDatabase()
{
$conn = $this->_em->getConnection();
$this->assertEquals('nop', $conn->fetchColumn('SELECT id4 FROM vct_auxiliary LIMIT 1'));
$this->assertEquals('qrs', $conn->fetchColumn('SELECT id1 FROM vct_inversed_onetomany_compositeid_foreignkey LIMIT 1'));
$this->assertEquals('nop', $conn->fetchColumn('SELECT foreign_id FROM vct_inversed_onetomany_compositeid_foreignkey LIMIT 1'));
$this->assertEquals('tuv', $conn->fetchColumn('SELECT id2 FROM vct_owning_manytoone_compositeid_foreignkey LIMIT 1'));
$this->assertEquals('qrs', $conn->fetchColumn('SELECT associated_id FROM vct_owning_manytoone_compositeid_foreignkey LIMIT 1'));
$this->assertEquals('nop', $conn->fetchColumn('SELECT associated_foreign_id FROM vct_owning_manytoone_compositeid_foreignkey LIMIT 1'));
}
/**
* @depends testThatTheValueOfIdentifiersAreConvertedInTheDatabase
*/
public function testThatEntitiesAreFetchedFromTheDatabase()
{
$auxiliary = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\AuxiliaryEntity',
'abc'
);
$inversed = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\InversedOneToManyCompositeIdForeignKeyEntity',
array('id1' => 'def', 'foreignEntity' => 'abc')
);
$owning = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\OwningManyToOneCompositeIdForeignKeyEntity',
'ghi'
);
$this->assertInstanceOf('Doctrine\Tests\Models\ValueConversionType\AuxiliaryEntity', $auxiliary);
$this->assertInstanceOf('Doctrine\Tests\Models\ValueConversionType\InversedOneToManyCompositeIdForeignKeyEntity', $inversed);
$this->assertInstanceOf('Doctrine\Tests\Models\ValueConversionType\OwningManyToOneCompositeIdForeignKeyEntity', $owning);
}
/**
* @depends testThatEntitiesAreFetchedFromTheDatabase
*/
public function testThatTheValueOfIdentifiersAreConvertedBackAfterBeingFetchedFromTheDatabase()
{
$auxiliary = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\AuxiliaryEntity',
'abc'
);
$inversed = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\InversedOneToManyCompositeIdForeignKeyEntity',
array('id1' => 'def', 'foreignEntity' => 'abc')
);
$owning = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\OwningManyToOneCompositeIdForeignKeyEntity',
'ghi'
);
$this->assertEquals('abc', $auxiliary->id4);
$this->assertEquals('def', $inversed->id1);
$this->assertEquals('abc', $inversed->foreignEntity->id4);
$this->assertEquals('ghi', $owning->id2);
}
/**
* @depends testThatTheValueOfIdentifiersAreConvertedBackAfterBeingFetchedFromTheDatabase
*/
public function testThatInversedEntityIsFetchedFromTheDatabaseUsingAuxiliaryEntityAsId()
{
$auxiliary = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\AuxiliaryEntity',
'abc'
);
$inversed = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\InversedOneToManyCompositeIdForeignKeyEntity',
array('id1' => 'def', 'foreignEntity' => $auxiliary)
);
$this->assertInstanceOf('Doctrine\Tests\Models\ValueConversionType\InversedOneToManyCompositeIdForeignKeyEntity', $inversed);
}
/**
* @depends testThatEntitiesAreFetchedFromTheDatabase
*/
public function testThatTheProxyFromOwningToInversedIsLoaded()
{
$owning = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\OwningManyToOneCompositeIdForeignKeyEntity',
'ghi'
);
$inversedProxy = $owning->associatedEntity;
$this->assertSame('def', $inversedProxy->id1, 'Proxy identifier is converted');
$this->assertEquals('some value to be loaded', $inversedProxy->someProperty);
}
/**
* @depends testThatEntitiesAreFetchedFromTheDatabase
*/
public function testThatTheCollectionFromInversedToOwningIsLoaded()
{
$inversed = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\InversedOneToManyCompositeIdForeignKeyEntity',
array('id1' => 'def', 'foreignEntity' => 'abc')
);
$this->assertCount(1, $inversed->associatedEntities);
}
}

View File

@ -0,0 +1,129 @@
<?php
namespace Doctrine\Tests\ORM\Functional\ValueConversionType;
use Doctrine\DBAL\Types\Type as DBALType;
use Doctrine\Tests\Models\ValueConversionType as Entity;
use Doctrine\Tests\OrmFunctionalTestCase;
/**
* The entities all use a custom type that converst the value as identifier(s).
* {@see \Doctrine\Tests\DbalTypes\Rot13Type}
*
* Test that OneToMany associations with composite id work correctly.
*
* @group DDC-3380
*/
class OneToManyCompositeIdTest extends OrmFunctionalTestCase
{
public function setUp()
{
$this->useModelSet('vct_onetomany_compositeid');
parent::setUp();
$inversed = new Entity\InversedOneToManyCompositeIdEntity();
$inversed->id1 = 'abc';
$inversed->id2 = 'def';
$inversed->someProperty = 'some value to be loaded';
$owning = new Entity\OwningManyToOneCompositeIdEntity();
$owning->id3 = 'ghi';
$inversed->associatedEntities->add($owning);
$owning->associatedEntity = $inversed;
$this->_em->persist($inversed);
$this->_em->persist($owning);
$this->_em->flush();
$this->_em->clear();
}
public static function tearDownAfterClass()
{
$conn = static::$_sharedConn;
$conn->executeUpdate('DROP TABLE vct_owning_manytoone_compositeid');
$conn->executeUpdate('DROP TABLE vct_inversed_onetomany_compositeid');
}
public function testThatTheValueOfIdentifiersAreConvertedInTheDatabase()
{
$conn = $this->_em->getConnection();
$this->assertEquals('nop', $conn->fetchColumn('SELECT id1 FROM vct_inversed_onetomany_compositeid LIMIT 1'));
$this->assertEquals('qrs', $conn->fetchColumn('SELECT id2 FROM vct_inversed_onetomany_compositeid LIMIT 1'));
$this->assertEquals('tuv', $conn->fetchColumn('SELECT id3 FROM vct_owning_manytoone_compositeid LIMIT 1'));
$this->assertEquals('nop', $conn->fetchColumn('SELECT associated_id1 FROM vct_owning_manytoone_compositeid LIMIT 1'));
$this->assertEquals('qrs', $conn->fetchColumn('SELECT associated_id2 FROM vct_owning_manytoone_compositeid LIMIT 1'));
}
/**
* @depends testThatTheValueOfIdentifiersAreConvertedInTheDatabase
*/
public function testThatEntitiesAreFetchedFromTheDatabase()
{
$inversed = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\InversedOneToManyCompositeIdEntity',
array('id1' => 'abc', 'id2' => 'def')
);
$owning = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\OwningManyToOneCompositeIdEntity',
'ghi'
);
$this->assertInstanceOf('Doctrine\Tests\Models\ValueConversionType\InversedOneToManyCompositeIdEntity', $inversed);
$this->assertInstanceOf('Doctrine\Tests\Models\ValueConversionType\OwningManyToOneCompositeIdEntity', $owning);
}
/**
* @depends testThatEntitiesAreFetchedFromTheDatabase
*/
public function testThatTheValueOfIdentifiersAreConvertedBackAfterBeingFetchedFromTheDatabase()
{
$inversed = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\InversedOneToManyCompositeIdEntity',
array('id1' => 'abc', 'id2' => 'def')
);
$owning = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\OwningManyToOneCompositeIdEntity',
'ghi'
);
$this->assertEquals('abc', $inversed->id1);
$this->assertEquals('def', $inversed->id2);
$this->assertEquals('ghi', $owning->id3);
}
/**
* @depends testThatEntitiesAreFetchedFromTheDatabase
*/
public function testThatTheProxyFromOwningToInversedIsLoaded()
{
$owning = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\OwningManyToOneCompositeIdEntity',
'ghi'
);
$inversedProxy = $owning->associatedEntity;
$this->assertEquals('some value to be loaded', $inversedProxy->someProperty);
}
/**
* @depends testThatEntitiesAreFetchedFromTheDatabase
*/
public function testThatTheCollectionFromInversedToOwningIsLoaded()
{
$inversed = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\InversedOneToManyCompositeIdEntity',
array('id1' => 'abc', 'id2' => 'def')
);
$this->assertCount(1, $inversed->associatedEntities);
}
}

View File

@ -0,0 +1,106 @@
<?php
namespace Doctrine\Tests\ORM\Functional\ValueConversionType;
use Doctrine\DBAL\Types\Type as DBALType;
use Doctrine\Tests\Models\ValueConversionType as Entity;
use Doctrine\Tests\OrmFunctionalTestCase;
/**
* The entities all use a custom type that converst the value as identifier(s).
* {@see \Doctrine\Tests\DbalTypes\Rot13Type}
*
* Test that OneToMany associations work correctly, focusing on EXTRA_LAZY
* functionality.
*
* @group DDC-3380
*/
class OneToManyExtraLazyTest extends OrmFunctionalTestCase
{
public function setUp()
{
$this->useModelSet('vct_onetomany_extralazy');
parent::setUp();
$inversed = new Entity\InversedOneToManyExtraLazyEntity();
$inversed->id1 = 'abc';
$owning1 = new Entity\OwningManyToOneExtraLazyEntity();
$owning1->id2 = 'def';
$owning2 = new Entity\OwningManyToOneExtraLazyEntity();
$owning2->id2 = 'ghi';
$owning3 = new Entity\OwningManyToOneExtraLazyEntity();
$owning3->id2 = 'jkl';
$inversed->associatedEntities->add($owning1);
$owning1->associatedEntity = $inversed;
$inversed->associatedEntities->add($owning2);
$owning2->associatedEntity = $inversed;
$inversed->associatedEntities->add($owning3);
$owning3->associatedEntity = $inversed;
$this->_em->persist($inversed);
$this->_em->persist($owning1);
$this->_em->persist($owning2);
$this->_em->persist($owning3);
$this->_em->flush();
$this->_em->clear();
}
public static function tearDownAfterClass()
{
$conn = static::$_sharedConn;
$conn->executeUpdate('DROP TABLE vct_owning_manytoone_extralazy');
$conn->executeUpdate('DROP TABLE vct_inversed_onetomany_extralazy');
}
public function testThatExtraLazyCollectionIsCounted()
{
$inversed = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\InversedOneToManyExtraLazyEntity',
'abc'
);
$this->assertEquals(3, $inversed->associatedEntities->count());
}
public function testThatExtraLazyCollectionContainsAnEntity()
{
$inversed = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\InversedOneToManyExtraLazyEntity',
'abc'
);
$owning = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\OwningManyToOneExtraLazyEntity',
'def'
);
$this->assertTrue($inversed->associatedEntities->contains($owning));
}
public function testThatExtraLazyCollectionContainsAnIndexbyKey()
{
$inversed = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\InversedOneToManyExtraLazyEntity',
'abc'
);
$this->assertTrue($inversed->associatedEntities->containsKey('def'));
}
public function testThatASliceOfTheExtraLazyCollectionIsLoaded()
{
$inversed = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\InversedOneToManyExtraLazyEntity',
'abc'
);
$this->assertCount(2, $inversed->associatedEntities->slice(0, 2));
}
}

View File

@ -0,0 +1,125 @@
<?php
namespace Doctrine\Tests\ORM\Functional\ValueConversionType;
use Doctrine\DBAL\Types\Type as DBALType;
use Doctrine\Tests\Models\ValueConversionType as Entity;
use Doctrine\Tests\OrmFunctionalTestCase;
/**
* The entities all use a custom type that converst the value as identifier(s).
* {@see \Doctrine\Tests\DbalTypes\Rot13Type}
*
* Test that OneToMany associations work correctly.
*
* @group DDC-3380
*/
class OneToManyTest extends OrmFunctionalTestCase
{
public function setUp()
{
$this->useModelSet('vct_onetomany');
parent::setUp();
$inversed = new Entity\InversedOneToManyEntity();
$inversed->id1 = 'abc';
$inversed->someProperty = 'some value to be loaded';
$owning = new Entity\OwningManyToOneEntity();
$owning->id2 = 'def';
$inversed->associatedEntities->add($owning);
$owning->associatedEntity = $inversed;
$this->_em->persist($inversed);
$this->_em->persist($owning);
$this->_em->flush();
$this->_em->clear();
}
public static function tearDownAfterClass()
{
$conn = static::$_sharedConn;
$conn->executeUpdate('DROP TABLE vct_owning_manytoone');
$conn->executeUpdate('DROP TABLE vct_inversed_onetomany');
}
public function testThatTheValueOfIdentifiersAreConvertedInTheDatabase()
{
$conn = $this->_em->getConnection();
$this->assertEquals('nop', $conn->fetchColumn('SELECT id1 FROM vct_inversed_onetomany LIMIT 1'));
$this->assertEquals('qrs', $conn->fetchColumn('SELECT id2 FROM vct_owning_manytoone LIMIT 1'));
$this->assertEquals('nop', $conn->fetchColumn('SELECT associated_id FROM vct_owning_manytoone LIMIT 1'));
}
/**
* @depends testThatTheValueOfIdentifiersAreConvertedInTheDatabase
*/
public function testThatEntitiesAreFetchedFromTheDatabase()
{
$inversed = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\InversedOneToManyEntity',
'abc'
);
$owning = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\OwningManyToOneEntity',
'def'
);
$this->assertInstanceOf('Doctrine\Tests\Models\ValueConversionType\InversedOneToManyEntity', $inversed);
$this->assertInstanceOf('Doctrine\Tests\Models\ValueConversionType\OwningManyToOneEntity', $owning);
}
/**
* @depends testThatEntitiesAreFetchedFromTheDatabase
*/
public function testThatTheValueOfIdentifiersAreConvertedBackAfterBeingFetchedFromTheDatabase()
{
$inversed = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\InversedOneToManyEntity',
'abc'
);
$owning = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\OwningManyToOneEntity',
'def'
);
$this->assertEquals('abc', $inversed->id1);
$this->assertEquals('def', $owning->id2);
}
/**
* @depends testThatEntitiesAreFetchedFromTheDatabase
*/
public function testThatTheProxyFromOwningToInversedIsLoaded()
{
$owning = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\OwningManyToOneEntity',
'def'
);
$inversedProxy = $owning->associatedEntity;
$this->assertEquals('some value to be loaded', $inversedProxy->someProperty);
}
/**
* @depends testThatEntitiesAreFetchedFromTheDatabase
*/
public function testThatTheCollectionFromInversedToOwningIsLoaded()
{
$inversed = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\InversedOneToManyEntity',
'abc'
);
$this->assertCount(1, $inversed->associatedEntities);
}
}

View File

@ -0,0 +1,166 @@
<?php
namespace Doctrine\Tests\ORM\Functional\ValueConversionType;
use Doctrine\DBAL\Types\Type as DBALType;
use Doctrine\Tests\Models\ValueConversionType as Entity;
use Doctrine\Tests\OrmFunctionalTestCase;
/**
* The entities all use a custom type that converst the value as identifier(s).
* {@see \Doctrine\Tests\DbalTypes\Rot13Type}
*
* Test that OneToOne associations with composite id of which one is a
* association itself work correctly.
*
* @group DDC-3380
*/
class OneToOneCompositeIdForeignKeyTest extends OrmFunctionalTestCase
{
public function setUp()
{
$this->useModelSet('vct_onetoone_compositeid_foreignkey');
parent::setUp();
$auxiliary = new Entity\AuxiliaryEntity();
$auxiliary->id4 = 'abc';
$inversed = new Entity\InversedOneToOneCompositeIdForeignKeyEntity();
$inversed->id1 = 'def';
$inversed->foreignEntity = $auxiliary;
$inversed->someProperty = 'some value to be loaded';
$owning = new Entity\OwningOneToOneCompositeIdForeignKeyEntity();
$owning->id2 = 'ghi';
$inversed->associatedEntity = $owning;
$owning->associatedEntity = $inversed;
$this->_em->persist($auxiliary);
$this->_em->persist($inversed);
$this->_em->persist($owning);
$this->_em->flush();
$this->_em->clear();
}
public static function tearDownAfterClass()
{
$conn = static::$_sharedConn;
$conn->executeUpdate('DROP TABLE vct_owning_onetoone_compositeid_foreignkey');
$conn->executeUpdate('DROP TABLE vct_inversed_onetoone_compositeid_foreignkey');
$conn->executeUpdate('DROP TABLE vct_auxiliary');
}
public function testThatTheValueOfIdentifiersAreConvertedInTheDatabase()
{
$conn = $this->_em->getConnection();
$this->assertEquals('nop', $conn->fetchColumn('SELECT id4 FROM vct_auxiliary LIMIT 1'));
$this->assertEquals('qrs', $conn->fetchColumn('SELECT id1 FROM vct_inversed_onetoone_compositeid_foreignkey LIMIT 1'));
$this->assertEquals('nop', $conn->fetchColumn('SELECT foreign_id FROM vct_inversed_onetoone_compositeid_foreignkey LIMIT 1'));
$this->assertEquals('tuv', $conn->fetchColumn('SELECT id2 FROM vct_owning_onetoone_compositeid_foreignkey LIMIT 1'));
$this->assertEquals('qrs', $conn->fetchColumn('SELECT associated_id FROM vct_owning_onetoone_compositeid_foreignkey LIMIT 1'));
$this->assertEquals('nop', $conn->fetchColumn('SELECT associated_foreign_id FROM vct_owning_onetoone_compositeid_foreignkey LIMIT 1'));
}
/**
* @depends testThatTheValueOfIdentifiersAreConvertedInTheDatabase
*/
public function testThatEntitiesAreFetchedFromTheDatabase()
{
$auxiliary = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\AuxiliaryEntity',
'abc'
);
$inversed = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\InversedOneToOneCompositeIdForeignKeyEntity',
array('id1' => 'def', 'foreignEntity' => 'abc')
);
$owning = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\OwningOneToOneCompositeIdForeignKeyEntity',
'ghi'
);
$this->assertInstanceOf('Doctrine\Tests\Models\ValueConversionType\AuxiliaryEntity', $auxiliary);
$this->assertInstanceOf('Doctrine\Tests\Models\ValueConversionType\InversedOneToOneCompositeIdForeignKeyEntity', $inversed);
$this->assertInstanceOf('Doctrine\Tests\Models\ValueConversionType\OwningOneToOneCompositeIdForeignKeyEntity', $owning);
}
/**
* @depends testThatEntitiesAreFetchedFromTheDatabase
*/
public function testThatTheValueOfIdentifiersAreConvertedBackAfterBeingFetchedFromTheDatabase()
{
$auxiliary = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\AuxiliaryEntity',
'abc'
);
$inversed = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\InversedOneToOneCompositeIdForeignKeyEntity',
array('id1' => 'def', 'foreignEntity' => 'abc')
);
$owning = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\OwningOneToOneCompositeIdForeignKeyEntity',
'ghi'
);
$this->assertEquals('abc', $auxiliary->id4);
$this->assertEquals('def', $inversed->id1);
$this->assertEquals('abc', $inversed->foreignEntity->id4);
$this->assertEquals('ghi', $owning->id2);
}
/**
* @depends testThatTheValueOfIdentifiersAreConvertedBackAfterBeingFetchedFromTheDatabase
*/
public function testThatInversedEntityIsFetchedFromTheDatabaseUsingAuxiliaryEntityAsId()
{
$auxiliary = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\AuxiliaryEntity',
'abc'
);
$inversed = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\InversedOneToOneCompositeIdForeignKeyEntity',
array('id1' => 'def', 'foreignEntity' => $auxiliary)
);
$this->assertInstanceOf('Doctrine\Tests\Models\ValueConversionType\InversedOneToOneCompositeIdForeignKeyEntity', $inversed);
}
/**
* @depends testThatEntitiesAreFetchedFromTheDatabase
*/
public function testThatTheProxyFromOwningToInversedIsLoaded()
{
$owning = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\OwningOneToOneCompositeIdForeignKeyEntity',
'ghi'
);
$inversedProxy = $owning->associatedEntity;
$this->assertEquals('some value to be loaded', $inversedProxy->someProperty);
}
/**
* @depends testThatEntitiesAreFetchedFromTheDatabase
*/
public function testThatTheEntityFromInversedToOwningIsEagerLoaded()
{
$inversed = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\InversedOneToOneCompositeIdForeignKeyEntity',
array('id1' => 'def', 'foreignEntity' => 'abc')
);
$this->assertInstanceOf('Doctrine\Tests\Models\ValueConversionType\OwningOneToOneCompositeIdForeignKeyEntity', $inversed->associatedEntity);
}
}

View File

@ -0,0 +1,128 @@
<?php
namespace Doctrine\Tests\ORM\Functional\ValueConversionType;
use Doctrine\DBAL\Types\Type as DBALType;
use Doctrine\Tests\Models\ValueConversionType as Entity;
use Doctrine\Tests\OrmFunctionalTestCase;
/**
* The entities all use a custom type that converst the value as identifier(s).
* {@see \Doctrine\Tests\DbalTypes\Rot13Type}
*
* Test that OneToOne associations with composite id work correctly.
*
* @group DDC-3380
*/
class OneToOneCompositeIdTest extends OrmFunctionalTestCase
{
public function setUp()
{
$this->useModelSet('vct_onetoone_compositeid');
parent::setUp();
$inversed = new Entity\InversedOneToOneCompositeIdEntity();
$inversed->id1 = 'abc';
$inversed->id2 = 'def';
$inversed->someProperty = 'some value to be loaded';
$owning = new Entity\OwningOneToOneCompositeIdEntity();
$owning->id3 = 'ghi';
$inversed->associatedEntity = $owning;
$owning->associatedEntity = $inversed;
$this->_em->persist($inversed);
$this->_em->persist($owning);
$this->_em->flush();
$this->_em->clear();
}
public static function tearDownAfterClass()
{
$conn = static::$_sharedConn;
$conn->executeUpdate('DROP TABLE vct_owning_onetoone_compositeid');
$conn->executeUpdate('DROP TABLE vct_inversed_onetoone_compositeid');
}
public function testThatTheValueOfIdentifiersAreConvertedInTheDatabase()
{
$conn = $this->_em->getConnection();
$this->assertEquals('nop', $conn->fetchColumn('SELECT id1 FROM vct_inversed_onetoone_compositeid LIMIT 1'));
$this->assertEquals('qrs', $conn->fetchColumn('SELECT id2 FROM vct_inversed_onetoone_compositeid LIMIT 1'));
$this->assertEquals('tuv', $conn->fetchColumn('SELECT id3 FROM vct_owning_onetoone_compositeid LIMIT 1'));
$this->assertEquals('nop', $conn->fetchColumn('SELECT associated_id1 FROM vct_owning_onetoone_compositeid LIMIT 1'));
$this->assertEquals('qrs', $conn->fetchColumn('SELECT associated_id2 FROM vct_owning_onetoone_compositeid LIMIT 1'));
}
/**
* @depends testThatTheValueOfIdentifiersAreConvertedInTheDatabase
*/
public function testThatEntitiesAreFetchedFromTheDatabase()
{
$inversed = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\InversedOneToOneCompositeIdEntity',
array('id1' => 'abc', 'id2' => 'def')
);
$owning = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\OwningOneToOneCompositeIdEntity',
'ghi'
);
$this->assertInstanceOf('Doctrine\Tests\Models\ValueConversionType\InversedOneToOneCompositeIdEntity', $inversed);
$this->assertInstanceOf('Doctrine\Tests\Models\ValueConversionType\OwningOneToOneCompositeIdEntity', $owning);
}
/**
* @depends testThatEntitiesAreFetchedFromTheDatabase
*/
public function testThatTheValueOfIdentifiersAreConvertedBackAfterBeingFetchedFromTheDatabase()
{
$inversed = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\InversedOneToOneCompositeIdEntity',
array('id1' => 'abc', 'id2' => 'def')
);
$owning = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\OwningOneToOneCompositeIdEntity',
'ghi'
);
$this->assertEquals('abc', $inversed->id1);
$this->assertEquals('def', $inversed->id2);
$this->assertEquals('ghi', $owning->id3);
}
/**
* @depends testThatEntitiesAreFetchedFromTheDatabase
*/
public function testThatTheProxyFromOwningToInversedIsLoaded()
{
$owning = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\OwningOneToOneCompositeIdEntity',
'ghi'
);
$inversedProxy = $owning->associatedEntity;
$this->assertEquals('some value to be loaded', $inversedProxy->someProperty);
}
/**
* @depends testThatEntitiesAreFetchedFromTheDatabase
*/
public function testThatTheEntityFromInversedToOwningIsEagerLoaded()
{
$inversed = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\InversedOneToOneCompositeIdEntity',
array('id1' => 'abc', 'id2' => 'def')
);
$this->assertInstanceOf('Doctrine\Tests\Models\ValueConversionType\OwningOneToOneCompositeIdEntity', $inversed->associatedEntity);
}
}

View File

@ -0,0 +1,125 @@
<?php
namespace Doctrine\Tests\ORM\Functional\ValueConversionType;
use Doctrine\DBAL\Types\Type as DBALType;
use Doctrine\Tests\Models\ValueConversionType as Entity;
use Doctrine\Tests\OrmFunctionalTestCase;
/**
* The entities all use a custom type that converst the value as identifier(s).
* {@see \Doctrine\Tests\DbalTypes\Rot13Type}
*
* Test that OneToOne associations work correctly.
*
* @group DDC-3380
*/
class OneToOneTest extends OrmFunctionalTestCase
{
public function setUp()
{
$this->useModelSet('vct_onetoone');
parent::setUp();
$inversed = new Entity\InversedOneToOneEntity();
$inversed->id1 = 'abc';
$inversed->someProperty = 'some value to be loaded';
$owning = new Entity\OwningOneToOneEntity();
$owning->id2 = 'def';
$inversed->associatedEntity = $owning;
$owning->associatedEntity = $inversed;
$this->_em->persist($inversed);
$this->_em->persist($owning);
$this->_em->flush();
$this->_em->clear();
}
public static function tearDownAfterClass()
{
$conn = static::$_sharedConn;
$conn->executeUpdate('DROP TABLE vct_owning_onetoone');
$conn->executeUpdate('DROP TABLE vct_inversed_onetoone');
}
public function testThatTheValueOfIdentifiersAreConvertedInTheDatabase()
{
$conn = $this->_em->getConnection();
$this->assertEquals('nop', $conn->fetchColumn('SELECT id1 FROM vct_inversed_onetoone LIMIT 1'));
$this->assertEquals('qrs', $conn->fetchColumn('SELECT id2 FROM vct_owning_onetoone LIMIT 1'));
$this->assertEquals('nop', $conn->fetchColumn('SELECT associated_id FROM vct_owning_onetoone LIMIT 1'));
}
/**
* @depends testThatTheValueOfIdentifiersAreConvertedInTheDatabase
*/
public function testThatEntitiesAreFetchedFromTheDatabase()
{
$inversed = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\InversedOneToOneEntity',
'abc'
);
$owning = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\OwningOneToOneEntity',
'def'
);
$this->assertInstanceOf('Doctrine\Tests\Models\ValueConversionType\InversedOneToOneEntity', $inversed);
$this->assertInstanceOf('Doctrine\Tests\Models\ValueConversionType\OwningOneToOneEntity', $owning);
}
/**
* @depends testThatEntitiesAreFetchedFromTheDatabase
*/
public function testThatTheValueOfIdentifiersAreConvertedBackAfterBeingFetchedFromTheDatabase()
{
$inversed = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\InversedOneToOneEntity',
'abc'
);
$owning = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\OwningOneToOneEntity',
'def'
);
$this->assertEquals('abc', $inversed->id1);
$this->assertEquals('def', $owning->id2);
}
/**
* @depends testThatEntitiesAreFetchedFromTheDatabase
*/
public function testThatTheProxyFromOwningToInversedIsLoaded()
{
$owning = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\OwningOneToOneEntity',
'def'
);
$inversedProxy = $owning->associatedEntity;
$this->assertEquals('some value to be loaded', $inversedProxy->someProperty);
}
/**
* @depends testThatEntitiesAreFetchedFromTheDatabase
*/
public function testThatTheEntityFromInversedToOwningIsEagerLoaded()
{
$inversed = $this->_em->find(
'Doctrine\Tests\Models\ValueConversionType\InversedOneToOneEntity',
'abc'
);
$this->assertInstanceOf('Doctrine\Tests\Models\ValueConversionType\OwningOneToOneEntity', $inversed->associatedEntity);
}
}

View File

@ -2,6 +2,7 @@
namespace Doctrine\Tests;
use Doctrine\DBAL\Types\Type;
use Doctrine\Tests\EventListener\CacheMetadataListener;
use Doctrine\ORM\Cache\Logging\StatisticsCacheLogger;
use Doctrine\ORM\Cache\DefaultCacheFactory;
@ -199,6 +200,53 @@ abstract class OrmFunctionalTestCase extends OrmTestCase
'Doctrine\Tests\Models\Quote\Phone',
'Doctrine\Tests\Models\Quote\User'
),
'vct_onetoone' => array(
'Doctrine\Tests\Models\ValueConversionType\InversedOneToOneEntity',
'Doctrine\Tests\Models\ValueConversionType\OwningOneToOneEntity'
),
'vct_onetoone_compositeid' => array(
'Doctrine\Tests\Models\ValueConversionType\InversedOneToOneCompositeIdEntity',
'Doctrine\Tests\Models\ValueConversionType\OwningOneToOneCompositeIdEntity'
),
'vct_onetoone_compositeid_foreignkey' => array(
'Doctrine\Tests\Models\ValueConversionType\AuxiliaryEntity',
'Doctrine\Tests\Models\ValueConversionType\InversedOneToOneCompositeIdForeignKeyEntity',
'Doctrine\Tests\Models\ValueConversionType\OwningOneToOneCompositeIdForeignKeyEntity'
),
'vct_onetomany' => array(
'Doctrine\Tests\Models\ValueConversionType\InversedOneToManyEntity',
'Doctrine\Tests\Models\ValueConversionType\OwningManyToOneEntity'
),
'vct_onetomany_compositeid' => array(
'Doctrine\Tests\Models\ValueConversionType\InversedOneToManyCompositeIdEntity',
'Doctrine\Tests\Models\ValueConversionType\OwningManyToOneCompositeIdEntity'
),
'vct_onetomany_compositeid_foreignkey' => array(
'Doctrine\Tests\Models\ValueConversionType\AuxiliaryEntity',
'Doctrine\Tests\Models\ValueConversionType\InversedOneToManyCompositeIdForeignKeyEntity',
'Doctrine\Tests\Models\ValueConversionType\OwningManyToOneCompositeIdForeignKeyEntity'
),
'vct_onetomany_extralazy' => array(
'Doctrine\Tests\Models\ValueConversionType\InversedOneToManyExtraLazyEntity',
'Doctrine\Tests\Models\ValueConversionType\OwningManyToOneExtraLazyEntity'
),
'vct_manytomany' => array(
'Doctrine\Tests\Models\ValueConversionType\InversedManyToManyEntity',
'Doctrine\Tests\Models\ValueConversionType\OwningManyToManyEntity'
),
'vct_manytomany_compositeid' => array(
'Doctrine\Tests\Models\ValueConversionType\InversedManyToManyCompositeIdEntity',
'Doctrine\Tests\Models\ValueConversionType\OwningManyToManyCompositeIdEntity'
),
'vct_manytomany_compositeid_foreignkey' => array(
'Doctrine\Tests\Models\ValueConversionType\AuxiliaryEntity',
'Doctrine\Tests\Models\ValueConversionType\InversedManyToManyCompositeIdForeignKeyEntity',
'Doctrine\Tests\Models\ValueConversionType\OwningManyToManyCompositeIdForeignKeyEntity'
),
'vct_manytomany_extralazy' => array(
'Doctrine\Tests\Models\ValueConversionType\InversedManyToManyExtraLazyEntity',
'Doctrine\Tests\Models\ValueConversionType\OwningManyToManyExtraLazyEntity'
),
);
/**
@ -358,6 +406,68 @@ abstract class OrmFunctionalTestCase extends OrmTestCase
$conn->executeUpdate('DELETE FROM ' . $platform->quoteIdentifier("quote-user"));
}
if (isset($this->_usedModelSets['vct_onetoone'])) {
$conn->executeUpdate('DELETE FROM vct_owning_onetoone');
$conn->executeUpdate('DELETE FROM vct_inversed_onetoone');
}
if (isset($this->_usedModelSets['vct_onetoone_compositeid'])) {
$conn->executeUpdate('DELETE FROM vct_owning_onetoone_compositeid');
$conn->executeUpdate('DELETE FROM vct_inversed_onetoone_compositeid');
}
if (isset($this->_usedModelSets['vct_onetoone_compositeid_foreignkey'])) {
$conn->executeUpdate('DELETE FROM vct_owning_onetoone_compositeid_foreignkey');
$conn->executeUpdate('DELETE FROM vct_inversed_onetoone_compositeid_foreignkey');
$conn->executeUpdate('DELETE FROM vct_auxiliary');
}
if (isset($this->_usedModelSets['vct_onetomany'])) {
$conn->executeUpdate('DELETE FROM vct_owning_manytoone');
$conn->executeUpdate('DELETE FROM vct_inversed_onetomany');
}
if (isset($this->_usedModelSets['vct_onetomany_compositeid'])) {
$conn->executeUpdate('DELETE FROM vct_owning_manytoone_compositeid');
$conn->executeUpdate('DELETE FROM vct_inversed_onetomany_compositeid');
}
if (isset($this->_usedModelSets['vct_onetomany_compositeid_foreignkey'])) {
$conn->executeUpdate('DELETE FROM vct_owning_manytoone_compositeid_foreignkey');
$conn->executeUpdate('DELETE FROM vct_inversed_onetomany_compositeid_foreignkey');
$conn->executeUpdate('DELETE FROM vct_auxiliary');
}
if (isset($this->_usedModelSets['vct_onetomany_extralazy'])) {
$conn->executeUpdate('DELETE FROM vct_owning_manytoone_extralazy');
$conn->executeUpdate('DELETE FROM vct_inversed_onetomany_extralazy');
}
if (isset($this->_usedModelSets['vct_manytomany'])) {
$conn->executeUpdate('DELETE FROM vct_xref_manytomany');
$conn->executeUpdate('DELETE FROM vct_owning_manytomany');
$conn->executeUpdate('DELETE FROM vct_inversed_manytomany');
}
if (isset($this->_usedModelSets['vct_manytomany_compositeid'])) {
$conn->executeUpdate('DELETE FROM vct_xref_manytomany_compositeid');
$conn->executeUpdate('DELETE FROM vct_owning_manytomany_compositeid');
$conn->executeUpdate('DELETE FROM vct_inversed_manytomany_compositeid');
}
if (isset($this->_usedModelSets['vct_manytomany_compositeid_foreignkey'])) {
$conn->executeUpdate('DELETE FROM vct_xref_manytomany_compositeid_foreignkey');
$conn->executeUpdate('DELETE FROM vct_owning_manytomany_compositeid_foreignkey');
$conn->executeUpdate('DELETE FROM vct_inversed_manytomany_compositeid_foreignkey');
$conn->executeUpdate('DELETE FROM vct_auxiliary');
}
if (isset($this->_usedModelSets['vct_manytomany_extralazy'])) {
$conn->executeUpdate('DELETE FROM vct_xref_manytomany_extralazy');
$conn->executeUpdate('DELETE FROM vct_owning_manytomany_extralazy');
$conn->executeUpdate('DELETE FROM vct_inversed_manytomany_extralazy');
}
$this->_em->clear();
}
@ -395,6 +505,8 @@ abstract class OrmFunctionalTestCase extends OrmTestCase
*/
protected function setUp()
{
$this->setUpDBALTypes();
$forceCreateTables = false;
if ( ! isset(static::$_sharedConn)) {
@ -582,4 +694,16 @@ abstract class OrmFunctionalTestCase extends OrmTestCase
{
return count($this->_sqlLoggerStack->queries);
}
/**
* Configures DBAL types required in tests
*/
protected function setUpDBALTypes()
{
if (Type::hasType('rot13')) {
Type::overrideType('rot13', 'Doctrine\Tests\DbalTypes\Rot13Type');
} else {
Type::addType('rot13', 'Doctrine\Tests\DbalTypes\Rot13Type');
}
}
}