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

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Fake;
6
7use ZtdQuery\Sql\TransactionStatement;
8use ZtdQuery\Sql\TransactionStatementParser;
9
10/**
11 * A parser that reads the transaction statements every dialect spells alike.
12 *
13 * Each dialect writes savepoints and the words that open a transaction a
14 * little differently, which is why this is an interface. This reads the
15 * spellings they agree on, so a test about the contract is not about a
16 * dialect.
17 */
18final class FakeTransactionStatementParser implements TransactionStatementParser
19{
20    /**
21     * Answers the transaction statement a statement is, if it is one.
22     *
23     * @param string $sql Statement as it was written
24     *
25     * @return TransactionStatement|null What it does to the transaction, or null when it is not one
26     */
27    public function parse(string $sql): ?TransactionStatement
28    {
29        $normalized = strtoupper(trim($sql, " \t\n\r;"));
30
31        return match (true) {
32            $normalized === 'BEGIN' => TransactionStatement::begin(),
33            $normalized === 'COMMIT' => TransactionStatement::commit(),
34            $normalized === 'ROLLBACK' => TransactionStatement::rollback(),
35            str_starts_with($normalized, 'SAVEPOINT ') => TransactionStatement::savepoint(
36                substr($normalized, strlen('SAVEPOINT ')),
37            ),
38            str_starts_with($normalized, 'ROLLBACK TO ') => TransactionStatement::rollbackTo(
39                substr($normalized, strlen('ROLLBACK TO ')),
40            ),
41            str_starts_with($normalized, 'RELEASE ') => TransactionStatement::release(
42                substr($normalized, strlen('RELEASE ')),
43            ),
44            default => null,
45        };
46    }
47}
48