Passed
Push — master ( ec5f0a...0a099d )
by belamov
02:17
created

PostgresGrammarWithRangeTypes::typeDaterange()   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
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 typeNumrange(): string
32
    {
33
        return 'numrange';
34
    }
35
36
    /**
37
     * @return string
38
     */
39
    public function typeInt4range(): string
40
    {
41
        return 'int4range';
42
    }
43
44
    /**
45
     * @return string
46
     */
47
    public function typeInt8range(): string
48
    {
49
        return 'int8range';
50
    }
51
52
    /**
53
     * @return string
54
     */
55
    public function typeTimeRange(): string
56
    {
57
        $this->addTimeRangeType();
58
59
        return config('postgres-range.timerange_typename');
60
    }
61
62
    protected function addTimeRangeType(): void
63
    {
64
        $timeDiffFunctionName = config('postgres-range.timerange_subtype_diff_function_name');
65
        $timeRangeTypeName = config('postgres-range.timerange_typename');
66
67
        DB::statement(
68
            "CREATE OR REPLACE FUNCTION {$timeDiffFunctionName}(x time, y time) RETURNS float8 AS
69
        'SELECT EXTRACT(EPOCH FROM (x - y))' LANGUAGE sql STRICT IMMUTABLE;"
70
        );
71
72
        DB::statement("DO $$
73
        BEGIN
74
            IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = '{$timeRangeTypeName}') THEN
75
                CREATE TYPE {$timeRangeTypeName} AS RANGE (
76
                    subtype = time,
77
                    subtype_diff = {$timeDiffFunctionName}
78
                );
79
            END IF;
80
        END$$;"
81
        );
82
    }
83
84
    public function getFluentCommands(): array
85
    {
86
        return array_merge(parent::getFluentCommands(), ['excludeRangeOverlapping']);
87
    }
88
89
    /**
90
     * @param  Blueprint  $blueprint
91
     * @param  Fluent  $command
92
     * @return string
93
     */
94
    public function compileExcludeRangeOverlapping(Blueprint $blueprint, Fluent $command): string
95
    {
96
        if (! empty($command->additionalColumns)) {
97
            $this->addBtreeGistExtension();
98
        }
99
100
        return sprintf('alter table %s add exclude using gist (%s %s with &&)',
101
            $this->wrapTable($blueprint),
102
            $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

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