Completed
Branch feature/pre-split (7b42f5)
by Anton
03:44
created

TableState::setPrimaryKeys()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 1
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * Spiral Framework.
4
 *
5
 * @license   MIT
6
 * @author    Anton Titov (Wolfy-J)
7
 */
8
9
namespace Spiral\Database\Schemas;
10
11
use Spiral\Core\Component;
12
13
/**
14
 * TableSchema helper used to store original table elements and run comparation between them.
15
 *
16
 * Attention: this state IS MUTABLE!
17
 */
18
class TableState extends Component
19
{
20
    /**
21
     * @var string
22
     */
23
    private $name = '';
24
25
    /**
26
     * @var AbstractColumn[]
27
     */
28
    private $columns = [];
29
30
    /**
31
     * @var AbstractIndex[]
32
     */
33
    private $indexes = [];
34
35
    /**
36
     * @var AbstractReference[]
37
     */
38
    private $foreigns = [];
39
40
    /**
41
     * Primary key columns are stored separately from other indexes and can be modified only during
42
     * table creation.
43
     *
44
     * @var array
45
     */
46
    private $primaryKeys = [];
47
48
    /**
49
     * @param string $name
50
     */
51
    public function __construct($name)
52
    {
53
        $this->name = $name;
54
    }
55
56
    /**
57
     * Set table name. Operation will be applied at moment of saving.
58
     *
59
     * @param string $name
60
     */
61
    public function setName($name)
62
    {
63
        $this->name = $name;
64
    }
65
66
    /**
67
     * {@inheritdoc}
68
     */
69
    public function getName()
70
    {
71
        return $this->name;
72
    }
73
74
    /**
75
     * {@inheritdoc}
76
     *
77
     * Array key points to initial element name.
78
     *
79
     * @return AbstractColumn[]
80
     */
81
    public function getColumns()
82
    {
83
        return $this->columns;
84
    }
85
86
    /**
87
     * {@inheritdoc}
88
     *
89
     * Array key points to initial element name.
90
     *
91
     * @return AbstractIndex[]
92
     */
93
    public function getIndexes()
94
    {
95
        return $this->indexes;
96
    }
97
98
    /**
99
     * {@inheritdoc}
100
     *
101
     * Array key points to initial element name.
102
     *
103
     * @return AbstractReference[]
104
     */
105
    public function getForeigns()
106
    {
107
        return $this->foreigns;
108
    }
109
110
    /**
111
     * Set table primary keys.
112
     *
113
     * @param array $columns
114
     *
115
     * @return $this
116
     */
117
    public function setPrimaryKeys(array $columns)
118
    {
119
        $this->primaryKeys = $columns;
120
121
        return $this;
122
    }
123
124
    /**
125
     * {@inheritdoc}
126
     */
127
    public function getPrimaryKeys()
128
    {
129
        return $this->primaryKeys;
130
    }
131
132
    /**
133
     * @param string $name
134
     *
135
     * @return bool
136
     */
137
    public function knowsColumn($name)
138
    {
139
        return isset($this->columns[$name]);
140
    }
141
142
    /**
143
     * @param string $name
144
     *
145
     * @return bool
146
     */
147
    public function knowsIndex($name)
148
    {
149
        return isset($this->indexes[$name]);
150
    }
151
152
    /**
153
     * @param string $name
154
     *
155
     * @return bool
156
     */
157
    public function knowsForeign($name)
158
    {
159
        return isset($this->foreigns[$name]);
160
    }
161
162
    /**
163
     * {@inheritdoc}
164
     *
165
     * Lookup is performed based on initial column name.
166
     */
167
    public function hasColumn($name)
168
    {
169
        return !empty($this->findColumn($name));
170
    }
171
172
    /**
173
     * {@inheritdoc}
174
     */
175
    public function hasIndex(array $columns = [])
176
    {
177
        return !empty($this->findIndex($columns));
178
    }
179
180
    /**
181
     * {@inheritdoc}
182
     */
183
    public function hasForeign($column)
184
    {
185
        return !empty($this->findForeign($column));
186
    }
187
188
    /**
189
     * Register new column element.
190
     *
191
     * @param AbstractColumn $column
192
     *
193
     * @return AbstractColumn
194
     */
195
    protected function registerColumn(AbstractColumn $column)
196
    {
197
        $this->columns[$column->getName()] = $column;
198
199
        return $column;
200
    }
201
202
    /**
203
     * Register new index element.
204
     *
205
     * @param AbstractIndex $index
206
     *
207
     * @return AbstractIndex
208
     */
209
    protected function registerIndex(AbstractIndex $index)
210
    {
211
        $this->indexes[$index->getName()] = $index;
212
213
        return $index;
214
    }
215
216
    /**
217
     * Register new foreign key element.
218
     *
219
     * @param AbstractReference $foreign
220
     *
221
     * @return AbstractReference
222
     */
223
    protected function registerReference(AbstractReference $foreign)
224
    {
225
        $this->foreigns[$foreign->getName()] = $foreign;
226
227
        return $foreign;
228
    }
229
230
    /**
231
     * Drop column from table schema.
232
     *
233
     * @param AbstractColumn $column
234
     *
235
     * @return $this
236
     */
237
    protected function forgetColumn(AbstractColumn $column)
238
    {
239
        foreach ($this->columns as $name => $columnSchema) {
240
            if ($columnSchema == $column) {
241
                unset($this->columns[$name]);
242
                break;
243
            }
244
        }
245
246
        return $this;
247
    }
248
249
    /**
250
     * Drop index from table schema using it's name or forming columns.
251
     *
252
     * @param AbstractIndex $index
253
     *
254
     * @return $this
255
     */
256
    protected function forgetIndex(AbstractIndex $index)
257
    {
258
        foreach ($this->indexes as $name => $indexSchema) {
259
            if ($indexSchema == $index) {
260
                unset($this->indexes[$name]);
261
                break;
262
            }
263
        }
264
265
        return $this;
266
    }
267
268
    /**
269
     * Drop foreign key from table schema using it's forming column.
270
     *
271
     * @param AbstractReference $foreign
272
     *
273
     * @return $this
274
     */
275
    protected function forgetForeign(AbstractReference $foreign)
276
    {
277
        foreach ($this->foreigns as $name => $foreignSchema) {
278
            if ($foreignSchema == $foreign) {
279
                unset($this->foreigns[$name]);
280
                break;
281
            }
282
        }
283
284
        return $this;
285
    }
286
287
    /**
288
     * Find column by it's name or return null.
289
     *
290
     * @param string $name
291
     *
292
     * @return null|AbstractColumn
293
     */
294
    protected function findColumn($name)
295
    {
296
        foreach ($this->columns as $column) {
297
            if ($column->getName() == $name) {
298
                return $column;
299
            }
300
        }
301
302
        return null;
303
    }
304
305
    /**
306
     * Find index by it's columns or return null.
307
     *
308
     * @param array $columns
309
     *
310
     * @return null|AbstractIndex
311
     */
312
    protected function findIndex(array $columns)
313
    {
314
        foreach ($this->indexes as $index) {
315
            if ($index->getColumns() == $columns) {
316
                return $index;
317
            }
318
        }
319
320
        return null;
321
    }
322
323
    /**
324
     * Find foreign key by it's column or return null.
325
     *
326
     * @param string $column
327
     *
328
     * @return null|AbstractReference
329
     */
330
    protected function findForeign($column)
331
    {
332
        foreach ($this->foreigns as $reference) {
333
            if ($reference->getColumn() == $column) {
334
                return $reference;
335
            }
336
        }
337
338
        return null;
339
    }
340
341
    /**
342
     * Remount elements under their current name.
343
     *
344
     * @return self
345
     */
346
    protected function remountElements()
347
    {
348
        $columns = [];
349
        foreach ($this->columns as $column) {
350
            $columns[$column->getName()] = $column;
351
        }
352
353
        $indexes = [];
354
        foreach ($this->indexes as $index) {
355
            $indexes[$index->getName()] = $index;
356
        }
357
358
        $references = [];
359
        foreach ($this->foreigns as $reference) {
360
            $references[$reference->getName()] = $reference;
361
        }
362
363
        $this->columns = $columns;
364
        $this->indexes = $indexes;
365
        $this->foreigns = $references;
366
    }
367
368
    /**
369
     * Re-populate schema elements using other state as source. Elements will be cloned under their
370
     * schema name.
371
     *
372
     * @param TableState $source
373
     *
374
     * @return self
375
     */
376
    protected function syncSchema(TableState $source)
377
    {
378
        $this->name = $source->name;
379
        $this->primaryKeys = $source->primaryKeys;
380
381
        $this->columns = [];
382
        foreach ($source->columns as $name => $column) {
383
            $this->columns[$name] = clone $column;
384
        }
385
386
        $this->indexes = [];
387
        foreach ($source->indexes as $name => $index) {
388
            $this->indexes[$name] = clone $index;
389
        }
390
391
        $this->foreigns = [];
392
        foreach ($source->foreigns as $name => $reference) {
393
            $this->foreigns[$name] = clone $reference;
394
        }
395
396
        return $this;
397
    }
398
}
399