1<?php
2
3namespace Doctrine\DBAL\Platforms\Keywords;
4
5use Doctrine\DBAL\Schema\Column;
6use Doctrine\DBAL\Schema\ForeignKeyConstraint;
7use Doctrine\DBAL\Schema\Index;
8use Doctrine\DBAL\Schema\Schema;
9use Doctrine\DBAL\Schema\Sequence;
10use Doctrine\DBAL\Schema\Table;
11use Doctrine\DBAL\Schema\Visitor\Visitor;
12use function implode;
13use function str_replace;
14
15class ReservedKeywordsValidator implements Visitor
16{
17    /** @var KeywordList[] */
18    private $keywordLists = [];
19
20    /** @var string[] */
21    private $violations = [];
22
23    /**
24     * @param KeywordList[] $keywordLists
25     */
26    public function __construct(array $keywordLists)
27    {
28        $this->keywordLists = $keywordLists;
29    }
30
31    /**
32     * @return string[]
33     */
34    public function getViolations()
35    {
36        return $this->violations;
37    }
38
39    /**
40     * @param string $word
41     *
42     * @return string[]
43     */
44    private function isReservedWord($word)
45    {
46        if ($word[0] === '`') {
47            $word = str_replace('`', '', $word);
48        }
49
50        $keywordLists = [];
51        foreach ($this->keywordLists as $keywordList) {
52            if (! $keywordList->isKeyword($word)) {
53                continue;
54            }
55
56            $keywordLists[] = $keywordList->getName();
57        }
58
59        return $keywordLists;
60    }
61
62    /**
63     * @param string   $asset
64     * @param string[] $violatedPlatforms
65     *
66     * @return void
67     */
68    private function addViolation($asset, $violatedPlatforms)
69    {
70        if (! $violatedPlatforms) {
71            return;
72        }
73
74        $this->violations[] = $asset . ' keyword violations: ' . implode(', ', $violatedPlatforms);
75    }
76
77    /**
78     * {@inheritdoc}
79     */
80    public function acceptColumn(Table $table, Column $column)
81    {
82        $this->addViolation(
83            'Table ' . $table->getName() . ' column ' . $column->getName(),
84            $this->isReservedWord($column->getName())
85        );
86    }
87
88    /**
89     * {@inheritdoc}
90     */
91    public function acceptForeignKey(Table $localTable, ForeignKeyConstraint $fkConstraint)
92    {
93    }
94
95    /**
96     * {@inheritdoc}
97     */
98    public function acceptIndex(Table $table, Index $index)
99    {
100    }
101
102    /**
103     * {@inheritdoc}
104     */
105    public function acceptSchema(Schema $schema)
106    {
107    }
108
109    /**
110     * {@inheritdoc}
111     */
112    public function acceptSequence(Sequence $sequence)
113    {
114    }
115
116    /**
117     * {@inheritdoc}
118     */
119    public function acceptTable(Table $table)
120    {
121        $this->addViolation(
122            'Table ' . $table->getName(),
123            $this->isReservedWord($table->getName())
124        );
125    }
126}
127