Passed
Pull Request — master (#34)
by Marc
05:44
created

Cursor::request()   A

Complexity

Conditions 2
Paths 3

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 9.4285
c 0
b 0
f 0
ccs 0
cts 3
cp 0
cc 2
eloc 7
nc 3
nop 0
crap 6
1
<?php
2
declare(strict_types = 1);
3
4
namespace TBolier\RethinkQL\Response;
5
6
use TBolier\RethinkQL\Connection\ConnectionCursorInterface;
7
use TBolier\RethinkQL\Connection\ConnectionException;
8
use TBolier\RethinkQL\Message\MessageInterface;
9
use TBolier\RethinkQL\Types\Response\ResponseType;
10
11
class Cursor implements \Iterator, \Countable
12
{
13
    /**
14
     * @var ConnectionCursorInterface
15
     */
16
    private $connection;
17
    /**
18
     * @var int
19
     */
20
    private $index;
21
    /**
22
     * @var bool
23
     */
24
    private $isComplete;
25
    /**
26
     * @var MessageInterface
27
     */
28
    private $message;
29
    /**
30
     * @var ResponseInterface
31
     */
32
    private $response;
33
    /**
34
     * @var int
35
     */
36
    private $size;
37
    /**
38
     * @var int
39
     */
40
    private $token;
41
42
    /**
43
     * @param ConnectionCursorInterface $connection
44
     * @param int $token
45
     * @param ResponseInterface $response
46
     * @param MessageInterface $message
47
     */
48 3
    public function __construct(
49
        ConnectionCursorInterface $connection,
50
        int $token,
51
        ResponseInterface $response,
52
        MessageInterface $message
53
    ) {
54 3
        $this->connection = $connection;
55 3
        $this->token = $token;
56 3
        $this->addResponse($response);
57 3
        $this->message = $message;
58 3
    }
59
60
    /**
61
     * @inheritdoc
62
     * @throws \Exception
63
     */
64 1
    public function current()
65
    {
66 1
        $this->seek();
67
68 1
        if (!$this->valid()) {
69
            return;
70
        }
71
72 1
        if ($this->response->isAtomic()) {
73 1
            return $this->response->getData();
74
        }
75
76
        return $this->response->getData()[$this->index];
77
    }
78
79
    /**
80
     * @inheritdoc
81
     * @throws \Exception
82
     */
83
    public function next(): void
84
    {
85
        $this->index++;
86
87
        $this->seek();
88
    }
89
90
    /**
91
     * @inheritdoc
92
     */
93
    public function key(): int
94
    {
95
        return $this->index;
96
    }
97
98
    /**
99
     * @inheritdoc
100
     */
101 1
    public function valid(): bool
102
    {
103 1
        return (!$this->isComplete || ($this->index < $this->size));
104
    }
105
106
    /**
107
     * @inheritdoc
108
     * @throws ConnectionException
109
     */
110
    public function rewind(): void
111
    {
112
        $this->close();
113
114
        $this->addResponse($this->connection->rewindFromCursor($this->message));
115
    }
116
117
    /**
118
     * @inheritdoc
119
     */
120 3
    public function count()
121
    {
122 3
        return $this->size;
123 3
    }
124 3
125 3
    /**
126 3
     * @param ResponseInterface $response
127
     */
128
    private function addResponse(ResponseInterface $response)
129
    {
130
        $this->index = 0;
131
        $this->isComplete = $response->getType() === ResponseType::SUCCESS_SEQUENCE;
132 1
        $this->size = $response->isAtomic() ? 1 : \count($response->getData());
133
        $this->response = $response;
134 1
    }
135
136
    /**
137
     * @return void
138
     * @throws \Exception
139
     */
140
    private function seek(): void
141 1
    {
142
        while ($this->index === $this->size) {
143
            if ($this->isComplete) {
144
                return;
145
            }
146
147
            $this->request();
148
        }
149
    }
150
151
    /**
152
     * @return void
153
     * @throws \Exception
154
     */
155
    private function request(): void
156
    {
157
        try {
158
            $response = $this->connection->continueQuery($this->token);
159
            $this->addResponse($response);
160
        } catch (\Exception $e) {
161
            $this->isComplete = true;
162
            $this->close();
163
164
            throw $e;
165
        }
166
    }
167
168
    /**
169
     * @return void
170
     */
171
    private function close(): void
172
    {
173
        if (!$this->isComplete) {
174
            $this->connection->stopQuery($this->token);
175
            $this->isComplete = true;
176
        }
177
178
        $this->index = 0;
179
        $this->size = 0;
180
        $this->response = null;
181
    }
182
}
183