protected function fetchByTwoPassStrategy(QueryBuilder $builder, array $values, IEntityPreloadContainer $preloadContainer = NULL) { $builder = clone $builder; $targetPrimaryKey = $this->targetMapper->getStorageReflection()->getStoragePrimaryKey(); $isComposite = count($targetPrimaryKey) !== 1; foreach (array_unique(array_merge($targetPrimaryKey, [$this->joinStorageKey])) as $key) { $builder->addSelect("[{$key}]"); } $sqls = $args = []; foreach ($values as $primaryValue) { $builderPart = clone $builder; $builderPart->andWhere("%column = %any", $this->joinStorageKey, $primaryValue); $sqls[] = $builderPart->getQuerySQL(); $args = array_merge($args, $builderPart->getQueryParameters()); } $query = '(' . implode(') UNION ALL (', $sqls) . ')'; $result = $this->connection->queryArgs($query, $args); $map = $ids = []; if ($isComposite) { foreach ($result as $row) { $id = []; foreach ($targetPrimaryKey as $key) { $id[] = $row->{$key}; } $ids[] = $id; $map[$row->{$this->joinStorageKey}][] = implode(',', $id); } } else { $targetPrimaryKey = $targetPrimaryKey[0]; foreach ($result as $row) { $ids[] = $row->{$targetPrimaryKey}; $map[$row->{$this->joinStorageKey}][] = $row->{$targetPrimaryKey}; } } if (count($ids) === 0) { return new EntityIterator([], $preloadContainer); } if ($isComposite) { $builder = $this->targetMapper->builder(); $builder->andWhere('%column[] IN %any', $targetPrimaryKey, $ids); $entitiesResult = []; $collection = $this->targetMapper->toCollection($builder); foreach ($collection as $entity) { $entitiesResult[implode(',', $entity->getValue('id'))] = $entity; } } else { $entitiesResult = $this->targetRepository->findBy([$targetPrimaryKey => $ids])->fetchPairs($targetPrimaryKey, NULL); } $entities = []; foreach ($map as $joiningStorageKey => $primaryValues) { foreach ($primaryValues as $primaryValue) { $entity = $entitiesResult[$primaryValue]; $entities[$entity->getRawValue($this->metadata->relationship->property)][] = $entity; } } return new EntityIterator($entities, $preloadContainer); }
protected function createComponentGrid() : Ytnuk\Grid\Control { $grid = new Ytnuk\Grid\Control(function (Nextras\Orm\Entity\IEntity $entity = NULL) { if (!$entity) { $entityClass = $this->repository->getEntityMetadata()->getClassName(); $entity = new $entityClass(); } $form = $this->form->create($entity); $form->onSubmit[] = function () { $this->redirect('this'); }; return $form; }, function (array $order, array $filter) { return $this->repository->findBy($this->prepareValues($filter))->orderBy($this->prepareValues($order))->fetchPairs(current($this->repository->getEntityMetadata()->getPrimaryKey())); }); return $grid->setLink(function ($entity) { return $entity ? $this->getPresenter()->link('Presenter:edit', [current($this->repository->getEntityMetadata()->getPrimaryKey()) => $entity->id]) : $this->getPresenter()->link('Presenter:add'); })->filterInputs(['this']); }
private function fetchByTwoPassStrategy(QueryBuilder $builder, array $values) { $sourceTable = $builder->getFromAlias(); $targetTable = QueryBuilderHelper::getAlias($this->joinTable); $builder = clone $builder; $builder->leftJoin($sourceTable, '%table', $targetTable, '%column = %column', $this->joinTable, "{$targetTable}.{$this->primaryKeyTo}", "{$sourceTable}." . $this->targetRepository->getMapper()->getStorageReflection()->getStoragePrimaryKey()[0]); $builder->addSelect('%column', "{$targetTable}.{$this->primaryKeyTo}"); $builder->addSelect('%column', "{$targetTable}.{$this->primaryKeyFrom}"); if ($builder->hasLimitOffsetClause()) { // todo !== 1 $sqls = $args = []; foreach ($values as $value) { $builderPart = clone $builder; $builderPart->andWhere('%column = %any', "{$targetTable}.{$this->primaryKeyFrom}", $value); $sqls[] = $builderPart->getQuerySQL(); $args = array_merge($args, $builderPart->getQueryParameters()); } $query = '(' . implode(') UNION ALL (', $sqls) . ')'; $result = $this->connection->queryArgs($query, $args); } else { $builder->andWhere('%column IN %any', "{$targetTable}.{$this->primaryKeyFrom}", $values); $result = $this->connection->queryArgs($builder->getQuerySQL(), $builder->getQueryParameters()); } $values = []; foreach ($result as $row) { $values[$row->{$this->primaryKeyTo}] = NULL; } if (count($values) === 0) { return new EntityIterator([]); } $entitiesResult = $this->targetRepository->findBy(['id' => array_keys($values)]); $entities = $entitiesResult->fetchPairs('id', NULL); $grouped = []; foreach ($result as $row) { $grouped[$row->{$this->primaryKeyFrom}][] = $entities[$row->{$this->primaryKeyTo}]; } return new EntityIterator($grouped); }
protected function fetchByTwoPassStrategy(SqlBuilder $builder, array $values) { $builder = clone $builder; $targetPrimaryKey = $this->targetMapper->getStorageReflection()->getStoragePrimaryKey(); $isComposite = count($targetPrimaryKey) !== 1; foreach (array_unique(array_merge($targetPrimaryKey, [$this->joinStorageKey])) as $key) { $builder->addSelect($key); } $sqls = $args = []; foreach ($values as $primaryValue) { $builderPart = clone $builder; $builderPart->addWhere($this->joinStorageKey, $primaryValue); $sqls[] = $builderPart->buildSelectQuery(); $args = array_merge($args, $builderPart->getParameters()); } $query = '(' . implode(') UNION ALL (', $sqls) . ')'; $result = $this->context->queryArgs($query, $args); $map = $ids = []; if ($isComposite) { foreach ($result->fetchAll() as $row) { $id = []; foreach ($targetPrimaryKey as $key) { $id[] = $row->{$key}; } $ids[] = $id; $map[$row->{$this->joinStorageKey}][] = implode(',', $id); } } else { $targetPrimaryKey = $targetPrimaryKey[0]; foreach ($result->fetchAll() as $row) { $ids[] = $row->{$targetPrimaryKey}; $map[$row->{$this->joinStorageKey}][] = $row->{$targetPrimaryKey}; } } if (count($ids) === 0) { return new EntityIterator([]); } if ($isComposite) { $collectionMapper = $this->targetRepository->findAll()->getCollectionMapper(); if (!$collectionMapper instanceof CollectionMapper) { throw new InvalidStateException(); } $builder = $collectionMapper->getSqlBuilder(); $builder->addWhere($targetPrimaryKey, $ids); $collectionMapper = new SqlBuilderCollectionMapper($this->targetRepository, $this->context, $builder); $entitiesResult = []; foreach ($collectionMapper->getIterator() as $entity) { $entitiesResult[implode(',', $entity->getValue('id'))] = $entity; } } else { $entitiesResult = $this->targetRepository->findBy([$targetPrimaryKey => $ids])->fetchPairs($targetPrimaryKey, NULL); } $entities = []; foreach ($map as $joiningStorageKey => $primaryValues) { foreach ($primaryValues as $primaryValue) { $entity = $entitiesResult[$primaryValue]; $entities[$entity->getForeignKey($this->metadata->relationshipProperty)][] = $entity; } } return new EntityIterator($entities); }