packages/ztd-query-core/tests/Fake/FakeStatement.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Fake;
6
7use ZtdQuery\Connection\ResultColumn;
8use ZtdQuery\Connection\StatementInterface;
9use ZtdQuery\Platform\ResultColumnTypeResolver;
10use ZtdQuery\Schema\RowSet;
11use ZtdQuery\Schema\TableDefinition;
12
13/**
14 * A statement that answers from rows held in memory.
15 *
16 * Nothing here talks to a driver, so a test can say exactly what a statement
17 * hands back and then check what the code around it made of that.
18 *
19 * @phpstan-import-type Row from TableDefinition
20 */
21final class FakeStatement implements StatementInterface
22{
23    private RowSet $rows;
24
25    private bool $executed = false;
26
27    /**
28     * @var list<ResultColumnTypeResolver> Resolvers this statement was asked to read columns through
29     */
30    private array $typeResolversAsked = [];
31
32    /**
33     * @var list<ResultColumn> Columns this statement reports
34     */
35    private array $columns;
36
37    /**
38     * Builds a statement that answers with these rows.
39     *
40     * @param array<int, Row> $rows Rows to answer with
41     * @param list<ResultColumn> $columns Columns to report
42     */
43    public function __construct(array $rows = [], array $columns = [])
44    {
45        $this->rows = new RowSet($rows);
46        $this->columns = $columns;
47    }
48
49    /**
50     * Records that the statement was run.
51     *
52     * @param array<int|string, mixed>|null $params Ignored
53     *
54     * @return bool Always true, because nothing here can fail
55     */
56    public function execute(?array $params = null): bool
57    {
58        $this->executed = true;
59
60        return true;
61    }
62
63    /**
64     * Answers the rows this statement was built with.
65     *
66     * @return array<int, Row> The rows
67     */
68    public function fetchAll(): array
69    {
70        return $this->rows->rows;
71    }
72
73    /**
74     * Answers the columns this statement was built with.
75     *
76     * @param ResultColumnTypeResolver $typeResolver Recorded, so a caller can be asked which resolver it passed
77     *
78     * @return list<ResultColumn> The columns
79     */
80    public function resultColumns(ResultColumnTypeResolver $typeResolver): array
81    {
82        $this->typeResolversAsked[] = $typeResolver;
83
84        return $this->columns;
85    }
86
87    /**
88     * Answers how many rows this statement was built with.
89     *
90     * @return int The number of rows
91     */
92    public function rowCount(): int
93    {
94        return count($this->rows->rows);
95    }
96
97    /**
98     * Answers the resolvers this statement was asked to read its columns through.
99     *
100     * @return list<ResultColumnTypeResolver> The resolvers, in the order they arrived
101     */
102    public function typeResolversAsked(): array
103    {
104        return $this->typeResolversAsked;
105    }
106
107    /**
108     * Reports whether the statement was run.
109     *
110     * @return bool True once execute() has been called
111     */
112    public function isExecuted(): bool
113    {
114        return $this->executed;
115    }
116}
117