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

39 lines
1.9 KiB
Markdown

# 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:**
```rust
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:**
```rust
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:**
```rust
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:**
```rust
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`.