PostgresGrammarWithRangeTypes::typeDaterange()   A
last analyzed

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
namespace Belamov\PostgresRange;
4
5
use Illuminate\Database\Schema\Blueprint;
6
use Illuminate\Database\Schema\Grammars\PostgresGrammar;
7
use Illuminate\Support\Facades\DB;
8
use Illuminate\Support\Fluent;
9
10
class PostgresGrammarWithRangeTypes extends PostgresGrammar
11
{
12
    /**
13
     * @return string
14
     */
15
    public function typeDaterange(): string
16
    {
17
        return 'daterange';
18
    }
19
20
    /**
21
     * @return string
22
     */
23
    public function typeTsrange(): string
24
    {
25
        return 'tsrange';
26
    }
27
28
    /**
29
     * @return string
30
     */
31
    public function typeTstzrange(): string
32
    {
33
        return 'tstzrange';
34
    }
35
36
    /**
37
     * @return string
38
     */
39
    public function typeNumrange(): string
40
    {
41
        return 'numrange';
42
    }
43
44
    /**
45
     * @return string
46
     */
47
    public function typeInt4range(): string
48
    {
49
        return 'int4range';
50
    }
51
52
    /**
53
     * @return string
54
     */
55
    public function typeInt8range(): string
56
    {
57
        return 'int8range';
58
    }
59
60
    /**
61
     * @return string
62
     */
63
    public function typeTimeRange(): string
64
    {
65
        $this->addTimeRangeType();
66
67
        return config('postgres-range.timerange_typename');
68
    }
69
70
    protected function addTimeRangeType(): void
71
    {
72
        $timeDiffFunctionName = config('postgres-range.timerange_subtype_diff_function_name');
73
        $timeRangeTypeName = config('postgres-range.timerange_typename');
74
75
        DB::statement(
76
            "CREATE OR REPLACE FUNCTION {$timeDiffFunctionName}(x time, y time) RETURNS float8 AS
77
        'SELECT EXTRACT(EPOCH FROM (x - y))' LANGUAGE sql STRICT IMMUTABLE;"
78
        );
79
80
        DB::statement("DO $$
81
        BEGIN
82
            IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = '{$timeRangeTypeName}') THEN
83
                CREATE TYPE {$timeRangeTypeName} AS RANGE (
84
                    subtype = time,
85
                    subtype_diff = {$timeDiffFunctionName}
86
                );
87
            END IF;
88
        END$$;"
89
        );
90
    }
91
92
    public function getFluentCommands(): array
93
    {
94
        return array_merge(parent::getFluentCommands(), ['excludeRangeOverlapping']);
95
    }
96
97
    /**
98
     * @param  Blueprint  $blueprint
99
     * @param  Fluent  $command
100
     * @return string
101
     */
102
    public function compileExcludeRangeOverlapping(Blueprint $blueprint, Fluent $command): ?string
103
    {
104
        if (! $command->range_column) {
105
            return null;
106
        }
107
108
        if (! empty($command->additionalColumns)) {
109
            $this->addBtreeGistExtension();
110
        }
111
112
        return sprintf('alter table %s add exclude using gist (%s %s with &&)',
113
            $this->wrapTable($blueprint),
114
            $this->getAdditionalColumnsForExclude($command->additionalColumns),
0 ignored issues
show
Bug introduced by
$command->additionalColumns of type Illuminate\Support\TValue is incompatible with the type array|null expected by parameter $additionalColumns of Belamov\PostgresRange\Po...onalColumnsForExclude(). ( Ignorable by Annotation )

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

114
            $this->getAdditionalColumnsForExclude(/** @scrutinizer ignore-type */ $command->additionalColumns),
Loading history...
115
            $this->wrap($command->range_column)
116
        );
117
    }
118
119
    protected function addBtreeGistExtension(): void
120
    {
121
        DB::statement('CREATE EXTENSION IF NOT EXISTS btree_gist;');
122
    }
123
124
    private function getAdditionalColumnsForExclude(?array $additionalColumns = []): string
125
    {
126
        if (! is_array($additionalColumns)) {
0 ignored issues
show
introduced by
The condition is_array($additionalColumns) is always true.
Loading history...
127
            return '';
128
        }
129
130
        $columns = '';
131
132
        foreach ($additionalColumns as $additionalColumn) {
133
            $columns .= "$additionalColumn WITH =,";
134
        }
135
136
        return $columns;
137
    }
138
}
139