#1178 - reverting patch and keeping tests (rebase gone awry)
Also cleaning up `OrmFunctionalTestCase`
This commit is contained in:
parent
5c1d1931b7
commit
445798ed46
@ -25,8 +25,6 @@ use Doctrine\ORM\Persisters\SqlExpressionVisitor;
|
||||
use Doctrine\ORM\Persisters\SqlValueVisitor;
|
||||
use Doctrine\ORM\PersistentCollection;
|
||||
use Doctrine\ORM\Query;
|
||||
use Doctrine\ORM\UnitOfWork;
|
||||
use Doctrine\ORM\Utility\PersisterHelper;
|
||||
|
||||
/**
|
||||
* Persister for many-to-many collections.
|
||||
@ -376,20 +374,22 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
||||
$mapping = $collection->getMapping();
|
||||
$identifier = $this->uow->getEntityIdentifier($collection->getOwner());
|
||||
|
||||
$sourceClass = $this->em->getClassMetadata($mapping['sourceEntity']);
|
||||
$params = array();
|
||||
$types = array();
|
||||
|
||||
foreach ($mapping['relationToSourceKeyColumns'] as $columnName => $refColumnName) {
|
||||
$field = isset($sourceClass->fieldNames[$refColumnName])
|
||||
? $sourceClass->fieldNames[$refColumnName]
|
||||
: $sourceClass->getFieldForColumn($columnName);
|
||||
|
||||
$params[] = $identifier[$field];
|
||||
$types[] = PersisterHelper::getTypeOfField($field, $sourceClass, $this->em);
|
||||
// Optimization for single column identifier
|
||||
if (count($mapping['relationToSourceKeyColumns']) === 1) {
|
||||
return array(reset($identifier));
|
||||
}
|
||||
|
||||
return array($params, $types);
|
||||
// Composite identifier
|
||||
$sourceClass = $this->em->getClassMetadata($mapping['sourceEntity']);
|
||||
$params = array();
|
||||
|
||||
foreach ($mapping['relationToSourceKeyColumns'] as $columnName => $refColumnName) {
|
||||
$params[] = isset($sourceClass->fieldNames[$refColumnName])
|
||||
? $identifier[$sourceClass->fieldNames[$refColumnName]]
|
||||
: $identifier[$sourceClass->getFieldForColumn($columnName)];
|
||||
}
|
||||
|
||||
return $params;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -534,28 +534,24 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
||||
$indexBy = $mapping['indexBy'];
|
||||
$id = $this->uow->getEntityIdentifier($collection->getOwner());
|
||||
|
||||
$sourceClass = $this->em->getClassMetadata($mapping['sourceEntity']);
|
||||
$targetClass = $this->em->getClassMetadata($mapping['targetEntity']);
|
||||
$targetEntity = $this->em->getClassMetadata($mapping['targetEntity']);
|
||||
|
||||
if ( ! $mapping['isOwningSide']) {
|
||||
if (! $mapping['isOwningSide']) {
|
||||
$associationSourceClass = $this->em->getClassMetadata($mapping['targetEntity']);
|
||||
$mapping = $associationSourceClass->associationMappings[$mapping['mappedBy']];
|
||||
$mapping = $associationSourceClass->associationMappings[$mapping['mappedBy']];
|
||||
$joinColumns = $mapping['joinTable']['joinColumns'];
|
||||
$sourceRelationMode = 'relationToTargetKeyColumns';
|
||||
$targetRelationMode = 'relationToSourceKeyColumns';
|
||||
$relationMode = 'relationToTargetKeyColumns';
|
||||
} else {
|
||||
$associationSourceClass = $this->em->getClassMetadata($mapping['sourceEntity']);
|
||||
$joinColumns = $mapping['joinTable']['inverseJoinColumns'];
|
||||
$sourceRelationMode = 'relationToSourceKeyColumns';
|
||||
$targetRelationMode = 'relationToTargetKeyColumns';
|
||||
$associationSourceClass = $this->em->getClassMetadata($mapping['sourceEntity']);
|
||||
$relationMode = 'relationToSourceKeyColumns';
|
||||
}
|
||||
|
||||
$quotedJoinTable = $this->quoteStrategy->getJoinTableName($mapping, $associationSourceClass, $this->platform) . ' t';
|
||||
$quotedJoinTable = $this->quoteStrategy->getJoinTableName($mapping, $associationSourceClass, $this->platform). ' t';
|
||||
$whereClauses = array();
|
||||
$params = array();
|
||||
$types = array();
|
||||
|
||||
$joinNeeded = ! in_array($indexBy, $targetClass->identifier);
|
||||
$joinNeeded = !in_array($indexBy, $targetEntity->identifier);
|
||||
|
||||
if ($joinNeeded) { // extra join needed if indexBy is not a @id
|
||||
$joinConditions = array();
|
||||
@ -563,25 +559,21 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
||||
foreach ($joinColumns as $joinTableColumn) {
|
||||
$joinConditions[] = 't.' . $joinTableColumn['name'] . ' = tr.' . $joinTableColumn['referencedColumnName'];
|
||||
}
|
||||
$tableName = $this->quoteStrategy->getTableName($targetClass, $this->platform);
|
||||
$tableName = $this->quoteStrategy->getTableName($targetEntity, $this->platform);
|
||||
$quotedJoinTable .= ' JOIN ' . $tableName . ' tr ON ' . implode(' AND ', $joinConditions);
|
||||
$columnName = $targetClass->getColumnName($indexBy);
|
||||
|
||||
$whereClauses[] = 'tr.' . $columnName . ' = ?';
|
||||
$whereClauses[] = 'tr.' . $targetEntity->getColumnName($indexBy) . ' = ?';
|
||||
$params[] = $key;
|
||||
$types[] = PersisterHelper::getTypeOfColumn($columnName, $targetClass, $this->em);
|
||||
|
||||
}
|
||||
|
||||
foreach ($mapping['joinTableColumns'] as $joinTableColumn) {
|
||||
if (isset($mapping[$sourceRelationMode][$joinTableColumn])) {
|
||||
$column = $mapping[$sourceRelationMode][$joinTableColumn];
|
||||
|
||||
if (isset($mapping[$relationMode][$joinTableColumn])) {
|
||||
$whereClauses[] = 't.' . $joinTableColumn . ' = ?';
|
||||
$params[] = $id[$targetEntity->getFieldForColumn($mapping[$relationMode][$joinTableColumn])];
|
||||
} elseif (!$joinNeeded) {
|
||||
$whereClauses[] = 't.' . $joinTableColumn . ' = ?';
|
||||
$params[] = $key;
|
||||
$types[] = PersisterHelper::getTypeOfColumn($column, $targetClass, $this->em);
|
||||
}
|
||||
}
|
||||
|
||||
@ -594,7 +586,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
||||
}
|
||||
}
|
||||
|
||||
return array($quotedJoinTable, $whereClauses, $params, $types);
|
||||
return array($quotedJoinTable, $whereClauses, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -626,7 +618,6 @@ 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 . ' = ?';
|
||||
@ -634,11 +625,6 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
||||
if (isset($mapping['relationToTargetKeyColumns'][$joinTableColumn])) {
|
||||
$params[] = $targetId[$targetClass->getFieldForColumn($mapping['relationToTargetKeyColumns'][$joinTableColumn])];
|
||||
|
||||
$params[] = $targetClass->containsForeignIdentifier
|
||||
? $targetId[$targetClass->getFieldForColumn($column)]
|
||||
: $targetId[$targetClass->fieldNames[$column]];
|
||||
$types[] = PersisterHelper::getTypeOfColumn($column, $targetClass, $this->em);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -710,7 +710,6 @@ class BasicEntityPersister implements EntityPersister
|
||||
{
|
||||
$sql = $this->getSelectSQL($criteria, $assoc, $lockMode, $limit, null, $orderBy);
|
||||
list($params, $types) = $this->expandParameters($criteria);
|
||||
|
||||
$stmt = $this->conn->executeQuery($sql, $params, $types);
|
||||
|
||||
if ($entity !== null) {
|
||||
@ -863,12 +862,12 @@ class BasicEntityPersister implements EntityPersister
|
||||
list($params, $types) = $valueVisitor->getParamsAndTypes();
|
||||
|
||||
foreach ($params as $param) {
|
||||
$sqlParams[] = PersisterHelper::getValue($param, $this->em);
|
||||
$sqlParams[] = $this->getValue($param);
|
||||
}
|
||||
|
||||
foreach ($types as $type) {
|
||||
list($field, $value) = $type;
|
||||
$sqlTypes[] = $this->getType($field, $value, $this->class);
|
||||
$sqlTypes[] = $this->getType($field, $value);
|
||||
}
|
||||
|
||||
return array($sqlParams, $sqlTypes);
|
||||
@ -966,12 +965,11 @@ class BasicEntityPersister implements EntityPersister
|
||||
*/
|
||||
private function getManyToManyStatement(array $assoc, $sourceEntity, $offset = null, $limit = null)
|
||||
{
|
||||
$criteria = array();
|
||||
$parameters = array();
|
||||
$sourceClass = $this->em->getClassMetadata($assoc['sourceEntity']);
|
||||
$class = $sourceClass;
|
||||
$association = $assoc;
|
||||
$criteria = array();
|
||||
|
||||
$sourceClass = $this->em->getClassMetadata($assoc['sourceEntity']);
|
||||
$class = $sourceClass;
|
||||
$association = $assoc;
|
||||
|
||||
if ( ! $assoc['isOwningSide']) {
|
||||
$class = $this->em->getClassMetadata($assoc['targetEntity']);
|
||||
@ -986,8 +984,8 @@ class BasicEntityPersister implements EntityPersister
|
||||
|
||||
foreach ($joinColumns as $joinColumn) {
|
||||
|
||||
$sourceKeyColumn = $joinColumn['referencedColumnName'];
|
||||
$quotedKeyColumn = $this->quoteStrategy->getJoinColumnName($joinColumn, $class, $this->platform);
|
||||
$sourceKeyColumn = $joinColumn['referencedColumnName'];
|
||||
$quotedKeyColumn = $this->quoteStrategy->getJoinColumnName($joinColumn, $class, $this->platform);
|
||||
|
||||
switch (true) {
|
||||
case $sourceClass->containsForeignIdentifier:
|
||||
@ -1014,11 +1012,10 @@ 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->expandToManyParameters($parameters);
|
||||
list($params, $types) = $this->expandParameters($criteria);
|
||||
|
||||
return $this->conn->executeQuery($sql, $params, $types);
|
||||
}
|
||||
@ -1306,13 +1303,16 @@ class BasicEntityPersister implements EntityPersister
|
||||
$targetClass = $this->em->getClassMetadata($assoc['targetEntity']);
|
||||
|
||||
foreach ($assoc['joinColumns'] as $joinColumn) {
|
||||
$type = null;
|
||||
$isIdentifier = isset($assoc['id']) && $assoc['id'] === true;
|
||||
$quotedColumn = $this->quoteStrategy->getJoinColumnName($joinColumn, $this->class, $this->platform);
|
||||
$resultColumnName = $this->getSQLColumnAlias($joinColumn['name']);
|
||||
$columnList[] = $this->getSQLTableAlias($class->name, ($alias == 'r' ? '' : $alias) )
|
||||
. '.' . $quotedColumn . ' AS ' . $resultColumnName;
|
||||
|
||||
$type = PersisterHelper::getTypeOfColumn($joinColumn['referencedColumnName'], $targetClass, $this->em);
|
||||
if (isset($targetClass->fieldNames[$joinColumn['referencedColumnName']])) {
|
||||
$type = $targetClass->fieldMappings[$targetClass->fieldNames[$joinColumn['referencedColumnName']]]['type'];
|
||||
}
|
||||
|
||||
$this->rsm->addMetaResult($alias, $resultColumnName, $quotedColumn, $isIdentifier, $type);
|
||||
}
|
||||
@ -1713,9 +1713,7 @@ class BasicEntityPersister implements EntityPersister
|
||||
*/
|
||||
private function getOneToManyStatement(array $assoc, $sourceEntity, $offset = null, $limit = null)
|
||||
{
|
||||
$criteria = array();
|
||||
$parameters = array();
|
||||
|
||||
$criteria = array();
|
||||
$owningAssoc = $this->class->associationMappings[$assoc['mappedBy']];
|
||||
$sourceClass = $this->em->getClassMetadata($assoc['sourceEntity']);
|
||||
|
||||
@ -1732,20 +1730,15 @@ class BasicEntityPersister implements EntityPersister
|
||||
}
|
||||
|
||||
$criteria[$tableAlias . "." . $targetKeyColumn] = $value;
|
||||
$parameters[] = array('value' => $value, 'field' => $field, 'class' => $sourceClass);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$field = $sourceClass->fieldNames[$sourceKeyColumn];
|
||||
$value = $sourceClass->reflFields[$field]->getValue($sourceEntity);
|
||||
|
||||
$criteria[$tableAlias . "." . $targetKeyColumn] = $value;
|
||||
$parameters[] = array('value' => $value, 'field' => $field, 'class' => $sourceClass);
|
||||
$criteria[$tableAlias . "." . $targetKeyColumn] = $sourceClass->reflFields[$sourceClass->fieldNames[$sourceKeyColumn]]->getValue($sourceEntity);
|
||||
}
|
||||
|
||||
$sql = $this->getSelectSQL($criteria, $assoc, null, $limit, $offset);
|
||||
list($params, $types) = $this->expandToManyParameters($parameters);
|
||||
list($params, $types) = $this->expandParameters($criteria);
|
||||
|
||||
return $this->conn->executeQuery($sql, $params, $types);
|
||||
}
|
||||
@ -1763,53 +1756,25 @@ class BasicEntityPersister implements EntityPersister
|
||||
continue; // skip null values.
|
||||
}
|
||||
|
||||
$types[] = $this->getType($field, $value, $this->class);
|
||||
$params[] = PersisterHelper::getValue($value, $this->em);
|
||||
$types[] = $this->getType($field, $value);
|
||||
$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.
|
||||
* Infers field type to be used by parameter type casting.
|
||||
*
|
||||
* @param array $criteria
|
||||
* @param string $field
|
||||
* @param mixed $value
|
||||
*
|
||||
* @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::getValue($criterion['value'], $this->em);
|
||||
}
|
||||
|
||||
return array($params, $types);
|
||||
}
|
||||
|
||||
/**
|
||||
* Infers the binding type of a field by parameter type casting.
|
||||
*
|
||||
* @param string $fieldName
|
||||
* @param mixed $value
|
||||
* @param ClassMetadata|null $class
|
||||
*
|
||||
* @return int|string|null
|
||||
* @return integer
|
||||
*
|
||||
* @throws \Doctrine\ORM\Query\QueryException
|
||||
*/
|
||||
private function getType($fieldName, $value, ClassMetadata $class)
|
||||
private function getType($field, $value)
|
||||
{
|
||||
$type = Helper::getTypeOfField($fieldName, $class, $this->em);
|
||||
|
||||
switch (true) {
|
||||
case (isset($this->class->fieldMappings[$field])):
|
||||
$type = $this->class->fieldMappings[$field]['type'];
|
||||
@ -1837,8 +1802,8 @@ class BasicEntityPersister implements EntityPersister
|
||||
|
||||
break;
|
||||
|
||||
case (isset($class->associationMappings[$field])):
|
||||
$assoc = $class->associationMappings[$field];
|
||||
case (isset($this->class->associationMappings[$field])):
|
||||
$assoc = $this->class->associationMappings[$field];
|
||||
|
||||
if (count($assoc['sourceToTargetKeyColumns']) > 1) {
|
||||
throw Query\QueryException::associationPathCompositeKeyNotSupported();
|
||||
@ -1866,6 +1831,44 @@ class BasicEntityPersister implements EntityPersister
|
||||
return $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves parameter value.
|
||||
*
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function getValue($value)
|
||||
{
|
||||
if ( ! is_array($value)) {
|
||||
return $this->getIndividualValue($value);
|
||||
}
|
||||
|
||||
$newValue = array();
|
||||
|
||||
foreach ($value as $itemValue) {
|
||||
$newValue[] = $this->getIndividualValue($itemValue);
|
||||
}
|
||||
|
||||
return $newValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves an individual parameter value.
|
||||
*
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function getIndividualValue($value)
|
||||
{
|
||||
if ( ! is_object($value) || ! $this->em->getMetadataFactory()->hasMetadataFor(ClassUtils::getClass($value))) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
return $this->em->getUnitOfWork()->getSingleIdentifierValue($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@ -1883,21 +1886,20 @@ class BasicEntityPersister implements EntityPersister
|
||||
. $this->getLockTablesSql(null)
|
||||
. ' WHERE ' . $this->getSelectConditionSQL($criteria);
|
||||
|
||||
list($params, $types) = $this->expandParameters($criteria);
|
||||
list($params) = $this->expandParameters($criteria);
|
||||
|
||||
if (null !== $extraConditions) {
|
||||
$sql .= ' AND ' . $this->getSelectConditionCriteriaSQL($extraConditions);
|
||||
list($extraParams, $extraTypes) = $this->expandCriteriaParameters($extraConditions);
|
||||
$sql .= ' AND ' . $this->getSelectConditionCriteriaSQL($extraConditions);
|
||||
list($criteriaParams, $values) = $this->expandCriteriaParameters($extraConditions);
|
||||
|
||||
$params = array_merge($params, $extraParams);
|
||||
$types = array_merge($types, $extraTypes);
|
||||
$params = array_merge($params, $criteriaParams);
|
||||
}
|
||||
|
||||
if ($filterSql = $this->generateFilterConditionSQL($this->class, $alias)) {
|
||||
$sql .= ' AND ' . $filterSql;
|
||||
}
|
||||
|
||||
return (bool) $this->conn->fetchColumn($sql, $params, 0, $types);
|
||||
return (bool) $this->conn->fetchColumn($sql, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1920,9 +1922,7 @@ class BasicEntityPersister implements EntityPersister
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $columnName
|
||||
*
|
||||
* @return string
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getSQLColumnAlias($columnName)
|
||||
{
|
||||
|
@ -19,16 +19,6 @@ class SchemaValidatorTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
if ($modelSet == "customtype") {
|
||||
continue;
|
||||
}
|
||||
|
||||
// DDC-3380: Register DBAL type for these modelsets
|
||||
if (substr($modelSet, 0, 4) == 'vct_') {
|
||||
if (DBALType::hasType('rot13')) {
|
||||
DBALType::overrideType('rot13', 'Doctrine\Tests\DbalTypes\Rot13Type');
|
||||
} else {
|
||||
DBALType::addType('rot13', 'Doctrine\Tests\DbalTypes\Rot13Type');
|
||||
}
|
||||
}
|
||||
|
||||
$modelSets[] = array($modelSet);
|
||||
}
|
||||
return $modelSets;
|
||||
|
@ -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;
|
||||
@ -504,6 +505,8 @@ abstract class OrmFunctionalTestCase extends OrmTestCase
|
||||
*/
|
||||
protected function setUp()
|
||||
{
|
||||
$this->setUpDBALTypes();
|
||||
|
||||
$forceCreateTables = false;
|
||||
|
||||
if ( ! isset(static::$_sharedConn)) {
|
||||
@ -691,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');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user