Completed
Push — master ( c7c0ed...b4dd43 )
by Ivan
03:12
created

TableQueryIterator::key()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
ccs 0
cts 4
cp 0
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 2
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
    public function __construct(Collection $result, array $pkey, array $relations = [])
34
    {
35
        $this->pkey = $pkey;
36
        $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
        $this->relations = $relations;
38
    }
39
40
    public function key()
41
    {
42
        return $this->fetched;
43
    }
44
    public function current()
45
    {
46
        $result = null;
47
        while ($this->result->valid()) {
48
            $row = $this->result->current();
49
            $pk = [];
50
            foreach ($this->pkey as $field) {
51
                $pk[$field] = $row[$field];
52
            }
53
            $pk = json_encode($pk);
54
            if ($this->primary !== null && $pk !== $this->primary) {
55
                break;
56
            }
57
            $this->primary = $pk;
58
            if (!$result) {
59
                $result = $row;
60
            }
61
            foreach ($this->relations as $name => $relation) {
62
                if (!isset($result[$name])) {
63
                    $result[$name] = $relation->many ? [] : null;
64
                }
65
                $fields = [];
66
                $exists = false;
67
                foreach ($relation->table->getColumns() as $column) {
68
                    $fields[$column] = $row[$name . '___' . $column];
69
                    if (!$exists && $row[$name . '___' . $column] !== null) {
70
                        $exists = true;
71
                    }
72
                    unset($result[$name . '___' . $column]);
73
                }
74
                if ($exists) {
75
                    if ($relation->many) {
76
                        $rpk = [];
77
                        foreach ($relation->table->getPrimaryKey() as $field) {
78
                            $rpk[$field] = $fields[$field];
79
                        }
80
                        $result[$name][json_encode($rpk)] = $fields;
81
                    } else {
82
                        $result[$name] = $fields;
83
                    }
84
                }
85
            }
86
            $this->result->next();
87
        }
88
        if ($result) {
89
            foreach ($this->relations as $name => $relation) {
90
                if ($relation->many) {
91
                    $result[$name] = array_values($result[$name]);
92
                }
93
            }
94
        }
95
        return $result;
96
    }
97
98
    public function rewind()
99
    {
100
        $this->fetched = 0;
101
        $this->primary = null;
102
        return $this->result->rewind();
103
    }
104
    public function next()
105
    {
106
        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
        $this->fetched ++;
119
        while ($this->result->valid()) {
120
            $row = $this->result->current();
121
            $pk = [];
122
            foreach ($this->pkey as $field) {
123
                $pk[$field] = $row[$field];
124
            }
125
            $pk = json_encode($pk);
126
            if ($this->primary !== $pk) {
127
                $this->primary = $pk;
128
                break;
129
            }
130
            $this->result->next();
131
        }
132
    }
133
    public function valid()
134
    {
135
        return $this->result->valid();
136
    }
137
138
    public function offsetGet($offset)
139
    {
140
        $index = $this->fetched;
141
        $item = null;
142
        foreach ($this as $k => $v) {
143
            if ($k === $offset) {
144
                $item = $v;
145
            }
146
        }
147
        foreach ($this as $k => $v) {
148
            if ($k === $index) {
149
                break;
150
            }
151
        }
152
        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