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