Skip to content

Commit 7bcb7f2

Browse files
committed
feat: migrate ClickHouse adapter to utopia-php/query 0.3.x builder
Replaces the hand-rolled SQL strings in src/Usage/Adapter/ClickHouse.php with the utopia-php/query 0.3.x builder + schema layer. The adapter is now a thin HTTP runtime: every DDL statement, INSERT, SELECT, and DELETE fragment is produced by Schema\ClickHouse or Builder\ClickHouse. Schema (DDL via Utopia\Query\Schema\ClickHouse): - setup() emits events/gauges tables through Table\ClickHouse with typed columns (string, datetime, bigInteger), Engine::MergeTree, monthly partitioning, ORDER BY, bloom_filter skip indexes, and SETTINGS. - createDailyTable() emits the SummingMergeTree daily aggregation table via Engine::SummingMergeTree('value'). - createDailyMaterializedView() emits the MV via Schema\ClickHouse::createMaterializedView. The MV body remains a hand SELECT because subquery-aggregation MV bodies do not round-trip cleanly through the builder yet (deferred upstream). Reads (SELECT via Utopia\Query\Builder\ClickHouse): - A per-call builder is initialised with `useNamedBindings()` plus `withParamTypes()` so every `?` placeholder rewrites to ClickHouse `{paramN:Type}` form (DateTime64(3), Int64, String, Nullable(String)). - find/findFromTable, findAggregatedFromTable, count/countFromTable, sum/sumFromTable, findDaily (FINAL), sumDaily, sumDailyBatch, getTotal/getTotalFromEvents/getTotalFromGauges, getTotalBatch, getTimeSeries/getTimeSeriesFromTable all compose filters via $builder->filter([Query::...]) and emit aggregations through $builder->sum()/->count()/selectRaw. - Time-bucketed aggregation consumes Query::groupByTimeBucket via the builder's native GROUP BY emission, paired with selectRaw/orderByRaw for the bucket projection and ordering. - Cursor pagination keeps the tuple-keyset comparison as a whereRaw fragment and merges its named bindings into the builder Statement at HTTP execute time. Writes (INSERT via Utopia\Query\Builder\ClickHouse::insertFormat): - addBatch() builds `INSERT INTO t (...) FORMAT JSONEachRow` via the builder's insertFormat helper; the JSONEachRow payload is streamed in the HTTP body. Deletes (DELETE via Utopia\Query\Builder\ClickHouse::delete): - purge() and purgeDaily() emit lightweight DELETE through the builder. UsageQuery is removed. Downstream callers must switch from `UsageQuery::groupByInterval('time', '1h')` to `Query::groupByTimeBucket('time', '1h')`. The 0.3.x library rejects non-enumerated intervals through ValidationException at construction. HTTP transport and configuration setters (validateHost/validatePort, escapeIdentifier, setNamespace/setTenant/setSharedTables/setDatabase/ setSecure/setTimeout/setCompression/setKeepAlive/setMaxRetries/ setRetryDelay/setAsyncInserts, healthCheck, query/insert/executeWithRetry, logQuery, getConnectionStats/getQueryLog/clearQueryLog) stay untouched - the migration is strictly to the SQL-building layer. LowCardinality wrapping on the country column is dropped (the schema layer wraps `LowCardinality` inside `Nullable`, but ClickHouse only accepts `LowCardinality(Nullable(T))`; the column stays a plain Nullable(String) until the upstream wrapping order is fixed - deferred upstream). References utopia-php/query#11.
1 parent f0ded73 commit 7bcb7f2

5 files changed

Lines changed: 1326 additions & 1983 deletions

File tree

0 commit comments

Comments
 (0)