From 56dcbcb3574faf669729e4d7d4ed13ac37624d02 Mon Sep 17 00:00:00 2001 From: Guicherd Date: Thu, 11 Jan 2024 17:13:41 +0100 Subject: [PATCH] feature #98 Total count JobExecution matched by query --- .../src/DoctrineDBALJobExecutionStorage.php | 83 +++++++++++++------ .../DoctrineDBALJobExecutionStorageTest.php | 2 + .../Storage/FilesystemJobExecutionStorage.php | 5 ++ .../QueryableJobExecutionStorageInterface.php | 5 ++ .../FilesystemJobExecutionStorageTest.php | 11 ++- 5 files changed, 80 insertions(+), 26 deletions(-) diff --git a/src/batch-doctrine-dbal/src/DoctrineDBALJobExecutionStorage.php b/src/batch-doctrine-dbal/src/DoctrineDBALJobExecutionStorage.php index 21c8f278..2692175e 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,34 +148,10 @@ 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; - } - switch ($query->sort()) { case Query::SORT_BY_START_ASC: $qb->orderBy('start_time', 'asc'); @@ -193,7 +170,19 @@ public function query(Query $query): iterable $qb->setMaxResults($query->limit()); $qb->setFirstResult($query->offset()); - yield from $this->queryList($qb->getSQL(), $queryParameters, $queryTypes); + yield from $this->queryList($qb->getSQL(), ...$this->addWheres($query, $qb)); + } + + public function count(Query $query): int + { + $qb = $this->connection->createQueryBuilder(); + $qb->select('count(*)') + ->from($this->table); + + $qb->setMaxResults($query->limit()); + $qb->setFirstResult($query->offset()); + + return $this->queryCount($qb->getSQL(), ...$this->addWheres($query, $qb)); } private function getSchema(): Schema @@ -303,6 +292,18 @@ private function queryList(string $query, array $parameters, array $types): Gene $statement->free(); } + /** + * @phpstan-param array $parameters + * @phpstan-param array $types + */ + private function queryCount(string $query, array $parameters, array $types): int + { + /** @var Result $statement */ + $statement = $this->connection->executeQuery($query, $parameters, $types); +dd(__METHOD__, current($statement->fetchOne())); + return current($statement->fetchOne()); + } + /** * @phpstan-return array */ @@ -325,4 +326,36 @@ private function getNormalizer(): JobExecutionRowNormalizer return $this->normalizer; } + + /** + * @return 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; + } + + return [$queryParameters, $queryTypes]; + } } diff --git a/src/batch-doctrine-dbal/tests/DoctrineDBALJobExecutionStorageTest.php b/src/batch-doctrine-dbal/tests/DoctrineDBALJobExecutionStorageTest.php index 027ad8db..307917e9 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(5, $storage->count($queryBuilder->getQuery())); } public function queries(): Generator @@ -302,6 +303,7 @@ public function queries(): Generator ['export', '123'], ['import', '987'], ], + 5 ]; yield 'Filter job names' => [ (new QueryBuilder()) diff --git a/src/batch/src/Storage/FilesystemJobExecutionStorage.php b/src/batch/src/Storage/FilesystemJobExecutionStorage.php index 1a7646a7..b1b56c71 100644 --- a/src/batch/src/Storage/FilesystemJobExecutionStorage.php +++ b/src/batch/src/Storage/FilesystemJobExecutionStorage.php @@ -139,6 +139,11 @@ public function query(Query $query): iterable return \array_slice($candidates, $query->offset(), $query->limit()); } + public function count(Query $query): int + { + return count($this->query($query)); + } + 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 3d34c8a2..9b9b40d9 100644 --- a/src/batch/tests/Storage/FilesystemJobExecutionStorageTest.php +++ b/src/batch/tests/Storage/FilesystemJobExecutionStorageTest.php @@ -142,7 +142,7 @@ public function list(): \Generator /** * @dataProvider query */ - public function testQueryWithProvider(QueryBuilder $query, array $expectedCouples): void + public function testQueryWithProvider(QueryBuilder $query, array $expectedCouples, int $expectedCount): void { $storage = $this->createStorage( __DIR__ . '/fixtures/filesystem-job-execution', @@ -150,6 +150,7 @@ public function testQueryWithProvider(QueryBuilder $query, array $expectedCouple ); self::assertExecutions($expectedCouples, $storage->query($query->getQuery())); + self::assertEquals($expectedCount, $storage->count($query->getQuery())); } public function query(): \Generator @@ -163,6 +164,7 @@ public function query(): \Generator ['list', '20210915'], ['list', '20210920'], ], + 5 ]; yield 'Filter ids' => [ (new QueryBuilder()) @@ -171,6 +173,7 @@ public function query(): \Generator ['export', '20210920'], ['list', '20210920'], ], + 2 ]; yield 'Filter job names' => [ (new QueryBuilder()) @@ -180,6 +183,7 @@ public function query(): \Generator ['list', '20210915'], ['list', '20210920'], ], + 3 ]; yield 'Filter statuses' => [ (new QueryBuilder()) @@ -187,6 +191,7 @@ public function query(): \Generator [ ['list', '20210910'], ], + 1 ]; yield 'Order by start ASC' => [ (new QueryBuilder()) @@ -198,6 +203,7 @@ public function query(): \Generator ['list', '20210920'], ['export', '20210922'], ], + 5 ]; yield 'Order by start DESC' => [ (new QueryBuilder()) @@ -209,6 +215,7 @@ public function query(): \Generator ['list', '20210915'], ['list', '20210910'], ], + 5 ]; yield 'Order by end ASC' => [ (new QueryBuilder()) @@ -220,6 +227,7 @@ public function query(): \Generator ['list', '20210920'], ['export', '20210922'], ], + 5 ]; yield 'Order by end DESC' => [ (new QueryBuilder()) @@ -231,6 +239,7 @@ public function query(): \Generator ['list', '20210915'], ['list', '20210910'], ], + 5 ]; }