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

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Fake;
6
7use ZtdQuery\Platform\ParameterBindingCompiler;
8
9/**
10 * A compiler that writes named parameters out as positional ones.
11 *
12 * Some drivers take only positional parameters, so a statement written with
13 * names has to be rewritten and its values put in the order the names first
14 * appear. That reordering is the part of the contract worth showing.
15 */
16final class FakeParameterBindingCompiler implements ParameterBindingCompiler
17{
18    /**
19     * Rewrites a statement and its values into the form a driver will take.
20     *
21     * @param string $sql Statement as it was written
22     * @param array<int|string, mixed>|null $params Values to bind, or null when there are none
23     *
24     * @return array{sql: string, params: array<int|string, mixed>|null} The statement and its values
25     */
26    public function compile(string $sql, ?array $params): array
27    {
28        if ($params === null) {
29            return ['sql' => $sql, 'params' => null];
30        }
31
32        $ordered = [];
33        $compiled = preg_replace_callback(
34            '/:([A-Za-z_][A-Za-z0-9_]*)/',
35            static function (array $match) use ($params, &$ordered): string {
36                $ordered[] = $params[$match[1]] ?? null;
37
38                return '?';
39            },
40            $sql,
41        );
42
43        return ['sql' => $compiled ?? $sql, 'params' => $ordered === [] ? $params : $ordered];
44    }
45}
46