Passed
Push — master ( 9fe3b0...ea33af )
by belamov
02:37 queued 21s
created

PostgresGrammarWithRangeTypes::typeInt4range()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 1
b 0
f 0
1
<?php
2
3
4
namespace Belamov\PostgresRange;
5
6
7
use Illuminate\Database\Schema\Blueprint;
8
use Illuminate\Database\Schema\Grammars\PostgresGrammar;
9
use Illuminate\Support\Facades\DB;
10
use Illuminate\Support\Fluent;
11
12
class PostgresGrammarWithRangeTypes extends PostgresGrammar
13
{
14
    protected string $timeRangeTypeName = 'timerange';
15
    protected string $timeDiffFunctionName = 'time_subtype_diff';
16
17
    /**
18
     * @return string
19
     */
20
    public function typeDaterange(): string
21
    {
22
        return 'daterange';
23
    }
24
25
    /**
26
     * @return string
27
     */
28
    public function typeTsrange(): string
29
    {
30
        return 'tsrange';
31
    }
32
33
    /**
34
     * @return string
35
     */
36
    public function typeNumrange(): string
37
    {
38
        return 'numrange';
39
    }
40
41
    /**
42
     * @return string
43
     */
44
    public function typeInt4range(): string
45
    {
46
        return 'int4range';
47
    }
48
49
    /**
50
     * @return string
51
     */
52
    public function typeInt8range(): string
53
    {
54
        return 'int8range';
55
    }
56
57
    /**
58
     * @return string
59
     */
60
    public function typeTimeRange(): string
61
    {
62
        $this->addTimeRangeType();
63
        return 'timerange';
64
    }
65
66
    protected function addTimeRangeType(): void
67
    {
68
        DB::statement(
69
            "CREATE OR REPLACE FUNCTION {$this->timeDiffFunctionName}(x time, y time) RETURNS float8 AS
70
        'SELECT EXTRACT(EPOCH FROM (x - y))' LANGUAGE sql STRICT IMMUTABLE;"
71
        );
72
73
        DB::statement("DO $$
74
        BEGIN
75
            IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = '{$this->timeRangeTypeName}') THEN
76
                CREATE TYPE {$this->timeRangeTypeName} AS RANGE (
77
                    subtype = time,
78
                    subtype_diff = {$this->timeDiffFunctionName}
79
                );
80
            END IF;
81
        END$$;"
82
        );
83
    }
84
85
    public function getFluentCommands(): array
86
    {
87
        return array_merge(parent::getFluentCommands(), ['uniqueRange']);
88
    }
89
90
    /**
91
     * @param  Blueprint  $blueprint
92
     * @param  Fluent  $command
93
     * @return string
94
     */
95
    public function compileUniqueRange(Blueprint $blueprint, Fluent $command): string
96
    {
97
        if (!empty($command->additionalColumns)) {
98
            $this->addBtreeGistExtension();
99
        }
100
101
        return sprintf('alter table %s add exclude using gist (%s %s with &&)',
102
            $this->wrapTable($blueprint),
103
            $this->getAdditionalColumnsForExclude($command->additionalColumns),
0 ignored issues
show
Bug introduced by
It seems like $command->additionalColumns can also be of type null; however, parameter $additionalColumns of Belamov\PostgresRange\Po...onalColumnsForExclude() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

103
            $this->getAdditionalColumnsForExclude(/** @scrutinizer ignore-type */ $command->additionalColumns),
Loading history...
104
            $this->wrap($command->column)
105
        );
106
    }
107
108
    protected function addBtreeGistExtension(): void
109
    {
110
        DB::statement('CREATE EXTENSION IF NOT EXISTS btree_gist;');
111
    }
112
113
    /**
114
     * @param  array  $additionalColumns
115
     * @return string
116
     */
117
    private function getAdditionalColumnsForExclude(array $additionalColumns): string
118
    {
119
        $columns = '';
120
121
        foreach ($additionalColumns as $additionalColumn) {
122
            $columns .= "{$additionalColumn} WITH =,";
123
        }
124
125
        return $columns;
126
    }
127
}