Skip to content

Commit e015262

Browse files
guich25yann-eugone
andauthored
Allow fetching total count JobExecution matched by query (#117)
* feature #98 Total count JobExecution matched by query * #98 fix phpstan * #98 fix unit test * Rebase branch --------- Co-authored-by: Yann Eugoné <eugone.yann@gmail.com>
1 parent cf1c154 commit e015262

File tree

5 files changed

+103
-55
lines changed

5 files changed

+103
-55
lines changed

src/batch-doctrine-dbal/src/DoctrineDBALJobExecutionStorage.php

Lines changed: 88 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Doctrine\DBAL\Connection;
88
use Doctrine\DBAL\Driver\Result;
99
use Doctrine\DBAL\Exception as DBALException;
10+
use Doctrine\DBAL\Query\QueryBuilder;
1011
use Doctrine\DBAL\Schema\Comparator;
1112
use Doctrine\DBAL\Schema\Schema;
1213
use Doctrine\DBAL\Types\Types;
@@ -147,65 +148,15 @@ public function list(string $jobName): iterable
147148

148149
public function query(Query $query): iterable
149150
{
150-
$queryParameters = [];
151-
$queryTypes = [];
152-
153151
$qb = $this->connection->createQueryBuilder();
154152
$qb->select('*')
155153
->from($this->table);
156154

157-
$names = $query->jobs();
158-
if (\count($names) > 0) {
159-
$qb->andWhere($qb->expr()->in('job_name', ':jobNames'));
160-
$queryParameters['jobNames'] = $names;
161-
$queryTypes['jobNames'] = Connection::PARAM_STR_ARRAY;
162-
}
163-
164-
$ids = $query->ids();
165-
if (\count($ids) > 0) {
166-
$qb->andWhere($qb->expr()->in('id', ':ids'));
167-
$queryParameters['ids'] = $ids;
168-
$queryTypes['ids'] = Connection::PARAM_STR_ARRAY;
169-
}
170-
171-
$statuses = $query->statuses();
172-
if (\count($statuses) > 0) {
173-
$qb->andWhere($qb->expr()->in('status', ':statuses'));
174-
$queryParameters['statuses'] = $statuses;
175-
$queryTypes['statuses'] = Connection::PARAM_INT_ARRAY;
176-
}
177-
178-
if ($query->startTime()) {
179-
$qb->andWhere($qb->expr()->isNotNull('start_time'));
180-
}
181-
$startDateFrom = $query->startTime()?->getFrom();
182-
if ($startDateFrom) {
183-
$qb->andWhere($qb->expr()->gte('start_time', ':startDateFrom'));
184-
$queryParameters['startDateFrom'] = $startDateFrom;
185-
$queryTypes['startDateFrom'] = Types::DATETIME_IMMUTABLE;
186-
}
187-
$startDateTo = $query->startTime()?->getTo();
188-
if ($startDateTo) {
189-
$qb->andWhere($qb->expr()->lte('start_time', ':startDateTo'));
190-
$queryParameters['startDateTo'] = $startDateTo;
191-
$queryTypes['startDateTo'] = Types::DATETIME_IMMUTABLE;
192-
}
193-
194-
if ($query->endTime()) {
195-
$qb->andWhere($qb->expr()->isNotNull('start_time'));
196-
}
197-
$endDateFrom = $query->endTime()?->getFrom();
198-
if ($endDateFrom) {
199-
$qb->andWhere($qb->expr()->gte('end_time', ':endDateFrom'));
200-
$queryParameters['endDateFrom'] = $endDateFrom;
201-
$queryTypes['endDateFrom'] = Types::DATETIME_IMMUTABLE;
202-
}
203-
$endDateTo = $query->endTime()?->getTo();
204-
if ($endDateTo) {
205-
$qb->andWhere($qb->expr()->lte('end_time', ':endDateTo'));
206-
$queryParameters['endDateTo'] = $endDateTo;
207-
$queryTypes['endDateTo'] = Types::DATETIME_IMMUTABLE;
208-
}
155+
/**
156+
* @phpstan-var array<string, mixed> $queryParameters
157+
* @phpstan-var array<string, string|int> $queryTypes
158+
*/
159+
[$queryParameters, $queryTypes] = $this->addWheres($query, $qb);
209160

210161
switch ($query->sort()) {
211162
case Query::SORT_BY_START_ASC:
@@ -228,6 +179,24 @@ public function query(Query $query): iterable
228179
yield from $this->queryList($qb->getSQL(), $queryParameters, $queryTypes);
229180
}
230181

182+
public function count(Query $query): int
183+
{
184+
$qb = $this->connection->createQueryBuilder();
185+
$qb->select('count(*)')
186+
->from($this->table);
187+
188+
/**
189+
* @phpstan-var array<string, mixed> $queryParameters
190+
* @phpstan-var array<string, string|int> $queryTypes
191+
*/
192+
[$queryParameters, $queryTypes] = $this->addWheres($query, $qb);
193+
194+
/** @var int $result */
195+
$result = $this->connection->executeQuery($qb->getSQL(), $queryParameters, $queryTypes)->fetchOne();
196+
197+
return $result;
198+
}
199+
231200
private function getSchema(): Schema
232201
{
233202
$schema = new Schema();
@@ -357,4 +326,68 @@ private function getNormalizer(): JobExecutionRowNormalizer
357326

358327
return $this->normalizer;
359328
}
329+
330+
/**
331+
* @return array{array<string, mixed>, array<string, string|int>}
332+
*/
333+
private function addWheres(Query $query, QueryBuilder $qb): array
334+
{
335+
$queryParameters = [];
336+
$queryTypes = [];
337+
338+
$names = $query->jobs();
339+
if (\count($names) > 0) {
340+
$qb->andWhere($qb->expr()->in('job_name', ':jobNames'));
341+
$queryParameters['jobNames'] = $names;
342+
$queryTypes['jobNames'] = Connection::PARAM_STR_ARRAY;
343+
}
344+
345+
$ids = $query->ids();
346+
if (\count($ids) > 0) {
347+
$qb->andWhere($qb->expr()->in('id', ':ids'));
348+
$queryParameters['ids'] = $ids;
349+
$queryTypes['ids'] = Connection::PARAM_STR_ARRAY;
350+
}
351+
352+
$statuses = $query->statuses();
353+
if (\count($statuses) > 0) {
354+
$qb->andWhere($qb->expr()->in('status', ':statuses'));
355+
$queryParameters['statuses'] = $statuses;
356+
$queryTypes['statuses'] = Connection::PARAM_INT_ARRAY;
357+
}
358+
359+
if ($query->startTime()) {
360+
$qb->andWhere($qb->expr()->isNotNull('start_time'));
361+
}
362+
$startDateFrom = $query->startTime()?->getFrom();
363+
if ($startDateFrom) {
364+
$qb->andWhere($qb->expr()->gte('start_time', ':startDateFrom'));
365+
$queryParameters['startDateFrom'] = $startDateFrom;
366+
$queryTypes['startDateFrom'] = Types::DATETIME_IMMUTABLE;
367+
}
368+
$startDateTo = $query->startTime()?->getTo();
369+
if ($startDateTo) {
370+
$qb->andWhere($qb->expr()->lte('start_time', ':startDateTo'));
371+
$queryParameters['startDateTo'] = $startDateTo;
372+
$queryTypes['startDateTo'] = Types::DATETIME_IMMUTABLE;
373+
}
374+
375+
if ($query->endTime()) {
376+
$qb->andWhere($qb->expr()->isNotNull('start_time'));
377+
}
378+
$endDateFrom = $query->endTime()?->getFrom();
379+
if ($endDateFrom) {
380+
$qb->andWhere($qb->expr()->gte('end_time', ':endDateFrom'));
381+
$queryParameters['endDateFrom'] = $endDateFrom;
382+
$queryTypes['endDateFrom'] = Types::DATETIME_IMMUTABLE;
383+
}
384+
$endDateTo = $query->endTime()?->getTo();
385+
if ($endDateTo) {
386+
$qb->andWhere($qb->expr()->lte('end_time', ':endDateTo'));
387+
$queryParameters['endDateTo'] = $endDateTo;
388+
$queryTypes['endDateTo'] = Types::DATETIME_IMMUTABLE;
389+
}
390+
391+
return [$queryParameters, $queryTypes];
392+
}
360393
}

src/batch-doctrine-dbal/tests/DoctrineDBALJobExecutionStorageTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@ public function testQuery(QueryBuilder $queryBuilder, array $expectedCouples): v
282282
$this->loadFixtures($storage);
283283

284284
self::assertExecutions($expectedCouples, $storage->query($queryBuilder->getQuery()));
285+
self::assertSame(\count($expectedCouples), $storage->count($queryBuilder->getQuery()));
285286
}
286287

