Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php
2
 
3
namespace Illuminate\Database\Schema\Grammars;
4
 
5
use Illuminate\Database\Connection;
6
use Illuminate\Database\Schema\Blueprint;
7
use Illuminate\Support\Fluent;
8
 
9
class PostgresGrammar extends Grammar
10
{
11
    /**
12
     * If this Grammar supports schema changes wrapped in a transaction.
13
     *
14
     * @var bool
15
     */
16
    protected $transactions = true;
17
 
18
    /**
19
     * The possible column modifiers.
20
     *
21
     * @var string[]
22
     */
23
    protected $modifiers = ['Collate', 'Increment', 'Nullable', 'Default', 'VirtualAs', 'StoredAs'];
24
 
25
    /**
26
     * The columns available as serials.
27
     *
28
     * @var string[]
29
     */
30
    protected $serials = ['bigInteger', 'integer', 'mediumInteger', 'smallInteger', 'tinyInteger'];
31
 
32
    /**
33
     * The commands to be executed outside of create or alter command.
34
     *
35
     * @var string[]
36
     */
37
    protected $fluentCommands = ['Comment'];
38
 
39
    /**
40
     * Compile a create database command.
41
     *
42
     * @param  string  $name
43
     * @param  \Illuminate\Database\Connection  $connection
44
     * @return string
45
     */
46
    public function compileCreateDatabase($name, $connection)
47
    {
48
        return sprintf(
49
            'create database %s encoding %s',
50
            $this->wrapValue($name),
51
            $this->wrapValue($connection->getConfig('charset')),
52
        );
53
    }
54
 
55
    /**
56
     * Compile a drop database if exists command.
57
     *
58
     * @param  string  $name
59
     * @return string
60
     */
61
    public function compileDropDatabaseIfExists($name)
62
    {
63
        return sprintf(
64
            'drop database if exists %s',
65
            $this->wrapValue($name)
66
        );
67
    }
68
 
69
    /**
70
     * Compile the query to determine if a table exists.
71
     *
72
     * @return string
73
     */
74
    public function compileTableExists()
75
    {
76
        return "select * from information_schema.tables where table_catalog = ? and table_schema = ? and table_name = ? and table_type = 'BASE TABLE'";
77
    }
78
 
79
    /**
80
     * Compile the query to determine the list of columns.
81
     *
82
     * @return string
83
     */
84
    public function compileColumnListing()
85
    {
86
        return 'select column_name from information_schema.columns where table_catalog = ? and table_schema = ? and table_name = ?';
87
    }
88
 
89
    /**
90
     * Compile a create table command.
91
     *
92
     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
93
     * @param  \Illuminate\Support\Fluent  $command
94
     * @return array
95
     */
96
    public function compileCreate(Blueprint $blueprint, Fluent $command)
97
    {
98
        return array_values(array_filter(array_merge([sprintf('%s table %s (%s)',
99
            $blueprint->temporary ? 'create temporary' : 'create',
100
            $this->wrapTable($blueprint),
101
            implode(', ', $this->getColumns($blueprint))
102
        )], $this->compileAutoIncrementStartingValues($blueprint))));
103
    }
104
 
105
    /**
106
     * Compile a column addition command.
107
     *
108
     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
109
     * @param  \Illuminate\Support\Fluent  $command
110
     * @return string
111
     */
112
    public function compileAdd(Blueprint $blueprint, Fluent $command)
113
    {
114
        return array_values(array_filter(array_merge([sprintf('alter table %s %s',
115
            $this->wrapTable($blueprint),
116
            implode(', ', $this->prefixArray('add column', $this->getColumns($blueprint)))
117
        )], $this->compileAutoIncrementStartingValues($blueprint))));
118
    }
119
 
120
    /**
121
     * Compile the auto-incrementing column starting values.
122
     *
123
     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
124
     * @return array
125
     */
126
    public function compileAutoIncrementStartingValues(Blueprint $blueprint)
127
    {
128
        return collect($blueprint->autoIncrementingStartingValues())->map(function ($value, $column) use ($blueprint) {
129
            return 'alter sequence '.$blueprint->getTable().'_'.$column.'_seq restart with '.$value;
130
        })->all();
131
    }
132
 
133
    /**
134
     * Compile a rename column command.
135
     *
136
     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
137
     * @param  \Illuminate\Support\Fluent  $command
138
     * @param  \Illuminate\Database\Connection  $connection
139
     * @return array|string
140
     */
141
    public function compileRenameColumn(Blueprint $blueprint, Fluent $command, Connection $connection)
142
    {
143
        return $connection->usingNativeSchemaOperations()
144
            ? sprintf('alter table %s rename column %s to %s',
145
                $this->wrapTable($blueprint),
146
                $this->wrap($command->from),
147
                $this->wrap($command->to)
148
            )
149
            : parent::compileRenameColumn($blueprint, $command, $connection);
150
    }
151
 
152
    /**
153
     * Compile a primary key command.
154
     *
155
     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
156
     * @param  \Illuminate\Support\Fluent  $command
157
     * @return string
158
     */
159
    public function compilePrimary(Blueprint $blueprint, Fluent $command)
160
    {
161
        $columns = $this->columnize($command->columns);
162
 
163
        return 'alter table '.$this->wrapTable($blueprint)." add primary key ({$columns})";
164
    }
165
 
166
    /**
167
     * Compile a unique key command.
168
     *
169
     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
170
     * @param  \Illuminate\Support\Fluent  $command
171
     * @return string
172
     */
173
    public function compileUnique(Blueprint $blueprint, Fluent $command)
174
    {
175
        $sql = sprintf('alter table %s add constraint %s unique (%s)',
176
            $this->wrapTable($blueprint),
177
            $this->wrap($command->index),
178
            $this->columnize($command->columns)
179
        );
180
 
181
        if (! is_null($command->deferrable)) {
182
            $sql .= $command->deferrable ? ' deferrable' : ' not deferrable';
183
        }
184
 
185
        if ($command->deferrable && ! is_null($command->initiallyImmediate)) {
186
            $sql .= $command->initiallyImmediate ? ' initially immediate' : ' initially deferred';
187
        }
188
 
189
        return $sql;
190
    }
191
 
192
    /**
193
     * Compile a plain index key command.
194
     *
195
     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
196
     * @param  \Illuminate\Support\Fluent  $command
197
     * @return string
198
     */
199
    public function compileIndex(Blueprint $blueprint, Fluent $command)
200
    {
201
        return sprintf('create index %s on %s%s (%s)',
202
            $this->wrap($command->index),
203
            $this->wrapTable($blueprint),
204
            $command->algorithm ? ' using '.$command->algorithm : '',
205
            $this->columnize($command->columns)
206
        );
207
    }
208
 
209
    /**
210
     * Compile a fulltext index key command.
211
     *
212
     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
213
     * @param  \Illuminate\Support\Fluent  $command
214
     * @return string
215
     *
216
     * @throws \RuntimeException
217
     */
218
    public function compileFulltext(Blueprint $blueprint, Fluent $command)
219
    {
220
        $language = $command->language ?: 'english';
221
 
222
        $columns = array_map(function ($column) use ($language) {
223
            return "to_tsvector({$this->quoteString($language)}, {$this->wrap($column)})";
224
        }, $command->columns);
225
 
226
        return sprintf('create index %s on %s using gin ((%s))',
227
            $this->wrap($command->index),
228
            $this->wrapTable($blueprint),
229
            implode(' || ', $columns)
230
        );
231
    }
232
 
233
    /**
234
     * Compile a spatial index key command.
235
     *
236
     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
237
     * @param  \Illuminate\Support\Fluent  $command
238
     * @return string
239
     */
240
    public function compileSpatialIndex(Blueprint $blueprint, Fluent $command)
241
    {
242
        $command->algorithm = 'gist';
243
 
244
        return $this->compileIndex($blueprint, $command);
245
    }
246
 
247
    /**
248
     * Compile a foreign key command.
249
     *
250
     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
251
     * @param  \Illuminate\Support\Fluent  $command
252
     * @return string
253
     */
254
    public function compileForeign(Blueprint $blueprint, Fluent $command)
255
    {
256
        $sql = parent::compileForeign($blueprint, $command);
257
 
258
        if (! is_null($command->deferrable)) {
259
            $sql .= $command->deferrable ? ' deferrable' : ' not deferrable';
260
        }
261
 
262
        if ($command->deferrable && ! is_null($command->initiallyImmediate)) {
263
            $sql .= $command->initiallyImmediate ? ' initially immediate' : ' initially deferred';
264
        }
265
 
266
        if (! is_null($command->notValid)) {
267
            $sql .= ' not valid';
268
        }
269
 
270
        return $sql;
271
    }
272
 
273
    /**
274
     * Compile a drop table command.
275
     *
276
     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
277
     * @param  \Illuminate\Support\Fluent  $command
278
     * @return string
279
     */
280
    public function compileDrop(Blueprint $blueprint, Fluent $command)
281
    {
282
        return 'drop table '.$this->wrapTable($blueprint);
283
    }
284
 
285
    /**
286
     * Compile a drop table (if exists) command.
287
     *
288
     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
289
     * @param  \Illuminate\Support\Fluent  $command
290
     * @return string
291
     */
292
    public function compileDropIfExists(Blueprint $blueprint, Fluent $command)
293
    {
294
        return 'drop table if exists '.$this->wrapTable($blueprint);
295
    }
296
 
297
    /**
298
     * Compile the SQL needed to drop all tables.
299
     *
300
     * @param  array  $tables
301
     * @return string
302
     */
303
    public function compileDropAllTables($tables)
304
    {
305
        return 'drop table '.implode(',', $this->escapeNames($tables)).' cascade';
306
    }
307
 
308
    /**
309
     * Compile the SQL needed to drop all views.
310
     *
311
     * @param  array  $views
312
     * @return string
313
     */
314
    public function compileDropAllViews($views)
315
    {
316
        return 'drop view '.implode(',', $this->escapeNames($views)).' cascade';
317
    }
318
 
319
    /**
320
     * Compile the SQL needed to drop all types.
321
     *
322
     * @param  array  $types
323
     * @return string
324
     */
325
    public function compileDropAllTypes($types)
326
    {
327
        return 'drop type '.implode(',', $this->escapeNames($types)).' cascade';
328
    }
329
 
330
    /**
331
     * Compile the SQL needed to retrieve all table names.
332
     *
333
     * @param  string|array  $searchPath
334
     * @return string
335
     */
336
    public function compileGetAllTables($searchPath)
337
    {
338
        return "select tablename, concat('\"', schemaname, '\".\"', tablename, '\"') as qualifiedname from pg_catalog.pg_tables where schemaname in ('".implode("','", (array) $searchPath)."')";
339
    }
340
 
341
    /**
342
     * Compile the SQL needed to retrieve all view names.
343
     *
344
     * @param  string|array  $searchPath
345
     * @return string
346
     */
347
    public function compileGetAllViews($searchPath)
348
    {
349
        return "select viewname, concat('\"', schemaname, '\".\"', viewname, '\"') as qualifiedname from pg_catalog.pg_views where schemaname in ('".implode("','", (array) $searchPath)."')";
350
    }
351
 
352
    /**
353
     * Compile the SQL needed to retrieve all type names.
354
     *
355
     * @return string
356
     */
357
    public function compileGetAllTypes()
358
    {
359
        return 'select distinct pg_type.typname from pg_type inner join pg_enum on pg_enum.enumtypid = pg_type.oid';
360
    }
361
 
362
    /**
363
     * Compile a drop column command.
364
     *
365
     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
366
     * @param  \Illuminate\Support\Fluent  $command
367
     * @return string
368
     */
369
    public function compileDropColumn(Blueprint $blueprint, Fluent $command)
370
    {
371
        $columns = $this->prefixArray('drop column', $this->wrapArray($command->columns));
372
 
373
        return 'alter table '.$this->wrapTable($blueprint).' '.implode(', ', $columns);
374
    }
375
 
376
    /**
377
     * Compile a drop primary key command.
378
     *
379
     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
380
     * @param  \Illuminate\Support\Fluent  $command
381
     * @return string
382
     */
383
    public function compileDropPrimary(Blueprint $blueprint, Fluent $command)
384
    {
385
        $index = $this->wrap("{$blueprint->getTable()}_pkey");
386
 
387
        return 'alter table '.$this->wrapTable($blueprint)." drop constraint {$index}";
388
    }
389
 
390
    /**
391
     * Compile a drop unique key command.
392
     *
393
     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
394
     * @param  \Illuminate\Support\Fluent  $command
395
     * @return string
396
     */
397
    public function compileDropUnique(Blueprint $blueprint, Fluent $command)
398
    {
399
        $index = $this->wrap($command->index);
400
 
401
        return "alter table {$this->wrapTable($blueprint)} drop constraint {$index}";
402
    }
403
 
404
    /**
405
     * Compile a drop index command.
406
     *
407
     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
408
     * @param  \Illuminate\Support\Fluent  $command
409
     * @return string
410
     */
411
    public function compileDropIndex(Blueprint $blueprint, Fluent $command)
412
    {
413
        return "drop index {$this->wrap($command->index)}";
414
    }
415
 
416
    /**
417
     * Compile a drop fulltext index command.
418
     *
419
     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
420
     * @param  \Illuminate\Support\Fluent  $command
421
     * @return string
422
     */
423
    public function compileDropFullText(Blueprint $blueprint, Fluent $command)
424
    {
425
        return $this->compileDropIndex($blueprint, $command);
426
    }
427
 
428
    /**
429
     * Compile a drop spatial index command.
430
     *
431
     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
432
     * @param  \Illuminate\Support\Fluent  $command
433
     * @return string
434
     */
435
    public function compileDropSpatialIndex(Blueprint $blueprint, Fluent $command)
436
    {
437
        return $this->compileDropIndex($blueprint, $command);
438
    }
439
 
440
    /**
441
     * Compile a drop foreign key command.
442
     *
443
     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
444
     * @param  \Illuminate\Support\Fluent  $command
445
     * @return string
446
     */
447
    public function compileDropForeign(Blueprint $blueprint, Fluent $command)
448
    {
449
        $index = $this->wrap($command->index);
450
 
451
        return "alter table {$this->wrapTable($blueprint)} drop constraint {$index}";
452
    }
453
 
454
    /**
455
     * Compile a rename table command.
456
     *
457
     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
458
     * @param  \Illuminate\Support\Fluent  $command
459
     * @return string
460
     */
461
    public function compileRename(Blueprint $blueprint, Fluent $command)
462
    {
463
        $from = $this->wrapTable($blueprint);
464
 
465
        return "alter table {$from} rename to ".$this->wrapTable($command->to);
466
    }
467
 
468
    /**
469
     * Compile a rename index command.
470
     *
471
     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
472
     * @param  \Illuminate\Support\Fluent  $command
473
     * @return string
474
     */
475
    public function compileRenameIndex(Blueprint $blueprint, Fluent $command)
476
    {
477
        return sprintf('alter index %s rename to %s',
478
            $this->wrap($command->from),
479
            $this->wrap($command->to)
480
        );
481
    }
482
 
483
    /**
484
     * Compile the command to enable foreign key constraints.
485
     *
486
     * @return string
487
     */
488
    public function compileEnableForeignKeyConstraints()
489
    {
490
        return 'SET CONSTRAINTS ALL IMMEDIATE;';
491
    }
492
 
493
    /**
494
     * Compile the command to disable foreign key constraints.
495
     *
496
     * @return string
497
     */
498
    public function compileDisableForeignKeyConstraints()
499
    {
500
        return 'SET CONSTRAINTS ALL DEFERRED;';
501
    }
502
 
503
    /**
504
     * Compile a comment command.
505
     *
506
     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
507
     * @param  \Illuminate\Support\Fluent  $command
508
     * @return string
509
     */
510
    public function compileComment(Blueprint $blueprint, Fluent $command)
511
    {
512
        return sprintf('comment on column %s.%s is %s',
513
            $this->wrapTable($blueprint),
514
            $this->wrap($command->column->name),
515
            "'".str_replace("'", "''", $command->value)."'"
516
        );
517
    }
518
 
519
    /**
520
     * Compile a table comment command.
521
     *
522
     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
523
     * @param  \Illuminate\Support\Fluent  $command
524
     * @return string
525
     */
526
    public function compileTableComment(Blueprint $blueprint, Fluent $command)
527
    {
528
        return sprintf('comment on table %s is %s',
529
            $this->wrapTable($blueprint),
530
            "'".str_replace("'", "''", $command->comment)."'"
531
        );
532
    }
533
 
534
    /**
535
     * Quote-escape the given tables, views, or types.
536
     *
537
     * @param  array  $names
538
     * @return array
539
     */
540
    public function escapeNames($names)
541
    {
542
        return array_map(static function ($name) {
543
            return '"'.collect(explode('.', $name))
544
                ->map(fn ($segment) => trim($segment, '\'"'))
545
                ->implode('"."').'"';
546
        }, $names);
547
    }
548
 
549
    /**
550
     * Create the column definition for a char type.
551
     *
552
     * @param  \Illuminate\Support\Fluent  $column
553
     * @return string
554
     */
555
    protected function typeChar(Fluent $column)
556
    {
557
        if ($column->length) {
558
            return "char({$column->length})";
559
        }
560
 
561
        return 'char';
562
    }
563
 
564
    /**
565
     * Create the column definition for a string type.
566
     *
567
     * @param  \Illuminate\Support\Fluent  $column
568
     * @return string
569
     */
570
    protected function typeString(Fluent $column)
571
    {
572
        if ($column->length) {
573
            return "varchar({$column->length})";
574
        }
575
 
576
        return 'varchar';
577
    }
578
 
579
    /**
580
     * Create the column definition for a tiny text type.
581
     *
582
     * @param  \Illuminate\Support\Fluent  $column
583
     * @return string
584
     */
585
    protected function typeTinyText(Fluent $column)
586
    {
587
        return 'varchar(255)';
588
    }
589
 
590
    /**
591
     * Create the column definition for a text type.
592
     *
593
     * @param  \Illuminate\Support\Fluent  $column
594
     * @return string
595
     */
596
    protected function typeText(Fluent $column)
597
    {
598
        return 'text';
599
    }
600
 
601
    /**
602
     * Create the column definition for a medium text type.
603
     *
604
     * @param  \Illuminate\Support\Fluent  $column
605
     * @return string
606
     */
607
    protected function typeMediumText(Fluent $column)
608
    {
609
        return 'text';
610
    }
611
 
612
    /**
613
     * Create the column definition for a long text type.
614
     *
615
     * @param  \Illuminate\Support\Fluent  $column
616
     * @return string
617
     */
618
    protected function typeLongText(Fluent $column)
619
    {
620
        return 'text';
621
    }
622
 
623
    /**
624
     * Create the column definition for an integer type.
625
     *
626
     * @param  \Illuminate\Support\Fluent  $column
627
     * @return string
628
     */
629
    protected function typeInteger(Fluent $column)
630
    {
631
        return $this->generatableColumn('integer', $column);
632
    }
633
 
634
    /**
635
     * Create the column definition for a big integer type.
636
     *
637
     * @param  \Illuminate\Support\Fluent  $column
638
     * @return string
639
     */
640
    protected function typeBigInteger(Fluent $column)
641
    {
642
        return $this->generatableColumn('bigint', $column);
643
    }
644
 
645
    /**
646
     * Create the column definition for a medium integer type.
647
     *
648
     * @param  \Illuminate\Support\Fluent  $column
649
     * @return string
650
     */
651
    protected function typeMediumInteger(Fluent $column)
652
    {
653
        return $this->generatableColumn('integer', $column);
654
    }
655
 
656
    /**
657
     * Create the column definition for a tiny integer type.
658
     *
659
     * @param  \Illuminate\Support\Fluent  $column
660
     * @return string
661
     */
662
    protected function typeTinyInteger(Fluent $column)
663
    {
664
        return $this->generatableColumn('smallint', $column);
665
    }
666
 
667
    /**
668
     * Create the column definition for a small integer type.
669
     *
670
     * @param  \Illuminate\Support\Fluent  $column
671
     * @return string
672
     */
673
    protected function typeSmallInteger(Fluent $column)
674
    {
675
        return $this->generatableColumn('smallint', $column);
676
    }
677
 
678
    /**
679
     * Create the column definition for a generatable column.
680
     *
681
     * @param  string  $type
682
     * @param  \Illuminate\Support\Fluent  $column
683
     * @return string
684
     */
685
    protected function generatableColumn($type, Fluent $column)
686
    {
687
        if (! $column->autoIncrement && is_null($column->generatedAs)) {
688
            return $type;
689
        }
690
 
691
        if ($column->autoIncrement && is_null($column->generatedAs)) {
692
            return with([
693
                'integer' => 'serial',
694
                'bigint' => 'bigserial',
695
                'smallint' => 'smallserial',
696
            ])[$type];
697
        }
698
 
699
        $options = '';
700
 
701
        if (! is_bool($column->generatedAs) && ! empty($column->generatedAs)) {
702
            $options = sprintf(' (%s)', $column->generatedAs);
703
        }
704
 
705
        return sprintf(
706
            '%s generated %s as identity%s',
707
            $type,
708
            $column->always ? 'always' : 'by default',
709
            $options
710
        );
711
    }
712
 
713
    /**
714
     * Create the column definition for a float type.
715
     *
716
     * @param  \Illuminate\Support\Fluent  $column
717
     * @return string
718
     */
719
    protected function typeFloat(Fluent $column)
720
    {
721
        return $this->typeDouble($column);
722
    }
723
 
724
    /**
725
     * Create the column definition for a double type.
726
     *
727
     * @param  \Illuminate\Support\Fluent  $column
728
     * @return string
729
     */
730
    protected function typeDouble(Fluent $column)
731
    {
732
        return 'double precision';
733
    }
734
 
735
    /**
736
     * Create the column definition for a real type.
737
     *
738
     * @param  \Illuminate\Support\Fluent  $column
739
     * @return string
740
     */
741
    protected function typeReal(Fluent $column)
742
    {
743
        return 'real';
744
    }
745
 
746
    /**
747
     * Create the column definition for a decimal type.
748
     *
749
     * @param  \Illuminate\Support\Fluent  $column
750
     * @return string
751
     */
752
    protected function typeDecimal(Fluent $column)
753
    {
754
        return "decimal({$column->total}, {$column->places})";
755
    }
756
 
757
    /**
758
     * Create the column definition for a boolean type.
759
     *
760
     * @param  \Illuminate\Support\Fluent  $column
761
     * @return string
762
     */
763
    protected function typeBoolean(Fluent $column)
764
    {
765
        return 'boolean';
766
    }
767
 
768
    /**
769
     * Create the column definition for an enumeration type.
770
     *
771
     * @param  \Illuminate\Support\Fluent  $column
772
     * @return string
773
     */
774
    protected function typeEnum(Fluent $column)
775
    {
776
        return sprintf(
777
            'varchar(255) check ("%s" in (%s))',
778
            $column->name,
779
            $this->quoteString($column->allowed)
780
        );
781
    }
782
 
783
    /**
784
     * Create the column definition for a json type.
785
     *
786
     * @param  \Illuminate\Support\Fluent  $column
787
     * @return string
788
     */
789
    protected function typeJson(Fluent $column)
790
    {
791
        return 'json';
792
    }
793
 
794
    /**
795
     * Create the column definition for a jsonb type.
796
     *
797
     * @param  \Illuminate\Support\Fluent  $column
798
     * @return string
799
     */
800
    protected function typeJsonb(Fluent $column)
801
    {
802
        return 'jsonb';
803
    }
804
 
805
    /**
806
     * Create the column definition for a date type.
807
     *
808
     * @param  \Illuminate\Support\Fluent  $column
809
     * @return string
810
     */
811
    protected function typeDate(Fluent $column)
812
    {
813
        return 'date';
814
    }
815
 
816
    /**
817
     * Create the column definition for a date-time type.
818
     *
819
     * @param  \Illuminate\Support\Fluent  $column
820
     * @return string
821
     */
822
    protected function typeDateTime(Fluent $column)
823
    {
824
        return $this->typeTimestamp($column);
825
    }
826
 
827
    /**
828
     * Create the column definition for a date-time (with time zone) type.
829
     *
830
     * @param  \Illuminate\Support\Fluent  $column
831
     * @return string
832
     */
833
    protected function typeDateTimeTz(Fluent $column)
834
    {
835
        return $this->typeTimestampTz($column);
836
    }
837
 
838
    /**
839
     * Create the column definition for a time type.
840
     *
841
     * @param  \Illuminate\Support\Fluent  $column
842
     * @return string
843
     */
844
    protected function typeTime(Fluent $column)
845
    {
846
        return 'time'.(is_null($column->precision) ? '' : "($column->precision)").' without time zone';
847
    }
848
 
849
    /**
850
     * Create the column definition for a time (with time zone) type.
851
     *
852
     * @param  \Illuminate\Support\Fluent  $column
853
     * @return string
854
     */
855
    protected function typeTimeTz(Fluent $column)
856
    {
857
        return 'time'.(is_null($column->precision) ? '' : "($column->precision)").' with time zone';
858
    }
859
 
860
    /**
861
     * Create the column definition for a timestamp type.
862
     *
863
     * @param  \Illuminate\Support\Fluent  $column
864
     * @return string
865
     */
866
    protected function typeTimestamp(Fluent $column)
867
    {
868
        $columnType = 'timestamp'.(is_null($column->precision) ? '' : "($column->precision)").' without time zone';
869
 
870
        return $column->useCurrent ? "$columnType default CURRENT_TIMESTAMP" : $columnType;
871
    }
872
 
873
    /**
874
     * Create the column definition for a timestamp (with time zone) type.
875
     *
876
     * @param  \Illuminate\Support\Fluent  $column
877
     * @return string
878
     */
879
    protected function typeTimestampTz(Fluent $column)
880
    {
881
        $columnType = 'timestamp'.(is_null($column->precision) ? '' : "($column->precision)").' with time zone';
882
 
883
        return $column->useCurrent ? "$columnType default CURRENT_TIMESTAMP" : $columnType;
884
    }
885
 
886
    /**
887
     * Create the column definition for a year type.
888
     *
889
     * @param  \Illuminate\Support\Fluent  $column
890
     * @return string
891
     */
892
    protected function typeYear(Fluent $column)
893
    {
894
        return $this->typeInteger($column);
895
    }
896
 
897
    /**
898
     * Create the column definition for a binary type.
899
     *
900
     * @param  \Illuminate\Support\Fluent  $column
901
     * @return string
902
     */
903
    protected function typeBinary(Fluent $column)
904
    {
905
        return 'bytea';
906
    }
907
 
908
    /**
909
     * Create the column definition for a uuid type.
910
     *
911
     * @param  \Illuminate\Support\Fluent  $column
912
     * @return string
913
     */
914
    protected function typeUuid(Fluent $column)
915
    {
916
        return 'uuid';
917
    }
918
 
919
    /**
920
     * Create the column definition for an IP address type.
921
     *
922
     * @param  \Illuminate\Support\Fluent  $column
923
     * @return string
924
     */
925
    protected function typeIpAddress(Fluent $column)
926
    {
927
        return 'inet';
928
    }
929
 
930
    /**
931
     * Create the column definition for a MAC address type.
932
     *
933
     * @param  \Illuminate\Support\Fluent  $column
934
     * @return string
935
     */
936
    protected function typeMacAddress(Fluent $column)
937
    {
938
        return 'macaddr';
939
    }
940
 
941
    /**
942
     * Create the column definition for a spatial Geometry type.
943
     *
944
     * @param  \Illuminate\Support\Fluent  $column
945
     * @return string
946
     */
947
    protected function typeGeometry(Fluent $column)
948
    {
949
        return $this->formatPostGisType('geometry', $column);
950
    }
951
 
952
    /**
953
     * Create the column definition for a spatial Point type.
954
     *
955
     * @param  \Illuminate\Support\Fluent  $column
956
     * @return string
957
     */
958
    protected function typePoint(Fluent $column)
959
    {
960
        return $this->formatPostGisType('point', $column);
961
    }
962
 
963
    /**
964
     * Create the column definition for a spatial LineString type.
965
     *
966
     * @param  \Illuminate\Support\Fluent  $column
967
     * @return string
968
     */
969
    protected function typeLineString(Fluent $column)
970
    {
971
        return $this->formatPostGisType('linestring', $column);
972
    }
973
 
974
    /**
975
     * Create the column definition for a spatial Polygon type.
976
     *
977
     * @param  \Illuminate\Support\Fluent  $column
978
     * @return string
979
     */
980
    protected function typePolygon(Fluent $column)
981
    {
982
        return $this->formatPostGisType('polygon', $column);
983
    }
984
 
985
    /**
986
     * Create the column definition for a spatial GeometryCollection type.
987
     *
988
     * @param  \Illuminate\Support\Fluent  $column
989
     * @return string
990
     */
991
    protected function typeGeometryCollection(Fluent $column)
992
    {
993
        return $this->formatPostGisType('geometrycollection', $column);
994
    }
995
 
996
    /**
997
     * Create the column definition for a spatial MultiPoint type.
998
     *
999
     * @param  \Illuminate\Support\Fluent  $column
1000
     * @return string
1001
     */
1002
    protected function typeMultiPoint(Fluent $column)
1003
    {
1004
        return $this->formatPostGisType('multipoint', $column);
1005
    }
1006
 
1007
    /**
1008
     * Create the column definition for a spatial MultiLineString type.
1009
     *
1010
     * @param  \Illuminate\Support\Fluent  $column
1011
     * @return string
1012
     */
1013
    public function typeMultiLineString(Fluent $column)
1014
    {
1015
        return $this->formatPostGisType('multilinestring', $column);
1016
    }
1017
 
1018
    /**
1019
     * Create the column definition for a spatial MultiPolygon type.
1020
     *
1021
     * @param  \Illuminate\Support\Fluent  $column
1022
     * @return string
1023
     */
1024
    protected function typeMultiPolygon(Fluent $column)
1025
    {
1026
        return $this->formatPostGisType('multipolygon', $column);
1027
    }
1028
 
1029
    /**
1030
     * Create the column definition for a spatial MultiPolygonZ type.
1031
     *
1032
     * @param  \Illuminate\Support\Fluent  $column
1033
     * @return string
1034
     */
1035
    protected function typeMultiPolygonZ(Fluent $column)
1036
    {
1037
        return $this->formatPostGisType('multipolygonz', $column);
1038
    }
1039
 
1040
    /**
1041
     * Format the column definition for a PostGIS spatial type.
1042
     *
1043
     * @param  string  $type
1044
     * @param  \Illuminate\Support\Fluent  $column
1045
     * @return string
1046
     */
1047
    private function formatPostGisType($type, Fluent $column)
1048
    {
1049
        if ($column->isGeometry === null) {
1050
            return sprintf('geography(%s, %s)', $type, $column->projection ?? '4326');
1051
        }
1052
 
1053
        if ($column->projection !== null) {
1054
            return sprintf('geometry(%s, %s)', $type, $column->projection);
1055
        }
1056
 
1057
        return "geometry({$type})";
1058
    }
1059
 
1060
    /**
1061
     * Get the SQL for a collation column modifier.
1062
     *
1063
     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
1064
     * @param  \Illuminate\Support\Fluent  $column
1065
     * @return string|null
1066
     */
1067
    protected function modifyCollate(Blueprint $blueprint, Fluent $column)
1068
    {
1069
        if (! is_null($column->collation)) {
1070
            return ' collate '.$this->wrapValue($column->collation);
1071
        }
1072
    }
1073
 
1074
    /**
1075
     * Get the SQL for a nullable column modifier.
1076
     *
1077
     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
1078
     * @param  \Illuminate\Support\Fluent  $column
1079
     * @return string|null
1080
     */
1081
    protected function modifyNullable(Blueprint $blueprint, Fluent $column)
1082
    {
1083
        return $column->nullable ? ' null' : ' not null';
1084
    }
1085
 
1086
    /**
1087
     * Get the SQL for a default column modifier.
1088
     *
1089
     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
1090
     * @param  \Illuminate\Support\Fluent  $column
1091
     * @return string|null
1092
     */
1093
    protected function modifyDefault(Blueprint $blueprint, Fluent $column)
1094
    {
1095
        if (! is_null($column->default)) {
1096
            return ' default '.$this->getDefaultValue($column->default);
1097
        }
1098
    }
1099
 
1100
    /**
1101
     * Get the SQL for an auto-increment column modifier.
1102
     *
1103
     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
1104
     * @param  \Illuminate\Support\Fluent  $column
1105
     * @return string|null
1106
     */
1107
    protected function modifyIncrement(Blueprint $blueprint, Fluent $column)
1108
    {
1109
        if ((in_array($column->type, $this->serials) || ($column->generatedAs !== null)) && $column->autoIncrement) {
1110
            return ' primary key';
1111
        }
1112
    }
1113
 
1114
    /**
1115
     * Get the SQL for a generated virtual column modifier.
1116
     *
1117
     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
1118
     * @param  \Illuminate\Support\Fluent  $column
1119
     * @return string|null
1120
     */
1121
    protected function modifyVirtualAs(Blueprint $blueprint, Fluent $column)
1122
    {
1123
        if ($column->virtualAs !== null) {
1124
            return " generated always as ({$column->virtualAs})";
1125
        }
1126
    }
1127
 
1128
    /**
1129
     * Get the SQL for a generated stored column modifier.
1130
     *
1131
     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
1132
     * @param  \Illuminate\Support\Fluent  $column
1133
     * @return string|null
1134
     */
1135
    protected function modifyStoredAs(Blueprint $blueprint, Fluent $column)
1136
    {
1137
        if ($column->storedAs !== null) {
1138
            return " generated always as ({$column->storedAs}) stored";
1139
        }
1140
    }
1141
}