Expand description
The query-building half of qbrs: scope tracking,
expressions, the SELECT/INSERT/UPDATE/DELETE builders, and the SQL
renderer. No I/O, no async runtime, no driver — and no dependency at all
unless a schema asks for one (the chrono, uuid and decimal features).
Depend on qbrs rather than this crate directly; it re-exports everything
here alongside #[derive(Table)], #[derive(FromRow)], label! and
with!, which have to be proc macros and so live in qbrs-macros.
scope is the load-bearing module: a query’s FROM/JOIN set is a flat
type-level list, and every “is this column in scope, and is the join making
it nullable?” question is a lookup in it. Reading that module first makes
the rest of the crate follow.
Modules§
- cte
- Common table expressions:
WITH name AS (..) SELECT .. FROM name ... - delete
DELETE FROM .. WHERE ...- dialect
- Dialect markers and capability gating.
- expr
- SQL types, columns, and the typed expression AST.
- insert
INSERT INTO .. VALUES ...- prepare
prepare!{}: declares a named, typed parameter struct for a reusable prepared query (select::Prepared). See that module’s doc comment for the design and its soundness caveat.- raw
- The
sql!{}escape hatch: a pressure valve for SQL constructs the typed builder doesn’t cover yet. - render
- Rendering
ExprKindinto a SQL string plus a positional parameter list. Generic overD: Dialectfor identifier quoting and placeholder style, butExprKind/Valuethemselves stay closed, non-generic types, so this costs one instantiation per dialect used in a program rather than one per query shape. - row
- Rows keyed by column rather than by position.
- scope
- Type-level FROM/JOIN scope tracking.
- select
- The
SELECTbuilder:select(..).from(..).join(..).filter(..) .order_by(..).limit(..), in SQL keyword order, with tables passed as arguments rather than by turbofish. - statement
- What
INSERT,UPDATEandDELETEhave in common: they write to one table, and any of them can be asked for the rows it touched. - update
UPDATE .. SET .. WHERE ...- window
- Window functions:
row_number()/rank()/dense_rank().over(window() .partition_by(..).order_by(..)).