Skip to content

Commit 3db4299

Browse files
committed
* rename var $unionOfQueries to $flattedQueryBuilder as it now will be the only query in $queries when it contains only one query
* now will only re-add `ORDER BY` and `LIMIT` clause which is same with ones in `setResult()` when `$queries` contains more than one query so `$flattedQueryBuilder` is a union of them * extract callback `$getParametersInterpolatedRawSQL` from the `Collection::reduce()` callback in `$flattedQueryBuilder` for reusing it in the assign to `$rawSQL` @ `getPostQueriesResult()` * rename method `getUnionQueryResult()` to `getPostQueriesResult()` and key `unionOfQueriesSQL` in its returned array to `rawSQL` @ `App\PostsQuery\QueryResult` * replace invoking of built-in function `count()` on `Collection` with its method with the same name @ `App\Controller\UsersController::query()` @ be
1 parent 7cdd8d1 commit 3db4299

2 files changed

Lines changed: 35 additions & 25 deletions

File tree

be/src/Controller/UsersController.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ function (int $paramIndex, QueryBuilder $queryBuilder, $paramValue, string $para
5454

5555
['result' => $result, 'hasMorePages' => $hasMorePages] =
5656
$this->queryResult->getQueryResult($queries, $this->perPageItems);
57-
$resultCount = count($result);
57+
$resultCount = $result->count();
5858
Helper::abortAPIIf(40402, $resultCount === 0);
5959

6060
return [

be/src/PostsQuery/QueryResult.php

Lines changed: 34 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -116,11 +116,11 @@ public function setResult(
116116
$qb->setParameter("cursor_$fieldName", $fieldValue)); // prevent overwriting existing param
117117
});
118118
[
119-
'unionOfQueriesSQL' => $unionOfQueriesSQL,
119+
'rawSQL' => $rawSQL,
120120
'postsKeyByTypePluralName' => $postsKeyByTypePluralName,
121121
'hasMorePages' => $hasMorePages,
122122
'queryPlan' => $queryPlan
123-
] = $this->getUnionQueryResult($queries, $isOrderByDesc, $maxResults);
123+
] = $this->getPostQueriesResult($queries, $isOrderByDesc, $maxResults);
124124

125125
$this->threads = $postsKeyByTypePluralName->get('threads', collect());
126126
$this->replies = $postsKeyByTypePluralName->get('replies', collect());
@@ -134,7 +134,7 @@ public function setResult(
134134
$queryByPostIDParamsName->map(static fn(string $postID) => Helper::POST_ID_TO_TYPE_PLURAL[$postID])
135135
))
136136
: null;
137-
$this->query = ['query' => $unionOfQueriesSQL, 'plan' => $queryPlan];
137+
$this->query = ['query' => $rawSQL, 'plan' => $queryPlan];
138138

