Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
35 / 35
100.00% covered (success)
100.00%
7 / 7
CRAP
100.00% covered (success)
100.00%
1 / 1
AbstractSqlDriver
100.00% covered (success)
100.00%
35 / 35
100.00% covered (success)
100.00%
7 / 7
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%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 findById
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 findBy
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
5
 findOneBy
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
2
 deleteById
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 exists
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 save
n/a
0 / 0
n/a
0 / 0
0
 quoteTableName
n/a
0 / 0
n/a
0 / 0
0
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 Phexium\Plugin\SqlDriver\Internal;
11
12use Override;
13use PDO;
14use Phexium\Domain\Id\IdInterface;
15use Phexium\Domain\Specification\SpecificationInterface;
16use Phexium\Plugin\SqlDriver\Port\SqlDriverInterface;
17
18abstract class AbstractSqlDriver implements SqlDriverInterface
19{
20    public function __construct(
21        protected PDO $pdo
22    ) {}
23
24    #[Override]
25    public function findAll(string $table): array
26    {
27        $sql = sprintf('SELECT * FROM %s', $this->quoteTableName($table));
28        $stmt = $this->pdo->prepare($sql);
29        $stmt->execute();
30
31        return $stmt->fetchAll(PDO::FETCH_ASSOC);
32    }
33
34    #[Override]
35    public function findById(string $table, IdInterface $id): ?array
36    {
37        $sql = sprintf('SELECT * FROM %s WHERE id = :id LIMIT 1', $this->quoteTableName($table));
38        $stmt = $this->pdo->prepare($sql);
39        $stmt->execute(['id' => $id->getValue()]);
40
41        $result = $stmt->fetch(PDO::FETCH_ASSOC);
42
43        return $result !== false ? $result : null;
44    }
45
46    #[Override]
47    public function findBy(string $table, SpecificationInterface $specification, ?array $orderBy = null, ?int $offset = null, ?int $limit = null): array
48    {
49        $specSql = $specification->toSql();
50        $sql = sprintf('SELECT * FROM %s WHERE %s', $this->quoteTableName($table), $specSql['sql']);
51
52        if ($orderBy !== null) {
53            $orderClauses = [];
54
55            foreach ($orderBy as $field => $direction) {
56                $orderClauses[] = sprintf('%s %s', $field, $direction);
57            }
58
59            $sql .= ' ORDER BY '.implode(', ', $orderClauses);
60        }
61
62        if ($limit !== null) {
63            $sql .= ' LIMIT '.$limit;
64        }
65
66        if ($offset !== null) {
67            $sql .= ' OFFSET '.$offset;
68        }
69
70        $stmt = $this->pdo->prepare($sql);
71        $stmt->execute($specSql['params']);
72
73        return $stmt->fetchAll(PDO::FETCH_ASSOC);
74    }
75
76    #[Override]
77    public function findOneBy(string $table, SpecificationInterface $specification): ?array
78    {
79        $specSql = $specification->toSql();
80        $sql = sprintf('SELECT * FROM %s WHERE %s LIMIT 1', $this->quoteTableName($table), $specSql['sql']);
81        $stmt = $this->pdo->prepare($sql);
82        $stmt->execute($specSql['params']);
83
84        $result = $stmt->fetch(PDO::FETCH_ASSOC);
85
86        return $result !== false ? $result : null;
87    }
88
89    #[Override]
90    public function deleteById(string $table, IdInterface $id): int
91    {
92        $sql = sprintf('DELETE FROM %s WHERE id = :id', $this->quoteTableName($table));
93        $stmt = $this->pdo->prepare($sql);
94        $stmt->execute(['id' => $id->getValue()]);
95
96        return $stmt->rowCount();
97    }
98
99    #[Override]
100    public function exists(string $table, IdInterface $id): bool
101    {
102        return $this->findById($table, $id) !== null;
103    }
104
105    abstract public function save(string $table, array $row): void;
106
107    abstract protected function quoteTableName(string $tableName): string;
108}