Issues (57)

src/Response/Cursor.php (1 issue)

Severity
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
    public function __construct(
43
        ConnectionCursorInterface $connection,
44
        int $token,
45
        ResponseInterface $response,
46
        MessageInterface $message
47
    ) {
48 3
        $this->connection = $connection;
49
        $this->token = $token;
50
        $this->addResponse($response);
51
        $this->message = $message;
52
    }
53
54 3
    /**
55 3
     * @throws \Exception
56 3
     */
57 3
    public function current()
58 3
    {
59
        $this->seek();
60
61
        if (!$this->valid()) {
62
            return;
63
        }
64 1
65
        if ($this->response->isAtomic()) {
66 1
            return $this->response->getData();
67
        }
68 1
69
        return $this->response->getData()[$this->index];
70
    }
71
72 1
    /**
73 1
     * @throws \Exception
74
     */
75
    public function next(): void
76
    {
77
        $this->index++;
78
79
        $this->seek();
80
    }
81
82
    public function key(): int
83
    {
84
        return $this->index;
85
    }
86
87
    public function valid(): bool
88
    {
89
        return (!$this->isComplete || ($this->index < $this->size));
90
    }
91
92
    /**
93
     * @throws ConnectionException
94
     */
95
    public function rewind(): void
96
    {
97
        if ($this->index === 0) {
98
            return;
99
        }
100
101 1
        $this->close();
102
        $this->addResponse($this->connection->rewindFromCursor($this->message));
103 1
    }
104
105
    public function count()
106
    {
107
        return $this->size;
108
    }
109
110
    private function addResponse(ResponseInterface $response)
111
    {
112
        $this->index = 0;
113
        $this->isComplete = $response->getType() === ResponseType::SUCCESS_SEQUENCE;
114
115
        if (\is_null($response->getData())) {
0 ignored issues
show
The condition is_null($response->getData()) is always false.
Loading history...
116
            $this->size = 0;
117
        } else {
118
            $this->size = $response->isAtomic() ? 1 : \count($response->getData());
119
        }
120 3
121
        $this->response = $response;
122 3
    }
123 3
124 3
    /**
125 3
     * @throws \Exception
126 3
     */
127
    private function seek(): void
128
    {
129
        if ($this->index >= $this->size && !$this->isComplete) {
130
            $this->request();
131
        }
132 1
    }
133
134 1
    /**
135
     * @throws \Exception
136
     */
137
    private function request(): void
138
    {
139
        try {
140
            $response = $this->connection->continueQuery($this->token);
141 1
            $this->addResponse($response);
142
        } catch (\Exception $e) {
143
            $this->isComplete = true;
144
            $this->close();
145
146
            throw $e;
147
        }
148
    }
149
150
    private function close(): void
151
    {
152
        if (!$this->isComplete) {
153
            $this->connection->stopQuery($this->token);
154
            $this->isComplete = true;
155
        }
156
157
        $this->index = 0;
158
        $this->size = 0;
159
        $this->response = null;
160
    }
161
}
162