Skip to main content

sqlmodel_query/
lib.rs

1//! Type-safe SQL query builder for SQLModel Rust.
2//!
3//! `sqlmodel-query` is the **query construction layer**. It provides the fluent builder
4//! API and expression DSL that turn `Model` metadata into executable SQL plus parameters.
5//!
6//! # Role In The Architecture
7//!
8//! - **Query macros**: `select!`, `insert!`, `update!`, `delete!` build typed queries.
9//! - **Expression DSL**: `Expr` and operators build WHERE/HAVING clauses safely.
10//! - **Dialect support**: generates SQL for Postgres, MySQL, and SQLite.
11//!
12//! The resulting queries execute through the `Connection` trait from `sqlmodel-core`.
13//! Most users access these builders via the `sqlmodel` facade crate.
14
15pub mod builder;
16pub mod cache;
17pub mod clause;
18pub mod cte;
19pub mod eager;
20pub mod expr;
21pub mod join;
22pub mod select;
23pub mod set_ops;
24pub mod subquery;
25
26pub use builder::{
27    DeleteBuilder, InsertBuilder, InsertManyBuilder, OnConflict, QueryBuilder, SetClause,
28    UpdateBuilder,
29};
30pub use cache::{StatementCache, cache_key};
31pub use clause::{Limit, Offset, OrderBy, Where};
32pub use cte::{Cte, CteRef, WithQuery};
33pub use eager::{EagerLoader, IncludePath};
34pub use expr::{
35    BinaryOp, Dialect, Expr, UnaryOp, WindowBuilder, WindowFrame, WindowFrameBound, WindowFrameType,
36};
37pub use join::{Join, JoinType};
38pub use select::{
39    PolymorphicJoined, PolymorphicJoined2, PolymorphicJoined3, PolymorphicJoinedSelect,
40    PolymorphicJoinedSelect2, PolymorphicJoinedSelect3, Select,
41};
42pub use set_ops::{
43    SetOpType, SetOperation, except, except_all, intersect, intersect_all, union, union_all,
44};
45pub use subquery::SelectQuery;
46
47use asupersync::{Cx, Outcome};
48use sqlmodel_core::{Connection, Row, Value};
49
50/// Create a SELECT query for a model.
51///
52/// # Example
53///
54/// ```ignore
55/// let heroes = select!(Hero)
56///     .filter(Hero::age.gt(18))
57///     .order_by(Hero::name.asc())
58///     .all(cx, &conn)
59///     .await?;
60/// ```
61#[macro_export]
62macro_rules! select {
63    ($model:ty) => {
64        $crate::Select::<$model>::new()
65    };
66}
67
68/// Create an INSERT query for a model.
69///
70/// # Example
71///
72/// ```ignore
73/// let id = insert!(hero)
74///     .execute(cx, &conn)
75///     .await?;
76/// ```
77#[macro_export]
78macro_rules! insert {
79    ($model:expr) => {
80        $crate::builder::InsertBuilder::new($model)
81    };
82}
83
84/// Create a bulk INSERT query for multiple models.
85///
86/// # Example
87///
88/// ```ignore
89/// let heroes = vec![hero1, hero2, hero3];
90/// let count = insert_many!(heroes)
91///     .execute(cx, &conn)
92///     .await?;
93///
94/// // With UPSERT
95/// insert_many!(heroes)
96///     .on_conflict_do_update(&["name", "age"])
97///     .execute(cx, &conn)
98///     .await?;
99/// ```
100#[macro_export]
101macro_rules! insert_many {
102    ($models:expr) => {
103        $crate::builder::InsertManyBuilder::new($models)
104    };
105}
106
107/// Create an UPDATE query for a model.
108///
109/// # Example
110///
111/// ```ignore
112/// update!(hero)
113///     .execute(cx, &conn)
114///     .await?;
115/// ```
116#[macro_export]
117macro_rules! update {
118    ($model:expr) => {
119        $crate::builder::UpdateBuilder::new($model)
120    };
121}
122
123/// Create a DELETE query for a model.
124///
125/// # Example
126///
127/// ```ignore
128/// delete!(Hero)
129///     .filter(Hero::age.lt(18))
130///     .execute(cx, &conn)
131///     .await?;
132/// ```
133#[macro_export]
134macro_rules! delete {
135    ($model:ty) => {
136        $crate::builder::DeleteBuilder::<$model>::new()
137    };
138}
139
140/// Raw SQL query execution.
141///
142/// For queries that can't be expressed with the type-safe builder.
143pub async fn raw_query<C: Connection>(
144    cx: &Cx,
145    conn: &C,
146    sql: &str,
147    params: &[Value],
148) -> Outcome<Vec<Row>, sqlmodel_core::Error> {
149    conn.query(cx, sql, params).await
150}
151
152/// Raw SQL statement execution.
153pub async fn raw_execute<C: Connection>(
154    cx: &Cx,
155    conn: &C,
156    sql: &str,
157    params: &[Value],
158) -> Outcome<u64, sqlmodel_core::Error> {
159    conn.execute(cx, sql, params).await
160}