Passed
Push — master ( 9302c9...f08430 )
by Dawid
02:34
created

Cursor::hydrateWith()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace Igni\Storage\Driver\MongoDB;
4
5
use Igni\Storage\Driver\MemorySavingCursor;
6
use Igni\Storage\Hydration\MemorySavingHydrator;
7
use Igni\Storage\EntityManager;
8
use MongoDB\Driver\Command;
9
use Igni\Storage\Storable;
10
use Igni\Storage\Exception\CursorException;
11
use Igni\Storage\Hydration\ObjectHydrator;
12
use IteratorIterator;
13
14
class Cursor implements MemorySavingCursor
15
{
16
    /** @var Connection  */
17
    private $connection;
18
    /** @var Command */
19
    private $command;
20
    /** @var ObjectHydrator */
21
    private $hydrator;
22
    /** @var \MongoDB\Driver\Cursor */
23
    private $baseCursor;
24
    /** @var ConnectionOptions */
25
    private $options;
26
    /** @var Storable|object|array|null */
27
    private $current = null;
28
    /** @var  IteratorIterator */
29
    private $iterator;
30
    /** @var EntityManager */
31
    private $manager;
0 ignored issues
show
introduced by
The private property $manager is not used, and could be removed.
Loading history...
32
    /** @var bool */
33
    private $saveMemory = false;
0 ignored issues
show
introduced by
The private property $saveMemory is not used, and could be removed.
Loading history...
34
35 39
    public function __construct(
36
        Connection $connection,
37
        ConnectionOptions $options,
38
        Command $command
39
    ) {
40 39
        $this->connection = $connection;
41 39
        $this->command = $command;
42 39
        $this->options = $options;
43 39
    }
44
45
    public function getId(): string
46
    {
47
        return (string) $this->baseCursor->getId();
48
    }
49
50
    public function getBaseCursor(): \MongoDB\Driver\Cursor
51
    {
52
        $this->open();
53
        return $this->baseCursor;
54
    }
55
56
    public function getConnection(): \Igni\Storage\Driver\Connection
57
    {
58
        return $this->connection;
59
    }
60
61 2
    public function hydrateWith(ObjectHydrator $hydrator): void
62
    {
63 2
        $this->hydrator = $hydrator;
64 2
    }
65
66
    public function saveMemory(bool $save = true): void
67
    {
68
        if ($this->hydrator instanceof MemorySavingHydrator) {
69
            $this->hydrator->saveMemory($save);
70
        }
71
    }
72
73 7
    public function current()
74
    {
75 7
        $this->open();
76 7
        return $this->current;
77
    }
78
79 5
    public function next(): void
80
    {
81 5
        $this->open();
82 5
        $this->iterator->next();
83 5
        $this->current = $this->fetch();
84 5
    }
85
86 5
    public function key(): int
87
    {
88 5
        $this->open();
89 5
        return $this->iterator->key();
90
    }
91
92 6
    public function valid(): bool
93
    {
94 6
        $this->open();
95 6
        return $this->iterator->valid();
96
    }
97
98 6
    public function rewind(): void
99
    {
100 6
        $this->close();
101 6
        $this->open();
102 6
    }
103
104 5
    public function toArray(): array
105
    {
106 5
        return iterator_to_array($this);
107
    }
108
109 39
    public function open(): void
110
    {
111 39
        if ($this->iterator) {
112 6
            return;
113
        }
114
        try {
115 39
            $this->baseCursor = $this->connection
116 39
                ->getBaseConnection()
117 39
                ->executeCommand(
118 39
                    $this->options->getDatabase(),
119 39
                    $this->command
120
                );
121 39
            $this->baseCursor->setTypeMap(['root' => 'array', 'document' => 'array', 'array' => 'array']);
122 39
            $this->iterator = new IteratorIterator($this->baseCursor);
123 39
            $this->iterator->rewind();
124 39
            if ($this->iterator->valid()) {
125 39
                $this->current = $this->fetch();
126
            }
127 1
        } catch (\Exception $e) {
128 1
            throw CursorException::forExecutionFailure($this, $e->getMessage());
129
        }
130 39
    }
131
132 39
    public function close(): void
133
    {
134 39
        $this->current = null;
135 39
        if ($this->baseCursor) {
136 39
            $this->baseCursor = null;
137 39
            $this->iterator = null;
138
        }
139 39
    }
140
141 39
    public function execute(): void
142
    {
143 39
        $this->open();
144 39
        $this->close();
145 39
    }
146
147 39
    private function fetch()
148
    {
149 39
        $fetched = $this->iterator->current();
150 39
        if (isset($fetched['_id'])) {
151 7
            $fetched['id'] = $fetched['_id'];
152 7
            unset($fetched['_id']);
153
        }
154 39
        if ($this->hydrator && $fetched !== null) {
155 2
            $fetched = $this->hydrator->hydrate($fetched);
156
        }
157
158 39
        return $fetched;
159
    }
160
161 39
    public function __destruct()
162
    {
163 39
        $this->close();
164 39
    }
165
}
166