TableTrait   A
last analyzed

Complexity

Total Complexity 35

Size/Duplication

Total Lines 225
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 84
c 1
b 0
f 0
dl 0
loc 225
rs 9.6
wmc 35

11 Methods

Rating   Name   Duplication   Size   Complexity  
A alterTableSql() 0 12 2
A indexesSql() 0 11 1
A composeColumn() 0 13 3
A primaryKeysSql() 0 18 5
A indexKeysSql() 0 20 5
A columnAttrSql() 0 10 3
A dropTableSql() 0 3 1
A dropIndexesSql() 0 15 3
A renameTableSql() 0 3 1
A createTableSql() 0 12 2
B columnsSql() 0 35 9
1
<?php
2
3
/**
4
 * Quantum PHP Framework
5
 *
6
 * An open source software development framework for PHP
7
 *
8
 * @package Quantum
9
 * @author Arman Ag. <[email protected]>
10
 * @copyright Copyright (c) 2018 Softberg LLC (https://softberg.org)
11
 * @link http://quantum.softberg.org/
12
 * @since 2.9.5
13
 */
14
15
namespace Quantum\Libraries\Database\Traits;
16
17
use Quantum\Libraries\Database\Schemas\Column;
18
use Quantum\Libraries\Database\Constants\Key;
19
20
/**
21
 * Trait TableTrait
22
 * @package Quantum\Libraries\Database
23
 */
24
trait TableTrait
25
{
26
27
    /**
28
     * Generates create table statement
29
     * @return string
30
     */
31
    protected function createTableSql(): string
32
    {
33
        $tableSchema = array_filter([$this->columnsSql(), $this->indexesSql()]);
34
        $sql = '';
35
36
        if ($tableSchema) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $tableSchema of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
37
            $sql = 'CREATE TABLE `' . $this->name . '` (';
38
            $sql .= implode(', ', $tableSchema);
39
            $sql .= ');';
40
        }
41
42
        return $sql;
43
    }
44
45
    /**
46
     * Generates alter table statement
47
     * @return string
48
     */
49
    protected function alterTableSql(): string
50
    {
51
        $tableSchema = array_filter([$this->columnsSql(), $this->indexesSql(), $this->dropIndexesSql()]);
52
        $sql = '';
53
54
        if ($tableSchema) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $tableSchema of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
55
            $sql = 'ALTER TABLE `' . $this->name . '` ';
56
            $sql .= implode(', ', $tableSchema);
57
            $sql .= ';';
58
        }
59
60
        return $sql;
61
    }
62
63
    /**
64
     * Prepares rename table statement
65
     * @return string
66
     */
67
    protected function renameTableSql(): string
68
    {
69
        return 'RENAME TABLE `' . $this->name . '` TO `' . $this->newName . '`;';
70
    }
71
72
    /**
73
     * Prepares drop table statement
74
     * @return string
75
     */
76
    protected function dropTableSql(): string
77
    {
78
        return 'DROP TABLE `' . $this->name . '`';
79
    }
80
81
    /**
82
     * Prepares columns statements for table
83
     * @return string
84
     */
85
    protected function columnsSql(): string
86
    {
87
        $sql = '';
88
89
        if ($this->columns) {
90
            $columns = [];
91
92
            foreach ($this->columns as $entry) {
93
                $columnString = '';
94
95
                if ($entry['action'] != Column::ADD_INDEX && $entry['action'] != Column::DROP_INDEX) {
96
                    $columnString .= ($entry['action'] ? $entry['action'] . ' COLUMN ' : '');
97
                    $columnString .= $this->composeColumn($entry['column'], $entry['action']);
98
                }
99
100
                if ($entry['column']->get('indexKey')) {
101
                    $this->indexKeys[$entry['column']->get('indexKey')][] = [
0 ignored issues
show
Bug Best Practice introduced by
The property indexKeys does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
102
                        'columnName' => $entry['column']->get('name'),
103
                        'indexName' => $entry['column']->get('indexName'),
104
                    ];
105
                }
106
107
                if ($entry['column']->get('indexDrop')) {
108
                    $this->droppedIndexKeys[] = $entry['column']->get('indexDrop');
0 ignored issues
show
Bug Best Practice introduced by
The property droppedIndexKeys does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
109
                }
110
111
                if ($columnString) {
112
                    $columns[] = $columnString;
113
                }
114
            }
115
116
            $sql = implode(', ', $columns);
117
        }
118
119
        return $sql;
120
    }
121
122
    /**
123
     * Composes the column
124
     * @param Column $column
125
     * @param string|null $action
126
     * @return string
127
     */
