Passed
Push — master ( 95e8b1...8e215e )
by y
01:35
created

Column::offsetSet()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 2
rs 10
cc 1
nc 1
nop 2
1
<?php
2
3
namespace Helix\DB;
4
5
use ArrayAccess;
6
use Helix\DB;
7
use Helix\DB\SQL\AggregateTrait;
8
use Helix\DB\SQL\CastTrait;
9
use Helix\DB\SQL\ComparisonTrait;
10
use Helix\DB\SQL\DateTimeTrait;
11
use Helix\DB\SQL\NumTrait;
12
use Helix\DB\SQL\TextTrait;
13
use Helix\DB\SQL\ValueInterface;
14
use LogicException;
15
16
/**
17
 * Immutable column expression. Can produce all available transformations.
18
 *
19
 * Read-only array access is provided for easily retrieving aggregate function results.
20
 *
21
 * @immutable Mutations operate on and return clones.
22
 *
23
 * @method static static factory(DB $db, string $name, string $qualifier = '')
24
 */
25
class Column implements ArrayAccess, ValueInterface {
26
27
    use AggregateTrait;
28
    use CastTrait;
29
    use ComparisonTrait;
30
    use DateTimeTrait;
31
    use FactoryTrait;
32
    use NumTrait;
33
    use TextTrait;
34
35
    /**
36
     * @var string
37
     */
38
    protected $name;
39
40
    /**
41
     * @var string
42
     */
43
    protected $qualifier;
44
45
    /**
46
     * @param DB $db
47
     * @param string $name
48
     * @param string $qualifier
49
     */
50
    public function __construct (DB $db, string $name, string $qualifier = '') {
51
        $this->db = $db;
52
        $this->name = $name;
53
        $this->qualifier = $qualifier;
54
    }
55
56
    /**
57
     * Returns the qualified name.
58
     *
59
     * @return string
60
     */
61
    public function __toString () {
62
        if (strlen($this->qualifier)) {
63
            return "{$this->qualifier}.{$this->name}";
64
        }
65
        return $this->name;
66
    }
67
68
    /**
69
     * @return string
70
     */
71
    final public function getName (): string {
72
        return $this->name;
73
    }
74
75
    /**
76
     * @return string
77
     */
78
    final public function getQualifier (): string {
79
        return $this->qualifier;
80
    }
81
82
    /**
83
     * Aggregate function results are always available.
84
     *
85
     * @param mixed $value
86
     * @return true
87
     */
88
    final public function offsetExists ($value) {
89
        return true;
90
    }
91
92
    /**
93
     * Returns the result of an aggregate function run over the column expression.
94
     *
95
     * Example: `min` returns the result of `SELECT MIN($this) FROM $this->qualifier`
96
     *
97
     * @see AggregateTrait
98
     * @param string $aggregator
99
     * @return null|string
100
     */
101
    public function offsetGet ($aggregator) {
102
        $aggregator = preg_replace('/[ _()]/', '', $aggregator); // accept a variety of forms
103
        $aggregator = $this->{$aggregator}(); // methods are not case sensitive
104
        return Select::factory($this->db, $this->qualifier, [$aggregator])->getResult();
105
    }
106
107
    /**
108
     * Throws.
109
     *
110
     * @param mixed $offset
111
     * @param mixed $value
112
     * @throws LogicException
113
     */
114
    final public function offsetSet ($offset, $value) {
115
        throw new LogicException("Column aggregation is read-only");
116
    }
117
118
    /**
119
     * Throws.
120
     *
121
     * @param mixed $offset
122
     * @throws LogicException
123
     */
124
    final public function offsetUnset ($offset) {
125
        throw new LogicException("Column aggregation is read-only");
126
    }
127
128
    /**
129
     * Returns a {@link Select} for the column's values. The column must be qualified.
130
     *
131
     * @return Select|scalar[]
132
     */
133
    public function select () {
134
        return Select::factory($this->db, $this->qualifier, [$this->name])
135
            ->setFetcher(function(Statement $statement) {
136
                while (false !== $value = $statement->fetchColumn()) {
137
                    yield $value;
138
                }
139
            });
140
    }
141
142
    /**
143
     * Returns an aliased clone.
144
     *
145
     * If you want to rename the column in the schema, use {@link Schema::renameColumn()}
146
     *
147
     * @param string $name
148
     * @return $this
149
     */
150
    public function setName (string $name) {
151
        $clone = clone $this;
152
        $clone->name = $name;
153
        return $clone;
154
    }
155
156
    /**
157
     * @param string $qualifier
158
     * @return $this
159
     */
160
    public function setQualifier (string $qualifier) {
161
        $clone = clone $this;
162
        $clone->qualifier = $qualifier;
163
        return $clone;
164
    }
165
}