|
6 | 6 |
|
7 | 7 | use Closure; |
8 | 8 | use DateTimeInterface; |
| 9 | +use DateTimeZone; |
9 | 10 | use Psr\Http\Message\StreamInterface; |
10 | 11 | use SimPod\ClickHouseClient\Exception\UnsupportedParamType; |
11 | 12 | use SimPod\ClickHouseClient\Sql\Escaper; |
| 13 | +use SimPod\ClickHouseClient\Exception\UnsupportedParamValue; |
12 | 14 | use SimPod\ClickHouseClient\Sql\Type; |
13 | 15 |
|
14 | 16 | use function array_keys; |
|
18 | 20 | use function implode; |
19 | 21 | use function in_array; |
20 | 22 | use function is_array; |
| 23 | +use function is_float; |
| 24 | +use function is_int; |
21 | 25 | use function is_string; |
22 | 26 | use function json_encode; |
23 | 27 | use function sprintf; |
|
26 | 30 | use function trim; |
27 | 31 |
|
28 | 32 | /** |
29 | | - * @phpstan-type Converter = Closure(mixed, Type|string|null, bool):(StreamInterface|string) |
30 | | - * @phpstan-type ConverterRegistry = array<string, Converter> |
| 33 | + * @phpstan-type Converter Closure(mixed, Type|string|null, bool):(StreamInterface|string) |
| 34 | + * @phpstan-type ConverterRegistry array<string, Converter> |
31 | 35 | */ |
32 | | -final class ParamValueConverterRegistry |
| 36 | +final readonly class ParamValueConverterRegistry |
33 | 37 | { |
34 | | - /** @var list<string> */ |
35 | | - private static array $caseInsensitiveTypes = [ |
| 38 | + private const CaseInsensitiveTypes = [ |
36 | 39 | 'bool', |
37 | 40 | 'date', |
38 | 41 | 'date32', |
@@ -90,10 +93,10 @@ public function __construct(array $registry = []) |
90 | 93 |
|
91 | 94 | 'bool' => static fn (bool $value) => $value, |
92 | 95 |
|
93 | | - 'date' => self::dateConverter(), |
94 | | - 'date32' => self::dateConverter(), |
95 | | - 'datetime' => self::dateTimeConverter(), |
96 | | - 'datetime32' => self::dateTimeConverter(), |
| 96 | + 'date' => self::dateConverter($this->clickHouseTimeZone), |
| 97 | + 'date32' => self::dateConverter($this->clickHouseTimeZone), |
| 98 | + 'datetime' => self::dateTimeConverter($this->clickHouseTimeZone), |
| 99 | + 'datetime32' => self::dateTimeConverter($this->clickHouseTimeZone), |
97 | 100 | 'datetime64' => static fn (DateTimeInterface|string|int|float $value) => $value instanceof DateTimeInterface |
98 | 101 | ? $value->format('U.u') |
99 | 102 | : $value, |
@@ -232,7 +235,7 @@ public function get(Type|string $type): Closure |
232 | 235 |
|
233 | 236 | $typeName = strtolower($typeName); |
234 | 237 | $converter = $this->registry[$typeName] ?? null; |
235 | | - if ($converter !== null && in_array($typeName, self::$caseInsensitiveTypes, true)) { |
| 238 | + if ($converter !== null && in_array($typeName, self::CaseInsensitiveTypes, true)) { |
236 | 239 | return $converter; |
237 | 240 | } |
238 | 241 |
|
@@ -271,17 +274,32 @@ private static function decimalConverter(): Closure |
271 | 274 |
|
272 | 275 | private static function dateConverter(): Closure |
273 | 276 | { |
274 | | - return static fn (DateTimeInterface|string|int|float $value) => $value instanceof DateTimeInterface |
275 | | - // We cannot convert to timestamp yet https://github.com/ClickHouse/ClickHouse/issues/75217 |
276 | | - ? $value->format('Y-m-d') |
277 | | - : $value; |
| 277 | + return static function (mixed $value) { |
| 278 | + if ($value instanceof DateTimeInterface) { |
| 279 | + return $value->format('Y-m-d'); |
| 280 | + } |
| 281 | + |
| 282 | + if (is_string($value) || is_float($value) || is_int($value)) { |
| 283 | + return $value; |
| 284 | + } |
| 285 | + |
| 286 | + throw UnsupportedParamValue::type($value); |
| 287 | + }; |
278 | 288 | } |
279 | 289 |
|
280 | 290 | private static function dateTimeConverter(): Closure |
281 | 291 | { |
282 | | - return static fn (DateTimeInterface|string|int|float $value) => $value instanceof DateTimeInterface |
283 | | - ? $value->getTimestamp() |
284 | | - : $value; |
| 292 | + return static function (mixed $value) { |
| 293 | + if ($value instanceof DateTimeInterface) { |
| 294 | + return $value->getTimestamp(); |
| 295 | + } |
| 296 | + |
| 297 | + if (is_string($value) || is_float($value) || is_int($value)) { |
| 298 | + return $value; |
| 299 | + } |
| 300 | + |
| 301 | + throw UnsupportedParamValue::type($value); |
| 302 | + }; |
285 | 303 | } |
286 | 304 |
|
287 | 305 | private static function dateIntervalConverter(): Closure |
|
0 commit comments