KeiSeiKit-1.0/_blocks/db-sqlx.md
Parfii-bot 0be354a920 KeiSeiKit-public — clean state
Single-commit clean baseline after security scrub of niche-tells,
project codenames, internal jargon, and contributor-email leaks.

Contents:
- 100 Rust crates (_primitives/_rust/)
- 37 agent manifests (_manifests/) + generated specs (_generated/)
- 67 user-invocable skills (skills/)
- 33 hooks (hooks/)
- Composition blocks (_blocks/)
- Documentation (docs/, README.md)
- TS adapter packages (_ts_packages/)
- Assembler (_assembler/)
- Roles (_roles/)
- Templates (_templates/)
- Forgejo CI (.forgejo/)

Author: Denis Parfionovich <info@greendragon.info>

License: see LICENSE.
2026-05-01 12:09:03 +08:00

1.9 KiB

DB — SQLx (Rust) patterns

Use when the project is Rust and needs a SQL-first (not ORM) query layer with compile-time checking. Pairs with stack-rust-axum, stack-rust-cli. [E4 — expert assessment]

Core versions: sqlx = "0.8" (current as of 2026-04) with features runtime-tokio, tls-rustls, and one of postgres / sqlite / mysql. Never mix runtime-async-std and runtime-tokio — they clash at link time. [UNVERIFIED: verify latest on crates.io before pinning]

Compile-time checked queries:

let row = sqlx::query!("SELECT id, name FROM users WHERE id = $1", user_id)
    .fetch_one(&pool).await?;

Requires either:

  • DATABASE_URL env set during cargo build (live DB) — convenient in dev, brittle in CI.
  • Offline mode (recommended for CI): cargo sqlx prepare commits .sqlx/query-*.json to the repo, then CI builds with SQLX_OFFLINE=true and no DB access.

Connection pool:

let pool = sqlx::postgres::PgPoolOptions::new()
    .max_connections(20)                  // tune to server max_connections / replica count
    .acquire_timeout(Duration::from_secs(3))
    .connect(&database_url).await?;

Single PgPool per process, Arc-cloned into handlers. Don't open per-request.

Migrations:

sqlx::migrate!("./migrations").run(&pool).await?;

Built-in runner reads YYYYMMDDHHMMSS_<name>.sql files. For richer UX (up/down, status, create scaffolding) use the kei-migrate primitive in this kit.

Transactions:

let mut tx = pool.begin().await?;
sqlx::query!("...").execute(&mut *tx).await?;
sqlx::query!("...").execute(&mut *tx).await?;
tx.commit().await?;                       // explicit; Drop = rollback

Forbidden: sqlx::query (non-macro) with untrusted input without bind() — that's string concat, i.e. SQL injection; .unwrap() on DB calls in prod paths; enabling both runtime-tokio and runtime-async-std; committing a live DATABASE_URL to .env.example.