Documentation
¶
Overview ¶
Package clickhouse opens the application's ClickHouse connection pools (admin + readonly) and exposes a golang-migrate driver constructor. The bootstrap.go file in this package owns the one-time-per-boot DDL needed to make a fresh CH instance ready for the app (CREATE DATABASE, provision the readonly user).
Index ¶
- func CreateDatabase(ctx context.Context, cfg config.Config) error
- func MigrateDriver(db *sql.DB, cfg config.Config) (database.Driver, error)
- func OpenAdmin(ctx context.Context, cfg config.Config) (*sql.DB, error)
- func OpenReadonly(ctx context.Context, cfg config.Config) (*sql.DB, error)
- func ProvisionReadonlyUser(ctx context.Context, db *sql.DB, cfg config.Config) error
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func CreateDatabase ¶
CreateDatabase runs `CREATE DATABASE IF NOT EXISTS <dbname>` as admin. Idempotent. Uses a connection that does NOT pre-select a database, since the database may not exist yet on first boot.
func MigrateDriver ¶
MigrateDriver wraps an admin *sql.DB as a golang-migrate driver scoped to cfg.ClickHouseDatabase. The caller still owns the *sql.DB it passes in; migrate.Run closes the driver but not the underlying DB (matches the clickhouse migrate driver's behavior).
func OpenAdmin ¶
OpenAdmin returns a connected *sql.DB authenticated as the admin user, scoped to the analytics database.
func OpenReadonly ¶
OpenReadonly returns a connected *sql.DB authenticated as the readonly user. Must be called after ProvisionReadonlyUser has succeeded for this boot.
func ProvisionReadonlyUser ¶
ProvisionReadonlyUser makes the readonly user's state deterministic on every boot:
CREATE USER IF NOT EXISTS <user> IDENTIFIED ... SETTINGS readonly=2 ALTER USER <user> IDENTIFIED ... SETTINGS readonly=2 -- forces pw/settings GRANT SELECT ON <db>.* TO <user> -- idempotent CREATE ROW POLICY OR REPLACE ... ON system.tables USING 0 TO <user>
Eliminates silent divergence if a pre-existing user has wrong password, readonly setting, or grants (review finding 2.1 / decision 5).
readonly=2 keeps DDL/DML blocked but allows the app to attach per-request SELECT settings such as additional_table_filters, max_result_rows, and max_execution_time. The built-in readonly profile is too strict for Step 6.
system.tables is in ClickHouse's hardcoded always-accessible allowlist, so it cannot be revoked or gated by select_from_system_db_requires_grant. Its total_rows/total_bytes columns expose global counts across every project — a cross-tenant aggregate leak. A USING 0 row policy hides all of its rows from the readonly user; unlike an app-layer SQL blocklist it can't be bypassed by SELECT * or quoted identifiers. Schema introspection uses DESCRIBE, not system.tables, so it is unaffected.
Types ¶
This section is empty.