Skip to main content

autumn_plugin_clickhouse/
lib.rs

1//! Autumn plugin for ClickHouse.
2//!
3//! Add [`ClickHousePlugin`] to the app. Then use the [`ClickHouse`] extractor in a handler.
4//! ClickHouse is the OLAP/analytics counterpart to the `DuckDB` plugin: it queries a remote
5//! ClickHouse server over HTTP instead of an embedded database.
6//!
7//! ```rust,no_run
8//! use autumn_plugin_clickhouse::{ClickHouse, ClickHousePlugin, ClickHouseResultExt as _};
9//! use autumn_web::prelude::*;
10//!
11//! #[derive(clickhouse::Row, serde::Serialize, serde::Deserialize)]
12//! struct EventCount {
13//!     name: String,
14//!     count: u64,
15//! }
16//!
17//! #[get("/events/counts")]
18//! async fn event_counts(db: ClickHouse) -> AutumnResult<Json<Vec<EventCount>>> {
19//!     let rows = db
20//!         .fetch_all::<EventCount>("SELECT name, count() AS count FROM events GROUP BY name")
21//!         .await
22//!         .or_http()?;
23//!     Ok(Json(rows))
24//! }
25//!
26//! # async fn run() {
27//! autumn_web::app()
28//!     .plugin(ClickHousePlugin::new().configure(|c| {
29//!         c.url = "http://localhost:8123".into();
30//!         c.database = "analytics".into();
31//!     }))
32//!     .routes(routes![event_counts])
33//!     .run()
34//!     .await;
35//! # }
36//! ```
37//!
38//! The plugin reads `[clickhouse]` in `autumn.toml`. See [`config`] for the keys.
39//!
40//! # What the plugin gives
41//!
42//! - [`ClickHouse`]: typed `SELECT` queries with `#[derive(clickhouse::Row)]` structs,
43//!   one-batch [`ClickHouse::insert`] and the batching [`Inserter`],
44//!   plus [`ClickHouse::execute`] for DDL.
45//! - [`migrate`]: runs ordered `CREATE TABLE IF NOT EXISTS` migrations at startup.
46//! - A `HealthOnly` readiness check that runs `SELECT 1`, and Prometheus call counters.
47//!
48//! # Limits
49//!
50//! - Each call has the `timeout_ms` timeout. A timed-out call gives [`ClickHouseError::Timeout`].
51//! - Rows must be owned structs: `#[derive(clickhouse::Row, serde::Serialize, serde::Deserialize)]`
52//!   without lifetimes.
53//! - Logs, error text and `Debug` output do not have row data, server messages or passwords.
54//! - The plugin needs a reachable ClickHouse server. The startup ping stops the boot if the
55//!   server is down. Tests use the `clickhouse` mock server, not a live server.
56
57mod client;
58pub mod config;
59mod error;
60mod health;
61mod metrics;
62mod migrate;
63mod plugin;
64
65/// The `clickhouse` crate that the plugin uses. Use it for the `Row` derive.
66pub use clickhouse;
67pub use client::{ClickHouse, InsertStats, Inserter};
68pub use config::{ClickHouseConfig, ConfigError, DEFAULT_SECTION};
69pub use error::{ClickHouseError, ClickHouseResultExt, ErrorKind};
70pub use metrics::Metrics;
71pub use migrate::{Migration, migrate};
72pub use plugin::{ClickHousePlugin, PLUGIN_NAME};