packages/ztd-query-mysqli-adapter/src/Driver/MysqliResultStatement.php

1<?php
2
3declare(strict_types=1);
4
5namespace ZtdQuery\Adapter\Mysqli\Driver;
6
7use mysqli_result;
8use ZtdQuery\Connection\StatementInterface;
9use ZtdQuery\Platform\ResultColumnTypeResolver;
10
11/**
12 * mysqli result adapter implementing StatementInterface for ZTD layer.
13 *
14 * This class wraps a mysqli_result from query() and provides the minimal interface
15 * required by the ZTD session for fetching results.
16 */
17final class MysqliResultStatement implements StatementInterface
18{
19    private ?mysqli_result $result;
20
21    private int $affectedRows;
22
23    /**
24     * Wrap an executed result and normalize its affected row count.
25     */
26    public function __construct(?mysqli_result $result, int|string $affectedRows)
27    {
28        $this->result = $result;
29        $normalizedAffectedRows = filter_var($affectedRows, FILTER_VALIDATE_INT);
30        $this->affectedRows = $normalizedAffectedRows === false ? PHP_INT_MAX : $normalizedAffectedRows;
31    }
32
33    /**
34     * {@inheritDoc}
35     *
36     * This is a no-op for result statements from query() as they're already executed.
37     */
38    public function execute(?array $params = null): bool
39    {
40        return true;
41    }
42
43    /**
44     * {@inheritDoc}
45     */
46    public function fetchAll(): array
47    {
48        if ($this->result === null) {
49            return [];
50        }
51
52        $rows = mysqli_fetch_all($this->result, MYSQLI_ASSOC);
53
54        return $rows;
55    }
56
57    /**
58     * {@inheritDoc}
59     */
60    public function resultColumns(ResultColumnTypeResolver $typeResolver): array
61    {
62        if ($this->result === null) {
63            return [];
64        }
65
66        return MysqliResultColumnExtractor::extract($this->result, $typeResolver);
67    }
68
69    /**
70     * {@inheritDoc}
71     */
72    public function rowCount(): int
73    {
74        return $this->affectedRows;
75    }
76}
77