Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
17 / 17
100.00% covered (success)
100.00%
10 / 10
CRAP
100.00% covered (success)
100.00%
1 / 1
PostgresqlBookRepository
100.00% covered (success)
100.00%
17 / 17
100.00% covered (success)
100.00%
10 / 10
13
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 findAll
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 findBy
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 findOneBy
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 findById
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 getById
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 exists
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 save
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 delete
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 deleteById
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3// ╔════════════════════════════════════════════════════════════╗
4// ║ MIT Licence (#Expat) - https://opensource.org/licenses/MIT ║
5// ║ Copyright 2026 Frederic Poeydomenge <dyno@phexium.com>     ║
6// ╚════════════════════════════════════════════════════════════╝
7
8declare(strict_types=1);
9
10namespace AppDemo\Library\Infrastructure;
11
12use AppDemo\Library\Domain\Book;
13use AppDemo\Library\Domain\BookRepository;
14use AppDemo\Library\Domain\BooksCollection;
15use AppDemo\Library\Infrastructure\Trait\BookRepositoryMappingTrait;
16use InvalidArgumentException;
17use Override;
18use Phexium\Domain\Id\IdInterface;
19use Phexium\Domain\Specification\SpecificationInterface;
20use Phexium\Plugin\IdGenerator\Port\IdGeneratorInterface;
21use Phexium\Plugin\SqlDriver\Adapter\PostgresqlDriver;
22
23final readonly class PostgresqlBookRepository implements BookRepository
24{
25    use BookRepositoryMappingTrait;
26
27    private const string TABLE = 'book';
28
29    public function __construct(
30        private PostgresqlDriver $driver,
31        private IdGeneratorInterface $idGenerator,
32    ) {}
33
34    #[Override]
35    public function findAll(): BooksCollection
36    {
37        $rows = $this->driver->findAll(self::TABLE);
38
39        return BooksCollection::fromMap($rows, fn (array $row): Book => $this->rowToBook($row));
40    }
41
42    #[Override]
43    public function findBy(SpecificationInterface $specification, ?array $orderBy = null, ?int $offset = null, ?int $limit = null): BooksCollection
44    {
45        $rows = $this->driver->findBy(self::TABLE, $specification, $orderBy, $offset, $limit);
46
47        return BooksCollection::fromMap($rows, fn (array $row): Book => $this->rowToBook($row));
48    }
49
50    #[Override]
51    public function findOneBy(SpecificationInterface $specification): ?Book
52    {
53        $row = $this->driver->findOneBy(self::TABLE, $specification);
54
55        return $row !== null ? $this->rowToBook($row) : null;
56    }
57
58    #[Override]
59    public function findById(IdInterface $id): ?Book
60    {
61        $row = $this->driver->findById(self::TABLE, $id);
62
63        return $row !== null ? $this->rowToBook($row) : null;
64    }
65
66    #[Override]
67    public function getById(IdInterface $id): Book
68    {
69        $book = $this->findById($id);
70
71        if (!$book instanceof Book) {
72            throw new InvalidArgumentException('Book with ID='.$id->getValue().' not found');
73        }
74
75        return $book;
76    }
77
78    #[Override]
79    public function exists(IdInterface $id): bool
80    {
81        return $this->driver->exists(self::TABLE, $id);
82    }
83
84    #[Override]
85    public function save(Book $book): void
86    {
87        $this->driver->save(self::TABLE, $this->bookToRow($book));
88    }
89
90    #[Override]
91    public function delete(Book $book): int
92    {
93        return $this->deleteById($book->getId());
94    }
95
96    #[Override]
97    public function deleteById(IdInterface $id): int
98    {
99        return $this->driver->deleteById(self::TABLE, $id);
100    }
101}