Completed
Push — 4.0 ( eb4219...df36c7 )
by Arjay
02:00
created

OracleGrammar::wrapValue()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 4
rs 10
cc 2
eloc 2
nc 2
nop 1
1
<?php
2
3
namespace Yajra\Oci8\Schema\Grammars;
4
5
use Illuminate\Database\Connection;
6
use Illuminate\Database\Schema\Blueprint;
7
use Illuminate\Database\Schema\Grammars\Grammar;
8
use Illuminate\Support\Fluent;
9
use Yajra\Oci8\OracleReservedWords;
10
11
class OracleGrammar extends Grammar
12
{
13
    use OracleReservedWords;
14
15
    /**
16
     * The keyword identifier wrapper format.
17
     *
18
     * @var string
19
     */
20
    protected $wrapper = '%s';
21
22
    /**
23
     * The possible column modifiers.
24
     *
25
     * @var array
26
     */
27
    protected $modifiers = ['Increment', 'Nullable', 'Default'];
28
29
    /**
30
     * The possible column serials
31
     *
32
     * @var array
33
     */
34
    protected $serials = ['bigInteger', 'integer', 'mediumInteger', 'smallInteger', 'tinyInteger'];
35
36
    /**
37
     * Compile a create table command.
38
     *
39
     * @param  \Illuminate\Database\Schema\Blueprint $blueprint
40
     * @param  \Illuminate\Support\Fluent $command
41
     * @return string
42
     */
43
    public function compileCreate(Blueprint $blueprint, Fluent $command)
44
    {
45
        $columns = implode(', ', $this->getColumns($blueprint));
46
47
        $sql = 'create table ' . $this->wrapTable($blueprint) . " ( $columns";
48
49
        /**
50
         * To be able to name the primary/foreign keys when the table is
51
         * initially created we will need to check for a primary/foreign
52
         * key commands and add the columns to the table's declaration
53
         * here so they can be created on the tables.
54
         */
55
        $sql .= (string) $this->addForeignKeys($blueprint);
56
57
        $sql .= (string) $this->addPrimaryKeys($blueprint);
58
59
        $sql .= ' )';
60
61
        return $sql;
62
    }
63
64
    /**
65
     * Get the foreign key syntax for a table creation statement.
66
     *
67
     * @param  \Illuminate\Database\Schema\Blueprint $blueprint
68
     * @return string
69
     */
70
    protected function addForeignKeys(Blueprint $blueprint)
71
    {
72
        $sql = '';
73
74
        $foreigns = $this->getCommandsByName($blueprint, 'foreign');
75
76
        // Once we have all the foreign key commands for the table creation statement
77
        // we'll loop through each of them and add them to the create table SQL we
78
        // are building
79
        foreach ($foreigns as $foreign) {
80
            $on = $this->wrapTable($foreign->on);
81
82
            $columns = $this->columnize($foreign->columns);
83
84
            $onColumns = $this->columnize((array) $foreign->references);
85
86
            $sql .= ", constraint {$foreign->index} foreign key ( {$columns} ) references {$on} ( {$onColumns} )";
87
88
            // Once we have the basic foreign key creation statement constructed we can
89
            // build out the syntax for what should happen on an update or delete of
90
            // the affected columns, which will get something like "cascade", etc.
91
            if (! is_null($foreign->onDelete)) {
92
                $sql .= " on delete {$foreign->onDelete}";
93
            }
94
        }
95
96
        return $sql;
97
    }
98
99
    /**
100
     * Get the primary key syntax for a table creation statement.
101
     *
102
     * @param  \Illuminate\Database\Schema\Blueprint $blueprint
103
     * @return string|null
104
     */
105
    protected function addPrimaryKeys(Blueprint $blueprint)
106
    {
107
        $primary = $this->getCommandByName($blueprint, 'primary');
108
109
        if (! is_null($primary)) {
110
            $columns = $this->columnize($primary->columns);
111
112
            return ", constraint {$primary->index} primary key ( {$columns} )";
113
        }
114
115
        return "";
116
    }
117
118
    /**
119
     * Compile the query to determine if a table exists.
120
     *
121
     * @return string
122
     */
123
    public function compileTableExists()
124
    {
125
        return "select * from user_tables where upper(table_name) = upper(?)";
126
    }
127
128
    /**
129
     * Compile the query to determine the list of columns.
130
     *
131
     * @return string
132
     */
133
    public function compileColumnExists()
134
    {
135
        return "select column_name from user_tab_columns where table_name = upper(?) and column_name = upper(?)";
136
    }
137
138
    /**
139
     * Compile an add column command.
140
     *
141
     * @param  \Illuminate\Database\Schema\Blueprint $blueprint
142
     * @param  \Illuminate\Support\Fluent $command
143
     * @return string
144
     */
145
    public function compileAdd(Blueprint $blueprint, Fluent $command)
146
    {
147
        $columns = implode(', ', $this->getColumns($blueprint));
148
149
        $sql = 'alter table ' . $this->wrapTable($blueprint) . " add ( $columns";
150
151
        $sql .= (string) $this->addPrimaryKeys($blueprint);
152
153
        return $sql .= ' )';
154
    }
155
156
    /**
157
     * Compile a primary key command.
158
     *
159
     * @param  \Illuminate\Database\Schema\Blueprint $blueprint
160
     * @param  \Illuminate\Support\Fluent $command
161
     * @return string
162
     */
163
    public function compilePrimary(Blueprint $blueprint, Fluent $command)
164
    {
165
        $create = $this->getCommandByName($blueprint, 'create');
166
167
        if (is_null($create)) {
168
            $columns = $this->columnize($command->columns);
169
170
            $table = $this->wrapTable($blueprint);
171
172
            return "alter table {$table} add constraint {$command->index} primary key ({$columns})";
173
        }
174
    }
175
176
    /**
177
     * Compile a foreign key command.
178
     *
179
     * @param  \Illuminate\Database\Schema\Blueprint $blueprint
180
     * @param  \Illuminate\Support\Fluent $command
181
     * @return string|void
182
     */
183
    public function compileForeign(Blueprint $blueprint, Fluent $command)
184
    {
185
        $create = $this->getCommandByName($blueprint, 'create');
186
187
        if (is_null($create)) {
188
            $table = $this->wrapTable($blueprint);
189
190
            $on = $this->wrapTable($command->on);
191
192
            // We need to prepare several of the elements of the foreign key definition
193
            // before we can create the SQL, such as wrapping the tables and convert
194
            // an array of columns to comma-delimited strings for the SQL queries.
195
            $columns = $this->columnize($command->columns);
196
197
            $onColumns = $this->columnize((array) $command->references);
198
199
            $sql = "alter table {$table} add constraint {$command->index} ";
200
201
            $sql .= "foreign key ( {$columns} ) references {$on} ( {$onColumns} )";
202
203
            // Once we have the basic foreign key creation statement constructed we can
204
            // build out the syntax for what should happen on an update or delete of
205
            // the affected columns, which will get something like "cascade", etc.
206
            if (! is_null($command->onDelete)) {
207
                $sql .= " on delete {$command->onDelete}";
208
            }
209
210
            return $sql;
211
        }
212
    }
213
214
    /**
215
     * Compile a unique key command.
216
     *
217
     * @param  \Illuminate\Database\Schema\Blueprint $blueprint
218
     * @param  \Illuminate\Support\Fluent $command
219
     * @return string
220
     */
221
    public function compileUnique(Blueprint $blueprint, Fluent $command)
222
    {
223
        return "alter table " . $this->wrapTable($blueprint) . " add constraint {$command->index} unique ( " . $this->columnize($command->columns) . " )";
224
    }
225
226
    /**
227
     * Compile a plain index key command.
228
     *
229
     * @param  \Illuminate\Database\Schema\Blueprint $blueprint
230
     * @param  \Illuminate\Support\Fluent $command
231
     * @return string
232
     */
233
    public function compileIndex(Blueprint $blueprint, Fluent $command)
234
    {
235
        return "create index {$command->index} on " . $this->wrapTable($blueprint) . " ( " . $this->columnize($command->columns) . " )";
236
    }
237
238
    /**
239
     * Compile a drop table command.
240
     *
241
     * @param  \Illuminate\Database\Schema\Blueprint $blueprint
242
     * @param  \Illuminate\Support\Fluent $command
243
     * @return string
244
     */
245
    public function compileDrop(Blueprint $blueprint, Fluent $command)
246
    {
247
        return 'drop table ' . $this->wrapTable($blueprint);
248
    }
249
250
    /**
251
     * Compile a drop table (if exists) command.
252
     *
253
     * @param  \Illuminate\Database\Schema\Blueprint $blueprint
254
     * @param  \Illuminate\Support\Fluent $command
255
     * @return string
256
     */
257
    public function compileDropIfExists(Blueprint $blueprint, Fluent $command)
258
    {
259
        $table = $this->wrapTable($blueprint);
260
261
        return "declare c int;
262
            begin
263
               select count(*) into c from user_tables where table_name = upper('$table');
264
               if c = 1 then
265
                  execute immediate 'drop table $table';
266
               end if;
267
            end;";
268
    }
269
270
    /**
271
     * Compile a drop column command.
272
     *
273
     * @param  \Illuminate\Database\Schema\Blueprint $blueprint
274
     * @param  \Illuminate\Support\Fluent $command
275
     * @return string
276
     */
277
    public function compileDropColumn(Blueprint $blueprint, Fluent $command)
278
    {
279
        $columns = $this->wrapArray($command->columns);
280
281
        $table = $this->wrapTable($blueprint);
282
283
        return 'alter table ' . $table . ' drop ( ' . implode(', ', $columns) . ' )';
284
    }
285
286
    /**
287
     * Compile a drop primary key command.
288
     *
289
     * @param  \Illuminate\Database\Schema\Blueprint $blueprint
290
     * @param  \Illuminate\Support\Fluent $command
291
     * @return string
292
     */
293
    public function compileDropPrimary(Blueprint $blueprint, Fluent $command)
294
    {
295
        return $this->dropConstraint($blueprint, $command, 'primary');
296
    }
297
298
    /**
299
     * @param Blueprint $blueprint
300
     * @param Fluent $command
301
     * @param string $type
302
     * @return string
303
     */
304
    private function dropConstraint(Blueprint $blueprint, Fluent $command, $type)
305
    {
306
        $table = $this->wrapTable($blueprint);
307
        $index = substr($command->index, 0, 30);
308
309
        if ($type === 'index') {
310
            return "drop index {$index}";
311
        }
312
313
        return "alter table {$table} drop constraint {$index}";
314
    }
315
316
    /**
317
     * Compile a drop unique key command.
318
     *
319
     * @param  \Illuminate\Database\Schema\Blueprint $blueprint
320
     * @param  \Illuminate\Support\Fluent $command
321
     * @return string
322
     */
323
    public function compileDropUnique(Blueprint $blueprint, Fluent $command)
324
    {
325
        return $this->dropConstraint($blueprint, $command, 'unique');
326
    }
327
328
    /**
329
     * Compile a drop index command.
330
     *
331
     * @param  \Illuminate\Database\Schema\Blueprint $blueprint
332
     * @param  \Illuminate\Support\Fluent $command
333
     * @return string
334
     */
335
    public function compileDropIndex(Blueprint $blueprint, Fluent $command)
336
    {
337
        return $this->dropConstraint($blueprint, $command, 'index');
338
    }
339
340
    /**
341
     * Compile a drop foreign key command.
342
     *
343
     * @param  \Illuminate\Database\Schema\Blueprint $blueprint
344
     * @param  \Illuminate\Support\Fluent $command
345
     * @return string
346
     */
347
    public function compileDropForeign(Blueprint $blueprint, Fluent $command)
348
    {
349
        return $this->dropConstraint($blueprint, $command, 'foreign');
350
    }
351
352
    /**
353
     * Compile a rename table command.
354
     *
355
     * @param  \Illuminate\Database\Schema\Blueprint $blueprint
356
     * @param  \Illuminate\Support\Fluent $command
357
     * @return string
358
     */
359
    public function compileRename(Blueprint $blueprint, Fluent $command)
360
    {
361
        $from = $this->wrapTable($blueprint);
362
363
        return "alter table {$from} rename to " . $this->wrapTable($command->to);
364
    }
365
366
    /**
367
     * Compile a rename column command.
368
     *
369
     * @param  \Illuminate\Database\Schema\Blueprint $blueprint
370
     * @param  \Illuminate\Support\Fluent $command
371
     * @param  \Illuminate\Database\Connection $connection
372
     * @return array
373
     */
374
    public function compileRenameColumn(Blueprint $blueprint, Fluent $command, Connection $connection)
375
    {
376
        $table = $this->wrapTable($blueprint);
377
378
        $rs    = [];
379
        $rs[0] = 'alter table ' . $table . ' rename column ' . $command->from . ' to ' . $command->to;
380
381
        return (array) $rs;
382
    }
383
384
    /**
385
     * Create the column definition for a char type.
386
     *
387
     * @param  \Illuminate\Support\Fluent $column
388
     * @return string
389
     */
390
    protected function typeChar(Fluent $column)
391
    {
392
        return "char({$column->length})";
393
    }
394
395
    /**
396
     * Create the column definition for a string type.
397
     *
398
     * @param  \Illuminate\Support\Fluent $column
399
     * @return string
400
     */
401
    protected function typeString(Fluent $column)
402
    {
403
        return "varchar2({$column->length})";
404
    }
405
406
    /**
407
     * Create the column definition for a text type.
408
     *
409
     * @param  \Illuminate\Support\Fluent $column
410
     * @return string
411
     */
412
    protected function typeText(Fluent $column)
413
    {
414
        return "clob";
415
    }
416
417
    /**
418
     * Create the column definition for a medium text type.
419
     *
420
     * @param  \Illuminate\Support\Fluent $column
421
     * @return string
422
     */
423
    protected function typeMediumText(Fluent $column)
424
    {
425
        return 'clob';
426
    }
427
428
    /**
429
     * Create the column definition for a long text type.
430
     *
431
     * @param  \Illuminate\Support\Fluent $column
432
     * @return string
433
     */
434
    protected function typeLongText(Fluent $column)
435
    {
436
        return 'clob';
437
    }
438
439
    /**
440
     * Create the column definition for a integer type.
441
     *
442
     * @param  \Illuminate\Support\Fluent $column
443
     * @return string
444
     */
445
    protected function typeInteger(Fluent $column)
446
    {
447
        $length = ($column->length) ? $column->length : 10;
448
449
        return "number({$length},0)";
450
    }
451
452
    /**
453
     * Create the column definition for a integer type.
454
     *
455
     * @param  \Illuminate\Support\Fluent $column
456
     * @return string
457
     */
458
    protected function typeBigInteger(Fluent $column)
459
    {
460
        $length = ($column->length) ? $column->length : 19;
461
462
        return "number({$length},0)";
463
    }
464
465
    /**
466
     * Create the column definition for a medium integer type.
467
     *
468
     * @param  \Illuminate\Support\Fluent $column
469
     * @return string
470
     */
471
    protected function typeMediumInteger(Fluent $column)
472
    {
473
        $length = ($column->length) ? $column->length : 7;
474
475
        return "number({$length},0)";
476
    }
477
478
    /**
479
     * Create the column definition for a small integer type.
480
     *
481
     * @param  \Illuminate\Support\Fluent $column
482
     * @return string
483
     */
484
    protected function typeSmallInteger(Fluent $column)
485
    {
486
        $length = ($column->length) ? $column->length : 5;
487
488
        return "number({$length},0)";
489
    }
490
491
    /**
492
     * Create the column definition for a tiny integer type.
493
     *
494
     * @param  \Illuminate\Support\Fluent $column
495
     * @return string
496
     */
497
    protected function typeTinyInteger(Fluent $column)
498
    {
499
        $length = ($column->length) ? $column->length : 3;
500
501
        return "number({$length},0)";
502
    }
503
504
    /**
505
     * Create the column definition for a float type.
506
     *
507
     * @param  \Illuminate\Support\Fluent $column
508
     * @return string
509
     */
510
    protected function typeFloat(Fluent $column)
511
    {
512
        return "number({$column->total}, {$column->places})";
513
    }
514
515
    /**
516
     * Create the column definition for a double type.
517
     *
518
     * @param  \Illuminate\Support\Fluent $column
519
     * @return string
520
     */
521
    protected function typeDouble(Fluent $column)
522
    {
523
        return "number({$column->total}, {$column->places})";
524
    }
525
526
    /**
527
     * Create the column definition for a decimal type.
528
     *
529
     * @param  \Illuminate\Support\Fluent $column
530
     * @return string
531
     */
532
    protected function typeDecimal(Fluent $column)
533
    {
534
        return "number({$column->total}, {$column->places})";
535
    }
536
537
    /**
538
     * Create the column definition for a boolean type.
539
     *
540
     * @param  \Illuminate\Support\Fluent $column
541
     * @return string
542
     */
543
    protected function typeBoolean(Fluent $column)
544
    {
545
        return "char(1)";
546
    }
547
548
    /**
549
     * Create the column definition for a enum type.
550
     *
551
     * @param  \Illuminate\Support\Fluent $column
552
     * @return string
553
     */
554
    protected function typeEnum(Fluent $column)
555
    {
556
        $length = ($column->length) ? $column->length : 255;
557
558
        return "varchar2({$length})";
559
    }
560
561
    /**
562
     * Create the column definition for a date type.
563
     *
564
     * @param  \Illuminate\Support\Fluent $column
565
     * @return string
566
     */
567
    protected function typeDate(Fluent $column)
568
    {
569
        return 'date';
570
    }
571
572
    /**
573
     * Create the column definition for a date-time type.
574
     *
575
     * @param  \Illuminate\Support\Fluent $column
576
     * @return string
577
     */
578
    protected function typeDateTime(Fluent $column)
579
    {
580
        return 'date';
581
    }
582
583
    /**
584
     * Create the column definition for a time type.
585
     *
586
     * @param  \Illuminate\Support\Fluent $column
587
     * @return string
588
     */
589
    protected function typeTime(Fluent $column)
590
    {
591
        return 'date';
592
    }
593
594
    /**
595
     * Create the column definition for a timestamp type.
596
     *
597
     * @param  \Illuminate\Support\Fluent $column
598
     * @return string
599
     */
600
    protected function typeTimestamp(Fluent $column)
601
    {
602
        return 'timestamp';
603
    }
604
605
    /**
606
     * Create the column definition for a timestamp type with timezone.
607
     *
608
     * @param Fluent $column
609
     * @return string
610
     */
611
    protected function typeTimestampTz(Fluent $column)
612
    {
613
        return 'timestamp with time zone';
614
    }
615
616
    /**
617
     * Create the column definition for a binary type.
618
     *
619
     * @param  \Illuminate\Support\Fluent $column
620
     * @return string
621
     */
622
    protected function typeBinary(Fluent $column)
623
    {
624
        return 'blob';
625
    }
626
627
    /**
628
     * Get the SQL for a nullable column modifier.
629
     *
630
     * @param  \Illuminate\Database\Schema\Blueprint $blueprint
631
     * @param  \Illuminate\Support\Fluent $column
632
     * @return string
633
     */
634
    protected function modifyNullable(Blueprint $blueprint, Fluent $column)
635
    {
636
        // check if field is declared as enum
637
        $enum = "";
638
        if (count((array) $column->allowed)) {
639
            $enum = " check ({$column->name} in ('" . implode("', '", $column->allowed) . "'))";
640
        }
641
642
        $null = $column->nullable ? ' null' : ' not null';
643
        $null .= $enum;
644
645
        if (! is_null($column->default)) {
646
            return " default " . $this->getDefaultValue($column->default) . $null;
647
        }
648
649
        return $null;
650
    }
651
652
    /**
653
     * Get the SQL for a default column modifier.
654
     *
655
     * @param  \Illuminate\Database\Schema\Blueprint $blueprint
656
     * @param  \Illuminate\Support\Fluent $column
657
     * @return string
658
     */
659
    protected function modifyDefault(Blueprint $blueprint, Fluent $column)
660
    {
661
        // implemented @modifyNullable
662
        return "";
663
    }
664
665
    /**
666
     * Get the SQL for an auto-increment column modifier.
667
     *
668
     * @param  \Illuminate\Database\Schema\Blueprint $blueprint
669
     * @param  \Illuminate\Support\Fluent $column
670
     * @return string|null
671
     */
672
    protected function modifyIncrement(Blueprint $blueprint, Fluent $column)
673
    {
674
        if (in_array($column->type, $this->serials) && $column->autoIncrement) {
675
            $blueprint->primary($column->name);
676
        }
677
    }
678
}
679