Completed
Push — master ( 80f0e4...ba08af )
by Samuel
9s
created

Selection::__clone()   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
dl 0
loc 4
ccs 0
cts 3
cp 0
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
crap 2
1
<?php
2
3
namespace SimpleMapper;
4
5
use Nette\Database\Table\IRow;
6
use Nette\Database\Table\Selection as NetteDatabaseSelection;
7
use Nette\Database\Table\ActiveRow as NetteDatabaseActiveRow;
8
use Nette\InvalidArgumentException;
9
use ArrayAccess;
10
use Iterator;
11
use Countable;
12
use Traversable;
13
14
class Selection implements Iterator, Countable, ArrayAccess
15
{
16
    /** @var NetteDatabaseSelection */
17
    private $selection;
18
19
    /** @var Structure */
20
    protected $structure;
21
22
    /**
23
     * @param NetteDatabaseSelection $selection
24
     * @param Structure|null $structure
25
     */
26 36
    public function __construct(NetteDatabaseSelection $selection, Structure $structure = null)
27
    {
28 36
        $this->selection = $selection;
29 36
        $this->structure = $structure;
30 36
    }
31
32
    /**
33
     * @return NetteDatabaseSelection
34
     */
35 2
    public function getSelection()
36
    {
37 2
        return $this->selection;
38
    }
39
40
    /**
41
     * Clone object
42
     */
43
    public function __clone()
44
    {
45
        $this->selection = clone $this->selection;
46
    }
47
48
    /**********************************************************************\
49
     * Wrapper function - fetch
50
    \**********************************************************************/
51
52
    /**
53
     * Returns row specified by primary key
54
     * @param mixed $key    Primary key
55
     * @return mixed
56
     */
57 2
    public function get($key)
58
    {
59 2
        $row = $this->selection->get($key);
60 2
        return $row instanceof NetteDatabaseActiveRow ? $this->prepareRecord($row) : $row;
61
    }
62
63
    /**
64
     * Returns one record
65
     * @return bool|mixed
66
     */
67 6
    public function fetch()
68
    {
69 6
        $row = $this->selection->fetch();
70 6
        return $row ? $this->prepareRecord($row) : $row;
71
    }
72
73
    /**
74
     * Fetches single field
75
     * @param string|null $column
76
     * @return mixed
77
     */
78 2
    public function fetchField($column = null)
79
    {
80 2
        return $this->selection->fetchField($column);
81
    }
82
83
    /**
84
     * Fetch key => value pairs
85
     * @param string|null $key
86
     * @param string|null $value
87
     * @return array
88
     */
89 2
    public function fetchPairs($key = null, $value = null)
90
    {
91 2
        $result = [];
92
93 2
        $pairs = $this->selection->fetchPairs($key, $value);
94 2
        foreach ($pairs as $k => $v) {
95 2
            $result[$k] = $v instanceof NetteDatabaseActiveRow ? $this->prepareRecord($v) : $v;
96 1
        }
97 2
        return $result;
98
    }
99
100
    /**
101
     * Returns all records
102
     * @return array
103
     */
104 4
    public function fetchAll()
105
    {
106 4
        return $this->prepareRecords($this->selection->fetchAll());
107
    }
108
109
    /**
110
     * Some examples of usage: https://github.com/nette/utils/blob/master/tests%2FUtils%2FArrays.associate().phpt
111
     * @param string $path
112
     * @return array|\stdClass
113
     */
114 2
    public function fetchAssoc($path)
115
    {
116 2
        return $this->selection->fetchAssoc($path);
117
    }
118
119
    /**********************************************************************\
120
     * Wrapper function - sql selections
121
    \**********************************************************************/
122
123
    /**
124
     * Adds select clause, more calls appends to the end
125
     * @param string $columns   for example "column, MD5(column) AS column_md5"
126
     * @param mixed ...$params
127
     * @return Selection
128
     */
129 4
    public function select($columns, ...$params)
130
    {
131 4
        $this->selection->select($columns, ...$params);
132 4
        return $this;
133
    }
134
135
    /**
136
     * Adds condition for primary key
137
     * @param mixed $key
138
     * @return Selection
139
     */
140 2
    public function wherePrimary($key)
141
    {
142 2
        $this->selection->wherePrimary($key);
143 2
        return $this;
144
    }
145
146
    /**
147
     * Adds where condition, more calls appends with AND
148
     * @param string $condition
149
     * @param mixed ...$params
150
     * @return Selection
151
     */
152 6
    public function where($condition, ...$params)
153
    {
154 6
        $this->selection->where($condition, ...$params);
155 6
        return $this;
156
    }
157
158
    /**
159
     * Adds ON condition when joining specified table, more calls appends with AND
160
     * @param string $tableChain    table chain or table alias for which you need additional left join condition
161
     * @param string $condition     condition possibly containing ?
162
     * @param mixed ...$params
163
     * @return Selection
164
     */
165
    public function joinWhere($tableChain, $condition, ...$params)
166
    {
167
        $this->selection->joinWhere($tableChain, $condition, ...$params);
168
        return $this;
169
    }
170
171
    /**
172
     * Adds where condition using the OR operator between parameters
173
     * More calls appends with AND.
174
     * @param array $parameters     ['column1' => 1, 'column2 > ?' => 2, 'full condition']
175
     * @return Selection
176
     * @throws InvalidArgumentException
177
     */
178 2
    public function whereOr(array $parameters)
179
    {
180 2
        $this->selection->whereOr($parameters);
181 2
        return $this;
182
    }
183
184
    /**
185
     * Adds order clause, more calls appends to the end
186
     * @param string $columns       for example 'column1, column2 DESC'
187
     * @param mixed ...$params
188
     * @return Selection
189
     */
190 4
    public function order($columns, ...$params)
191
    {
192 4
        $this->selection->order($columns, ...$params);
193 4
        return $this;
194
    }
195
196
    /**
197
     * Sets limit clause, more calls rewrite old values
198
     * @param int $limit
199
     * @param int $offset
200
     * @return Selection
201
     */
202 2
    public function limit($limit, $offset = null)
203
    {
204 2
        $this->selection->limit($limit, $offset);
205 2
        return $this;
206 1
    }
207
208
    /**
209
     * Sets offset using page number, more calls rewrite old values
210
     * @param int $page
211
     * @param int $itemsPerPage
212
     * @param int|null $numOfPages
213
     * @return Selection
214
     */
215 2
    public function page($page, $itemsPerPage, & $numOfPages = null)
216
    {
217 2
        $this->selection->page($page, $itemsPerPage, $numOfPages);
218 2
        return $this;
219
    }
220
221
    /**
222
     * Sets group clause, more calls rewrite old value
223
     * @param string $columns
224
     * @param mixed ...$params
225
     * @return Selection
226
     */
227 2
    public function group($columns, ...$params)
228
    {
229 2
        $this->selection->group($columns, ...$params);
230 2
        return $this;
231
    }
232
233
    /**
234
     * Sets having clause, more calls rewrite old value
235
     * @param string $having
236
     * @param mixed ...$params
237
     * @return Selection
238
     */
239 2
    public function having($having, ...$params)
240
    {
241 2
        $this->selection->having($having, ...$params);
242 2
        return $this;
243
    }
244
245
    /**
246
     * Aliases table. Example ':book:book_tag.tag', 'tg'
247
     * @param string $tableChain
248
     * @param string $alias
249
     * @return Selection
250
     */
251
    public function alias($tableChain, $alias)
252
    {
253
        $this->selection->alias($tableChain, $alias);
254
        return $this;
255
    }
256
257
    /**********************************************************************\
258
     * Wrapper function - aggregations
259
    \**********************************************************************/
260
261
    /**
262
     * Executes aggregation function
263
     * @param string $function      select call in "FUNCTION(column)" format
264
     * @return string
265
     */
266 2
    public function aggregation($function)
267 1
    {
268 2
        return $this->selection->aggregation($function);
269
    }
270
271
    /**
272
     * Counts number of rows
273
     * Countable interface
274
     * @param string $column    If it is not provided returns count of result rows, otherwise runs new sql counting query
275
     * @return int
276
     */
277 12
    public function count($column = null)
278
    {
279 12
        return $this->selection->count($column);
280
    }
281
282
    /**
283
     * Returns minimum value from a column
284
     * @param string $column
285
     * @return int
286
     */
287 2
    public function min($column)
288
    {
289 2
        return $this->selection->min($column);
290
    }
291
292
    /**
293
     * Returns maximum value from a column
294
     * @param string $column
295
     * @return int
296
     */
297 2
    public function max($column)
298
    {
299 2
        return $this->selection->max($column);
300
    }
301
302
    /**
303
     * Returns sum of values in a column
304
     * @param string $column
305
     * @return int
306
     */
307 2
    public function sum($column)
308
    {
309 2
        return $this->selection->sum($column);
310
    }
311
312
    /**********************************************************************\
313
     * Wrapper function - manipulation
314
    \**********************************************************************/
315
316
    /**
317
     * Inserts row in a table
318
     * @param  array|Traversable|Selection $data
319
     * @return IRow|int|bool
320
     */
321 2
    public function insert($data)
322
    {
323 2
        $insertResult = $this->selection->insert($data);
324 2
        return $insertResult instanceof IRow ? $this->prepareRecord($insertResult) : $insertResult;
325
    }
326
327
    /**
328
     * Updates all rows in result set
329
     * @param  array|Traversable $data      ($column => $value)
330
     * @return int
331
     */
332 2
    public function update($data)
333
    {
334 2
        return $this->selection->update($data);
335
    }
336
337
    /**
338
     * Deletes all rows in result set
339
     * @return int
340
     */
341 2
    public function delete()
342
    {
343 2
        return $this->selection->delete();
344
    }
345
346
    /**********************************************************************\
347
     * Iterator interface
348
    \**********************************************************************/
349
350
    /**
351
     * Rewind selection
352
     */
353 12
    public function rewind()
354
    {
355 12
        $this->selection->rewind();
356 12
    }
357
358
    /**
359
     * Returns current selection data record
360
     * @return bool|mixed
361
     */
362 12
    public function current()
363
    {
364 12
        $row = $this->selection->current();
365 12
        return $row instanceof IRow ? $this->prepareRecord($row) : false;
366
    }
367
368
    /**
369
     * Returns current selection data key
370
     * @return string
371
     */
372 2
    public function key()
373
    {
374 2
        return $this->selection->key();
375
    }
376
377
    /**
378
     * Move iterator
379
     */
380 12
    public function next()
381
    {
382 12
        $this->selection->next();
383 12
    }
384
385
    /**
386
     * It is selection valid
387
     * @return bool
388
     */
389 12
    public function valid()
390
    {
391 12
        return $this->selection->valid();
392
    }
393
394
    /**********************************************************************\
395
     * ArrayAccess interface
396
    \**********************************************************************/
397
398
    /**
399
     * @param string $key   Row ID
400
     * @param IRow $value
401
     */
402 2
    public function offsetSet($key, $value)
403
    {
404 2
        $this->selection->offsetSet($key, $value);
405 2
    }
406
407
    /**
408
     * Returns specified row
409
     * @param string $key   Row ID
410
     * @return IRow|null
411
     */
412 2
    public function offsetGet($key)
413
    {
414 2
        $row = $this->selection->offsetGet($key);
415 2
        return $row instanceof IRow ? $this->prepareRecord($row) : $row;
416
    }
417
418
    /**
419
     * Tests if row exists
420
     * @param string $key   Row ID
421
     * @return bool
422
     */
423 2
    public function offsetExists($key)
424
    {
425 2
        return $this->selection->offsetExists($key);
426
    }
427
428
    /**
429
     * Removes row from result set
430
     * @param string $key   Row ID
431
     */
432 2
    public function offsetUnset($key)
433
    {
434 2
        $this->selection->offsetUnset($key);
435 2
    }
436
437
    /**********************************************************************\
438
     * Build methods
439
    \**********************************************************************/
440
441
    /**
442
     * Prepare one record
443
     * @param IRow $row
444
     * @return mixed
445
     */
446 26
    protected function prepareRecord(IRow $row)
447
    {
448 26
        $recordClass = $this->structure->getActiveRowClass($row->getTable()->getName());
449 26
        return new $recordClass($row, $this->structure);
450
    }
451
452
    /**
453
     * Prepare records array
454
     * @param array $rows
455
     * @return array
456
     */
457 4
    protected function prepareRecords(array $rows)
458
    {
459 4
        $result = [];
460 4
        foreach ($rows as $row) {
461 4
            $result[] = $this->prepareRecord($row);
462 2
        }
463 4
        return $result;
464
    }
465
}
466