287288
public function queries(): Generator

src/batch/src/Storage/FilesystemJobExecutionStorage.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,14 @@ public function query(Query $query): iterable
159159
return \array_slice($candidates, $query->offset(), $query->limit());
160160
}
161161

162+
public function count(Query $query): int
163+
{
164+
/** @var JobExecution[] $result */
165+
$result = $this->query($query);
166+
167+
return \count($result);
168+
}
169+
162170
private function buildFilePath(string $jobName, string $executionId): string
163171
{
164172
return \implode(DIRECTORY_SEPARATOR, [$this->directory, $jobName, $executionId]) .

src/batch/src/Storage/QueryableJobExecutionStorageInterface.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,9 @@ interface QueryableJobExecutionStorageInterface extends ListableJobExecutionStor
1717
* @return iterable|JobExecution[]
1818
*/
1919
public function query(Query $query): iterable;
20+
21+
/**
22+
* Execute query against stored job executions, and return count result.
23+
*/
24+
public function count(Query $query): int;
2025
}

src/batch/tests/Storage/FilesystemJobExecutionStorageTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ public function testQueryWithProvider(QueryBuilder $query, array $expectedCouple
150150
);
151151

152152
self::assertExecutions($expectedCouples, $storage->query($query->getQuery()));
153+
self::assertEquals(\count($expectedCouples), $storage->count($query->getQuery()));
153154
}
154155

155156
public function query(): \Generator

0 commit comments

Comments
 (0)