Completed
Branch develop (c2aa4c)
by Anton
05:17
created

AbstractCommander::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
/**
3
 * Spiral Framework.
4
 *
5
 * @license   MIT
6
 * @author    Anton Titov (Wolfy-J)
7
 */
8
namespace Spiral\Database\Entities\Schemas;
9
10
use Spiral\Database\Entities\Driver;
11
12
/**
13
 * Holds set of DBMS specific element operations.
14
 */
15
abstract class AbstractCommander
16
{
17
    /**
18
     * @var Driver
19
     */
20
    private $driver = null;
21
22
    /**
23
     * @param Driver $driver
24
     */
25
    public function __construct(Driver $driver)
26
    {
27
        $this->driver = $driver;
28
    }
29
30
    /**
31
     * Associated driver.
32
     *
33
     * @return Driver
34
     */
35
    public function driver()
36
    {
37
        return $this->driver;
38
    }
39
40
    /**
41
     * Create table!
42
     *
43
     * @param AbstractTable $table
44
     * @return self
45
     */
46
    public function createTable(AbstractTable $table)
47
    {
48
        //Executing!
49
        $this->run($this->createStatement($table));
50
51
        //Not all databases support adding index while table creation, so we can do it after
52
        foreach ($table->getIndexes() as $index) {
53
            $this->addIndex($table, $index);
54
        }
55
56
        return $this;
57
    }
58
59
    /**
60
     * Drop table from database.
61
     *
62
     * @param string $table
63
     */
64
    public function dropTable($table)
65
    {
66
        $this->run("DROP TABLE {$this->quote($table)}");
67
    }
68
69
    /**
70
     * Rename table from one name to another.
71
     *
72
     * @param string $table
73
     * @param string $name
74
     * @return self
75
     */
76
    public function renameTable($table, $name)
77
    {
78
        $this->run("ALTER TABLE {$this->quote($table)} RENAME TO {$this->quote($name)}");
79
80
        return $this;
81
    }
82
83
    /**
84
     * Driver specific column add command.
85
     *
86
     * @param AbstractTable  $table
87
     * @param AbstractColumn $column
88
     * @return self
89
     */
90
    public function addColumn(AbstractTable $table, AbstractColumn $column)
91
    {
92
        $this->run("ALTER TABLE {$table->getName(true)} ADD COLUMN {$column->sqlStatement()}");
93
94
        return $this;
95
    }
96
97
    /**
98
     * Driver specific column remove (drop) command.
99
     *
100
     * @param AbstractTable  $table
101
     * @param AbstractColumn $column
102
     * @return self
103
     */
104
    public function dropColumn(AbstractTable $table, AbstractColumn $column)
105
    {
106
        foreach ($column->getConstraints() as $constraint) {
107
            //We have to erase all associated constraints
108
            $this->dropConstrain($table, $constraint);
109
        }
110
111
        $this->run("ALTER TABLE {$table->getName(true)} DROP COLUMN {$column->getName(true)}");
112
113
        return $this;
114
    }
115
116
    /**
117
     * Driver specific column alter command.
118
     *
119
     * @param AbstractTable  $table
120
     * @param AbstractColumn $initial
121
     * @param AbstractColumn $column
122
     * @return self
123
     */
124
    abstract public function alterColumn(
125
        AbstractTable $table,
126
        AbstractColumn $initial,
127
        AbstractColumn $column
128
    );
129
130
    /**
131
     * Driver specific index adding command.
132
     *
133
     * @param AbstractTable $table
134
     * @param AbstractIndex $index
135
     * @return self
136
     */
137
    public function addIndex(AbstractTable $table, AbstractIndex $index)
0 ignored issues
show
Unused Code introduced by
The parameter $table is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
138
    {
139
        $this->run("CREATE {$index->sqlStatement()}");
140
141
        return $this;
142
    }
143
144
    /**
145
     * Driver specific index remove (drop) command.
146
     *
147
     * @param AbstractTable $table
148
     * @param AbstractIndex $index
149
     * @return self
150
     */
151
    public function dropIndex(AbstractTable $table, AbstractIndex $index)
152
    {
153
        $this->run("DROP INDEX {$index->getName(true)}");
154
155
        return $this;
156
    }
157
158
    /**
159
     * Driver specific index alter command, by default it will remove and add index.
160
     *
161
     * @param AbstractTable $table
162
     * @param AbstractIndex $initial
163
     * @param AbstractIndex $index
164
     * @return self
165
     */
166
    public function alterIndex(AbstractTable $table, AbstractIndex $initial, AbstractIndex $index)
167
    {
168
        return $this->dropIndex($table, $initial)->addIndex($table, $index);
169
    }
170
171
    /**
172
     * Driver specific foreign key adding command.
173
     *
174
     * @param AbstractTable     $table
175
     * @param AbstractReference $foreign
176
     * @return self
177
     */
178
    public function addForeign(AbstractTable $table, AbstractReference $foreign)
179
    {
180
        $this->run("ALTER TABLE {$table->getName(true)} ADD {$foreign->sqlStatement()}");
181
182
        return $this;
183
    }
184
185
    /**
186
     * Driver specific foreign key remove (drop) command.
187
     *
188
     * @param AbstractTable     $table
189
     * @param AbstractReference $foreign
190
     * @return self
191
     */
192
    public function dropForeign(AbstractTable $table, AbstractReference $foreign)
193
    {
194
        return $this->dropConstrain($table, $foreign->getName());
195
    }
196
197
    /**
198
     * Driver specific foreign key alter command, by default it will remove and add foreign key.
199
     *
200
     * @param AbstractTable     $table
201
     * @param AbstractReference $initial
202
     * @param AbstractReference $foreign
203
     * @return self
204
     */
205
    public function alterForeign(
206
        AbstractTable $table,
207
        AbstractReference $initial,
208
        AbstractReference $foreign
209
    ) {
210
        return $this->dropForeign($table, $initial)->addForeign($table, $foreign);
211
    }
212
213
    /**
214
     * Drop column constraint using it's name.
215
     *
216
     * @param AbstractTable $table
217
     * @param string        $constraint
218
     * @return self
219
     */
220
    public function dropConstrain(AbstractTable $table, $constraint)
221
    {
222
        $this->run("ALTER TABLE {$table->getName(true)} DROP CONSTRAINT {$this->quote($constraint)}");
223
224
        return $this;
225
    }
226
227
    /**
228
     * Execute statement.
229
     *
230
     * @param string $statement
231
     * @param array  $parameters
232
     * @return \PDOStatement
233
     */
234
    protected function run($statement, array $parameters = [])
235
    {
236
        return $this->driver->statement($statement, $parameters);
237
    }
238
239
    /**
240
     * Quote identifier.
241
     *
242
     * @param string $identifier
243
     * @return string
244
     */
245
    protected function quote($identifier)
246
    {
247
        return $this->driver->identifier($identifier);
248
    }
249
250
    /**
251
     * Get statement needed to create table.
252
     *
253
     * @param AbstractTable $table
254
     * @return string
255
     */
256
    protected function createStatement(AbstractTable $table)
257
    {
258
        $statement = ["CREATE TABLE {$table->getName(true)} ("];
259
        $innerStatement = [];
260
261
        //Columns
262
        foreach ($table->getColumns() as $column) {
263
            $innerStatement[] = $column->sqlStatement();
264
        }
265
266
        //Primary key
267
        if (!empty($table->getPrimaryKeys())) {
268
            $primaryKeys = array_map([$this, 'quote'], $table->getPrimaryKeys());
269
270
            $innerStatement[] = 'PRIMARY KEY (' . join(', ', $primaryKeys) . ')';
271
        }
272
273
        //Constraints and foreign keys
274
        foreach ($table->getForeigns() as $reference) {
275
            $innerStatement[] = $reference->sqlStatement();
276
        }
277
278
        $statement[] = "    " . join(",\n    ", $innerStatement);
279
        $statement[] = ')';
280
281
        return join("\n", $statement);
282
    }
283
}