Skip to main content

Crate clickhouse_kit

Crate clickhouse_kit 

Source
Expand description

§smooai-clickhouse-kit (imports as clickhouse_kit)

A safe-by-construction ClickHouse schema toolkit with two jobs:

  • TS→Rust bridge for developer-authored (static) tables: TypeScript owns the schema; introspect reads the live ClickHouse back into Rust and codegen emits #[derive(Row)] structs, with check_drift asserting the Rust view ≡ the live DB. Rows stay Serde-native.
  • Runtime toolkit for user-defined / multi-tenant (dynamic) tables: an allowlisted type system, identifier safety, DDL generation, flexible_table, forward-only migrations, and additive evolution — the safe-by-construction path for turning untrusted customer input into SQL (that guarantee only counts in the process holding the input, which is why this layer is canonical in Rust).

See the repo ROADMAP.md.

Re-exports§

pub use client::ChError;
pub use client::ChExecutor;
pub use codegen::ch_type_to_rust;
pub use codegen::rust_row_struct;
pub use drift::check_drift;
pub use drift::Drift;
pub use drift::DriftResult;
pub use evolve::alter_add_columns_sql;
pub use evolve::diff_columns;
pub use evolve::ColumnDiff;
pub use evolve::LiveColumn;
pub use flatten::coerce_to_table;
pub use flatten::flatten_record;
pub use flatten::CoerceResult;
pub use flatten::FlattenOptions;
pub use flexible::flexible_table;
pub use flexible::FlexibleConfig;
pub use introspect::introspect_columns;
pub use introspect::introspect_row_struct;
pub use migrate::run_migrations;
pub use migrate::split_sql_statements;
pub use migrate::MigrationRunResult;
pub use safety::assert_column_count;
pub use safety::assert_not_reserved;
pub use safety::quote_identifier;
pub use safety::validate_identifier;
pub use safety::ColumnTypeSpec;
pub use safety::ScalarType;
pub use safety::SchemaError;
pub use safety::SchemaLimits;
pub use safety::StringOnly;
pub use safety::DEFAULT_RESERVED_COLUMNS;
pub use table::to_create_table_sql;
pub use table::ColumnSpec;
pub use table::TableSpec;

Modules§

client
The bring-your-own-client seam. clickhouse-kit never depends on a concrete ClickHouse driver — the I/O layer (migration runner, drift gate) is written against the small ChExecutor trait, and the caller implements it over whatever client they already have (the clickhouse crate, an HTTP shim, a test double). This keeps the crate driver-agnostic and dependency-light.
codegen
TS→Rust bridge codegen. TypeScript owns the (static) schema; this turns a ClickHouse table’s live/spec columns into a Rust row struct#[derive(Row, Deserialize)] — so the Rust services get faithful, drift-checked rows for the TS-authored tables instead of hand-writing them (the class of bug that bit api-prime’s hand-copied structs). Pair with introspect + check_drift: the generated rows are asserted ≡ the live ClickHouse in CI.
drift
Drift gate: compare a set of expected TableSpecs against the live schema introspected from system.columns. Read-only — it reports divergence, it never mutates. Intended to run in CI to catch a deployed schema that no longer matches the code’s model.
evolve
Additive, bounded schema evolution — grow a dynamic per-tenant table to match its TableSpec without ever dropping or modifying existing columns.
flatten
Flatten + coerce — where arbitrary input meets a table.
flexible
The flexible/hybrid multi-tenant table — the most-reused shape.
introspect
The live→Rust half of the TS→Rust bridge. TypeScript authors the (static) schema and ClickHouse holds it; this reads it back into Rust — columns for check_drift, and a generated row struct via codegen — so the Rust side is a faithful, drift-checked view of the TS-owned schema and can never silently diverge.
migrate
Forward-only migration runner. Applies *.sql files from a directory in lexical order, recording each in a _ch_migrations bookkeeping table so re-runs are idempotent. There is no auto-diff and no down-migration — schema change is expressed as ordered, append-only SQL files.
safety
Safe-by-construction primitives for user-defined / multi-tenant ClickHouse schemas — the Rust-canonical port of @smooai/clickhouse-kit’s safety core.
table
Runtime table construction from untrusted specs → CREATE TABLE DDL. Every identifier is validated and every type goes through the allowlist (ColumnTypeSpec), so a spec built from customer input cannot inject SQL.