diff --git a/src/batch-doctrine-dbal/src/DoctrineDBALJobExecutionStorage.php b/src/batch-doctrine-dbal/src/DoctrineDBALJobExecutionStorage.php index b5bceb8e..5133e0c7 100644 --- a/src/batch-doctrine-dbal/src/DoctrineDBALJobExecutionStorage.php +++ b/src/batch-doctrine-dbal/src/DoctrineDBALJobExecutionStorage.php @@ -7,6 +7,7 @@ use Doctrine\DBAL\Connection; use Doctrine\DBAL\Driver\Result; use Doctrine\DBAL\Exception as DBALException; +use Doctrine\DBAL\Query\QueryBuilder; use Doctrine\DBAL\Schema\Comparator; use Doctrine\DBAL\Schema\Schema; use Doctrine\DBAL\Types\Types; @@ -147,65 +148,15 @@ public function list(string $jobName): iterable public function query(Query $query): iterable { - $queryParameters = []; - $queryTypes = []; - $qb = $this->connection->createQueryBuilder(); $qb->select('*') ->from($this->table); - $names = $query->jobs(); - if (\count($names) > 0) { - $qb->andWhere($qb->expr()->in('job_name', ':jobNames')); - $queryParameters['jobNames'] = $names; - $queryTypes['jobNames'] = Connection::PARAM_STR_ARRAY; - } - - $ids = $query->ids(); - if (\count($ids) > 0) { - $qb->andWhere($qb->expr()->in('id', ':ids')); - $queryParameters['ids'] = $ids; - $queryTypes['ids'] = Connection::PARAM_STR_ARRAY; - } - - $statuses = $query->statuses(); - if (\count($statuses) > 0) { - $qb->andWhere($qb->expr()->in('status', ':statuses')); - $queryParameters['statuses'] = $statuses; - $queryTypes['statuses'] = Connection::PARAM_INT_ARRAY; - } - - if ($query->startTime()) { - $qb->andWhere($qb->expr()->isNotNull('start_time')); - } - $startDateFrom = $query->startTime()?->getFrom(); - if ($startDateFrom) { - $qb->andWhere($qb->expr()->gte('start_time', ':startDateFrom')); - $queryParameters['startDateFrom'] = $startDateFrom; - $queryTypes['startDateFrom'] = Types::DATETIME_IMMUTABLE; - } - $startDateTo = $query->startTime()?->getTo(); - if ($startDateTo) { - $qb->andWhere($qb->expr()->lte('start_time', ':startDateTo')); - $queryParameters['startDateTo'] = $startDateTo; - $queryTypes['startDateTo'] = Types::DATETIME_IMMUTABLE; - } - - if ($query->endTime()) { - $qb->andWhere($qb->expr()->isNotNull('start_time')); - } - $endDateFrom = $query->endTime()?->getFrom(); - if ($endDateFrom) { - $qb->andWhere($qb->expr()->gte('end_time', ':endDateFrom')); - $queryParameters['endDateFrom'] = $endDateFrom; - $queryTypes['endDateFrom'] = Types::DATETIME_IMMUTABLE; - } - $endDateTo = $query->endTime()?->getTo(); - if ($endDateTo) { - $qb->andWhere($qb->expr()->lte('end_time', ':endDateTo')); - $queryParameters['endDateTo'] = $endDateTo; - $queryTypes['endDateTo'] = Types::DATETIME_IMMUTABLE; - } + /** + * @phpstan-var array $queryParameters + * @phpstan-var array $queryTypes + */ + [$queryParameters, $queryTypes] = $this->addWheres($query, $qb); switch ($query->sort()) { case Query::SORT_BY_START_ASC: @@ -228,6 +179,24 @@ public function query(Query $query): iterable yield from $this->queryList($qb->getSQL(), $queryParameters, $queryTypes); } + public function count(Query $query): int + { + $qb = $this->connection->createQueryBuilder(); + $qb->select('count(*)') + ->from($this->table); + + /** + * @phpstan-var array $queryParameters + * @phpstan-var array $queryTypes + */ + [$queryParameters, $queryTypes] = $this->addWheres($query, $qb); + + /** @var int $result */ + $result = $this->connection->executeQuery($qb->getSQL(), $queryParameters, $queryTypes)->fetchOne(); + + return $result; + } + private function getSchema(): Schema { $schema = new Schema(); @@ -357,4 +326,68 @@ private function getNormalizer(): JobExecutionRowNormalizer return $this->normalizer; } + + /** + * @return array{array, array} + */ + private function addWheres(Query $query, QueryBuilder $qb): array + { + $queryParameters = []; + $queryTypes = []; + + $names = $query->jobs(); + if (\count($names) > 0) { + $qb->andWhere($qb->expr()->in('job_name', ':jobNames')); + $queryParameters['jobNames'] = $names; + $queryTypes['jobNames'] = Connection::PARAM_STR_ARRAY; + } + + $ids = $query->ids(); + if (\count($ids) > 0) { + $qb->andWhere($qb->expr()->in('id', ':ids')); + $queryParameters['ids'] = $ids; + $queryTypes['ids'] = Connection::PARAM_STR_ARRAY; + } + + $statuses = $query->statuses(); + if (\count($statuses) > 0) { + $qb->andWhere($qb->expr()->in('status', ':statuses')); + $queryParameters['statuses'] = $statuses; + $queryTypes['statuses'] = Connection::PARAM_INT_ARRAY; + } + + if ($query->startTime()) { + $qb->andWhere($qb->expr()->isNotNull('start_time')); + } + $startDateFrom = $query->startTime()?->getFrom(); + if ($startDateFrom) { + $qb->andWhere($qb->expr()->gte('start_time', ':startDateFrom')); + $queryParameters['startDateFrom'] = $startDateFrom; + $queryTypes['startDateFrom'] = Types::DATETIME_IMMUTABLE; + } + $startDateTo = $query->startTime()?->getTo(); + if ($startDateTo) { + $qb->andWhere($qb->expr()->lte('start_time', ':startDateTo')); + $queryParameters['startDateTo'] = $startDateTo; + $queryTypes['startDateTo'] = Types::DATETIME_IMMUTABLE; + } + + if ($query->endTime()) { + $qb->andWhere($qb->expr()->isNotNull('start_time')); + } + $endDateFrom = $query->endTime()?->getFrom(); + if ($endDateFrom) { + $qb->andWhere($qb->expr()->gte('end_time', ':endDateFrom')); + $queryParameters['endDateFrom'] = $endDateFrom; + $queryTypes['endDateFrom'] = Types::DATETIME_IMMUTABLE; + } + $endDateTo = $query->endTime()?->getTo(); + if ($endDateTo) { + $qb->andWhere($qb->expr()->lte('end_time', ':endDateTo')); + $queryParameters['endDateTo'] = $endDateTo; + $queryTypes['endDateTo'] = Types::DATETIME_IMMUTABLE; + } + + return [$queryParameters, $queryTypes]; + } } diff --git a/src/batch-doctrine-dbal/tests/DoctrineDBALJobExecutionStorageTest.php b/src/batch-doctrine-dbal/tests/DoctrineDBALJobExecutionStorageTest.php index 7ba5daca..09f00733 100644 --- a/src/batch-doctrine-dbal/tests/DoctrineDBALJobExecutionStorageTest.php +++ b/src/batch-doctrine-dbal/tests/DoctrineDBALJobExecutionStorageTest.php @@ -282,6 +282,7 @@ public function testQuery(QueryBuilder $queryBuilder, array $expectedCouples): v $this->loadFixtures($storage); self::assertExecutions($expectedCouples, $storage->query($queryBuilder->getQuery())); + self::assertSame(\count($expectedCouples), $storage->count($queryBuilder->getQuery())); } public function queries(): Generator diff --git a/src/batch/src/Storage/FilesystemJobExecutionStorage.php b/src/batch/src/Storage/FilesystemJobExecutionStorage.php index 51581b59..b16690ec 100644 --- a/src/batch/src/Storage/FilesystemJobExecutionStorage.php +++ b/src/batch/src/Storage/FilesystemJobExecutionStorage.php @@ -159,6 +159,14 @@ public function query(Query $query): iterable return \array_slice($candidates, $query->offset(), $query->limit()); } + public function count(Query $query): int + { + /** @var JobExecution[] $result */ + $result = $this->query($query); + + return \count($result); + } + private function buildFilePath(string $jobName, string $executionId): string { return \implode(DIRECTORY_SEPARATOR, [$this->directory, $jobName, $executionId]) . diff --git a/src/batch/src/Storage/QueryableJobExecutionStorageInterface.php b/src/batch/src/Storage/QueryableJobExecutionStorageInterface.php index 50f798f9..c4b1c90f 100644 --- a/src/batch/src/Storage/QueryableJobExecutionStorageInterface.php +++ b/src/batch/src/Storage/QueryableJobExecutionStorageInterface.php @@ -17,4 +17,9 @@ interface QueryableJobExecutionStorageInterface extends ListableJobExecutionStor * @return iterable|JobExecution[] */ public function query(Query $query): iterable; + + /** + * Execute query against stored job executions, and return count result. + */ + public function count(Query $query): int; } diff --git a/src/batch/tests/Storage/FilesystemJobExecutionStorageTest.php b/src/batch/tests/Storage/FilesystemJobExecutionStorageTest.php index bb945a9b..0a6d271d 100644 --- a/src/batch/tests/Storage/FilesystemJobExecutionStorageTest.php +++ b/src/batch/tests/Storage/FilesystemJobExecutionStorageTest.php @@ -150,6 +150,7 @@ public function testQueryWithProvider(QueryBuilder $query, array $expectedCouple ); self::assertExecutions($expectedCouples, $storage->query($query->getQuery())); + self::assertEquals(\count($expectedCouples), $storage->count($query->getQuery())); } public function query(): \Generator