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