#1178 - correctly handling initialization of collections referenced via custom DBAL types
This commit is contained in:
parent
91bceca7ee
commit
41900dca76
1 changed files with 43 additions and 54 deletions
|
@ -869,7 +869,7 @@ class BasicEntityPersister implements EntityPersister
|
||||||
|
|
||||||
foreach ($types as $type) {
|
foreach ($types as $type) {
|
||||||
list($field, $value) = $type;
|
list($field, $value) = $type;
|
||||||
$sqlTypes[] = $this->getType($field, $value);
|
$sqlTypes[] = $this->getType($field, $value, $this->class);
|
||||||
}
|
}
|
||||||
|
|
||||||
return array($sqlParams, $sqlTypes);
|
return array($sqlParams, $sqlTypes);
|
||||||
|
@ -971,7 +971,7 @@ class BasicEntityPersister implements EntityPersister
|
||||||
$class = $sourceClass;
|
$class = $sourceClass;
|
||||||
$association = $assoc;
|
$association = $assoc;
|
||||||
$criteria = array();
|
$criteria = array();
|
||||||
|
$parameters = array();
|
||||||
|
|
||||||
if ( ! $assoc['isOwningSide']) {
|
if ( ! $assoc['isOwningSide']) {
|
||||||
$class = $this->em->getClassMetadata($assoc['targetEntity']);
|
$class = $this->em->getClassMetadata($assoc['targetEntity']);
|
||||||
|
@ -1014,10 +1014,15 @@ class BasicEntityPersister implements EntityPersister
|
||||||
}
|
}
|
||||||
|
|
||||||
$criteria[$quotedJoinTable . '.' . $quotedKeyColumn] = $value;
|
$criteria[$quotedJoinTable . '.' . $quotedKeyColumn] = $value;
|
||||||
|
$parameters[] = array(
|
||||||
|
'value' => $value,
|
||||||
|
'field' => $field,
|
||||||
|
'class' => $sourceClass,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$sql = $this->getSelectSQL($criteria, $assoc, null, $limit, $offset);
|
$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);
|
return $this->conn->executeQuery($sql, $params, $types);
|
||||||
}
|
}
|
||||||
|
@ -1758,72 +1763,56 @@ class BasicEntityPersister implements EntityPersister
|
||||||
continue; // skip null values.
|
continue; // skip null values.
|
||||||
}
|
}
|
||||||
|
|
||||||
$types[] = $this->getType($field, $value);
|
$types[] = $this->getType($field, $value, $this->class);
|
||||||
$params[] = $this->getValue($value);
|
$params[] = $this->getValue($value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return array($params, $types);
|
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::getValue($criterion['value'], $this->em);
|
||||||
|
}
|
||||||
|
|
||||||
|
return array($params, $types);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Infers field type to be used by parameter type casting.
|
* Infers field type to be used by parameter type casting.
|
||||||
*
|
*
|
||||||
* @param string $field
|
* @param string $fieldName
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
|
* @param ClassMetadata $class
|
||||||
*
|
*
|
||||||
* @return integer
|
* @return integer
|
||||||
*
|
*
|
||||||
* @throws \Doctrine\ORM\Query\QueryException
|
* @throws \Doctrine\ORM\Query\QueryException
|
||||||
*/
|
*/
|
||||||
private function getType($field, $value)
|
private function getType($fieldName, $value, ClassMetadata $class)
|
||||||
{
|
{
|
||||||
switch (true) {
|
$type = PersisterHelper::getTypeOfField($fieldName, $class, $this->em);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_array($value)) {
|
if (is_array($value)) {
|
||||||
$type = Type::getType($type)->getBindingType();
|
$type = Type::getType($type)->getBindingType();
|
||||||
|
|
Loading…
Add table
Reference in a new issue