MysqlDatabaseColumn::formatDefaultValue()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 6
dl 0
loc 12
rs 10
c 0
b 0
f 0
cc 3
nc 3
nop 0
1
<?php
2
3
namespace Starkerxp\DatabaseChecker\Structure;
4
5
6
use Starkerxp\DatabaseChecker\Exception\TablenameHasNotDefinedException;
7
use Starkerxp\DatabaseChecker\LoggerTrait;
8
9
class MysqlDatabaseColumn implements DatabaseInterface
10
{
11
    use LoggerTrait;
12
13
    private $table;
14
    private $name;
15
    private $type;
16
    private $length;
17
    private $nullable;
18
    private $defaultValue;
19
    private $extra;
20
    private $collate;
21
22
    /**
23
     * DatabaseColumnStructure constructor.
24
     *
25
     * @param $name
26
     *
27
     * @param $type
28
     * @param $length
29
     * @param $nullable
30
     * @param $defaultValue
31
     * @param $extra
32
     *
33
     * @throws \RuntimeException
34
     */
35
    public function __construct($name, $type, $length, $nullable, $defaultValue, $extra)
36
    {
37
        if (empty($name)) {
38
            throw new \RuntimeException('');
39
        }
40
        $this->name = $name;
41
        $this->setType($type);
42
        $this->length = $length;
43
        $this->nullable = $nullable;
44
        $this->defaultValue = $defaultValue;
45
        $this->setExtra($extra);
46
    }
47
48
    private function setType($type): void
49
    {
50
        $type = strtolower($type);
51
        $this->type = $type;
52
    }
53
54
    /**
55
     * @param mixed $extra
56
     */
57
    public function setExtra($extra): void
58
    {
59
        $this->extra = strtoupper($extra);
60
    }
61
62
    public function optimizeType(): void
63
    {
64
        $isEnum = explode('enum', $this->type);
65
        if (!empty($isEnum)) {
66
            $numberElements = substr_count(str_replace(['(', ')', "'",], '', $isEnum[1]), ',') + 1;
67
            if ($numberElements == 2) {
68
                $this->type = 'tinyint';
69
                $this->length = 1;
70
            }
71
        }
72
    }
73
74
    public function toArray()
75
    {
76
        $tmp = get_object_vars($this);
77
        unset($tmp['logger']);
78
        $tmp['type'] = strtoupper($tmp['type']);
79
80
        return $tmp;
81
    }
82
83
    /**
84
     * @return array
85
     *
86
     * @throws TablenameHasNotDefinedException
87
     */
88
    public function createStatement()
89
    {
90
        $null = $this->getNullable() ? '' : 'NOT';
91
        $default = $this->formatDefaultValue();
92
        $collate = $this->formatCollate();
93
        $modification = sprintf('ALTER TABLE `%s` ADD COLUMN `%s` %s %s NULL %s %s %s;', $this->getTable(), $this->getName(), $this->getColonneType(), $null, $default, $this->getExtra(), $collate);
94
95
        return [str_replace(['   ', '  ',], ' ', $modification)];
96
    }
97
98
    /**
99
     * @return mixed
100
     */
101
    public function getNullable()
102
    {
103
        return $this->nullable;
104
    }
105
106
    /**
107
     * @return mixed
108
     */
109
    public function getDefaultValue()
110
    {
111
        return $this->defaultValue;
112
    }
113
114
    /**
115
     * @return string
116
     */
117
    public function getCollate(): ?string
118
    {
119
        $type = $this->getType();
120
        if (!\in_array($type, ['char', 'varchar', 'enum', 'longtext', 'mediumtext', 'text', 'tinytext', 'varchar'], false)) {
121
            return '';
122
        }
123
124
        return $this->collate;
125
    }
126
127
    /**
128
     * @return string
129
     */
130
    public function getType(): string
131
    {
132
        return $this->type;
133
    }
134
135
    /**
136
     * @return mixed
137
     *
138
     * @throws TablenameHasNotDefinedException
139
     */
140
    public function getTable()
141
    {
142
        if (!$this->table) {
143
            $this->critical('You need to define name of your table');
144
            throw new TablenameHasNotDefinedException('table not defined');
145
        }
146
147
        return $this->table;
148
    }
149
150
    public function getName()
151
    {
152
        return $this->name;
153
    }
154
155
    public function getColonneType()
156
    {
157
        $baseType = $this->type;
158
        $length = $this->length;
159
        $unsigned = '';
160
        if (false !== strpos($this->length, 'unsigned')) {
161
            $explode = explode(' ', $this->length);
162
            $length = $explode[0];
163
            $unsigned = !empty($explode[1]) ? ' UNSIGNED' : '';
164
        }
165
        if (\in_array($baseType, ['int', 'mediumint', 'tinyint', 'smallint', 'binary', 'varchar', 'bigint', 'char', 'float'], false)) {
166
            $baseType = $baseType . '(' . $length . ')' . $unsigned;
167
        }
168
169
        return strtoupper($baseType);
170
    }
171
172
    /**
173
     * @return mixed
174
     */
175
    public function getExtra()
176
    {
177
        return $this->extra;
178
    }
179
180
    /**
181
     * @param string $collate
182
     */
183
    public function setCollate($collate): void
184
    {
185
        $this->collate = $collate;
186
    }
187
188
    /**
189
     * @param mixed $table
190
     */
191
    public function setTable($table): void
192
    {
193
        $this->table = $table;
194
    }
195
196
    /**
197
     * @return array
198
     *
199
     * @throws TablenameHasNotDefinedException
200
     */
201
    public function alterStatement()
202
    {
203
        $null = $this->getNullable() ? '' : 'NOT';
204
        $default = $this->formatDefaultValue();
205
        $collate = $this->formatCollate();
206
        $modification = sprintf('ALTER TABLE `%s` CHANGE COLUMN `%s` `%s` %s %s NULL %s %s %s;', $this->getTable(), $this->getName(), $this->getName(), $this->getColonneType(), $null, $default, $this->getExtra(), $collate);
207
208
        return [str_replace(['   ', '  ',], ' ', $modification)];
209
    }
210
211
    public function deleteStatement(): string
212
    {
213
        return sprintf('ALTER TABLE `%s` DROP COLUMN `%s`;', $this->getTable(), $this->getName());
214
    }
215
216
    /**
217
     * @return string
218
     */
219
    private function formatDefaultValue(): string
220
    {
221
        $default = $this->getDefaultValue();
222
        if (empty($default)) {
223
            return '';
224
        }
225
226
        if ($default === 'NULL') {
227
            return ' DEFAULT NULL';
228
        }
229
230
        return " DEFAULT '" . $default . "'";
231
    }
232
233
    /**
234
     * @return null|string
235
     */
236
    private function formatCollate(): ?string
237
    {
238
        $collate = $this->getCollate();
239
        if (empty($collate)) {
240
            return '';
241
        }
242
243
        return sprintf("COLLATE '%s'", $collate);
244
    }
245
246
}
247