コード例 #1
0
 protected function fetch(QueryBuilder $builder, $hasJoin, array $values, IEntityPreloadContainer $preloadContainer = NULL)
 {
     $values = array_values(array_unique(array_filter($values, function ($value) {
         return $value !== NULL;
     })));
     if (count($values) === 0) {
         return new EntityContainer([], $preloadContainer);
     }
     $primaryKey = $this->targetRepository->getMapper()->getStorageReflection()->getStoragePrimaryKey()[0];
     $builder->andWhere('%column IN %any', $primaryKey, $values);
     $builder->addSelect(($hasJoin ? 'DISTINCT ' : '') . '%table.*', $builder->getFromAlias());
     $result = $this->connection->queryArgs($builder->getQuerySQL(), $builder->getQueryParameters());
     $entities = [];
     while ($data = $result->fetch()) {
         $entity = $this->targetRepository->hydrateEntity($data->toArray());
         $entities[$entity->getValue('id')] = $entity;
     }
     return new EntityContainer($entities, $preloadContainer);
 }
コード例 #2
0
 private function fetchCounts(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->primaryKeyFrom}");
     $builder->orderBy(NULL);
     if ($builder->hasLimitOffsetClause()) {
         $sqls = [];
         $args = [];
         foreach ($values as $value) {
             $build = clone $builder;
             $build->andWhere("%column = %any", $this->primaryKeyFrom, $value);
             $sqls[] = "SELECT %any AS %column, COUNT(*) AS [count] FROM (" . $build->getQuerySql() . ') [temp]';
             $args[] = $value;
             $args[] = $this->primaryKeyFrom;
             $args = array_merge($args, $build->getQueryParameters());
         }
         $sql = '(' . implode(') UNION ALL (', $sqls) . ')';
         $result = $this->connection->queryArgs($sql, $args);
     } else {
         $builder->addSelect('COUNT(%column) as count', $this->primaryKeyTo);
         $builder->andWhere('%column IN %any', $this->primaryKeyFrom, $values);
         $builder->groupBy('%column', $this->primaryKeyFrom);
         $result = $this->connection->queryArgs($builder->getQuerySql(), $builder->getQueryParameters());
     }
     $counts = [];
     foreach ($result as $row) {
         $counts[$row->{$this->primaryKeyFrom}] = $row->count;
     }
     return $counts;
 }
