-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathClickHouse.php
More file actions
154 lines (125 loc) · 4.26 KB
/
Copy pathClickHouse.php
File metadata and controls
154 lines (125 loc) · 4.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
<?php
namespace Utopia\Query\Schema\Column;
use Utopia\Query\Exception\ValidationException;
use Utopia\Query\Schema\Column;
use Utopia\Query\Schema\ColumnType;
use Utopia\Query\Schema\Forwarder;
use Utopia\Query\Schema\Table;
/**
* @extends Column<Table\ClickHouse>
*/
class ClickHouse extends Column
{
use Forwarder\ClickHouse;
public protected(set) bool $isLowCardinality = false;
/** Length when the column should be emitted as `FixedString(N)`; null otherwise. */
public protected(set) ?int $fixedStringLength = null;
/** @var list<string> Column-level CODEC clauses, e.g. ['Delta(4)', 'LZ4'] */
public protected(set) array $codecs = [];
/** Element type when the column is emitted as `Array(T)`; null otherwise. */
public protected(set) ?ColumnType $arrayElementType = null;
/** @var list<ColumnType> Element types when the column is emitted as `Tuple(...)`. */
public protected(set) array $tupleElementTypes = [];
/**
* Mark the column as `FixedString(N)`.
*
* Used by {@see Table\ClickHouse::fixedString()} to attach the
* ClickHouse-specific FixedString width to a column whose generic
* {@see \Utopia\Query\Schema\ColumnType} is `String`. The compiler reads
* this state when emitting DDL.
*
* @throws ValidationException if $length is less than 1.
*/
public function asFixedString(int $length): static
{
if ($length < 1) {
throw new ValidationException('FixedString length must be at least 1.');
}
$this->fixedStringLength = $length;
return $this;
}
public function isFixedString(): bool
{
return $this->fixedStringLength !== null;
}
/**
* Mark the column as `Array(T)` wrapping the given element type.
*/
public function asArray(ColumnType $element): static
{
$this->arrayElementType = $element;
return $this;
}
public function isArray(): bool
{
return $this->arrayElementType !== null;
}
/**
* Mark the column as `Tuple(t1, t2, ...)` over the given element types.
*
* @param list<ColumnType> $elements
*
* @throws ValidationException if the element list is empty.
*/
public function asTuple(array $elements): static
{
if ($elements === []) {
throw new ValidationException('Tuple() requires at least one element type.');
}
$this->tupleElementTypes = $elements;
return $this;
}
public function isTuple(): bool
{
return $this->tupleElementTypes !== [];
}
/**
* @param list<string> $columns
*
* @phpstan-return ($columns is array{} ? static : Table\ClickHouse)
*/
public function primary(array $columns = []): static|Table
{
if ($columns === []) {
$this->isPrimary = true;
return $this;
}
return $this->table->primary($columns);
}
/**
* Wrap the column type in `LowCardinality(...)`.
*
* Suitable for string columns with a small number of distinct values
* (status enums, type discriminators, country codes). `Nullable` is
* applied inside `LowCardinality` to match ClickHouse's required
* wrapping order: `LowCardinality(Nullable(String))`.
*/
public function lowCardinality(): static
{
$this->isLowCardinality = true;
return $this;
}
/**
* Append a column-level CODEC clause.
*
* Multiple calls accumulate and emit `CODEC(c1, c2, ...)`. Pass either
* a bare codec name (`->codec('LZ4')`) or one with arguments
* (`->codec('Delta(4)')`, `->codec('ZSTD(3)')`). The codec string is
* emitted verbatim and must come from a trusted source.
*
* @throws ValidationException if the codec string is empty or contains
* a semicolon.
*/
public function codec(string $codec): static
{
$trimmed = \trim($codec);
if ($trimmed === '') {
throw new ValidationException('CODEC expression must not be empty.');
}
if (\str_contains($trimmed, ';')) {
throw new ValidationException('CODEC expression must not contain ";".');
}
$this->codecs[] = $trimmed;
return $this;
}
}