Passed
Push — next ( d68df8...ee030a )
by Bas
03:07
created

Statement::handleQueryResults()   A

Complexity

Conditions 4
Paths 8

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 4

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 7
c 1
b 0
f 0
nc 8
nop 1
dl 0
loc 12
ccs 8
cts 8
cp 1
crap 4
rs 10
1
<?php
2
3
namespace ArangoClient;
4
5
use Generator;
6
7
/**
8
 * Executes queries on ArangoDB
9
 *
10
 * @see https://www.arangodb.com/docs/stable/http/aql-query-cursor.html
11
 *
12
 * @package ArangoClient
13
 */
14
class Statement extends Manager
15
{
16
    protected ArangoClient $arangoClient;
17
18
    protected string $query;
19
20
    /**
21
     * @var array<scalar>
22
     */
23
    protected array $bindVars = [];
24
25
    /**
26
     * @var array<array>
27
     */
28
    protected array $collections = [];
29
30
    /**
31
     * @var array<scalar>
32
     */
33
    protected array $options = [];
34
35
    /**
36
     * @var array<mixed>
37
     */
38
    protected array $queryResults = [];
39
40
    /**
41
     * @var array<mixed>
42
     */
43
    protected array $queryStatistics = [];
44
45
    /**
46
     * @var array<mixed>
47
     */
48
    protected array $queryWarnings = [];
49
50
    /**
51
     * @var array<mixed>
52
     */
53
    protected array $cursor = [];
54
55
    /**
56
     * Statement constructor.
57
     * @param  ArangoClient  $arangoClient
58
     * @param  string  $query
59
     * @param  array<scalar>  $bindVars
60
     * @param  array<array>  $collections
61
     * @param  array<scalar>  $options
62
     */
63 7
    public function __construct(
64
        ArangoClient $arangoClient,
65
        string $query,
66
        array $bindVars = [],
67
        array $collections = [],
68
        array $options = []
69
    ) {
70 7
        $this->arangoClient = $arangoClient;
71 7
        $this->query = $query;
72 7
        $this->bindVars = $bindVars;
73 7
        $this->collections = $collections;
74 7
        $this->options = $options;
75 7
    }
76
77
    /**
78
     * @return bool
79
     * @throws Exceptions\ArangoException
80
     */
81 3
    public function execute(): bool
82
    {
83 3
        $this->queryResults = [];
84
85 3
        $bodyContent = $this->prepareQueryBodyContent();
86 3
        $body = $this->arangoClient->jsonEncode($bodyContent);
87
88 3
        $results = $this->arangoClient->request('post', '/_api/cursor', ['body' => $body]);
89
90 3
        $this->handleQueryResults($results);
91
92 3
        $this->requestOutstandingResults($body);
93
94 3
        return ! $results['error'];
95
    }
96
97
    /**
98
     * @return array<mixed>
99
     */
100 5
    protected function prepareQueryBodyContent(): array
101
    {
102 5
        $bodyContent = $this->options;
103 5
        $bodyContent['query'] = $this->query;
104 5
        $bodyContent['bindVars'] = $this->bindVars;
105 5
        $bodyContent['collections'] = $this->collections;
106
107 5
        return $bodyContent;
108
    }
109
110
    /**
111
     * @param  array<mixed>  $results
112
     */
113 3
    protected function handleQueryResults(array $results): void
114
    {
115 3
        $this->queryResults = array_merge($this->queryResults, (array) $results['result']);
116
117 3
        if (isset($results['extra']['stats'])) {
118 3
            $this->queryStatistics = (array)((array)$results['extra'])['stats'];
119
        }
120 3
        if (isset($results['extra']['warnings'])) {
121 3
            $this->queryWarnings = (array) ((array)$results['extra'])['warnings'];
122
        }
123 3
        $this->cursor['hasMore'] = (bool) $results['hasMore'];
124 3
        $this->cursor['id'] = $results['hasMore'] ?  $results['id'] : null;
125 3
    }
126
127
    /**
128
     * @param  string  $body
129
     * @throws Exceptions\ArangoException
130
     */
131 3
    public function requestOutstandingResults(string $body): void
132
    {
133 3
        while ($this->cursor['hasMore']) {
134 1
            $uri = '/_api/cursor/' . (string) $this->cursor['id'];
135
136 1
            $results = $this->arangoClient->request('put', $uri, ['body' => $body]);
137
138 1
            $this->handleQueryResults($results);
139
        }
140 3
    }
141
142
    /**
143
     * @return array<mixed>
144
     * @throws Exceptions\ArangoException
145
     */
146 1
    public function explain(): array
147
    {
148 1
        $bodyContent = $this->prepareQueryBodyContent();
149 1
        $body = $this->arangoClient->jsonEncode($bodyContent);
150
151 1
        $results = $this->arangoClient->request('post', '/_api/explain', ['body' => $body]);
152
153 1
        return $this->sanitizeRequestMetadata($results);
154
    }
155
156
    /**
157
     * @return array<mixed>
158
     * @throws Exceptions\ArangoException
159
     */
160 1
    public function parse(): array
161
    {
162 1
        $bodyContent = $this->prepareQueryBodyContent();
163 1
        $body = $this->arangoClient->jsonEncode($bodyContent);
164
165 1
        $results = $this->arangoClient->request('post', '/_api/query', ['body' => $body]);
166
167 1
        return $this->sanitizeRequestMetadata($results);
168
    }
169
170
    /**
171
     * @param  string  $query
172
     * @return Statement
173
     */
174 2
    public function setQuery(string $query): self
175
    {
176 2
        $this->query = $query;
177
178 2
        return $this;
179
    }
180
181
    /**
182
     * @return string
183
     */
184 1
    public function getQuery(): string
185
    {
186 1
        return $this->query;
187
    }
188
189
    // phpmd barfs on the return yield from lin
190
//    /**
191
//     * @return Generator<mixed>
192
//     */
193
//    public function fetch(): Generator
194
//    {
195
//        return yield from $this->queryResults;
196
//    }
197
198
    /**
199
     * @return array<mixed>
200
     */
201 2
    public function fetchAll(): array
202
    {
203 2
        return $this->queryResults;
204
    }
205
}
206