コード例 #3
0
 private function normalizeAndAddJoins(array $levels, $sourceEntity, QueryBuilder $builder, &$distinctNeeded = FALSE, &$value = NULL)
 {
     $column = array_pop($levels);
     $sourceMapper = $this->mapper;
     $sourceAlias = $builder->getFromAlias();
     $sourceReflection = $sourceMapper->getStorageReflection();
     $sourceEntityMeta = $this->metadataStorage->get($sourceEntity ?: $sourceMapper->getRepository()->getEntityClassNames()[0]);
     foreach ($levels as $levelIndex => $level) {
         $property = $sourceEntityMeta->getProperty($level);
         if ($property->relationship === NULL) {
             throw new InvalidArgumentException("Entity {$sourceEntityMeta->className}::\${$level} does not contain a relationship.");
         }
         $targetMapper = $this->model->getRepository($property->relationship->repository)->getMapper();
         $targetReflection = $targetMapper->getStorageReflection();
         $targetEntityMetadata = $this->metadataStorage->get($property->relationship->entity);
         $relType = $property->relationship->type;
         if ($relType === Relationship::ONE_HAS_MANY || $relType === Relationship::ONE_HAS_ONE_DIRECTED && !$property->relationship->isMain) {
             $targetColumn = $targetReflection->convertEntityToStorageKey($property->relationship->property);
             $sourceColumn = $sourceReflection->getStoragePrimaryKey()[0];
             $distinctNeeded = TRUE;
         } elseif ($relType === Relationship::MANY_HAS_MANY) {
             if ($property->relationship->isMain) {
                 list($joinTable, list($inColumn, $outColumn)) = $sourceMapper->getManyHasManyParameters($property, $targetMapper);
             } else {
                 $sourceProperty = $targetEntityMetadata->getProperty($property->relationship->property);
                 list($joinTable, list($outColumn, $inColumn)) = $targetMapper->getManyHasManyParameters($sourceProperty, $sourceMapper);
             }
             $sourceColumn = $sourceReflection->getStoragePrimaryKey()[0];
             $builder->leftJoin($sourceAlias, $joinTable, self::getAlias($joinTable), "[{$sourceAlias}.{$sourceColumn}] = [{$joinTable}.{$inColumn}]");
             $sourceAlias = $joinTable;
             $sourceColumn = $outColumn;
             $targetColumn = $targetReflection->getStoragePrimaryKey()[0];
             $distinctNeeded = TRUE;
         } else {
             $targetColumn = $targetReflection->getStoragePrimaryKey()[0];
             $sourceColumn = $sourceReflection->convertEntityToStorageKey($level);
         }
         $targetTable = $targetMapper->getTableName();
         $targetAlias = $level . str_repeat('_', $levelIndex);
         $builder->leftJoin($sourceAlias, $targetTable, $targetAlias, "[{$sourceAlias}.{$sourceColumn}] = [{$targetAlias}.{$targetColumn}]");
         $sourceAlias = $targetAlias;
         $sourceMapper = $targetMapper;
         $sourceReflection = $targetReflection;
         $sourceEntityMeta = $targetEntityMetadata;
     }
     $sourceEntityMeta->getProperty($column);
     // check if property exists
     if ($column === 'id' && count($sourceEntityMeta->getPrimaryKey()) > 1) {
         $pair = [];
         foreach ($sourceEntityMeta->getPrimaryKey() as $column) {
             $column = $sourceReflection->convertEntityToStorageKey($column);
             $pair[] = "{$sourceAlias}.{$column}";
         }
         if (!isset($value[0][0])) {
             $value = [$value];
         }
         return '(' . implode(', ', $pair) . ')';
     } else {
         $column = $sourceReflection->convertEntityToStorageKey($column);
         return "{$sourceAlias}.{$column}";
     }
 }
