Issues (19)

src/DB/Column.php (1 issue)

Severity
1
<?php
2
3
namespace Helix\DB;
4
5
use ArrayAccess;
6
use Helix\DB;
7
use Helix\DB\Fluent\DateTime\DateTimeTrait;
8
use Helix\DB\Fluent\Num\NumTrait;
9
use Helix\DB\Fluent\Str\StrTrait;
10
use Helix\DB\Fluent\ValueInterface;
11
use LogicException;
12
13
/**
14
 * Immutable column expression. Can be treated as any data type.
15
 *
16
 * Read-only array access is provided for easily retrieving aggregate function results.
17
 *
18
 * @immutable Mutations operate on and return clones.
19
 *
20
 * @method static static factory(DB $db, string $name, string $qualifier = '')
21
 */
22
class Column implements ArrayAccess, ValueInterface
23
{
24
25
    use FactoryTrait;
26
    use DateTimeTrait;
0 ignored issues
show
The trait Helix\DB\Fluent\DateTime\DateTimeTrait requires some properties which are not provided by Helix\DB\Column: $s, $y, $m, $i, $h, $d
Loading history...
27
    use NumTrait;
28
    use StrTrait;
29
30
    /**
31
     * @var string
32
     */
33
    protected $name;
34
35
    /**
36
     * @var string
37
     */
38
    protected $qualifier;
39
40
    /**
41
     * @param DB $db
42
     * @param string $name
43
     * @param string $qualifier
44
     */
45
    public function __construct(DB $db, string $name, string $qualifier = '')
46
    {
47
        $this->db = $db;
48
        $this->name = $name;
49
        $this->qualifier = $qualifier;
50
    }
51
52
    /**
53
     * Returns the qualified name.
54
     *
55
     * @return string
56
     */
57
    public function __toString()
58
    {
59
        if (strlen($this->qualifier)) {
60
            return "{$this->qualifier}.{$this->name}";
61
        }
62
        return $this->name;
63
    }
64
65
    /**
66
     * @return string
67
     */
68
    final public function getName(): string
69
    {
70
        return $this->name;
71
    }
72
73
    /**
74
     * @return string
75
     */
76
    final public function getQualifier(): string
77
    {
78
        return $this->qualifier;
79
    }
80
81
    /**
82
     * Aggregate function results are always available.
83
     *
84
     * @param mixed $value
85
     * @return true
86
     */
87
    final public function offsetExists($value)
88
    {
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 DB\Fluent\Value\AggregateTrait
98
     * @param string $aggregator
99
     * @return null|string
100
     */
101
    public function offsetGet($aggregator)
102
    {
103
        $aggregator = preg_replace('/[ _()]/', '', $aggregator); // accept a variety of forms
104
        $aggregator = $this->{$aggregator}(); // methods are not case sensitive
105
        return Select::factory($this->db, $this->qualifier, [$aggregator])->getResult();
106
    }
107
108
    /**
109
     * Throws.
110
     *
111
     * @param mixed $offset
112
     * @param mixed $value
113
     * @throws LogicException
114
     */
115
    final public function offsetSet($offset, $value)
116
    {
117
        throw new LogicException("Column aggregation is read-only");
118
    }
119
120
    /**
121
     * Throws.
122
     *
123
     * @param mixed $offset
124
     * @throws LogicException
125
     */
126
    final public function offsetUnset($offset)
127
    {
128
        throw new LogicException("Column aggregation is read-only");
129
    }
130
131
    /**
132
     * Returns a {@link Select} for the column's values. The column must be qualified.
133
     *
134
     * @return Select|scalar[]
135
     */
136
    public function select()
137
    {
138
        return Select::factory($this->db, $this->qualifier, [$this->name])
139
            ->setFetcher(function (Statement $statement) {
140
                while (false !== $value = $statement->fetchColumn()) {
141
                    yield $value;
142
                }
143
            });
144
    }
145
146
    /**
147
     * Returns an aliased clone.
148
     *
149
     * @param string $name
150
     * @return $this
151
     */
152
    public function setName(string $name)
153
    {
154
        $clone = clone $this;
155
        $clone->name = $name;
156
        return $clone;
157
    }
158
159
    /**
160
     * @param string $qualifier
161
     * @return $this
162
     */
163
    public function setQualifier(string $qualifier)
164
    {
165
        $clone = clone $this;
166
        $clone->qualifier = $qualifier;
167
        return $clone;
168
    }
169
}
170