packages/sql-faker/src/MySql/Generation/StartRuleResolver.php

1<?php
2
3declare(strict_types=1);
4
5namespace SqlFaker\MySql\Generation;
6
7use SqlFaker\Grammar\Model\Grammar;
8
9/**
10 * Resolves MySQL rule names across grammar releases.
11 *
12 * @visibility root
13 */
14final class StartRuleResolver
15{
16    /**
17 * @param Grammar $grammar Grammar whose rule names are resolved
18 */
19    public function __construct(private readonly Grammar $grammar)
20    {
21    }
22
23    /**
24     * Answers which of this grammar's rules a requested start rule is grown from.
25     *
26     * MySQL renamed its top-level rules across releases, so the name a caller
27     * asks for may not be the name this release declares. A request the
28     * grammar knows is taken as it stands; otherwise the rule that release
29     * calls the same thing is used, and a request nothing matches is handed
30     * back for the derivation to report.
31     *
32     * @param string|null $requested Rule the caller asked for, or null for the grammar's own entry point
33     *
34     * @return string Rule this grammar declares
35     */
36    public function startSymbolFor(?string $requested): string
37    {
38        if ($requested === null) {
39            return $this->grammar->startSymbol;
40        }
41        if (isset($this->grammar->ruleMap[$requested])) {
42            return $requested;
43        }
44
45        $fallbacks = [
46            'select_stmt' => 'select',
47            'insert_stmt' => 'insert',
48            'update_stmt' => 'update',
49            'delete_stmt' => 'delete',
50            'create_table_stmt' => 'create',
51            'alter_table_stmt' => 'alter',
52            'drop_table_stmt' => 'drop',
53            'simple_statement' => 'statement',
54            'simple_statement_or_begin' => $this->grammar->startSymbol,
55        ];
56        $fallback = $fallbacks[$requested] ?? $requested;
57
58        return isset($this->grammar->ruleMap[$fallback]) ? $fallback : $requested;
59    }
60}
61