Completed
Branch feature/pre-split (67216b)
by Anton
03:28
created

TableBlueprint   B

Complexity

Total Complexity 19

Size/Duplication

Total Lines 320
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 16

Importance

Changes 0
Metric Value
dl 0
loc 320
rs 8.4614
c 0
b 0
f 0
wmc 19
lcom 1
cbo 16

19 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A addColumn() 0 6 1
A alterColumn() 0 6 1
A renameColumn() 0 6 1
A dropColumn() 0 6 1
A addIndex() 0 6 1
A alterIndex() 0 6 1
A dropIndex() 0 6 1
A getSchema() 0 4 1
A addForeignKey() 0 17 1
A alterForeignKey() 0 17 1
A dropForeignKey() 0 6 1
A setPrimaryKeys() 0 6 1
A create() 0 8 1
A update() 0 8 1
A drop() 0 8 1
A rename() 0 8 1
A addOperation() 0 6 1
A execute() 0 4 1
1
<?php
2
/**
3
 * Spiral Framework, Core Components
4
 *
5
 * @author    Wolfy-J
6
 */
7
namespace Spiral\Migrations;
8
9
use Spiral\Database\Schemas\Prototypes\AbstractTable;
10
use Spiral\Migrations\Operations\Columns\AddColumn;
11
use Spiral\Migrations\Operations\Columns\AlterColumn;
12
use Spiral\Migrations\Operations\Columns\DropColumn;
13
use Spiral\Migrations\Operations\Columns\RenameColumn;
14
use Spiral\Migrations\Operations\Indexes\AddIndex;
15
use Spiral\Migrations\Operations\Indexes\AlterIndex;
16
use Spiral\Migrations\Operations\Indexes\DropIndex;
17
use Spiral\Migrations\Operations\References\AddReference;
18
use Spiral\Migrations\Operations\References\AlterReference;
19
use Spiral\Migrations\Operations\References\DropReference;
20
use Spiral\Migrations\Operations\Table\CreateTable;
21
use Spiral\Migrations\Operations\Table\DropTable;
22
use Spiral\Migrations\Operations\Table\PrimaryKeys;
23
use Spiral\Migrations\Operations\Table\RenameTable;
24
use Spiral\Migrations\Operations\Table\UpdateTable;
25
26
/**
27
 * TableBlueprint is abstraction wrapper at top of AbstractTable which converts command based
28
 * definitions into declarative.
29
 */
