1<?php
2
3
4namespace ComboStrap;
5
6
7use Antlr\Antlr4\Runtime\CommonTokenStream;
8use Antlr\Antlr4\Runtime\Error\Listeners\DiagnosticErrorListener;
9use Antlr\Antlr4\Runtime\InputStream;
10use Antlr\Antlr4\Runtime\Tree\ParseTreeWalker;
11use ComboStrap\PageSqlParser\PageSqlLexer;
12use ComboStrap\PageSqlParser\PageSqlParser;
13
14
15require_once(__DIR__ . '/PluginUtility.php');
16
17class PageSql
18{
19    const CANONICAL = "sql";
20
21    private $sql;
22    /**
23     * @var PageSqlTreeListener
24     */
25    private $listener;
26
27
28    public function __construct($text)
29    {
30        $this->sql = $text;
31    }
32
33    /**
34     * @param string $string
35     * @param MarkupPath|null $contextualPage - the page where the sql applies to
36     * @return PageSql
37     */
38    public static function create(string $string, MarkupPath $contextualPage = null): PageSql
39    {
40        $parser = new PageSql($string);
41        $parser->parse($contextualPage);
42        return $parser;
43    }
44
45    /**
46     * @param MarkupPath|null $contextualPage - for the page
47     * @return $this
48     */
49    function parse(MarkupPath $contextualPage = null): PageSql
50    {
51        $input = InputStream::fromString($this->sql);
52        $lexer = new PageSqlLexer($input);
53        $tokens = new CommonTokenStream($lexer);
54        $parser = new PageSqlParser($tokens);
55        $parser->addErrorListener(new DiagnosticErrorListener());
56        $parser->setBuildParseTree(true);
57        $tree = $parser->pageSql();
58
59        /**
60         * Performs a walk on the given parse tree starting at the root
61         * and going down recursively with depth-first search.
62         */
63        $this->listener = new PageSqlTreeListener($lexer, $parser, $this->sql, $contextualPage);
64        ParseTreeWalker::default()->walk($this->listener, $tree);
65        return $this;
66    }
67
68    public function getExecutableSql(): string
69    {
70        return $this->listener->getPhysicalSql();
71    }
72
73    public function getParameters(): array
74    {
75        return $this->listener->getParameters();
76    }
77
78    public function getColumns(): array
79    {
80        return $this->listener->getColumns();
81    }
82
83    public function __toString()
84    {
85        return $this->sql;
86    }
87
88    public function getTable(): ?string
89    {
90        return $this->listener->getTable();
91    }
92
93}
94