Completed
Push — master ( 625aec...8c64ad )
by Guillaume
03:33
created

MysqlDatabaseTable::formatCreateStatement()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 12
rs 9.2
c 0
b 0
f 0
cc 4
eloc 7
nc 5
nop 1
1
<?php
2
3
namespace Starkerxp\DatabaseChecker\Structure;
4
5
6
//@todo Manage data sync by option.
7
use Starkerxp\DatabaseChecker\Exception\TableHasNotColumnException;
8
use Starkerxp\DatabaseChecker\Exception\TableHasNotDefinedException;
9
10
class MysqlDatabaseTable implements DatabaseInterface
11
{
12
13
    private $table;
14
    /**
15
     * @var MysqlDatabaseColumn[]
16
     */
17
    private $columns = [];
18
19
    /**
20
     * @var MysqlDatabaseIndex[]
21
     */
22
    private $indexes = [];
23
24
    /**
25
     * @var string
26
     */
27
    private $collate;
28
29
    /**
30
     * DatabaseTableStructure constructor.
31
     *
32
     * @param $table
33
     *
34
     * @throws TableHasNotDefinedException
35
     */
36
    public function __construct($table)
37
    {
38
        if (empty($table)) {
39
            throw new TableHasNotDefinedException('');
40
        }
41
        $this->table = $table;
42
    }
43
44
    /**
45
     * @return string
46
     */
47
    public function getCollate()
48
    {
49
        return $this->collate;
50
    }
51
52
    /**
53
     * @param string $collate
54
     */
55
    public function setCollate($collate)
56
    {
57
        $this->collate = $collate;
58
    }
59
60
    public function addColumn(MysqlDatabaseColumn $column)
61
    {
62
        $column->setTable($this->getTable());
63
        $this->columns[$column->getName()] = $column;
64
    }
65
66
    /**
67
     * @return mixed
68
     */
69
    public function getTable()
70
    {
71
        return $this->table;
72
    }
73
74
    public function removeColumn($columnName)
75
    {
76
77
        unset($this->columns[$columnName]);
78
    }
79
80
    public function addIndex(array $columns, $indexName = '')
81
    {
82
        $this->addIndexType($indexName, 0, $columns);
83
    }
84
85
    /**
86
     * @param       $indexName
87
     * @param       $unique
88
     * @param array $columns
89
     */
90
    protected function addIndexType($indexName, $unique, array $columns)
91
    {
92
        if (empty($indexName)) {
93
            $indexName = ($unique ? 'UNI_' : 'IDX_') . md5(implode(',', $columns));
94
        }
95
        try {
96
            $index = new MysqlDatabaseIndex($indexName, $columns, $unique);
97
            $index->setTable($this->getTable());
98
            $this->indexes[$indexName] = $index;
99
        } catch (\Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
100
101
        }
102
    }
103
104
    public function addPrimary(array $columnName)
105
    {
106
        $this->addIndexType('PRIMARY', 1, $columnName);
107
    }
108
109
    public function addUnique(array $columnName, $indexName = '')
110
    {
111
        $this->addIndexType($indexName, 1, $columnName);
112
    }
113
114
    /**
115
     * @param $indexName
116
     *
117
     * @return MysqlDatabaseIndex
118
     *
119
     * @throws \RuntimeException
120
     */
121
    public function getIndex($indexName)
122
    {
123
124
        if (empty($this->indexes[$indexName])) {
125
            throw new \RuntimeException('');
126
        }
127
128
        return $this->indexes[$indexName];
129
    }
130
131
132
    /**
133
     * @return MysqlDatabaseColumn[]
134
     */
135
    public function getColumns()
136
    {
137
        return $this->columns;
138
    }
139
140
    public function getIndexes()
141
    {
142
        return $this->indexes;
143
    }
144
145
    /**
146
     * @return array
147
     *
148
     * @throws TableHasNotColumnException
149
     */
150
    public function createStatement()
151
    {
152
        $modifications = [];
153
        $modifications[] = [sprintf('CREATE TABLE IF NOT EXISTS `%s`', $this->getTable())];
154
        $columns = $this->getColumns();
155
        if (!count($columns)) {
156
            throw new TableHasNotColumnException('');
157
        }
158
        foreach ($columns as $column) {
159
            try {
160
                if ($this->getCollate() == '') {
161
                    $column->setCollate('');
162
                }
163
                $modifications[] = $column->createStatement();
164
            } catch (TableHasNotDefinedException $e) {
165
                continue;
166
            }
167
        }
168
        $indexes = $this->getIndexes();
169
        foreach ($indexes as $index) {
170
            try {
171
                if (!$this->getIndex($index->getName())) {
172
                    continue;
173
                }
174
                $modifications[] = $index->createStatement();
175
            } catch (\Exception $e) {
176
                continue;
177
            }
178
        }
179
180
        if (!$modifications = $this->formatStatements($modifications)) {
181
            return [];
182
        }
183
184
        return $this->formatCreateStatement($modifications);
185
186
    }
187
188
    /**
189
     * @param array $modificationsBetweenTable
190
     *
191
     * @return array
192
     */
193
    private function formatStatements(array $modificationsBetweenTable)
194
    {
195
        $statements = [];
196
        foreach ($modificationsBetweenTable as $modifications) {
197
            foreach ((array)$modifications as $modification) {
198
                $statements[] = $modification;
199
            }
200
        }
201
202
        return array_filter(array_unique($statements));
203
    }
204
205
    private function formatCreateStatement(array $modifications)
206
    {
207
        if (!$finalStatement = array_shift($modifications)) {
208
            return [];
209
        }
210
        $tmp = [];
211
        foreach ($modifications as $modification) {
212
            $tmp[] = trim(str_replace(['ALTER TABLE `' . $this->getTable() . '` ADD COLUMN', 'ALTER TABLE `' . $this->getTable() . '` ADD ', ';',], '', $modification));
213
        }
214
        $collate = $this->getCollate() == '' ? '' : sprintf("COLLATE='%s'", $this->getCollate());
215
216
        return [$finalStatement . '(' . implode(',', $tmp) . ')' . $collate . ';'];
217
    }
218
219
    /**
220
     *
221
     * @throws \RuntimeException
222
     */
223
    public function alterStatement()
224
    {
225
        $collate = $this->getCollate() == '' ? '' : sprintf("COLLATE='%s'", $this->getCollate());
226
        if ($collate == '') {
227
            throw new \RuntimeException('Not implemented');
228
        }
229
230
        return [sprintf('ALTER TABLE `%s` %s;', $this->getTable(), $collate)];
231
    }
232
233
}
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...
234