Completed
Push — master ( b71ad6...2211ef )
by Ivan
08:51
created

TableQueryIterator::rewind()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 6
ccs 4
cts 4
cp 1
rs 9.4285
cc 1
eloc 4
nc 1
nop 0
crap 1
1
<?php
2
namespace vakata\database\schema;
3
4
use vakata\collection\Collection;
5
use vakata\database\DBException;
6
7
/**
8
 * A table query iterator
9
 */
10
class TableQueryIterator implements \Iterator, \ArrayAccess
11
{
12
    /**
13
     * @var array
14
     */
15
    protected $pkey;
16
    /**
17
     * @var Result
18
     */
19
    protected $result;
20
    /**
21
     * @var array[]
22
     */
23
    protected $relations;
24
    /**
25
     * @var string|null
26
     */
27
    protected $primary = null;
28
    /**
29
     * @var int
30
     */
31
    protected $fetched = 0;
32
33 10
    public function __construct(Collection $result, array $pkey, array $relations = [])
34
    {
35 10
        $this->pkey = $pkey;
36 10
        $this->result = $result;
0 ignored issues
show
Documentation Bug introduced by
It seems like $result of type object<vakata\collection\Collection> is incompatible with the declared type object<vakata\database\schema\Result> of property $result.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
37 10
        $this->relations = $relations;
38 10
    }
39
40 10
    public function key()
41
    {
42 10
        return $this->fetched;
43
    }
44 10
    public function current()
45
    {
46 10
        $result = null;
47 10
        while ($this->result->valid()) {
48 10
            $row = $this->result->current();
49 10
            $pk = [];
50 10
            foreach ($this->pkey as $field) {
51 10
                $pk[$field] = $row[$field];
52
            }
53 10
            $pk = json_encode($pk);
54 10
            if ($this->primary !== null && $pk !== $this->primary) {
55 7
                break;
56
            }
57 10
            $this->primary = $pk;
58 10
            if (!$result) {
59 10
                $result = $row;
60
            }
61 10
            foreach ($this->relations as $name => $relation) {
62 3
                if (!isset($result[$name])) {
63 3
                    $result[$name] = $relation->many ? [] : null;
64
                }
65 3
                $fields = [];
66 3
                $exists = false;
67 3
                foreach ($relation->table->getColumns() as $column) {
68 3
                    $fields[$column] = $row[$name . '___' . $column];
69 3
                    if (!$exists && $row[$name . '___' . $column] !== null) {
70 3
                        $exists = true;
71
                    }
72 3
                    unset($result[$name . '___' . $column]);
73
                }
74 3
                if ($exists) {
75 3
                    if ($relation->many) {
76 3
                        $rpk = [];
77 3
                        foreach ($relation->table->getPrimaryKey() as $field) {
78 3
                            $rpk[$field] = $fields[$field];
79
                        }
80 3
                        $result[$name][json_encode($rpk)] = $fields;
81
                    } else {
82 3
                        $result[$name] = $fields;
83
                    }
84
                }
85
            }
86 10
            $this->result->next();
87
        }
88 10
        if ($result) {
89 10
            foreach ($this->relations as $name => $relation) {
90 3
                if ($relation->many) {
91 3
                    $result[$name] = array_values($result[$name]);
92
                }
93
            }
94
        }
95 10
        return $result;
96
    }
97
98 10
    public function rewind()
99
    {
100 10
        $this->fetched = 0;
101 10
        $this->primary = null;
102 10
        return $this->result->rewind();
103
    }
104 10
    public function next()
105
    {
106 10
        if ($this->primary === null) {
107
            $this->result->next();
108
            if ($this->result->valid()) {
109
                $row = $this->result->current();
110
                $temp = [];
111
                foreach ($this->pkey as $field) {
112
                    $temp[$field] = $row[$field];
113
                }
114
                $this->primary = json_encode($temp);
115
                return;
116
            }
117
        }
118 10
        $this->fetched ++;
119 10
        while ($this->result->valid()) {
120 7
            $row = $this->result->current();
121 7
            $pk = [];
122 7
            foreach ($this->pkey as $field) {
123 7
                $pk[$field] = $row[$field];
124
            }
125 7
            $pk = json_encode($pk);
126 7
            if ($this->primary !== $pk) {
127 7
                $this->primary = $pk;
128 7
                break;
129
            }
130
            $this->result->next();
131
        }
132 10
    }
133 10
    public function valid()
134
    {
135 10
        return $this->result->valid();
136
    }
137
138 8
    public function offsetGet($offset)
139
    {
140 8
        $index = $this->fetched;
141 8
        $item = null;
142 8
        foreach ($this as $k => $v) {
143 8
            if ($k === $offset) {
144 8
                $item = $v;
145
            }
146
        }
147 8
        foreach ($this as $k => $v) {
148 8
            if ($k === $index) {
149 8
                break;
150
            }
151
        }
152 8
        return $item;
153
    }
154
    public function offsetExists($offset)
155
    {
156
        $index = $this->fetched;
157
        $exists = false;
158
        foreach ($this as $k => $v) {
159
            if ($k === $offset) {
160
                $exists = true;
161
            }
162
        }
163
        foreach ($this as $k => $v) {
164
            if ($k === $index) {
165
                break;
166
            }
167
        }
168
        return $exists;
169
    }
170
    public function offsetSet($offset, $value)
171
    {
172
        throw new DBException('Invalid call to offsetSet');
173
    }
174
    public function offsetUnset($offset)
175
    {
176
        throw new DBException('Invalid call to offsetUnset');
177
    }
178
}
179