packages/ztd-query-core/tests/Fake/FakeConnection.php
1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Fake;
6
7use ZtdQuery\Connection\ConnectionInterface;
8use ZtdQuery\Connection\StatementInterface;
9use ZtdQuery\Schema\RowSet;
10use ZtdQuery\Schema\TableDefinition;
11
12/**
13 * Fake ConnectionInterface that returns pre-configured FakeStatements.
14 *
15 * Queries are recorded for inspection. Results can be pre-loaded per SQL string
16 * or a default result set can be provided. Specific queries can be configured to
17 * fail by returning false, enabling tests for error-handling branches.
18 *
19 * @phpstan-import-type Row from TableDefinition
20 */
21final class FakeConnection implements ConnectionInterface
22{
23 /**
24 * Recorded queries.
25 *
26 * @var array<int, string>
27 */
28 public array $queries = [];
29
30 /**
31 * Pre-configured results keyed by SQL.
32 *
33 * @var array<string, RowSet>
34 */
35 private array $results;
36
37 /**
38 * Default rows returned when no specific result is configured.
39 *
40 */
41 private RowSet $defaultRows;
42
43 /**
44 * SQL patterns that should return false (simulating query failure).
45 *
46 * @var array<int, string>
47 */
48 private array $failPatterns = [];
49
50 /**
51 * @param array<string, array<int, Row>> $results SQL => rows mapping.
52 * @param array<int, Row> $defaultRows Default rows for unconfigured queries.
53 */
54 public function __construct(array $results = [], array $defaultRows = [])
55 {
56 $this->results = [];
57 foreach ($results as $sql => $rows) {
58 $this->addResult($sql, $rows);
59 }
60 $this->defaultRows = new RowSet($defaultRows);
61 }
62
63 /**
64 * Query.
65 *
66 * @param string $sql
67 * @return StatementInterface|false
68 */
69 public function query(string $sql): StatementInterface|false
70 {
71 $this->queries[] = $sql;
72
73 foreach ($this->failPatterns as $pattern) {
74 if ($sql === $pattern) {
75 return false;
76 }
77 }
78
79 $rows = $this->results[$sql] ?? $this->defaultRows;
80
81 return new FakeStatement($rows->rows);
82 }
83
84 /**
85 * Pre-load a result for a specific SQL query.
86 *
87 * @param array<int, Row> $rows
88 */
89 public function addResult(string $sql, array $rows): void
90 {
91 $this->results[$sql] = new RowSet($rows);
92 }
93
94 /**
95 * Configure a query to return false (simulate failure).
96 */
97 public function failOnQuery(string $sql): void
98 {
99 $this->failPatterns[] = $sql;
100 }
101}
102