bootstrap generic doc manager and associated services

This commit is contained in:
2023-05-23 22:12:18 +02:00
parent 977299192f
commit afcd6e0605
10 changed files with 585 additions and 0 deletions

View File

@@ -0,0 +1,102 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\DocStoreBundle\GenericDoc;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\Person;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Exception;
class Manager
{
private readonly FetchQueryToSqlBuilder $builder;
public function __construct(
/**
* @var iterable<ProviderForAccompanyingPeriodInterface>
*/
private readonly iterable $providersForAccompanyingPeriod,
private readonly Connection $connection,
) {
$this->builder = new FetchQueryToSqlBuilder();
}
/**
* @throws Exception
*/
public function countDocForAccompanyingPeriod(
AccompanyingPeriod $accompanyingPeriod,
?\DateTimeImmutable $startDate = null,
?\DateTimeImmutable $endDate = null,
?string $content = null,
?string $origin = null
): int {
['sql' => $sql, 'params' => $params] = $this->buildUnionQuery($accompanyingPeriod, $startDate, $endDate, $content, $origin);
$countSql = "SELECT count(*) AS c FROM {$sql} AS sq";
$result = $this->connection->executeQuery($countSql, $params);
$number = $result->fetchOne();
if (false === $number) {
throw new \UnexpectedValueException("number of documents failed to load");
}
return $number['c'];
}
/**
* @throws Exception
*/
public function findDocForAccompanyingPeriod(
AccompanyingPeriod $accompanyingPeriod,
int $offset = 0,
int $limit = 20,
?\DateTimeImmutable $startDate = null,
?\DateTimeImmutable $endDate = null,
?string $content = null,
?string $origin = null
): iterable {
['sql' => $sql, 'params' => $params] = $this->buildUnionQuery($accompanyingPeriod, $startDate, $endDate, $content, $origin);
$runSql = "{$sql} LIMIT ? OFFSET ?";
$runParams = [...$params, ...[$limit, $offset]];
foreach($this->connection->iterateAssociative($runSql, $runParams) as $row) {
yield new GenericDocDTO($row['key'], $row['identifiers'], $row['date_doc']);
}
}
/**
*/
private function buildUnionQuery(
AccompanyingPeriod|Person $linked,
?\DateTimeImmutable $startDate = null,
?\DateTimeImmutable $endDate = null,
?string $content = null,
?string $origin = null
): array {
$sql = [];
$params = [];
if ($linked instanceof AccompanyingPeriod) {
foreach ($this->providersForAccompanyingPeriod as $provider) {
['sql' => $q, 'params' => $p ] = $this->builder
->toSql($provider->buildFetchQueryForAccompanyingPeriod($linked, $startDate, $endDate, $content, $origin));
$params = [...$params, ...$p];
$sql[] = $q;
}
}
return ['sql' => implode(' UNION ', $sql), 'params' => $params];
}
}