30
class TableBlueprint
31
{
32
    /**
33
     * @var CapsuleInterface
34
     */
35
    private $capsule = null;
36
37
    /**
38
     * Blueprint specific set of operations.
39
     *
40
     * @var array
41
     */
42
    private $operations = [];
43
44
    /**
45
     * @var string
46
     */
47
    private $table = '';
48
49
    /**
50
     * @var null|string
51
     */
52
    private $database = null;
53
54
    /**
55
     * @param CapsuleInterface $capsule
56
     * @param string           $table
57
     * @param string|null      $database
58
     */
59
    public function __construct(CapsuleInterface $capsule, string $table, string $database = null)
60
    {
61
        $this->capsule = $capsule;
62
        $this->table = $table;
63
        $this->database = $database;
64
    }
65
66
    /**
67
     * Get associated table schema.
68
     *
69
     * @return AbstractTable
70
     */
71
    public function getSchema(): AbstractTable
72
    {
73
        return $this->capsule->getSchema($this->table, $this->database);
74
    }
75
76
    /**
77
     * Example:
78
     * $table->addColumn('name', 'string', ['length' => 64]);
79
     * $table->addColumn('status', 'enum', [
80
     *      'values' => ['active', 'disabled']
81
     * ]);
82
     *
83
     * @param string $name
84
     * @param string $type
85
     * @param array  $options
86
     *
87
     * @return TableBlueprint
88
     */
89
    public function addColumn(string $name, string $type, array $options = []): self
90
    {
91
        return $this->addOperation(
92
            new AddColumn($this->database, $this->table, $name, $type, $options)
93
        );
94
    }
95
96
    /**
97
     * Example:
98
     * $table->alterColumn('name', 'string', ['length' => 128]);
99
     *
100
     * @param string $name
101
     * @param string $type
102
     * @param array  $options
103
     *
104
     * @return TableBlueprint
105
     */
106
    public function alterColumn(string $name, string $type, array $options = []): self
107
    {
108
        return $this->addOperation(
109
            new AlterColumn($this->database, $this->table, $name, $type, $options)
110
        );
111
    }
112
113
    /**
114
     * Example:
115
     * $table->renameColumn('column', 'new_name');
116
     *
117
     * @param string $name
118
     * @param string $newName
119
     *
120
     * @return TableBlueprint
121
     */
122
    public function renameColumn(string $name, string $newName): self
123
    {
124
        return $this->addOperation(
125
            new RenameColumn($this->database, $this->table, $name, $newName)
126
        );
127
    }
128
129
    /**
130
     * Example:
131
     * $table->dropColumn('email');
132
     *
133
     * @param string $name
134
     *
135
     * @return TableBlueprint
136
     */
137
    public function dropColumn(string $name): self
138
    {
139
        return $this->addOperation(
140
            new DropColumn($this->database, $this->table, $name)
141
        );
142
    }
143
144
    /**
145
     * Example:
146
     * $table->addIndex(['email'], ['unique' => true]);
147
     *
148
     * @param array $columns
149
     * @param array $options
150
     *
151
     * @return TableBlueprint
152
     */
153
    public function addIndex(array $columns, array $options = []): self
154
    {
155
        return $this->addOperation(
156
            new AddIndex($this->database, $this->table, $columns, $options)
157
        );
158
    }
159
160
    /**
161
     * Example:
162
     * $table->alterIndex(['email'], ['unique' => false]);
163
     *
164
     * @param array $columns
165
     * @param array $options
166
     *
167
     * @return TableBlueprint
168
     */
169
    public function alterIndex(array $columns, array $options): self
170
    {
171
        return $this->addOperation(
172
            new AlterIndex($this->database, $this->table, $columns, $options)
173
        );
174
    }
175
176
    /**
177
     * Example:
178
     * $table->dropIndex(['email']);
179
     *
180
     * @param array $columns
181
     *
182
     * @return TableBlueprint
183
     */
184
    public function dropIndex(array $columns): self
185
    {
186
        return $this->addOperation(
187
            new DropIndex($this->database, $this->table, $columns)
188
        );
189
    }
190
191
    /**
192
     * Example:
193
     * $table->addForeignKey('user_id', 'users', 'id', ['delete' => 'CASCADE']);
194
     *
195
     * @param string $column
196
     * @param string $foreignTable Database isolation prefix will be automatically added.
197
     * @param string $foreignKey
198
     * @param array  $options
199
     *
200
     * @return TableBlueprint
201
     */
202
    public function addForeignKey(
203
        string $column,
204
        string $foreignTable,
205
        string $foreignKey,
206
        array $options = []
207
    ): self {
208
        return $this->addOperation(
209
            new AddReference(
210
                $this->database,
211
                $this->table,
212
                $column,
213
                $foreignTable,
214
                $foreignKey,
215
                $options
216
            )
217
        );
218
    }
219
220
    /**
221
     * Example:
222
     * $table->alterForeignKey('user_id', 'users', 'id', ['delete' => 'NO ACTION']);
223
     *
224
     * @param string $column
225
     * @param string $foreignTable
226
     * @param string $foreignKey
227
     * @param array  $options
228
     *
229
     * @return TableBlueprint
230
     */
231
    public function alterForeignKey(
232
        string $column,
233
        string $foreignTable,
234
        string $foreignKey,
235
        array $options = []
236
    ): self {
237
        return $this->addOperation(
238
            new AlterReference(
239
                $this->database,
240
                $this->table,
241
                $column,
242
                $foreignTable,
243
                $foreignKey,
244
                $options
245
            )
246
        );
247
    }
248
249
    /**
250
     * Example:
251
     * $table->dropForeignKey('user_id');
252
     *
253
     * @param string $column
254
     *
255
     * @return TableBlueprint
256
     */
257
    public function dropForeignKey(string $column): self
258
    {
259
        return $this->addOperation(
260
            new DropReference($this->database, $this->table, $column)
261
        );
262
    }
263
264
    /**
265
     * Set table primary keys index. Attention, you can only call it when table being created.
266
     *
267
     * @param array $keys
268
     *
269
     * @return TableBlueprint
270
     */
271
    public function setPrimaryKeys(array $keys): self
272
    {
273
        return $this->addOperation(
274
            new PrimaryKeys($this->database, $this->table, $keys)
275
        );
276
    }
277
278
    /**
279
     * Create table schema.
280
     */
281
    public function create()
282
    {
283
        $this->addOperation(
284
            new CreateTable($this->database, $this->table)
285
        );
286
287
        $this->execute();
288
    }
289
290
    /**
291
     * Update table schema.
292
     */
293
    public function update()
294
    {
295
        $this->addOperation(
296
            new UpdateTable($this->database, $this->table)
297
        );
298
299
        $this->execute();
300
    }
301
302
    /**
303
     * Drop table.
304
     */
305
    public function drop()
306
    {
307
        $this->addOperation(
308
            new DropTable($this->database, $this->table)
309
        );
310
311
        $this->execute();
312
    }
313
314
    /**
315
     * Rename table.
316
     *
317
     * @param string $newName
318
     */
319
    public function rename(string $newName)
320
    {
321
        $this->addOperation(
322
            new RenameTable($this->database, $this->table, $newName)
323
        );
324
325
        $this->execute();
326
    }
327
328
    /**
329
     * Register new operation.
330
     *
331
     * @param OperationInterface $operation
332
     *
333
     * @return TableBlueprint
334
     */
335
    public function addOperation(OperationInterface $operation): self
336
    {
337
        $this->operations[] = $operation;
338
339
        return $this;
340
    }
341
342
    /**
343
     * Execute blueprint operations.
344
     */
345
    private function execute()
346
    {
347
        $this->capsule->execute($this->operations);
348
    }
349
}