Passed
Push — extract-store ( d338ce...38a23e )
by Konrad
04:01
created

SPARQLPlusParser::xGroupClause()   B

Complexity

Conditions 7
Paths 10

Size

Total Lines 23
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 7.116

Importance

Changes 0
Metric Value
cc 7
eloc 16
nc 10
nop 1
dl 0
loc 23
ccs 13
cts 15
cp 0.8667
crap 7.116
rs 8.8333
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * This file is part of the sweetrdf/InMemoryStoreSqlite package and licensed under
5
 * the terms of the GPL-3 license.
6
 *
7
 * (c) Konrad Abicht <[email protected]>
8
 * (c) Benjamin Nowack
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace sweetrdf\InMemoryStoreSqlite\Parser;
15
16
class SPARQLPlusParser extends SPARQLParser
17
{
18
    /* +1 */
19
20 85
    protected function xQuery($v)
21
    {
22 85
        list($r, $v) = $this->xPrologue($v);
23 85
        foreach (['Select', 'Construct', 'Describe', 'Ask', 'Insert', 'Delete', 'Load'] as $type) {
24 85
            $m = 'x'.$type.'Query';
25 85
            if ((list($r, $v) = $this->$m($v)) && $r) {
26 84
                return [$r, $v];
27
            }
28
        }
29
30 3
        return [0, $v];
31
    }
32
33
    /* +3 */
34
35 39
    protected function xResultVar($v)
36
    {
37 39
        $aggregate = '';
38
        /* aggregate */
39 39
        if ($sub_r = $this->x('\(?(AVG|COUNT|MAX|MIN|SUM)\s*\(\s*([^\)]+)\)\s+AS\s+([^\s\)]+)\)?', $v)) {
40 10
            $aggregate = $sub_r[1];
41 10
            $result_var = $sub_r[3];
42 10
            $v = $sub_r[2].$sub_r[4];
43
        }
44 39
        if ($sub_r && (list($sub_r, $sub_v) = $this->xVar($result_var)) && $sub_r) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $result_var does not seem to be defined for all execution paths leading up to this point.
Loading history...
45 10
            $result_var = $sub_r['value'];
46
        }
47
        /* * or var */
48 39
        if ((list($sub_r, $sub_v) = $this->x('\*', $v)) && $sub_r) {
49 2
            return [['var' => '*', 'aggregate' => $aggregate, 'alias' => $aggregate ? $result_var : ''], $sub_v];
50
        }
51 39
        if ((list($sub_r, $sub_v) = $this->xVar($v)) && $sub_r) {
52 36
            return [['var' => $sub_r['value'], 'aggregate' => $aggregate, 'alias' => $aggregate ? $result_var : ''], $sub_v];
53
        }
54
55 39
        return [0, $v];
56
    }
57
58
    /* +4 */
59
60 3
    protected function xLoadQuery($v)
61
    {
62 3
        if ($sub_r = $this->x('LOAD\s+', $v)) {
63
            $sub_v = $sub_r[1];
64
            if ((list($sub_r, $sub_v) = $this->xIRIref($sub_v)) && $sub_r) {
65
                $r = ['type' => 'load', 'url' => $sub_r, 'target_graph' => ''];
66
67
                return [$r, $sub_v];
68
            }
69
        }
70
71 3
        return [0, $v];
72
    }
73
74
    /* +5 */
75
76 74
    protected function xInsertQuery($v)
77
    {
78 74
        if ($sub_r = $this->x('INSERT\s+', $v)) {
79 74
            $r = [
80
                'type' => 'insert',
81
                'dataset' => [],
82
            ];
83 74
            $sub_v = $sub_r[1];
84
            /* target */
85 74
            if ($sub_r = $this->x('INTO\s+', $sub_v)) {
86 74
                $sub_v = $sub_r[1];
87 74
                if ((list($sub_r, $sub_v) = $this->xIRIref($sub_v)) && $sub_r) {
88 74
                    $r['target_graph'] = $sub_r;
89
                    /* CONSTRUCT keyword, optional */
90 74
                    if ($sub_r = $this->x('CONSTRUCT\s+', $sub_v)) {
91 1
                        $sub_v = $sub_r[1];
92
                    }
93
                    /* construct template */
94 74
                    if ((list($sub_r, $sub_v) = $this->xConstructTemplate($sub_v)) && \is_array($sub_r)) {
95 73
                        $r['construct_triples'] = $sub_r;
96
                    } else {
97 1
                        $this->logger->error('Construct Template not found');
98
99 1
                        return [0, $v];
100
                    }
101
                    /* dataset */
102 73
                    while ((list($sub_r, $sub_v) = $this->xDatasetClause($sub_v)) && $sub_r) {
103
                        $r['dataset'][] = $sub_r;
104
                    }
105
                    /* where */
106 73
                    if ((list($sub_r, $sub_v) = $this->xWhereClause($sub_v)) && $sub_r) {
107
                        $r['pattern'] = $sub_r;
108
                    }
109
                    /* solution modifier */
110 73
                    if ((list($sub_r, $sub_v) = $this->xSolutionModifier($sub_v)) && $sub_r) {
111
                        $r = array_merge($r, $sub_r);
112
                    }
113
114 73
                    return [$r, $sub_v];
115
                }
116
            }
117
        }
118
119 10
        return [0, $v];
120
    }
