packages/ztd-query-core/src/ResultSelectRunner.php

1<?php
2
3declare(strict_types=1);
4
5namespace ZtdQuery;
6
7use ZtdQuery\Connection\ResultSet;
8use ZtdQuery\Connection\StatementInterface;
9use ZtdQuery\Platform\ResultColumnTypeResolver;
10use ZtdQuery\Schema\TableDefinition;
11
12/**
13 * Executes result-select queries and returns rows.
14 *
15 * @phpstan-import-type Row from TableDefinition
16 * @phpstan-import-type RowValue from TableDefinition
17 */
18final class ResultSelectRunner
19{
20    /**
21     * Execute SQL using the provided executor and return result rows.
22     *
23     * @param callable(string): (StatementInterface|false) $executor
24     * @return array<int, Row>
25     */
26    public function run(
27        string $sql,
28        callable $executor,
29        ResultColumnTypeResolver $typeResolver,
30    ): array {
31        return $this->runResultSet($sql, $executor, $typeResolver)->rows;
32    }
33
34    /**
35     * @param callable(string): (StatementInterface|false) $executor
36     */
37    public function runResultSet(
38        string $sql,
39        callable $executor,
40        ResultColumnTypeResolver $typeResolver,
41    ): ResultSet {
42        $statement = $executor($sql);
43        if ($statement === false) {
44            return new ResultSet([], []);
45        }
46
47        return $this->readResultSet($statement, $typeResolver);
48    }
49
50    /**
51     * Execute a prepared statement and return result rows.
52     *
53     * @param array<int|string, RowValue>|null $params
54     * @return array<int, Row>
55     */
56    public function runStatement(
57        StatementInterface $statement,
58        ResultColumnTypeResolver $typeResolver,
59        ?array $params = null,
60    ): array {
61        $statement->execute($params);
62
63        return $this->readResultSet($statement, $typeResolver)->rows;
64    }
65
66    /**
67     * Reads result set.
68     *
69     * @param StatementInterface $statement
70     * @param ResultColumnTypeResolver $typeResolver
71     * @return ResultSet
72     */
73    public function readResultSet(
74        StatementInterface $statement,
75        ResultColumnTypeResolver $typeResolver,
76    ): ResultSet {
77        $columns = $statement->resultColumns($typeResolver);
78        $rows = $statement->fetchAll();
79
80        return new ResultSet($rows, $columns);
81    }
82}
83