128
    protected function composeColumn(Column $column, string $action = null): string
129
    {
130
        return
131
            $this->columnAttrSql($column->get(Column::NAME), '`', '`') .
132
            $this->columnAttrSql($column->get(Column::NEW_NAME), ' TO `', '`') .
133
            $this->columnAttrSql($column->get(Column::TYPE), ' ') .
134
            $this->columnAttrSql($column->get(Column::CONSTRAINT), '(', ')') .
135
            $this->columnAttrSql($column->get(Column::ATTRIBUTE), ' ') .
136
            $this->columnAttrSql($column->get(Column::NULLABLE, $action), ' ') .
137
            $this->columnAttrSql($column->get(Column::DEFAULT), ' DEFAULT ' . ($column->defaultQuoted() ? '\'' : ''), ($column->defaultQuoted() ? '\'' : '')) .
138
            $this->columnAttrSql($column->get(Column::COMMENT), ' COMMENT \'', '\'') .
139
            $this->columnAttrSql($column->get(Column::AFTER), ' AFTER `', '`') .
140
            $this->columnAttrSql($column->get(Column::AUTO_INCREMENT), ' ');
141
    }
142
143
    /**
144
     * Prepares column attributes
145
     * @param mixed $definition
146
     * @param string $before
147
     * @param string $after
148
     * @return string
149
     */
150
    protected function columnAttrSql($definition, string $before = '', string $after = ''): string
151
    {
152
        $sql = '';
153
154
        if (!is_null($definition)) {
155
156
            $sql .= $before . (is_array($definition) ? ("'" . implode("', '", $definition) . "'") : $definition) . $after;
157
        }
158
159
        return $sql;
160
    }
161
162
    /**
163
     * Prepares statement for primary key
164
     * @return string
165
     */
166
    protected function primaryKeysSql(): string
167
    {
168
        $sql = '';
169
170
        if (isset($this->indexKeys['primary'])) {
171
            $sql .= ($this->action == self::ALTER ? 'ADD ' : '');
0 ignored issues
show
Bug introduced by
The constant Quantum\Libraries\Databa...raits\TableTrait::ALTER was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
172
173
            $sql .= 'PRIMARY KEY (';
174
175
            foreach ($this->indexKeys['primary'] as $key => $primaryKey) {
176
                $sql .= '`' . $primaryKey['columnName'] . '`';
177
                $sql .= (array_key_last($this->indexKeys['primary']) != $key ? ', ' : '');
178
            }
179
180
            $sql .= ')';
181
        }
182
183
        return $sql;
184
    }
185
186
    /**
187
     * Prepares statement for index keys
188
     * @param string $type
189
     * @return string
190
     */
191
    protected function indexKeysSql(string $type): string
192
    {
193
        $sql = '';
194
195
        if (isset($this->indexKeys[$type])) {
196
            $indexes = [];
197
198
            foreach ($this->indexKeys[$type] as $indexKey) {
199
                $indexString = ($this->action == self::ALTER ? 'ADD ' : '');
0 ignored issues
show
Bug introduced by
The constant Quantum\Libraries\Databa...raits\TableTrait::ALTER was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
200
                $indexString .= strtoupper($type);
201
                $indexString .= ($indexKey['indexName'] ? ' `' . $indexKey['indexName'] . '`' : '');
202
                $indexString .= ' (`' . $indexKey['columnName'] . '`)';
203
204
                $indexes[] = $indexString;
205
            }
206
207
            $sql = implode(', ', $indexes);
208
        }
209
210
        return $sql;
211
    }
212
213
    /**
214
     * Builds a complete statement for index keys
215
     * @return string
216
     */
217
    protected function indexesSql(): string
218
    {
219
        $indexes = [
220
            $this->primaryKeysSql(),
221
            $this->indexKeysSql(Key::INDEX),
222
            $this->indexKeysSql(Key::UNIQUE),
223
            $this->indexKeysSql(Key::FULLTEXT),
224
            $this->indexKeysSql(Key::SPATIAL)
225
        ];
226
227
        return implode(', ', array_filter($indexes));
228
    }
229
230
    /**
231
     * Builds a statement for drop indexes
232
     * @return string
233
     */
234
    protected function dropIndexesSql(): string
235
    {
236
        $sql = '';
237
238
        if (!empty($this->droppedIndexKeys)) {
239
            $indexes = [];
240
241
            foreach ($this->droppedIndexKeys as $index) {
242
                $indexes[] = 'DROP INDEX `' . $index . '`';
243
            }
244
245
            $sql .= implode(', ', $indexes);
246
        }
247
248
        return $sql;
249
    }
250
}