Skip to main content

Crate qbrs_core

Crate qbrs_core 

Source
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 ExprKind into a SQL string plus a positional parameter list. Generic over D: Dialect for identifier quoting and placeholder style, but ExprKind/Value themselves 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 SELECT builder: select(..).from(..).join(..).filter(..) .order_by(..).limit(..), in SQL keyword order, with tables passed as arguments rather than by turbofish.
statement
What INSERT, UPDATE and DELETE have 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(..)).

Macros§

prepare
sql
sql!(Bool, "lower(?) = ?", users::email, "dan") -> a Declared expression over whatever tables its slots name — keyed as row::Anon, so it is selectable but not readable by name until .label(..). Slots are filled positionally, left to right.