Passed
Push — master ( 1b2537...c847ff )
by Timon
05:27 queued 02:23
created

Cursor::valid()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 2
eloc 2
nc 2
nop 0
crap 2
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
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
     * @param ResponseInterface $response
119
     */
120 3
    private function addResponse(ResponseInterface $response)
121
    {
122 3
        $this->index = 0;
123 3
        $this->isComplete = $response->getType() === ResponseType::SUCCESS_SEQUENCE;
124 3
        $this->size = \count($response->getData());
125 3
        $this->response = $response;
126 3
    }
127
128
    /**
129
     * @return void
130
     * @throws \Exception
131
     */
132 1
    private function seek(): void
133
    {
134 1
        while ($this->index === $this->size) {
135
            if ($this->isComplete) {
136
                return;
137
            }
138
139
            $this->request();
140
        }
141 1
    }
142
143
    /**
144
     * @return void
145
     * @throws \Exception
146
     */
147
    private function request(): void
148
    {
149
        try {
150
            $response = $this->connection->continueQuery($this->token);
151
            $this->addResponse($response);
152
        } catch (\Exception $e) {
153
            $this->isComplete = true;
154
            $this->close();
155
156
            throw $e;
157
        }
158
    }
159
160
    /**
161
     * @return void
162
     */
163
    private function close(): void
164
    {
165
        if (!$this->isComplete) {
166
            $this->connection->stopQuery($this->token);
167
            $this->isComplete = true;
168
        }
169
170
        $this->index = 0;
171
        $this->size = 0;
172
        $this->response = null;
173
    }
174
}
175