121
122
    /* +6 */
123
124 11
    protected function xDeleteQuery($v): array
125
    {
126 11
        if ($sub_r = $this->x('DELETE\s+', $v)) {
127 8
            $r = [
128
                'type' => 'delete',
129
                'target_graphs' => [],
130
            ];
131 8
            $sub_v = $sub_r[1];
132
            /* target */
133
            do {
134 8
                $proceed = false;
135 8
                if ($sub_r = $this->x('FROM\s+', $sub_v)) {
136 5
                    $sub_v = $sub_r[1];
137 5
                    if ((list($sub_r, $sub_v) = $this->xIRIref($sub_v)) && $sub_r) {
138 5
                        $r['target_graphs'][] = $sub_r;
139 5
                        $proceed = 1;
140
                    }
141
                }
142 8
            } while ($proceed);
0 ignored issues
show
Bug Best Practice introduced by
The expression $proceed of type false|integer is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
143
            /* CONSTRUCT keyword, optional */
144 8
            if ($sub_r = $this->x('CONSTRUCT\s+', $sub_v)) {
145
                $sub_v = $sub_r[1];
146
            }
147
            /* construct template */
148 8
            if ((list($sub_r, $sub_v) = $this->xConstructTemplate($sub_v)) && \is_array($sub_r)) {
149 4
                $r['construct_triples'] = $sub_r;
150
                /* dataset */
151 4
                while ((list($sub_r, $sub_v) = $this->xDatasetClause($sub_v)) && $sub_r) {
152
                    $r['dataset'][] = $sub_r;
153
                }
154
                /* where */
155 4
                if ((list($sub_r, $sub_v) = $this->xWhereClause($sub_v)) && $sub_r) {
156 2
                    $r['pattern'] = $sub_r;
157
                }
158
                /* solution modifier */
159 4
                if ((list($sub_r, $sub_v) = $this->xSolutionModifier($sub_v)) && $sub_r) {
160
                    $r = array_merge($r, $sub_r);
161
                }
162
            }
163
164 8
            return [$r, $sub_v];
165
        }
166
167 3
        return [0, $v];
168
    }
169
170
    /* +7 */
171
172 84
    protected function xSolutionModifier($v): array
173
    {
174 84
        $r = [];
175 84
        if ((list($sub_r, $sub_v) = $this->xGroupClause($v)) && $sub_r) {
176 5
            $r['group_infos'] = $sub_r;
177
        }
178 84
        if ((list($sub_r, $sub_v) = $this->xOrderClause($sub_v)) && $sub_r) {
179 4
            $r['order_infos'] = $sub_r;
180
        }
181 84
        while ((list($sub_r, $sub_v) = $this->xLimitOrOffsetClause($sub_v)) && $sub_r) {
182 3
            $r = array_merge($r, $sub_r);
183
        }
184
185 84
        return ($v == $sub_v) ? [0, $v] : [$r, $sub_v];
186
    }
187
188
    /* +8 */
189
190 84
    protected function xGroupClause($v): array
191
    {
192 84
        if ($sub_r = $this->x('GROUP BY\s+', $v)) {
193 5
            $sub_v = $sub_r[1];
194 5
            $r = [];
195
            do {
196 5
                $proceed = 0;
197 5
                if ((list($sub_r, $sub_v) = $this->xVar($sub_v)) && $sub_r) {
198 5
                    $r[] = $sub_r;
199 5
                    $proceed = 1;
200 5
                    if ($sub_r = $this->x('\,', $sub_v)) {
201
                        $sub_v = $sub_r[1];
202
                    }
203
                }
204 5
            } while ($proceed);
205 5
            if (\count($r)) {
206 5
                return [$r, $sub_v];
207
            } else {
208
                $this->logger->error('No columns specified in GROUP BY clause.');
209
            }
210
        }
211
212 84
        return [0, $v];
213
    }
214
}
215