Completed
Pull Request — master (#34)
by Rasmus
05:13
created

Mappers::index()   B

Complexity

Conditions 6
Paths 5

Size

Total Lines 16
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 6.2163

Importance

Changes 0
Metric Value
dl 0
loc 16
c 0
b 0
f 0
ccs 9
cts 11
cp 0.8182
rs 8.8571
cc 6
eloc 12
nc 5
nop 1
crap 6.2163
1
<?php
2
3
namespace mindplay\sql\model\components;
4
5
use mindplay\sql\framework\Indexer;
6
use mindplay\sql\framework\indexers\CallbackIndexer;
7
use mindplay\sql\framework\indexers\ValueIndexer;
8
use mindplay\sql\framework\Mapper;
9
use mindplay\sql\framework\mappers\BatchMapper;
10
use mindplay\sql\framework\mappers\RecordMapper;
11
use mindplay\sql\model\schema\Column;
12
use UnexpectedValueException;
13
14
/**
15
 * This trait implements support for mapping and indexing of results.
16
 */
17
trait Mappers
18
{
19
    /**
20
     * @var Mapper[] list of Mappers
21
     */
22
    protected $mappers = [];
23
24
    /**
25
     * @var Indexer|null
26
     */
27
    protected $indexer;
28
29
    /**
30
     * Append a Mapper instance to apply when each batch of a record-set is fetched.
31
     *
32
     * @param Mapper $mapper
33
     *
34
     * @see mapRecords() to map an anonymous function against every record
35
     * @see mapBatches() to map an anonymous function against each batch of records
36
     *                   
37
     * @return $this
38
     */
39
    public function map(Mapper $mapper)
40
    {
41
        $this->mappers[] = $mapper;
42
        
43
        return $this;
44
    }
45
46
    /**
47
     * Map an anonymous function against every record.
48
     *
49
     * @param callable $mapper function (mixed $record) : mixed
50
     *
51
     * @see mapBatches() to map an anonymous function against each batch of records
52
     *                   
53
     * @return $this
54
     */
55 1
    public function mapRecords(callable $mapper)
56
    {
57 1
        $this->mappers[] = new RecordMapper($mapper);
58
        
59 1
        return $this;
60
    }
61
62
    /**
63
     * Map an anonymous function against each batch of records.
64
     *
65
     * @param callable $mapper function (array $record_set) : array
66
     *
67
     * @see mapRecords() to map an anonymous function against every record
68
     *                   
69
     * @return $this
70
     */
71
    public function mapBatches(callable $mapper)
72
    {
73
        $this->mappers[] = new BatchMapper($mapper);
74
        
75
        return $this;
76
    }
77
78
    /**
79
     * Define an {@see Indexer}, callable, Column, or Column-name to use
80
     * to compute an index-value for the returned records.
81
     *
82
     * Note that this can lead to index-collisions - for example, using a foreign key
83
     * in a query with multiple records for the same foreign key, may cause the same
84
     * foreign key to occur as an index multiple times; this will cause a run-time
85
     * exception when calling e.g. {@see Result::all()}.
86
     *
87
     * Note that iterating over the `Result` instance directly (and *not* calling the
88
     * `all()` method) does permit iteration over results with duplicate indices - this
89
     * can be useful e.g. when collecting child records to append to a parent.
90
     *
91
     * @param Indexer|Column|callable|string $indexer
92
     *
93
     * @return $this
94
     */
95 1
    public function index($indexer)
96
    {
97 1
        if ($indexer instanceof Indexer) {
98 1
            $this->indexer = $indexer;
99
        } elseif ($indexer instanceof Column) {
100 1
            $this->indexer = new ValueIndexer($indexer->getAlias() ?: $indexer->getName());
101 1
        } elseif (is_string($indexer)) {
102 1
            $this->indexer = new ValueIndexer($indexer);
103 1
        } elseif (is_callable($indexer, true)) {
104 1
            $this->indexer = new CallbackIndexer($indexer);
105
        } else {
106
            throw new UnexpectedValueException("unsupported indexer: " . print_r($indexer, true));
107
        }
108
109 1
        return $this;
110
    }
111
}
112