コード例 #4
0
ファイル: QueryBuilderHelper.php プロジェクト: nextras/orm
 private function normalizeAndAddJoins(array $levels, $sourceEntity, QueryBuilder $builder, &$distinctNeeded = false, &$value = null, &$modifier = '%any')
 {
     $column = array_pop($levels);
     $sourceMapper = $this->mapper;
     $sourceAlias = $builder->getFromAlias();
     $sourceReflection = $sourceMapper->getStorageReflection();
     $sourceEntityMeta = $this->metadataStorage->get($sourceEntity ?: $sourceMapper->getRepository()->getEntityClassNames()[0]);
     foreach ($levels as $levelIndex => $level) {
         $property = $sourceEntityMeta->getProperty($level);
         if ($property->relationship === null) {
             throw new InvalidArgumentException("Entity {$sourceEntityMeta->className}::\${$level} does not contain a relationship.");
         }
         $targetMapper = $this->model->getRepository($property->relationship->repository)->getMapper();
         $targetReflection = $targetMapper->getStorageReflection();
         $targetEntityMetadata = $this->metadataStorage->get($property->relationship->entity);
         $relType = $property->relationship->type;
         if ($relType === Relationship::ONE_HAS_MANY || $relType === Relationship::ONE_HAS_ONE && !$property->relationship->isMain) {
             $targetColumn = $targetReflection->convertEntityToStorageKey($property->relationship->property);
             $sourceColumn = $sourceReflection->getStoragePrimaryKey()[0];
             $distinctNeeded = $relType === Relationship::ONE_HAS_MANY;
         } elseif ($relType === Relationship::MANY_HAS_MANY) {
             if ($property->relationship->isMain) {
                 list($joinTable, list($inColumn, $outColumn)) = $sourceMapper->getManyHasManyParameters($property, $targetMapper);
             } else {
                 $sourceProperty = $targetEntityMetadata->getProperty($property->relationship->property);
                 list($joinTable, list($outColumn, $inColumn)) = $targetMapper->getManyHasManyParameters($sourceProperty, $sourceMapper);
             }
             $sourceColumn = $sourceReflection->getStoragePrimaryKey()[0];
             $builder->leftJoin($sourceAlias, $joinTable, self::getAlias($joinTable), "[{$sourceAlias}.{$sourceColumn}] = [{$joinTable}.{$inColumn}]");
             $sourceAlias = $joinTable;
             $sourceColumn = $outColumn;
             $targetColumn = $targetReflection->getStoragePrimaryKey()[0];
             $distinctNeeded = true;
         } else {
             $targetColumn = $targetReflection->getStoragePrimaryKey()[0];
             $sourceColumn = $sourceReflection->convertEntityToStorageKey($level);
         }
         $targetTable = $targetMapper->getTableName();
         $targetAlias = $level . str_repeat('_', $levelIndex);
         $builder->leftJoin($sourceAlias, $targetTable, $targetAlias, "[{$sourceAlias}.{$sourceColumn}] = [{$targetAlias}.{$targetColumn}]");
         $sourceAlias = $targetAlias;
         $sourceMapper = $targetMapper;
         $sourceReflection = $targetReflection;
         $sourceEntityMeta = $targetEntityMetadata;
     }
     $targetProperty = $sourceEntityMeta->getProperty($column);
     if ($targetProperty->isPrimary && $targetProperty->isVirtual) {
         // primary-proxy
         $primaryKey = $sourceEntityMeta->getPrimaryKey();
         if (count($primaryKey) > 1) {
             // composite primary key
             $modifier = '%any';
             list($expression, $value) = $this->processMultiColumn($sourceReflection, $primaryKey, $value, $sourceAlias);
             return $expression;
         } else {
             $column = reset($primaryKey);
         }
     }
     list($expression, $modifier, $value) = $this->processColumn($sourceReflection, $column, $value, $sourceAlias);
     return $expression;
 }
 private function fetchCounts(QueryBuilder $builder, array $values)
 {
     $targetStoragePrimaryKey = $this->targetMapper->getStorageReflection()->getStoragePrimaryKey()[0];
     $sourceTable = $builder->getFromAlias();
     $builder = clone $builder;
     $builder->addSelect("{$sourceTable}.{$this->joinStorageKey}");
     $builder->orderBy(NULL);
     if ($builder->hasLimitOffsetClause()) {
         $sqls = [];
         $args = [];
         foreach ($values as $value) {
             $build = clone $builder;
             $build->andWhere("{$sourceTable}.{$this->joinStorageKey} = %any", $value);
             $sqls[] = "SELECT {$value} as {$this->joinStorageKey}, COUNT(*) AS count FROM (" . $build->getQuerySql() . ') temp';
             $args = array_merge($args, $build->getQueryParameters());
         }
         $sql = '(' . implode(') UNION ALL (', $sqls) . ')';
         $result = $this->connection->queryArgs($sql, $args);
     } else {
         $builder->addSelect("COUNT({$sourceTable}.{$targetStoragePrimaryKey}) AS count");
         $builder->andWhere("{$sourceTable}.{$this->joinStorageKey} IN %any", $values);
         $builder->groupBy("{$sourceTable}.{$this->joinStorageKey}");
         $result = $this->connection->queryArgs($builder->getQuerySql(), $builder->getQueryParameters());
     }
     $counts = [];
     foreach ($result as $row) {
         $counts[$row->{$this->joinStorageKey}] = $row->count;
     }
     return $counts;
 }