1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* MIT License |
5
|
|
|
* For full license information, please view the LICENSE file that was distributed with this source code. |
6
|
|
|
*/ |
7
|
|
|
|
8
|
|
|
namespace Phinx\Db; |
9
|
|
|
|
10
|
|
|
use InvalidArgumentException; |
11
|
|
|
use Phinx\Db\Action\AddColumn; |
12
|
|
|
use Phinx\Db\Action\AddForeignKey; |
13
|
|
|
use Phinx\Db\Action\AddIndex; |
14
|
|
|
use Phinx\Db\Action\ChangeColumn; |
15
|
|
|
use Phinx\Db\Action\ChangeComment; |
16
|
|
|
use Phinx\Db\Action\ChangePrimaryKey; |
17
|
|
|
use Phinx\Db\Action\CreateTable; |
18
|
|
|
use Phinx\Db\Action\DropForeignKey; |
19
|
|
|
use Phinx\Db\Action\DropIndex; |
20
|
|
|
use Phinx\Db\Action\DropTable; |
21
|
|
|
use Phinx\Db\Action\RemoveColumn; |
22
|
|
|
use Phinx\Db\Action\RenameColumn; |
23
|
|
|
use Phinx\Db\Action\RenameTable; |
24
|
|
|
use Phinx\Db\Adapter\AdapterInterface; |
25
|
|
|
use Phinx\Db\Plan\Intent; |
26
|
|
|
use Phinx\Db\Plan\Plan; |
27
|
|
|
use Phinx\Db\Table\Column; |
28
|
|
|
use Phinx\Db\Table\Table as TableValue; |
29
|
|
|
use RuntimeException; |
30
|
|
|
|
31
|
|
|
/** |
32
|
|
|
* This object is based loosely on: http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/Table.html. |
33
|
|
|
*/ |
34
|
|
|
class Table |
35
|
|
|
{ |
36
|
|
|
/** |
37
|
|
|
* @var \Phinx\Db\Table\Table |
38
|
|
|
*/ |
39
|
|
|
protected $table; |
40
|
|
|
|
41
|
|
|
/** |
42
|
|
|
* @var \Phinx\Db\Adapter\AdapterInterface |
43
|
|
|
*/ |
44
|
|
|
protected $adapter; |
45
|
|
|
|
46
|
|
|
/** |
47
|
|
|
* @var \Phinx\Db\Plan\Intent |
48
|
|
|
*/ |
49
|
|
|
protected $actions; |
50
|
|
|
|
51
|
|
|
/** |
52
|
|
|
* @var array |
53
|
|
|
*/ |
54
|
|
|
protected $data = []; |
55
|
|
|
|
56
|
|
|
/** |
57
|
|
|
* @param string $name Table Name |
58
|
|
|
* @param array $options Options |
59
|
|
|
* @param \Phinx\Db\Adapter\AdapterInterface|null $adapter Database Adapter |
60
|
|
|
*/ |
61
|
|
|
public function __construct($name, $options = [], AdapterInterface $adapter = null) |
62
|
|
|
{ |
63
|
|
|
$this->table = new TableValue($name, $options); |
64
|
|
|
$this->actions = new Intent(); |
65
|
|
|
|
66
|
|
|
if ($adapter !== null) { |
67
|
|
|
$this->setAdapter($adapter); |
68
|
|
|
} |
69
|
|
|
} |
70
|
|
|
|
71
|
|
|
/** |
72
|
|
|
* Gets the table name. |
73
|
|
|
* |
74
|
|
|
* @return string|null |
75
|
|
|
*/ |
76
|
|
|
public function getName() |
77
|
|
|
{ |
78
|
|
|
return $this->table->getName(); |
79
|
|
|
} |
80
|
|
|
|
81
|
|
|
/** |
82
|
|
|
* Gets the table options. |
83
|
|
|
* |
84
|
239 |
|
* @return array |
85
|
|
|
*/ |
86
|
239 |
|
public function getOptions() |
87
|
239 |
|
{ |
88
|
|
|
return $this->table->getOptions(); |
89
|
239 |
|
} |
90
|
231 |
|
|
91
|
231 |
|
/** |
92
|
239 |
|
* Gets the table name and options as an object |
93
|
|
|
* |
94
|
|
|
* @return \Phinx\Db\Table\Table |
95
|
|
|
*/ |
96
|
|
|
public function getTable() |
97
|
|
|
{ |
98
|
|
|
return $this->table; |
99
|
|
|
} |
100
|
239 |
|
|
101
|
|
|
/** |
102
|
239 |
|
* Sets the database adapter. |
103
|
239 |
|
* |
104
|
|
|
* @param \Phinx\Db\Adapter\AdapterInterface $adapter Database Adapter |
105
|
|
|
* |
106
|
|
|
* @return $this |
107
|
|
|
*/ |
108
|
|
|
public function setAdapter(AdapterInterface $adapter) |
109
|
|
|
{ |
110
|
|
|
$this->adapter = $adapter; |
111
|
215 |
|
|
112
|
|
|
return $this; |
113
|
215 |
|
} |
114
|
|
|
|
115
|
|
|
/** |
116
|
|
|
* Gets the database adapter. |
117
|
|
|
* |
118
|
|
|
* @throws \RuntimeException |
119
|
|
|
* |
120
|
|
|
* @return \Phinx\Db\Adapter\AdapterInterface|null |
121
|
|
|
*/ |
122
|
239 |
|
public function getAdapter() |
123
|
|
|
{ |
124
|
239 |
|
if (!$this->adapter) { |
125
|
239 |
|
throw new RuntimeException('There is no database adapter set yet, cannot proceed'); |
126
|
|
|
} |
127
|
|
|
|
128
|
|
|
return $this->adapter; |
129
|
|
|
} |
130
|
|
|
|
131
|
|
|
/** |
132
|
|
|
* Does the table have pending actions? |
133
|
189 |
|
* |
134
|
|
|
* @return bool |
135
|
189 |
|
*/ |
136
|
|
|
public function hasPendingActions() |
137
|
|
|
{ |
138
|
|
|
return count($this->actions->getActions()) > 0 || count($this->data) > 0; |
139
|
|
|
} |
140
|
|
|
|
141
|
|
|
/** |
142
|
|
|
* Does the table exist? |
143
|
|
|
* |
144
|
231 |
|
* @return bool |
145
|
|
|
*/ |
146
|
231 |
|
public function exists() |
147
|
231 |
|
{ |
148
|
|
|
return $this->getAdapter()->hasTable($this->getName()); |
149
|
|
|
} |
150
|
|
|
|
151
|
|
|
/** |
152
|
|
|
* Drops the database table. |
153
|
|
|
* |
154
|
|
|
* @return $this |
155
|
225 |
|
*/ |
156
|
|
|
public function drop() |
157
|
225 |
|
{ |
158
|
|
|
$this->actions->addAction(new DropTable($this->table)); |
159
|
|
|
|
160
|
|
|
return $this; |
161
|
|
|
} |
162
|
|
|
|
163
|
|
|
/** |
164
|
|
|
* Renames the database table. |
165
|
195 |
|
* |
166
|
|
|
* @param string $newTableName New Table Name |
167
|
195 |
|
* |
168
|
|
|
* @return $this |
169
|
|
|
*/ |
170
|
|
|
public function rename($newTableName) |
171
|
|
|
{ |
172
|
|
|
$this->actions->addAction(new RenameTable($this->table, $newTableName)); |
173
|
|
|
|
174
|
|
|
return $this; |
175
|
1 |
|
} |
176
|
|
|
|
177
|
1 |
|
/** |
178
|
1 |
|
* Changes the primary key of the database table. |
179
|
|
|
* |
180
|
|
|
* @param string|array|null $columns Column name(s) to belong to the primary key, or null to drop the key |
181
|
|
|
* |
182
|
|
|
* @return $this |
183
|
|
|
*/ |
184
|
|
|
public function changePrimaryKey($columns) |
185
|
|
|
{ |
186
|
3 |
|
$this->actions->addAction(new ChangePrimaryKey($this->table, $columns)); |
187
|
|
|
|
188
|
3 |
|
return $this; |
189
|
3 |
|
} |
190
|
3 |
|
|
191
|
|
|
/** |
192
|
|
|
* Changes the comment of the database table. |
193
|
|
|
* |
194
|
|
|
* @param string|null $comment New comment string, or null to drop the comment |
195
|
|
|
* |
196
|
|
|
* @return $this |
197
|
|
|
*/ |
198
|
|
|
public function changeComment($comment) |
199
|
|
|
{ |
200
|
|
|
$this->actions->addAction(new ChangeComment($this->table, $comment)); |
201
|
|
|
|
202
|
|
|
return $this; |
203
|
|
|
} |
204
|
|
|
|
205
|
|
|
/** |
206
|
|
|
* Gets an array of the table columns. |
207
|
|
|
* |
208
|
|
|
* @return \Phinx\Db\Table\Column[] |
209
|
|
|
*/ |
210
|
|
|
public function getColumns() |
211
|
10 |
|
{ |
212
|
|
|
return $this->getAdapter()->getColumns($this->getName()); |
213
|
10 |
|
} |
214
|
|
|
|
215
|
|
|
/** |
216
|
|
|
* Gets a table column if it exists. |
217
|
|
|
* |
218
|
|
|
* @param string $name Column name |
219
|
|
|
* |
220
|
|
|
* @return \Phinx\Db\Table\Column|null |
221
|
|
|
*/ |
222
|
196 |
|
public function getColumn($name) |
223
|
|
|
{ |
224
|
196 |
|
$columns = array_filter( |
225
|
196 |
|
$this->getColumns(), |
226
|
|
|
function ($column) use ($name) { |
227
|
|
|
return $column->getName() === $name; |
228
|
|
|
} |
229
|
|
|
); |
230
|
|
|
|
231
|
|
|
return array_pop($columns); |
232
|
|
|
} |
233
|
204 |
|
|
234
|
|
|
/** |
235
|
204 |
|
* Sets an array of data to be inserted. |
236
|
|
|
* |
237
|
|
|
* @param array $data Data |
238
|
|
|
* |
239
|
|
|
* @return $this |
240
|
|
|
*/ |
241
|
|
|
public function setData($data) |
242
|
|
|
{ |
243
|
|
|
$this->data = $data; |
244
|
196 |
|
|
245
|
|
|
return $this; |
246
|
196 |
|
} |
247
|
196 |
|
|
248
|
|
|
/** |
249
|
|
|
* Gets the data waiting to be inserted. |
250
|
|
|
* |
251
|
|
|
* @return array |
252
|
|
|
*/ |
253
|
|
|
public function getData() |
254
|
|
|
{ |
255
|
191 |
|
return $this->data; |
256
|
|
|
} |
257
|
191 |
|
|
258
|
|
|
/** |
259
|
|
|
* Resets all of the pending data to be inserted |
260
|
|
|
* |
261
|
|
|
* @return void |
262
|
|
|
*/ |
263
|
|
|
public function resetData() |
264
|
|
|
{ |
265
|
|
|
$this->setData([]); |
266
|
196 |
|
} |
267
|
|
|
|
268
|
196 |
|
/** |
269
|
196 |
|
* Resets all of the pending table changes. |
270
|
|
|
* |
271
|
|
|
* @return void |
272
|
|
|
*/ |
273
|
|
|
public function reset() |
274
|
|
|
{ |
275
|
|
|
$this->actions = new Intent(); |
276
|
|
|
$this->resetData(); |
277
|
192 |
|
} |
278
|
|
|
|
279
|
192 |
|
/** |
280
|
|
|
* Add a table column. |
281
|
|
|
* |
282
|
|
|
* Type can be: string, text, integer, float, decimal, datetime, timestamp, |
283
|
|
|
* time, date, binary, boolean. |
284
|
|
|
* |
285
|
|
|
* Valid options can be: limit, default, null, precision or scale. |
286
|
|
|
* |
287
|
|
|
* @param string|\Phinx\Db\Table\Column $columnName Column Name |
288
|
196 |
|
* @param string|\Phinx\Util\Literal|null $type Column Type |
289
|
|
|
* @param array $options Column Options |
290
|
196 |
|
* |
291
|
196 |
|
* @throws \InvalidArgumentException |
292
|
|
|
* |
293
|
|
|
* @return $this |
294
|
|
|
*/ |
295
|
|
|
public function addColumn($columnName, $type = null, $options = []) |
296
|
|
|
{ |
297
|
|
|
if ($columnName instanceof Column) { |
298
|
|
|
$action = new AddColumn($this->table, $columnName); |
299
|
197 |
|
} else { |
300
|
|
|
if ('sqlite' == $this->getAdapter()->getAdapterType() || 'sqlite' == (getenv('PHINX_TESTING_ADAPTER'))) { |
301
|
197 |
|
array_key_exists('null', $options) ?: $options['null'] = true; |
302
|
|
|
} |
303
|
|
|
$action = AddColumn::build($this->table, $columnName, $type, $options); |
304
|
|
|
} |
305
|
|
|
|
306
|
|
|
// Delegate to Adapters to check column type |
307
|
|
|
if (!$this->getAdapter()->isValidColumnType($action->getColumn())) { |
308
|
|
|
throw new InvalidArgumentException(sprintf( |
309
|
196 |
|
'An invalid column type "%s" was specified for column "%s".', |
310
|
|
|
$type, |
311
|
196 |
|
$action->getColumn()->getName() |
312
|
196 |
|
)); |
313
|
196 |
|
} |
314
|
196 |
|
|
315
|
196 |
|
$this->actions->addAction($action); |
316
|
|
|
|
317
|
|
|
return $this; |
318
|
|
|
} |
319
|
|
|
|
320
|
|
|
/** |
321
|
|
|
* Remove a table column. |
322
|
|
|
* |
323
|
|
|
* @param string $columnName Column Name |
324
|
|
|
* |
325
|
|
|
* @return $this |
326
|
|
|
*/ |
327
|
|
|
public function removeColumn($columnName) |
328
|
|
|
{ |
329
|
|
|
$action = RemoveColumn::build($this->table, $columnName); |
330
|
|
|
$this->actions->addAction($action); |
331
|
|
|
|
332
|
210 |
|
return $this; |
333
|
|
|
} |
334
|
|
|
|
335
|
210 |
|
/** |
336
|
1 |
|
* Rename a table column. |
337
|
|
|
* |
338
|
|
|
* @param string $oldName Old Column Name |
339
|
|
|
* @param string $newName New Column Name |
340
|
209 |
|
* |
341
|
207 |
|
* @return $this |
342
|
207 |
|
*/ |
343
|
207 |
|
public function renameColumn($oldName, $newName) |
344
|
207 |
|
{ |
345
|
207 |
|
$action = RenameColumn::build($this->table, $oldName, $newName); |
346
|
2 |
|
$this->actions->addAction($action); |
347
|
|
|
|
348
|
|
|
return $this; |
349
|
|
|
} |
350
|
209 |
|
|
351
|
1 |
|
/** |
352
|
1 |
|
* Change a table column type. |
353
|
1 |
|
* |
354
|
1 |
|
* @param string $columnName Column Name |
355
|
1 |
|
* @param string|\Phinx\Db\Table\Column|\Phinx\Util\Literal $newColumnType New Column Type |
356
|
|
|
* @param array $options Options |
357
|
|
|
* |
358
|
208 |
|
* @return $this |
359
|
208 |
|
*/ |
360
|
|
|
public function changeColumn($columnName, $newColumnType, array $options = []) |
361
|
|
|
{ |
362
|
|
|
if ($newColumnType instanceof Column) { |
363
|
|
|
$action = new ChangeColumn($this->table, $columnName, $newColumnType); |
364
|
|
|
} else { |
365
|
|
|
$action = ChangeColumn::build($this->table, $columnName, $newColumnType, $options); |
366
|
|
|
} |
367
|
|
|
$this->actions->addAction($action); |
368
|
1 |
|
|
369
|
|
|
return $this; |
370
|
1 |
|
} |
371
|
1 |
|
|
372
|
|
|
/** |
373
|
|
|
* Checks to see if a column exists. |
374
|
|
|
* |
375
|
|
|
* @param string $columnName Column Name |
376
|
|
|
* |
377
|
|
|
* @return bool |
378
|
|
|
*/ |
379
|
|
|
public function hasColumn($columnName) |
380
|
|
|
{ |
381
|
4 |
|
return $this->getAdapter()->hasColumn($this->getName(), $columnName); |
382
|
|
|
} |
383
|
4 |
|
|
384
|
4 |
|
/** |
385
|
|
|
* Add an index to a database table. |
386
|
|
|
* |
387
|
|
|
* In $options you can specific unique = true/false or name (index name). |
388
|
|
|
* |
389
|
|
|
* @param string|array|\Phinx\Db\Table\Index $columns Table Column(s) |
390
|
|
|
* @param array $options Index Options |
391
|
|
|
* |
392
|
|
|
* @return $this |
393
|
|
|
*/ |
394
|
|
|
public function addIndex($columns, array $options = []) |
395
|
17 |
|
{ |
396
|
|
|
$action = AddIndex::build($this->table, $columns, $options); |
397
|
|
|
$this->actions->addAction($action); |
398
|
17 |
|
|
399
|
4 |
|
return $this; |
400
|
4 |
|
} |
401
|
4 |
|
|
402
|
4 |
|
/** |
403
|
13 |
|
* Removes the given index from a table. |
404
|
|
|
* |
405
|
|
|
* @param string|array $columns Columns |
406
|
|
|
* |
407
|
17 |
|
* @return $this |
408
|
15 |
|
*/ |
409
|
15 |
|
public function removeIndex($columns) |
410
|
|
|
{ |
411
|
17 |
|
$action = DropIndex::build($this->table, is_string($columns) ? [$columns] : $columns); |
412
|
17 |
|
$this->actions->addAction($action); |
413
|
|
|
|
414
|
|
|
return $this; |
415
|
|
|
} |
416
|
|
|
|
417
|
|
|
/** |
418
|
|
|
* Removes the given index identified by its name from a table. |
419
|
|
|
* |
420
|
|
|
* @param string $name Index name |
421
|
89 |
|
* |
422
|
|
|
* @return $this |
423
|
89 |
|
*/ |
424
|
|
|
public function removeIndexByName($name) |
425
|
|
|
{ |
426
|
|
|
$action = DropIndex::buildFromName($this->table, $name); |
427
|
|
|
$this->actions->addAction($action); |
428
|
|
|
|
429
|
|
|
return $this; |
430
|
|
|
} |
431
|
|
|
|
432
|
|
|
/** |
433
|
|
|
* Checks to see if an index exists. |
434
|
|
|
* |
435
|
29 |
|
* @param string|array $columns Columns |
436
|
|
|
* |
437
|
|
|
* @return bool |
438
|
29 |
|
*/ |
439
|
28 |
|
public function hasIndex($columns) |
440
|
28 |
|
{ |
441
|
22 |
|
return $this->getAdapter()->hasIndex($this->getName(), $columns); |
|
|
|
|
442
|
22 |
|
} |
443
|
28 |
|
|
444
|
28 |
|
/** |
445
|
28 |
|
* Checks to see if an index specified by name exists. |
446
|
1 |
|
* |
447
|
|
|
* @param string $indexName |
448
|
|
|
* |
449
|
29 |
|
* @return bool |
450
|
29 |
|
*/ |
451
|
|
|
public function hasIndexByName($indexName) |
452
|
|
|
{ |
453
|
|
|
return $this->getAdapter()->hasIndexByName($this->getName(), $indexName); |
454
|
|
|
} |
455
|
|
|
|
456
|
|
|
/** |
457
|
|
|
* Add a foreign key to a database table. |
458
|
|
|
* |
459
|
1 |
|
* In $options you can specify on_delete|on_delete = cascade|no_action .., |
460
|
|
|
* on_update, constraint = constraint name. |
461
|
1 |
|
* |
462
|
1 |
|
* @param string|array $columns Columns |
463
|
|
|
* @param string|\Phinx\Db\Table $referencedTable Referenced Table |
464
|
|
|
* @param string|array $referencedColumns Referenced Columns |
465
|
|
|
* @param array $options Options |
466
|
|
|
* |
467
|
|
|
* @return $this |
468
|
|
|
*/ |
469
|
|
View Code Duplication |
public function addForeignKey($columns, $referencedTable, $referencedColumns = ['id'], $options = []) |
|
|
|
|
470
|
|
|
{ |
471
|
1 |
|
$action = AddForeignKey::build($this->table, $columns, $referencedTable, $referencedColumns, $options); |
|
|
|
|
472
|
|
|
$this->actions->addAction($action); |
473
|
1 |
|
|
474
|
1 |
|
return $this; |
475
|
|
|
} |
476
|
|
|
|
477
|
|
|
/** |
478
|
|
|
* Add a foreign key to a database table with a given name. |
479
|
|
|
* |
480
|
|
|
* In $options you can specify on_delete|on_delete = cascade|no_action .., |
481
|
|
|
* on_update, constraint = constraint name. |
482
|
|
|
* |
483
|
|
|
* @param string $name The constraint name |
484
|
12 |
|
* @param string|array $columns Columns |
485
|
|
|
* @param string|\Phinx\Db\Table $referencedTable Referenced Table |
486
|
12 |
|
* @param string|array $referencedColumns Referenced Columns |
487
|
|
|
* @param array $options Options |
488
|
|
|
* |
489
|
|
|
* @return $this |
490
|
|
|
*/ |
491
|
|
View Code Duplication |
public function addForeignKeyWithName($name, $columns, $referencedTable, $referencedColumns = ['id'], $options = []) |
|
|
|
|
492
|
|
|
{ |
493
|
|
|
$action = AddForeignKey::build( |
494
|
|
|
$this->table, |
495
|
|
|
$columns, |
|
|
|
|
496
|
|
|
$referencedTable, |
|
|
|
|
497
|
|
|
$referencedColumns, |
498
|
|
|
$options, |
499
|
|
|
$name |
500
|
|
|
); |
501
|
8 |
|
$this->actions->addAction($action); |
502
|
|
|
|
503
|
8 |
|
return $this; |
504
|
4 |
|
} |
505
|
4 |
|
|
506
|
8 |
|
/** |
507
|
8 |
|
* Removes the given foreign key from the table. |
508
|
|
|
* |
509
|
|
|
* @param string|array $columns Column(s) |
510
|
8 |
|
* @param string|null $constraint Constraint names |
511
|
|
|
* |
512
|
8 |
|
* @return $this |
513
|
8 |
|
*/ |
514
|
8 |
|
public function dropForeignKey($columns, $constraint = null) |
515
|
8 |
|
{ |
516
|
|
|
$action = DropForeignKey::build($this->table, $columns, $constraint); |
|
|
|
|
517
|
8 |
|
$this->actions->addAction($action); |
518
|
|
|
|
519
|
|
|
return $this; |
520
|
|
|
} |
521
|
|
|
|
522
|
|
|
/** |
523
|
|
|
* Checks to see if a foreign key exists. |
524
|
|
|
* |
525
|
|
|
* @param string|array $columns Column(s) |
526
|
|
|
* @param string|null $constraint Constraint names |
527
|
1 |
|
* |
528
|
|
|
* @return bool |
529
|
1 |
|
*/ |
530
|
1 |
|
public function hasForeignKey($columns, $constraint = null) |
531
|
1 |
|
{ |
532
|
1 |
|
return $this->getAdapter()->hasForeignKey($this->getName(), $columns, $constraint); |
|
|
|
|
533
|
|
|
} |
534
|
|
|
|
535
|
1 |
|
/** |
536
|
|
|
* Add timestamp columns created_at and updated_at to the table. |
537
|
|
|
* |
538
|
1 |
|
* @param string|null $createdAt Alternate name for the created_at column |
539
|
|
|
* @param string|null $updatedAt Alternate name for the updated_at column |
540
|
|
|
* @param bool $withTimezone Whether to set the timezone option on the added columns |
541
|
|
|
* |
542
|
|
|
* @return $this |
543
|
|
|
*/ |
544
|
|
|
public function addTimestamps($createdAt = 'created_at', $updatedAt = 'updated_at', $withTimezone = false) |
545
|
|
|
{ |
546
|
|
|
$createdAt = $createdAt === null ? 'created_at' : $createdAt; |
547
|
|
|
$updatedAt = $updatedAt === null ? 'updated_at' : $updatedAt; |
548
|
1 |
|
|
549
|
|
|
$this->addColumn($createdAt, 'timestamp', [ |
550
|
1 |
|
'default' => 'CURRENT_TIMESTAMP', |
551
|
|
|
'update' => '', |
552
|
|
|
'timezone' => $withTimezone, |
553
|
|
|
]) |
554
|
|
|
->addColumn($updatedAt, 'timestamp', [ |
555
|
|
|
'null' => true, |
556
|
|
|
'default' => null, |
557
|
|
|
'timezone' => $withTimezone, |
558
|
|
|
]); |
559
|
|
|
|
560
|
|
|
return $this; |
561
|
15 |
|
} |
562
|
|
|
|
563
|
15 |
|
/** |
564
|
15 |
|
* Alias that always sets $withTimezone to true |
565
|
15 |
|
* |
566
|
15 |
|
* @see addTimestamps |
567
|
|
|
* |
568
|
15 |
|
* @param string|null $createdAt Alternate name for the created_at column |
569
|
15 |
|
* @param string|null $updatedAt Alternate name for the updated_at column |
570
|
15 |
|
* |
571
|
|
|
* @return $this |
572
|
15 |
|
*/ |
573
|
|
|
public function addTimestampsWithTimezone($createdAt = null, $updatedAt = null) |
574
|
15 |
|
{ |
575
|
|
|
$this->addTimestamps($createdAt, $updatedAt, true); |
576
|
|
|
|
577
|
|
|
return $this; |
578
|
|
|
} |
579
|
|
|
|
580
|
|
|
/** |
581
|
|
|
* Insert data into the table. |
582
|
|
|
* |
583
|
|
|
* @param array $data array of data in the form: |
584
|
|
|
* array( |
585
|
|
|
* array("col1" => "value1", "col2" => "anotherValue1"), |
586
|
|
|
* array("col2" => "value2", "col2" => "anotherValue2"), |
587
|
|
|
* ) |
588
|
|
|
* or array("col1" => "value1", "col2" => "anotherValue1") |
589
|
17 |
|
* |
590
|
|
|
* @return $this |
591
|
|
|
*/ |
592
|
17 |
|
public function insert($data) |
593
|
11 |
|
{ |
594
|
11 |
|
// handle array of array situations |
595
|
11 |
|
$keys = array_keys($data); |
596
|
11 |
|
$firstKey = array_shift($keys); |
597
|
|
|
if ($firstKey !== null && is_array($data[$firstKey])) { |
598
|
8 |
|
foreach ($data as $row) { |
599
|
8 |
|
$this->data[] = $row; |
600
|
|
|
} |
601
|
|
|
|
602
|
|
|
return $this; |
603
|
|
|
} |
604
|
|
|
|
605
|
|
|
if (count($data) > 0) { |
606
|
|
|
$this->data[] = $data; |
607
|
196 |
|
} |
608
|
|
|
|
609
|
196 |
|
return $this; |
610
|
196 |
|
} |
611
|
196 |
|
|
612
|
196 |
|
/** |
613
|
|
|
* Creates a table from the object instance. |
614
|
|
|
* |
615
|
|
|
* @return void |
616
|
|
|
*/ |
617
|
|
|
public function create() |
618
|
|
|
{ |
619
|
|
|
$this->executeActions(false); |
620
|
46 |
|
$this->saveData(); |
621
|
|
|
$this->reset(); // reset pending changes |
622
|
46 |
|
} |
623
|
|
|
|
624
|
|
|
/** |
625
|
|
|
* Updates a table from the object instance. |
626
|
|
|
* |
627
|
46 |
|
* @return void |
628
|
38 |
|
*/ |
629
|
46 |
|
public function update() |
630
|
|
|
{ |
631
|
46 |
|
$this->executeActions(true); |
632
|
6 |
|
$this->saveData(); |
633
|
46 |
|
$this->reset(); // reset pending changes |
634
|
|
|
} |
635
|
46 |
|
|
636
|
3 |
|
/** |
637
|
46 |
|
* Commit the pending data waiting for insertion. |
638
|
|
|
* |
639
|
46 |
|
* @return void |
640
|
46 |
|
*/ |
641
|
46 |
|
public function saveData() |
642
|
|
|
{ |
643
|
|
|
$rows = $this->getData(); |
644
|
|
|
if (empty($rows)) { |
645
|
|
|
return; |
646
|
|
|
} |
647
|
|
|
|
648
|
196 |
|
$bulk = true; |
649
|
|
|
$row = current($rows); |
650
|
196 |
|
$c = array_keys($row); |
651
|
196 |
|
foreach ($this->getData() as $row) { |
652
|
192 |
|
$k = array_keys($row); |
653
|
|
|
if ($k != $c) { |
654
|
|
|
$bulk = false; |
655
|
12 |
|
break; |
656
|
12 |
|
} |
657
|
12 |
|
} |
658
|
12 |
|
|
659
|
12 |
|
if ($bulk) { |
660
|
12 |
|
$this->getAdapter()->bulkinsert($this->table, $this->getData()); |
661
|
1 |
|
} else { |
662
|
1 |
|
foreach ($this->getData() as $row) { |
663
|
|
|
$this->getAdapter()->insert($this->table, $row); |
664
|
12 |
|
} |
665
|
|
|
} |
666
|
12 |
|
|
667
|
11 |
|
$this->resetData(); |
668
|
11 |
|
} |
669
|
1 |
|
|
670
|
1 |
|
/** |
671
|
1 |
|
* Immediately truncates the table. This operation cannot be undone |
672
|
|
|
* |
673
|
12 |
|
* @return void |
674
|
|
|
*/ |
675
|
|
|
public function truncate() |
676
|
|
|
{ |
677
|
|
|
$this->getAdapter()->truncateTable($this->getName()); |
678
|
|
|
} |
679
|
|
|
|
680
|
2 |
|
/** |
681
|
|
|
* Commits the table changes. |
682
|
2 |
|
* |
683
|
2 |
|
* If the table doesn't exist it is created otherwise it is updated. |
684
|
|
|
* |
685
|
|
|
* @return void |
686
|
|
|
*/ |
687
|
|
|
public function save() |
688
|
|
|
{ |
689
|
|
|
if ($this->exists()) { |
690
|
|
|
$this->update(); // update the table |
691
|
|
|
} else { |
692
|
195 |
|
$this->create(); // create the table |
693
|
|
|
} |
694
|
195 |
|
} |
695
|
45 |
|
|
696
|
45 |
|
/** |
697
|
195 |
|
* Executes all the pending actions for this table |
698
|
|
|
* |
699
|
|
|
* @param bool $exists Whether or not the table existed prior to executing this method |
700
|
195 |
|
* |
701
|
195 |
|
* @return void |
702
|
|
|
*/ |
703
|
|
|
protected function executeActions($exists) |
704
|
|
|
{ |
705
|
|
|
// Renaming a table is tricky, specially when running a reversible migration |
706
|
|
|
// down. We will just assume the table already exists if the user commands a |
707
|
|
|
// table rename. |
708
|
|
|
$renamed = collection($this->actions->getActions()) |
709
|
|
|
->filter(function ($action) { |
710
|
|
|
return $action instanceof RenameTable; |
711
|
|
|
}) |
712
|
|
|
->first(); |
713
|
|
|
|
714
|
|
|
if ($renamed) { |
715
|
|
|
$exists = true; |
716
|
|
|
} |
717
|
|
|
|
718
|
|
|
// If the table does not exist, the last command in the chain needs to be |
719
|
|
|
// a CreateTable action. |
720
|
|
|
if (!$exists) { |
721
|
|
|
$this->actions->addAction(new CreateTable($this->table)); |
722
|
|
|
} |
723
|
|
|
|
724
|
|
|
$plan = new Plan($this->actions); |
725
|
|
|
$plan->execute($this->getAdapter()); |
|
|
|
|
726
|
|
|
} |
727
|
|
|
} |
728
|
|
|
|
This check looks at variables that have been passed in as parameters and are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.