139139
$this->stopwatch->stop('setResult');
140140
}
@@ -151,41 +151,51 @@ public function setResult(
151151
* @param Collection<Helpecr::POST_TYPE, QueryBuilder> $queries
152152
* @param bool $isOrderByDesc
153153
* @param int $maxResults
154-
* @return array{unionOfQueriesSQL: string, postsKeyByTypePluralName: PostsKeyByTypePluralName, hasMorePages: bool, queryPlan: array}
154+
* @return array{rawSQL: string, postsKeyByTypePluralName: PostsKeyByTypePluralName, hasMorePages: bool, queryPlan: array}
155155
*/
156-
private function getUnionQueryResult(Collection $queries, bool $isOrderByDesc, int $maxResults): array
156+
private function getPostQueriesResult(Collection $queries, bool $isOrderByDesc, int $maxResults): array
157157
{
158-
/** @var DBALQueryBuilder $unionOfQueries */
159-
// https://stackoverflow.com/questions/36959801/doctrine-orm-querybuilder-or-dbal-querybuilder
160-
$unionOfQueries = $queries->reduce(function (?DBALQueryBuilder $dbalQueryBuilder, QueryBuilder $ormQueryBuilder) {
161-
$ormQuery = $ormQueryBuilder->getQuery();
162-
$ormQuery->setHint(\Doctrine\ORM\Query::HINT_CUSTOM_OUTPUT_WALKER, InterpolateParametersSQLOutputWalker::class);
163-
$sql = $ormQuery->getSQL();
164-
if ($dbalQueryBuilder === null) {
165-
return $ormQueryBuilder->getEntityManager()->getConnection()
166-
->createQueryBuilder()->union($sql);
167-
}
168-
return $dbalQueryBuilder->addUnion($sql, UnionType::ALL);
169-
});
158+
$getParametersInterpolatedRawSQL = static function (QueryBuilder $queryBuilder) {
159+
$query = $queryBuilder->getQuery();
160+
$query->setHint(\Doctrine\ORM\Query::HINT_CUSTOM_OUTPUT_WALKER, InterpolateParametersSQLOutputWalker::class);
161+
return $query->getSQL();
162+
};
170163
$firstQuery = $queries->first();
164+
/** @var DBALQueryBuilder|QueryBuilder $flattedQueryBuilder */
165+
$flattedQueryBuilder = $queries->count() === 1
166+
? $firstQuery
167+
// https://stackoverflow.com/questions/36959801/doctrine-orm-querybuilder-or-dbal-querybuilder
168+
: $queries->reduce(function (?DBALQueryBuilder $dbalQueryBuilder, QueryBuilder $ormQueryBuilder) use ($getParametersInterpolatedRawSQL) {
169+
$sql = $getParametersInterpolatedRawSQL($ormQueryBuilder);
170+
if ($dbalQueryBuilder === null) {
171+
return $ormQueryBuilder->getEntityManager()->getConnection()
172+
->createQueryBuilder()->union($sql);
173+
}
174+
return $dbalQueryBuilder->addUnion($sql, UnionType::ALL);
175+
});
171176

172177
/** @var array{key-of<UnionPostKey>, string} $firstQueryFieldAliases */
173178
// field name and aliases in the first query in a union will override any other queries in union
174179
$firstQueryFieldAliases = array_flip((new Parser($firstQuery->getQuery()))
175180
->parse()->getResultSetMapping()->scalarMappings);
176-
$unionOfQueries = $unionOfQueries
177-
->addOrderBy($firstQueryFieldAliases['orderByField'], $isOrderByDesc === true ? 'DESC' : 'ASC')
178-
->addOrderBy($firstQueryFieldAliases['postId'])
179-
->setMaxResults($maxResults);
180-
$unionOfQueriesSQL = (new SqlFormatter(new NullHighlighter()))->format($unionOfQueries->getSQL());
181+
if ($flattedQueryBuilder instanceof DBALQueryBuilder) {
182+
$flattedQueryBuilder = $flattedQueryBuilder
183+
->addOrderBy($firstQueryFieldAliases['orderByField'], $isOrderByDesc === true ? 'DESC' : 'ASC')
184+
->addOrderBy($firstQueryFieldAliases['postId'])
185+
->setMaxResults($maxResults);
186+
}
187+
$rawSQL = (new SqlFormatter(new NullHighlighter()))->format(match (true) {
188+
$flattedQueryBuilder instanceof DBALQueryBuilder => $flattedQueryBuilder->getSQL(),
189+
$flattedQueryBuilder instanceof QueryBuilder => $getParametersInterpolatedRawSQL($flattedQueryBuilder)
190+
});
181191

182192
$rsm = new ResultSetMapping();
183193
foreach ($firstQueryFieldAliases as $fieldName => $fieldAlias) {
184194
$rsm->addScalarResult($fieldAlias, $fieldName);
185195
}
186196

187197
['result' => $result, 'hasMorePages' => $hasMorePages, 'queryPlan' => $queryPlan] = $this->getQueryResult(
188-
$firstQuery->getEntityManager()->createNativeQuery($unionOfQueriesSQL, $rsm),
198+
$firstQuery->getEntityManager()->createNativeQuery($rawSQL, $rsm),
189199
$this->perPageItems
190200
);
191201
/** @var PostsKeyByTypePluralName $postsKeyByTypePluralName */
@@ -211,7 +221,7 @@ private function getUnionQueryResult(Collection $queries, bool $isOrderByDesc, i
211221
Helper::abortAPIIf(40401, $postsKeyByTypePluralName->every(static fn(Collection $i) => $i->isEmpty()));
212222

213223
return [
214-
'unionOfQueriesSQL' => $unionOfQueriesSQL,
224+
'rawSQL' => $rawSQL,
215225
'postsKeyByTypePluralName' => $postsKeyByTypePluralName,
216226
'hasMorePages' => $hasMorePages,
217227
'queryPlan' => $queryPlan

0 commit comments

Comments
 (0)