Completed
Push — master ( d278b5...81f2b1 )
by Guillaume
02:18
created

MysqlDatabaseCheckerService::disabledCollate()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 4
nc 2
nop 1
1
<?php
2
3
namespace Starkerxp\DatabaseChecker\Checker;
4
5
6
use Starkerxp\DatabaseChecker\Exception\ColumnNotExistException;
7
use Starkerxp\DatabaseChecker\Exception\NotCompareDifferentColumnException;
8
use Starkerxp\DatabaseChecker\Exception\NotCompareDifferentTableException;
9
use Starkerxp\DatabaseChecker\Exception\TableHasNotColumnException;
10
use Starkerxp\DatabaseChecker\Exception\TableHasNotDefinedException;
11
use Starkerxp\DatabaseChecker\Exception\TableNotExistException;
12
use Starkerxp\DatabaseChecker\Structure\DatabaseInterface;
13
use Starkerxp\DatabaseChecker\Structure\MysqlDatabaseColumn;
14
use Starkerxp\DatabaseChecker\Structure\MysqlDatabaseTable;
15
16
class MysqlDatabaseCheckerService
17
{
18
    /**
19
     * @var boolean
20
     */
21
    private $checkCollate;
22
23
    /**
24
     * @var boolean
25
     */
26
    private $checkCasse;
0 ignored issues
show
introduced by
The private property $checkCasse is not used, and could be removed.
Loading history...
27
28
    /**
29
     * @param MysqlDatabaseTable[] $tables
30
     * @param MysqlDatabaseTable[] $newTables
31
     *
32
     * @return array
33
     */
34
    public function diff(array $tables, array $newTables)
35
    {
36
        $modificationsBetweenTable = [];
37
38
        // check Table
39
        foreach ($tables as $table) {
40
            try {
41
                $newTable = $this->getTable($table, $newTables);
42
                $modificationsBetweenTable[] = $this->checkTable($table, $newTable);
43
            } catch (TableNotExistException $e) {
44
                //@todo Drop statement.
45
                //@todo config for generate create or drop.
46
                $modificationsBetweenTable[] = $this->createStatement($table);
47
                continue;
48
            } catch (NotCompareDifferentTableException $e) {
49
                continue;
50
            }
51
        }
52
53
        foreach ($newTables as $newTable) {
54
            try {
55
                $this->getTable($newTable, $tables);
56
            } catch (TableNotExistException $e) {
57
                $modificationsBetweenTable[] = $this->createStatement($newTable);
58
                continue;
59
            }
60
        }
61
62
        return $this->formatStatements($modificationsBetweenTable);
63
    }
64
65
    /**
66
     * @param MysqlDatabaseTable   $table
67
     * @param MysqlDatabaseTable[] $newTables
68
     *
69
     * @return mixed
70
     * @throws TableNotExistException
71
     */
72
    private function getTable($table, array $newTables)
73
    {
74
        foreach ($newTables as $newTable) {
75
            if ($table->getTable() == $newTable->getTable()) {
76
                return $newTable;
77
            }
78
        }
79
        throw new TableNotExistException('');
80
    }
81
82
    /**
83
     * @param MysqlDatabaseTable $table
84
     * @param MysqlDatabaseTable $newTable
85
     *
86
     * @return array
87
     *
88
     * @throws NotCompareDifferentTableException
89
     */
90
    private function checkTable(MysqlDatabaseTable $table, MysqlDatabaseTable $newTable)
91
    {
92
        if ($table->getTable() != $newTable->getTable()) {
93
            throw new NotCompareDifferentTableException('On ne compare pas deux table avec un nom diff�rent');
94
        }
95
        // Aucune différence
96
        if ($this->tableIsEquals($table, $newTable)) {
97
            return [];
98
        }
99
100
        $modificationsBetweenTable = [];
101
        $columns = $table->getColumns();
102
        $newColumns = $newTable->getColumns();
103
104
        foreach ($columns as $column) {
105
            try {
106
                $newColumn = $this->getColumn($column, $newColumns);
107
                $modificationsBetweenTable[$newColumn->getName()] = $this->checkColumn($column, $newColumn);
108
            } catch (ColumnNotExistException $e) {
109
                $modificationsBetweenTable[$column->getName()] = $this->createStatement($column);
110
                continue;
111
            } catch (\Exception $e) {
112
                continue;
113
            }
114
        }
115
116
        $columnNeedAlter = array_unique(array_keys($modificationsBetweenTable));
117
        $indexes = $newTable->getIndexes();
118
        foreach ($indexes as $indexName => $index) {
119
            foreach ($columnNeedAlter as $colonne) {
120
                if (in_array($colonne, $index->getColumns(), false)) {
121
                    try {
122
                        $modificationsBetweenTable[] = $index->alterStatement();
123
                    } catch (TableHasNotDefinedException $e) {
124
                        continue;
125
                    }
126
                }
127
            }
128
        }
129
130
        return $this->formatStatements($modificationsBetweenTable);
131
    }
132
133
    private function tableIsEquals(MysqlDatabaseTable $table, MysqlDatabaseTable $newTable)
134
    {
135
        // Table is equals no need more check
136
        if ($table == $newTable) {
137
            return true;
138
        }
139
140
        if (!$this->checkCollate) {
141
            $this->disabledCollate($table);
142
            $this->disabledCollate($newTable);
143
        }
144
145
        return $table == $newTable;
146
    }
147
148
    /**
149
     * @param MysqlDatabaseTable $table
150
     */
151
    private function disabledCollate(MysqlDatabaseTable $table)
152
    {
153
        $table->setCollate('');
154
        $columns = $table->getColumns();
155
        foreach ($columns as $column) {
156
            $column->setCollate('');
157
        }
158
    }
159
160
    /**
161
     * @param MysqlDatabaseColumn   $column
162
     * @param MysqlDatabaseColumn[] $newColumns
163
     *
164
     * @return mixed
165
     *
166
     * @throws ColumnNotExistException
167
     */
168
    private function getColumn(MysqlDatabaseColumn $column, array $newColumns)
169
    {
170
        foreach ($newColumns as $newColumn) {
171
            if ($column->getName() == $newColumn->getName()) {
172
                return $newColumn;
173
            }
174
        }
175
        throw new ColumnNotExistException('');
176
    }
177
178
    /**
179
     * @param MysqlDatabaseColumn $column
180
     * @param MysqlDatabaseColumn $newColumn
181
     *
182
     * @return array
183
     *
184
     * @throws NotCompareDifferentColumnException
185
     * @throws \Starkerxp\DatabaseChecker\Exception\TableHasNotDefinedException
186
     */
187
    private function checkColumn(MysqlDatabaseColumn $column, MysqlDatabaseColumn $newColumn)
188
    {
189
        if ($column->getName() != $newColumn->getName()) {
190
            throw new NotCompareDifferentColumnException('On ne compare pas deux colonnes avec un nom diff�rent');
191
        }
192
        if ($this->columnIsEquals($column, $newColumn)) {
193
            return [];
194
        }
195
196
        try {
197
            $statements = $newColumn->alterStatement();
198
        } catch (\RuntimeException $e) {
199
            return [];
200
        }
201
202
        return $statements;
203
    }
204
205
    private function columnIsEquals(MysqlDatabaseColumn $column, MysqlDatabaseColumn $newColumn)
206
    {
207
        // Column is equals no need more check
208
        if ($column == $newColumn) {
209
            return true;
210
        }
211
212
        if (!$this->checkCollate) {
213
            $column->setCollate('');
214
            $newColumn->setCollate('');
215
        }
216
217
        return $column == $newColumn;
218
    }
219
220
    /**
221
     * @param  $databaseInterface
222
     *
223
     * @return array
224
     */
225
    protected function createStatement(DatabaseInterface $databaseInterface)
226
    {
227
        try {
228
            return $databaseInterface->createStatement();
229
        } catch (TableHasNotColumnException $e) {
230
            return [];
231
        }
232
    }
233
234
    /**
235
     * @param array $modificationsBetweenTable
236
     *
237
     * @return array
238
     */
239
    private function formatStatements(array $modificationsBetweenTable)
240
    {
241
        $statements = [];
242
        foreach ($modificationsBetweenTable as $modifications) {
243
            foreach ((array)$modifications as $modification) {
244
                $statements[] = $modification;
245
            }
246
        }
247
248
        return array_filter(array_unique($statements));
249
    }
250
251
}
0 ignored issues
show
Coding Style introduced by
As per coding style, files should not end with a newline character.

This check marks files that end in a newline character, i.e. an empy line.

Loading history...
252