61 $this->query = $query;
62 $this->result = $result;
75 foreach ($this->hiddenObjectFields as $fieldName)
77 unset($row[$fieldName]);
85 return $this->result->getFields();
90 return $this->result->getSelectedRowsCount();
95 return $this->result->fetchRowInternal();
103 final public function fetchObject()
111 $this->initializeFetchObject();
114 $row = $this->result->fetch();
128 $basePrimaryValues = [];
130 foreach ($this->primaryAliases as $primaryName => $primaryAlias)
133 $primaryField = $this->query->getEntity()->getField($primaryName);
134 $primaryValue = $primaryField->cast($row[$primaryAlias]);
136 $basePrimaryValues[$primaryName] = $primaryValue;
140 $baseAddToIM =
false;
141 $objectClass = $this->objectClass;
144 $object = $this->identityMap->get($objectClass, $basePrimaryValues);
148 $object =
new $objectClass(
false);
151 $object->sysChangeState(State::ACTUAL);
158 $relEntityCache = [];
161 foreach ($this->query->getSelectChains() as $selectChain)
167 $currentDefinitionParts = [];
168 $currentDefinition =
null;
171 $iterableElements = array_slice($selectChain->getAllElements(), 1);
174 foreach ($iterableElements as $element)
176 if ($currentObject ===
null)
182 $field = $element->getValue();
184 if (!($field instanceof Field))
192 $currentDefinitionParts[] = $field->getName();
193 $currentDefinition = join(
'.', $currentDefinitionParts);
196 $isRuntimeField = !empty($this->query->getRuntimeChains()[$currentDefinition]);
198 if ($field instanceof IReadable)
201 if ($currentObject !==
$object)
207 $value = $field->cast($row[$selectChain->getAlias()]);
211 ? $currentObject->sysSetRuntime($field->getName(), $value)
212 : $currentObject->sysSetActual($field->getName(), $value);
219 if (array_key_exists($currentDefinition, $relEntityCache))
221 $currentObject = $relEntityCache[$currentDefinition];
226 $remoteEntity = $field->getRefEntity();
230 $remotePrimary = $remoteEntity->getPrimaryArray();
231 $remoteObjectValues = [];
232 $remotePrimaryValues = [];
234 foreach ($this->selectChainsMap[$currentDefinition] as $remoteChain)
237 $remoteField = $remoteChain->getLastElement()->getValue();
238 $remoteValue = $row[$remoteChain->getAlias()];
240 $remoteObjectValues[$remoteField->getName()] = $remoteValue;
243 foreach ($remotePrimary as $primaryName)
245 if (!array_key_exists($primaryName, $remoteObjectValues))
247 throw new SystemException(sprintf(
248 'Primary of %s was not found in database result', $remoteEntity->getDataClass()
252 $remotePrimaryValues[$primaryName] = $remoteObjectValues[$primaryName];
256 if ($field instanceof Reference)
259 $remoteObject = $this->composeRemoteObject($remoteEntity, $remotePrimaryValues, $remoteObjectValues);
263 ? $currentObject->sysSetRuntime($field->getName(), $remoteObject)
264 : $currentObject->sysSetActual($field->getName(), $remoteObject);
266 elseif ($field instanceof OneToMany || $field instanceof ManyToMany)
271 if (empty($currentObject->sysGetRuntime($field->getName())))
275 $collection = $remoteEntity->createCollection();
276 $currentObject->sysSetRuntime($field->getName(), $collection);
280 $collection = $currentObject->sysGetRuntime($field->getName());
285 if (empty($currentObject->sysGetValue($field->getName())))
289 $collection = $remoteEntity->createCollection();
292 if ($this->query->getLimit() ===
null)
295 $noRelationInFilter =
true;
297 foreach ($this->query->getFilterChains() as $chain)
299 if (strpos($chain->getDefinition(), $currentDefinition) === 0)
301 $noRelationInFilter =
false;
306 if ($noRelationInFilter)
309 $collection->sysSetFilled();
313 $currentObject->sysSetActual($field->getName(), $collection);
317 $collection = $currentObject->sysGetValue($field->getName());
322 if (current($remotePrimaryValues) ===
null || !$collection->hasByPrimary($remotePrimaryValues))
325 $remoteObject = $this->composeRemoteObject($remoteEntity, $remotePrimaryValues, $remoteObjectValues);
328 if ($remoteObject !==
null)
330 $collection->sysAddActual($remoteObject);
335 $remoteObject = $collection->getByPrimary($remotePrimaryValues);
340 throw new SystemException(
'Unknown chain element value while fetching object');
344 $currentObject = $remoteObject;
347 $relEntityCache[$currentDefinition] = $remoteObject;
355 $this->identityMap->put(
$object);
365 final public function fetchCollection()
368 $this->initializeFetchObject(
true);
371 $collection = $this->query->getEntity()->createCollection();
373 while (
$object = $this->fetchObject())
375 $collection->sysAddActual(
$object);
388 protected function initializeFetchObject($asCollection =
false)
390 if (empty($this->objectInitPassed))
393 if (!empty($this->query->getGroupChains()))
395 throw new SystemException(
396 'Result of query with aggregation could not be fetched as an object'
401 if (empty($this->identityMap))
404 $this->identityMap =
new IdentityMap;
407 $this->objectClass = $this->query->getEntity()->getObjectClass();
415 $this->objectInitPassed =
true;
418 if (!$asCollection && $this->query->hasBackReference())
421 $collection = $this->fetchCollection();
424 $originalResult = $this->result;
426 $this->result =
new ArrayResult($collection->getAll());
431 if ($originalResult->getCount())
433 $this->result->setCount($originalResult->getCount());
436 catch (\
Bitrix\Main\ObjectPropertyException $e) {}
446 foreach ($this->query->getSelectChains() as $selectChain)
448 $this->selectChainsMap[$selectChain->getDefinition(-1)][] = $selectChain;
457 $primaryNames = $this->query->getEntity()->getPrimaryArray();
459 foreach ($this->query->getSelectChains() as $selectChain)
461 $field = $selectChain->getLastElement()->getValue();
464 if ($field->getEntity()->getDataClass() === $this->query->getEntity()->getDataClass()
465 && in_array($field->getName(), $primaryNames))
467 $this->primaryAliases[$field->getName()] = $selectChain->getAlias();
469 if (count($this->primaryAliases) == count($primaryNames))
476 if (count($this->primaryAliases) != count($primaryNames))
479 'Primary of %s was not found in database result', $this->query->getEntity()->getDataClass()
489 foreach ($this->query->getSelectChains() as $selectChain)
491 $alias = $selectChain->getAlias();
493 if (!isset($this->result->converters[$alias]))
495 $this->result->converters[$alias] = [
496 $this->result->getFields()[$alias],
512 protected function composeRemoteObject($entity, $primaryValues, $objectValues)
515 if (current($primaryValues) ===
null)
522 $objectClass = $entity->getObjectClass();
523 $remoteObject = $this->identityMap->get($objectClass, $primaryValues);
528 if (empty($remoteObject))
531 $remoteObject =
new $objectClass(
false);
534 $remoteObject->sysChangeState(State::ACTUAL);
541 foreach ($objectValues as $fieldName => $objectValue)
544 $field = $entity->getField($fieldName);
545 $castValue = $field->cast($objectValue);
547 $remoteObject->sysSetActual($fieldName, $castValue);
553 $this->identityMap->put($remoteObject);
556 return $remoteObject;
568 $this->identityMap = $map;
578 return $this->identityMap;
584 return $this->result->getResource();
589 $this->result->setReplacedAliases($replacedAliases);
594 $this->result->addReplacedAliases($replacedAliases);
599 $this->result->setSerializedFields($serializedFields);
604 $this->result->addFetchDataModifier($fetchDataModifier);
609 return $this->result->fetchRaw();
612 public function fetch(\
Bitrix\Main\Text\Converter $converter =
null)
614 $row = $this->result->fetch($converter);
616 if ($row && !empty($this->hiddenObjectFields))
626 if (empty($this->hiddenObjectFields))
628 return $this->result->fetchAll($converter);
632 $data = $this->result->fetchAll($converter);
634 foreach (
$data as &$row)
646 return $this->result->getTrackerQuery();
651 return $this->result->getConverters();
661 $this->result->setCount($n);
666 return $this->result->getCount();
671 return $this->result->getIterator();