Completed
Push — 5.3 ( 4ca8c4...dd3aaa )
by Arjay
04:56
created

OracleGrammar::compileTableExists()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
742
    {
743 177
        if ($this->isReserved($value)) {
744 3
            return parent::wrapValue($value);
745
        }
746
747 177
        return $value !== '*' ? sprintf($this->wrapper, $value) : $value;
748
    }
749
}
750