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