Passed
Pull Request — master (#7)
by Sandro
04:09
created

Statement::fullCount()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
ccs 0
cts 2
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 2
1
<?php
2
/**
3
 * Sandro Keil (https://sandro-keil.de)
4
 *
5
 * @link      http://github.com/sandrokeil/arangodb-php-client for the canonical source repository
6
 * @copyright Copyright (c) 2018-2019 Sandro Keil
7
 * @license   http://github.com/sandrokeil/arangodb-php-client/blob/master/LICENSE.md New BSD License
8
 */
9
10
namespace ArangoDb;
11
12
use ArangoDb\Exception\ServerException;
13
use ArangoDb\Statement\StreamHandler;
14
use ArangoDb\Statement\Statistic;
0 ignored issues
show
Bug introduced by
The type ArangoDb\Statement\Statistic was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
15
use ArangoDb\Statement\StreamHandlerFactoryInterface;
16
use Countable;
17
use Fig\Http\Message\RequestMethodInterface;
18
use Fig\Http\Message\StatusCodeInterface;
19
use Iterator;
20
use Psr\Http\Client\ClientExceptionInterface;
21
use Psr\Http\Client\ClientInterface;
22
use Psr\Http\Message\RequestFactoryInterface;
23
use Psr\Http\Message\RequestInterface;
24
25
final class Statement implements Iterator, Countable
26
{
27
    /**
28
     * @var ClientInterface
29
     */
30
    private $client;
31
32
    /**
33
     * @var RequestFactoryInterface
34
     */
35
    private $requestFactory;
36
37
    /**
38
     * @var RequestInterface
39
     */
40
    private $request;
41
42
    /**
43
     * @var StreamHandler
44
     */
45
    private $stream;
46
47
    /**
48
     * @var StreamHandlerFactoryInterface
49
     */
50
    private $streamHandlerFactory;
51
52
    /**
53
     * Number of HTTP calls that were made to build the cursor result
54
     *
55
     * @var int
56
     */
57
    private $fetches = 0;
58
59
    /**
60
     * Query is executed on first access
61
     *
62
     * @param ClientInterface $client - connection to be used
63
     * @param RequestInterface $request Cursor request
64
     * @param RequestFactoryInterface $requestFactory
65
     * @param StreamHandlerFactoryInterface $streamHandlerFactory
66
     */
67 7
    public function __construct(
68
        ClientInterface $client,
69
        RequestInterface $request,
70
        RequestFactoryInterface $requestFactory,
71
        StreamHandlerFactoryInterface $streamHandlerFactory
72
    ) {
73 7
        $this->client = $client;
74 7
        $this->request = $request;
75 7
        $this->requestFactory = $requestFactory;
76 7
        $this->streamHandlerFactory = $streamHandlerFactory;
77 7
    }
78
79
    /**
80
     * Fetch outstanding results from the server
81
     *
82
     * @return void
83
     * @throws ClientExceptionInterface
84
     */
85 7
    private function fetchOutstanding(): void
86
    {
87 7
        $request = $this->fetches === 0
88 7
            ? $this->request
89 3
            : $this->requestFactory->createRequest(
90 3
                RequestMethodInterface::METHOD_PUT,
91 7
                Url::CURSOR . '/' . $this->stream->cursorId()
92
            );
93
94 7
        $request->getBody()->rewind();
95 7
        $response = $this->client->sendRequest($request);
96
97 7
        $httpStatusCode = $response->getStatusCode();
98
99 7
        if ($httpStatusCode < StatusCodeInterface::STATUS_OK
100 7
            || $httpStatusCode > StatusCodeInterface::STATUS_MULTIPLE_CHOICES
101
        ) {
102
            throw ServerException::with($request, $response);
103
        }
104
105 7
        if ($this->fetches === 0) {
106 7
            $this->stream = $this->streamHandlerFactory->createStreamHandler($response->getBody());
107
        } else {
108 3
            $this->stream->appendStream($response->getBody());
109
        }
110 7
        $this->fetches++;
111 7
    }
112
113
    /**
114
     * Return the current result row depending on entry type
115
     *
116
     * This might issue additional HTTP requests to fetch any outstanding results from the server
117
     *
118
     * @return string|array|object Data
119
     * @throws ClientExceptionInterface
120
     */
121 5
    public function fetchAll()
122
    {
123 5
        while (null === $this->stream || $this->stream->hasMore()) {
124 5
            $this->fetchOutstanding();
125
        }
126
127 5
        return $this->stream->result();
128
    }
129
130
    /**
131
     * Get the total number of results in the cursor.
132
     *
133
     * This might issue additional HTTP requests to fetch any outstanding results from the server.
134
     *
135
     * @return int Total number of results
136
     * @throws ClientExceptionInterface
137
     */
138
    public function count()
139
    {
140
        while ($this->stream->hasMore()) {
141
            $this->fetchOutstanding();
142
        }
143
144
        return $this->stream->count();
145
    }
146
147
    /**
148
     * Rewind the cursor, loads first batch, can be repeated (new cursor will be created)
149
     *
150
     * @return void
151
     * @throws ClientExceptionInterface
152
     */
153 3
    public function rewind()
154
    {
155 3
        $this->fetches = 0;
156 3
        $this->fetchOutstanding();
157 3
    }
158
159
    /**
160
     * Return the current result row depending on entry type
161
     *
162
     * @return string|array|object Data
163
     */
164 3
    public function current()
165
    {
166 3
        return $this->stream->current();
167
    }
168
169 3
    public function key(): int
170
    {
171 3
        return $this->stream->key();
172
    }
173
174 3
    public function next(): void
175
    {
176 3
        $this->stream->next();
177 3
    }
178
179
    /**
180
     * @return bool
181
     * @throws ClientExceptionInterface
182
     */
183 3
    public function valid(): bool
184
    {
185 3
        if (true === $this->stream->valid()) {
186 3
            return true;
187
        }
188
189 3
        if (! $this->stream->hasMore() || $this->stream->cursorId() === null) {
190 3
            return false;
191
        }
192
193
        // need to fetch additional results from the server
194 2
        $this->fetchOutstanding();
195
196 2
        return $this->stream->valid();
197
    }
198
199
    /**
200
     * Returns the warnings issued during query execution
201
     *
202
     * @return array
203
     */
204
    public function warnings(): array
205
    {
206
        return $this->stream->warnings();
207
    }
208
209
    /**
210
     * Returns the number of HTTP calls that were made to build the cursor result
211
     *
212
     * @return int
213
     */
214 7
    public function fetches(): int
215
    {
216 7
        return $this->fetches;
217
    }
218
219
    /**
220
     * Returns cursor id only after first rewind / fetch
221
     *
222
     * @return string
223
     */
224
    public function getId(): ?string
225
    {
226
        return $this->stream->cursorId();
227
    }
228
229
    /**
230
     * Get the full count of the cursor if available. Does not load all data.
231
     *
232
     * @return int Total number of results
233
     */
234
    public function fullCount(): ?int
235
    {
236
        return $this->stream->fullCount();
237
    }
238
239
    /**
240
     * Get the cached attribute for the result set
241
     *
242
     * @return bool Whether or not the query result was served from the AQL query cache
243
     */
244
    public function isCached(): bool
245
    {
246
        return $this->stream->isCached();
247
    }
248
}
249