1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* This file is part of the sweetrdf/InMemoryStoreSqlite package and licensed under |
5
|
|
|
* the terms of the GPL-2 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\Store\QueryHandler; |
15
|
|
|
|
16
|
|
|
class DescribeQueryHandler extends SelectQueryHandler |
17
|
|
|
{ |
18
|
|
|
private array $added_triples; |
19
|
|
|
private array $described_ids; |
20
|
|
|
private array $ids; |
21
|
|
|
private array $r; |
22
|
|
|
|
23
|
3 |
|
public function runQuery($infos) |
24
|
|
|
{ |
25
|
3 |
|
$ids = $infos['query']['result_uris']; |
26
|
3 |
|
if ($vars = $infos['query']['result_vars']) { |
27
|
2 |
|
$sub_r = parent::runQuery($infos); |
28
|
2 |
|
$rf = $infos['result_format'] ?? ''; |
29
|
2 |
|
if (\in_array($rf, ['sql', 'structure', 'index'])) { |
30
|
|
|
return $sub_r; |
31
|
|
|
} |
32
|
2 |
|
$rows = $sub_r['rows'] ?? []; |
33
|
2 |
|
foreach ($rows as $row) { |
34
|
2 |
|
foreach ($vars as $info) { |
35
|
2 |
|
$val = isset($row[$info['var']]) ? $row[$info['var']] : ''; |
36
|
|
|
if ( |
37
|
2 |
|
$val |
38
|
2 |
|
&& ('literal' != $row[$info['var'].' type']) && !\in_array($val, $ids) |
39
|
|
|
) { |
40
|
2 |
|
$ids[] = $val; |
41
|
|
|
} |
42
|
|
|
} |
43
|
|
|
} |
44
|
|
|
} |
45
|
3 |
|
$this->r = []; |
46
|
3 |
|
$this->described_ids = []; |
47
|
3 |
|
$this->ids = $ids; |
48
|
3 |
|
$this->added_triples = []; |
49
|
3 |
|
$is_sub_describe = 0; |
50
|
3 |
|
while ($this->ids) { |
|
|
|
|
51
|
3 |
|
$id = $this->ids[0]; |
52
|
3 |
|
$this->described_ids[] = $id; |
53
|
3 |
|
$q = 'CONSTRUCT { <'.$id.'> ?p ?o . } WHERE {<'.$id.'> ?p ?o .}'; |
54
|
3 |
|
$sub_r = $this->store->query($q); |
55
|
3 |
|
$sub_index = \is_array($sub_r['result']) ? $sub_r['result'] : []; |
56
|
3 |
|
$this->mergeSubResults($sub_index, $is_sub_describe); |
57
|
3 |
|
$is_sub_describe = 1; |
58
|
|
|
} |
59
|
|
|
|
60
|
3 |
|
return $this->r; |
61
|
|
|
} |
62
|
|
|
|
63
|
3 |
|
private function mergeSubResults($index, $is_sub_describe = 1) |
64
|
|
|
{ |
65
|
3 |
|
foreach ($index as $s => $ps) { |
66
|
3 |
|
if (!isset($this->r[$s])) { |
67
|
3 |
|
$this->r[$s] = []; |
68
|
|
|
} |
69
|
3 |
|
foreach ($ps as $p => $os) { |
70
|
3 |
|
if (!isset($this->r[$s][$p])) { |
71
|
3 |
|
$this->r[$s][$p] = []; |
72
|
|
|
} |
73
|
3 |
|
foreach ($os as $o) { |
74
|
3 |
|
$id = md5($s.' '.$p.' '.serialize($o)); |
75
|
3 |
|
if (!isset($this->added_triples[$id])) { |
76
|
3 |
|
if (1 || !$is_sub_describe) { |
77
|
3 |
|
$this->r[$s][$p][] = $o; |
78
|
3 |
|
if (\is_array($o) && ('bnode' == $o['type']) && !\in_array($o['value'], $this->ids)) { |
79
|
3 |
|
$this->ids[] = $o['value']; |
80
|
|
|
} |
81
|
|
|
} elseif (!\is_array($o) || ('bnode' != $o['type'])) { |
82
|
|
|
$this->r[$s][$p][] = $o; |
83
|
|
|
} |
84
|
3 |
|
$this->added_triples[$id] = 1; |
85
|
|
|
} |
86
|
|
|
} |
87
|
|
|
} |
88
|
|
|
} |
89
|
|
|
/* adjust ids */ |
90
|
3 |
|
$ids = $this->ids; |
91
|
3 |
|
$this->ids = []; |
92
|
3 |
|
foreach ($ids as $id) { |
93
|
3 |
|
if (!\in_array($id, $this->described_ids)) { |
94
|
1 |
|
$this->ids[] = $id; |
95
|
|
|
} |
96
|
|
|
} |
97
|
|
|
} |
98
|
|
|
} |
99
|
|
|
|
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.