flush
[m6w6/pq-gateway] / lib / pq / Gateway / Rowset.php
1 <?php
2
3 namespace pq\Gateway;
4
5 class Rowset implements \SeekableIterator, \Countable, \JsonSerializable
6 {
7 /**
8 * @var \pq\Gateway\Table
9 */
10 protected $table;
11
12 /**
13 * @var int
14 */
15 protected $index = 0;
16
17 /**
18 * @var array
19 */
20 protected $rows;
21
22 /**
23 * @var string
24 */
25 protected $row;
26
27 /**
28 * @param \pq\Gateway\Table $table
29 * @param \pq\Result $result
30 */
31 function __construct(Table $table, \pq\Result $result, $row = "\\pq\\Gateway\\Row") {
32 $this->table = $table;
33 $this->row = $row;
34
35 $this->hydrate($result);
36 }
37
38 /**
39 * Copy constructor
40 * @param \pq\Result $result
41 * @return \pq\Gateway\Rowset
42 */
43 function __invoke(\pq\Result $result) {
44 $that = clone $this;
45 $that->hydrate($result);
46 return $that;
47 }
48
49 /**
50 *
51 * @param \pq\Result $result
52 * @return array
53 */
54 protected function hydrate(\pq\Result $result) {
55 $this->index = 0;
56 $this->rows = array();
57 $row = $this->row;
58
59 if (is_callable($row)) {
60 while (($data = $result->fetchRow(\pq\Result::FETCH_ASSOC))) {
61 $this->rows[] = $row($data);
62 }
63 } else {
64 while (($data = $result->fetchRow(\pq\Result::FETCH_ASSOC))) {
65 $this->rows[] = new $row($this->table, $data);
66 }
67 }
68 return $this;
69 }
70
71 /**
72 * @return \pq\Gateway\Table
73 */
74 function getTable() {
75 return $this->table;
76 }
77
78 function create() {
79 array_map(function ($row) {
80 $row->create();
81 }, $this->rows);
82 return $this;
83 }
84
85 function update() {
86 array_map(function ($row) {
87 $row->update();
88 }, $this->rows);
89 return $this;
90 }
91
92 function delete() {
93 array_map(function ($row) {
94 $row->delete();
95 }, $this->rows);
96 return $this;
97 }
98
99 /**
100 * @implements JsonSerilaizable
101 */
102 function jsonSerialize() {
103 return array_map(function($row) {
104 return $row->jsonSerialize();
105 }, $this->rows);
106 }
107
108 /**
109 * @implements \Iterator
110 */
111 function rewind() {
112 $this->index = 0;
113 }
114 /**
115 * @implements \Iterator
116 */
117 function next() {
118 ++$this->index;
119 }
120 /**
121 * @implements \Iterator
122 * @return bool
123 */
124 function valid() {
125 return $this->index < count($this->rows);
126 }
127 /**
128 * @implements \Iterator
129 * @return \pq\Gateway\Row
130 */
131 function current() {
132 return $this->rows[$this->index];
133 }
134 /**
135 * @implements \Iterator
136 * @return int
137 */
138 function key() {
139 return $this->index;
140 }
141
142 /**
143 * @implements SeekableIterator
144 * @param mixed $pos
145 */
146 function seek($pos) {
147 /* only index for now */
148 $this->index = $pos;
149
150 if (!$this->valid()) {
151 throw new \OutOfBoundsException("Invalid seek position ($pos)");
152 }
153 }
154
155 /**
156 * @implements \Countable
157 * @return int
158 */
159 function count() {
160 return count($this->rows);
161 }
162
163 /**
164 * Get the rows of this rowset
165 * @return array
166 */
167 function getRows() {
168 return $this->rows;
169 }
170
171 /**
172 * Filter by callback
173 * @param callable $cb
174 * @return \pq\Gateway\Rowset
175 */
176 function filter(callable $cb) {
177 $rowset = clone $this;
178 $rowset->rows = array_filter($this->rows, $cb);
179 return $rowset;
180 }
181 }