pub struct QueryBuilder<T> {
pub use_replica: bool,
/* private fields */
}Expand description
A fluent builder that produces parameterized SQL statements.
Conditions added with where_* methods are joined with AND.
Use or_where_* variants to join with OR.
§Example
use rok_orm_core::{QueryBuilder, SqlValue};
let (sql, params) = QueryBuilder::<()>::new("users")
.where_eq("active", true)
.or_where_eq("role", "admin")
.order_by_desc("created_at")
.limit(20)
.offset(40)
.to_sql();
assert!(sql.contains("WHERE"));
assert!(sql.contains("ORDER BY created_at DESC"));
assert!(sql.contains("LIMIT 20"));
assert!(sql.contains("OFFSET 40"));
assert_eq!(params.len(), 2);Fields§
§use_replica: boolWhen true (default), the execution layer should route this query to a
read replica if one is configured. Set to false via [on_write_db].
Implementations§
Source§impl<T> QueryBuilder<T>
impl<T> QueryBuilder<T>
pub fn new(table: impl Into<String>) -> Self
pub fn select(self, cols: &[&str]) -> Self
Sourcepub fn select_raw(self, expr: &str) -> Self
pub fn select_raw(self, expr: &str) -> Self
Emit SELECT <raw_expr> FROM … — overrides select().
Sourcepub fn add_select_expr(self, expr: impl Into<String>) -> Self
pub fn add_select_expr(self, expr: impl Into<String>) -> Self
Append an extra expression to the SELECT list without replacing existing columns.
Used internally by with_count, with_sum, etc.
Sourcepub fn distinct_on(self, cols: &[&str]) -> Self
pub fn distinct_on(self, cols: &[&str]) -> Self
Emit SELECT DISTINCT ON (col, …) … (PostgreSQL only).
Sourcepub fn inner_join(self, table: &str, on: &str) -> Self
pub fn inner_join(self, table: &str, on: &str) -> Self
Add an INNER JOIN table ON condition.
use rok_orm_core::QueryBuilder;
let (sql, _) = QueryBuilder::<()>::new("orders")
.inner_join("users", "users.id = orders.user_id")
.select(&["orders.id", "users.name"])
.to_sql();
assert!(sql.contains("INNER JOIN users ON users.id = orders.user_id"));Sourcepub fn right_join(self, table: &str, on: &str) -> Self
pub fn right_join(self, table: &str, on: &str) -> Self
Add a RIGHT JOIN table ON condition.
Sourcepub fn join_raw(self, raw: &str) -> Self
pub fn join_raw(self, raw: &str) -> Self
Append a raw JOIN fragment verbatim (e.g. "INNER JOIN s ON s.user_id = users.id AND s.active").
Sourcepub fn group_by(self, cols: &[&str]) -> Self
pub fn group_by(self, cols: &[&str]) -> Self
Add a GROUP BY clause.
use rok_orm_core::QueryBuilder;
let (sql, _) = QueryBuilder::<()>::new("orders")
.select(&["user_id", "COUNT(*) as total"])
.group_by(&["user_id"])
.having("COUNT(*) > 5")
.to_sql();
assert!(sql.contains("GROUP BY user_id"));
assert!(sql.contains("HAVING COUNT(*) > 5"));pub fn where_eq(self, col: &str, val: impl Into<SqlValue>) -> Self
pub fn where_ne(self, col: &str, val: impl Into<SqlValue>) -> Self
pub fn where_gt(self, col: &str, val: impl Into<SqlValue>) -> Self
pub fn where_gte(self, col: &str, val: impl Into<SqlValue>) -> Self
pub fn where_lt(self, col: &str, val: impl Into<SqlValue>) -> Self
pub fn where_lte(self, col: &str, val: impl Into<SqlValue>) -> Self
pub fn where_like(self, col: &str, pattern: &str) -> Self
pub fn where_not_like(self, col: &str, pattern: &str) -> Self
pub fn where_null(self, col: &str) -> Self
pub fn where_not_null(self, col: &str) -> Self
pub fn where_in(self, col: &str, vals: Vec<impl Into<SqlValue>>) -> Self
pub fn where_not_in(self, col: &str, vals: Vec<impl Into<SqlValue>>) -> Self
pub fn where_between( self, col: &str, lo: impl Into<SqlValue>, hi: impl Into<SqlValue>, ) -> Self
pub fn where_not_between( self, col: &str, lo: impl Into<SqlValue>, hi: impl Into<SqlValue>, ) -> Self
pub fn where_raw(self, sql: &str) -> Self
Sourcepub fn where_ilike(self, col: &str, pattern: &str) -> Self
pub fn where_ilike(self, col: &str, pattern: &str) -> Self
Add AND col ILIKE pattern (case-insensitive LIKE, PostgreSQL only).
Sourcepub fn or_where_ilike(self, col: &str, pattern: &str) -> Self
pub fn or_where_ilike(self, col: &str, pattern: &str) -> Self
Add OR col ILIKE pattern.
Sourcepub fn where_json(self, col: &str, key: &str, val: impl Into<SqlValue>) -> Self
pub fn where_json(self, col: &str, key: &str, val: impl Into<SqlValue>) -> Self
Add AND col->>'key' = val (JSONB text extraction, PostgreSQL).
Sourcepub fn or_where_json(
self,
col: &str,
key: &str,
val: impl Into<SqlValue>,
) -> Self
pub fn or_where_json( self, col: &str, key: &str, val: impl Into<SqlValue>, ) -> Self
Add OR col->>'key' = val.
Sourcepub fn where_json_contains(self, col: &str, json_val: &str) -> Self
pub fn where_json_contains(self, col: &str, json_val: &str) -> Self
Add AND col @> 'json_val'::jsonb (JSONB containment, PostgreSQL).
Sourcepub fn where_column(self, col: &str, op: &str, val: impl Into<SqlValue>) -> Self
pub fn where_column(self, col: &str, op: &str, val: impl Into<SqlValue>) -> Self
Add AND col <op> val — ergonomic alias for [where_op].
use rok_orm_core::QueryBuilder;
let (sql, _) = QueryBuilder::<()>::new("users").where_column("age", ">", 18i64).to_sql();
assert!(sql.contains("age > $1"));Sourcepub fn where_op(self, col: &str, op: &str, val: impl Into<SqlValue>) -> Self
pub fn where_op(self, col: &str, op: &str, val: impl Into<SqlValue>) -> Self
Add a comparison condition with an explicit operator string (=, !=, >, >=, <, <=).
Sourcepub fn where_group<F>(self, f: F) -> Self
pub fn where_group<F>(self, f: F) -> Self
Add a grouped sub-condition: AND (sub_cond1 AND/OR sub_cond2 …).
The closure receives a fresh QueryBuilder to build the sub-conditions.
Only the conditions of that builder are used (table/select/order etc. are ignored).
Sourcepub fn or_where_group<F>(self, f: F) -> Self
pub fn or_where_group<F>(self, f: F) -> Self
Add an OR grouped sub-condition: OR (sub_cond1 AND/OR sub_cond2 …).
Sourcepub fn or_where(self, col: &str, val: impl Into<SqlValue>) -> Self
pub fn or_where(self, col: &str, val: impl Into<SqlValue>) -> Self
Add OR col = val — ergonomic shorthand for [or_where_eq].
pub fn or_where_eq(self, col: &str, val: impl Into<SqlValue>) -> Self
pub fn or_where_ne(self, col: &str, val: impl Into<SqlValue>) -> Self
pub fn or_where_gt(self, col: &str, val: impl Into<SqlValue>) -> Self
pub fn or_where_gte(self, col: &str, val: impl Into<SqlValue>) -> Self
pub fn or_where_lt(self, col: &str, val: impl Into<SqlValue>) -> Self
pub fn or_where_lte(self, col: &str, val: impl Into<SqlValue>) -> Self
pub fn or_where_like(self, col: &str, pattern: &str) -> Self
pub fn or_where_null(self, col: &str) -> Self
pub fn or_where_not_null(self, col: &str) -> Self
pub fn or_where_in(self, col: &str, vals: Vec<impl Into<SqlValue>>) -> Self
pub fn or_where_between( self, col: &str, lo: impl Into<SqlValue>, hi: impl Into<SqlValue>, ) -> Self
pub fn or_where_raw(self, sql: &str) -> Self
pub fn order_by(self, col: &str) -> Self
pub fn order_by_desc(self, col: &str) -> Self
Sourcepub fn order_by_raw(self, expr: &str) -> Self
pub fn order_by_raw(self, expr: &str) -> Self
Append a raw ORDER BY expression (e.g. "NULLS LAST, score DESC").
Rendered after any column-based orders.
Sourcepub fn order_by_many(self, cols: &[(&str, OrderDir)]) -> Self
pub fn order_by_many(self, cols: &[(&str, OrderDir)]) -> Self
Append multiple column orders at once.
Sourcepub fn reorder_desc(self, col: &str) -> Self
pub fn reorder_desc(self, col: &str) -> Self
Replace all existing orders with col DESC.
pub fn limit(self, n: usize) -> Self
pub fn offset(self, n: usize) -> Self
Sourcepub fn to_sql(&self) -> (String, Vec<SqlValue>)
pub fn to_sql(&self) -> (String, Vec<SqlValue>)
Build a parameterized SELECT statement (PostgreSQL $N placeholders).
Returns (sql, params) — params are ordered to match $1, $2, …
For SQLite use to_sql_with_dialect(Dialect::Sqlite).
Sourcepub fn to_sql_with_dialect(&self, dialect: Dialect) -> (String, Vec<SqlValue>)
pub fn to_sql_with_dialect(&self, dialect: Dialect) -> (String, Vec<SqlValue>)
Build a parameterized SELECT statement for the given Dialect.
Dialect::Postgresemits$1, $2, …Dialect::Sqliteemits?, ?, …
Sourcepub fn to_count_sql(&self) -> (String, Vec<SqlValue>)
pub fn to_count_sql(&self) -> (String, Vec<SqlValue>)
Build a SELECT COUNT(*) FROM … statement (PostgreSQL dialect).
Sourcepub fn to_count_sql_with_dialect(
&self,
dialect: Dialect,
) -> (String, Vec<SqlValue>)
pub fn to_count_sql_with_dialect( &self, dialect: Dialect, ) -> (String, Vec<SqlValue>)
Build a SELECT COUNT(*) FROM … statement for the given dialect.
Sourcepub fn to_delete_sql(&self) -> (String, Vec<SqlValue>)
pub fn to_delete_sql(&self) -> (String, Vec<SqlValue>)
Build a DELETE FROM … WHERE … statement (PostgreSQL dialect).
Sourcepub fn to_delete_sql_with_dialect(
&self,
dialect: Dialect,
) -> (String, Vec<SqlValue>)
pub fn to_delete_sql_with_dialect( &self, dialect: Dialect, ) -> (String, Vec<SqlValue>)
Build a DELETE FROM … WHERE … statement for the given dialect.
Sourcepub fn to_update_sql(
&self,
data: &[(&str, SqlValue)],
) -> (String, Vec<SqlValue>)
pub fn to_update_sql( &self, data: &[(&str, SqlValue)], ) -> (String, Vec<SqlValue>)
Build an UPDATE … SET … WHERE … statement (PostgreSQL dialect).
Sourcepub fn to_update_sql_with_dialect(
&self,
dialect: Dialect,
data: &[(&str, SqlValue)],
) -> (String, Vec<SqlValue>)
pub fn to_update_sql_with_dialect( &self, dialect: Dialect, data: &[(&str, SqlValue)], ) -> (String, Vec<SqlValue>)
Build an UPDATE … SET … WHERE … statement for the given dialect.
Sourcepub fn insert_sql(
table: &str,
data: &[(&str, SqlValue)],
) -> (String, Vec<SqlValue>)
pub fn insert_sql( table: &str, data: &[(&str, SqlValue)], ) -> (String, Vec<SqlValue>)
Build an INSERT INTO statement (PostgreSQL $N placeholders).
Sourcepub fn insert_sql_with_dialect(
dialect: Dialect,
table: &str,
data: &[(&str, SqlValue)],
) -> (String, Vec<SqlValue>)
pub fn insert_sql_with_dialect( dialect: Dialect, table: &str, data: &[(&str, SqlValue)], ) -> (String, Vec<SqlValue>)
Build an INSERT INTO statement for the given dialect.
Sourcepub fn bulk_insert_sql(
table: &str,
rows: &[Vec<(&str, SqlValue)>],
) -> (String, Vec<SqlValue>)
pub fn bulk_insert_sql( table: &str, rows: &[Vec<(&str, SqlValue)>], ) -> (String, Vec<SqlValue>)
Build an INSERT INTO … VALUES …, … statement for multiple rows.
All rows must have the same columns in the same order as the first row.
use rok_orm_core::{QueryBuilder, SqlValue};
let rows: Vec<Vec<(&str, SqlValue)>> = vec![
vec![("name", "Alice".into()), ("email", "a@a.com".into())],
vec![("name", "Bob".into()), ("email", "b@b.com".into())],
];
let (sql, params) = QueryBuilder::<()>::bulk_insert_sql("users", &rows);
assert!(sql.contains("($1, $2), ($3, $4)"));
assert_eq!(params.len(), 4);Sourcepub fn update_sql(
table: &str,
data: &[(&str, SqlValue)],
conditions: &[(JoinOp, Condition)],
) -> (String, Vec<SqlValue>)
pub fn update_sql( table: &str, data: &[(&str, SqlValue)], conditions: &[(JoinOp, Condition)], ) -> (String, Vec<SqlValue>)
Build an UPDATE … SET … WHERE … statement from explicit conditions.
Prefer [to_update_sql] when you already have a QueryBuilder.
Sourcepub fn when<F>(self, condition: bool, f: F) -> Selfwhere
F: FnOnce(Self) -> Self,
pub fn when<F>(self, condition: bool, f: F) -> Selfwhere
F: FnOnce(Self) -> Self,
Apply f(self) only when condition is true; otherwise pass through unchanged.
use rok_orm_core::QueryBuilder;
let active_only = true;
let (sql, _) = QueryBuilder::<()>::new("users")
.when(active_only, |q| q.where_eq("active", true))
.to_sql();
assert!(sql.contains("WHERE active = $1"));Sourcepub fn when_some<V, F>(self, opt: Option<V>, f: F) -> Selfwhere
F: FnOnce(Self, V) -> Self,
pub fn when_some<V, F>(self, opt: Option<V>, f: F) -> Selfwhere
F: FnOnce(Self, V) -> Self,
Apply f(self, val) when opt is Some(val); otherwise pass through unchanged.
use rok_orm_core::QueryBuilder;
let role: Option<&str> = Some("admin");
let (sql, _) = QueryBuilder::<()>::new("users")
.when_some(role, |q, r| q.where_eq("role", r))
.to_sql();
assert!(sql.contains("WHERE role = $1"));Sourcepub fn push_condition(self, op: JoinOp, cond: Condition) -> Self
pub fn push_condition(self, op: JoinOp, cond: Condition) -> Self
Push an arbitrary Condition with the given join operator.
Useful when building conditions programmatically (e.g. Condition::Subquery).
Sourcepub fn on_write_db(self) -> Self
pub fn on_write_db(self) -> Self
Force this query to the write (primary) pool, bypassing read replicas.
Sourcepub fn nearest_to(self, col: &str, embedding: &[f32], k: usize) -> Self
pub fn nearest_to(self, col: &str, embedding: &[f32], k: usize) -> Self
KNN search: ORDER BY {col} <-> '[…]'::vector LIMIT k (L2 distance).
Sourcepub fn where_cosine_distance(
self,
col: &str,
embedding: &[f32],
op: &str,
threshold: f64,
) -> Self
pub fn where_cosine_distance( self, col: &str, embedding: &[f32], op: &str, threshold: f64, ) -> Self
WHERE {col} <=> '[…]'::vector {op} {threshold} (cosine distance).
Sourcepub fn where_vector_distance(
self,
col: &str,
embedding: &[f32],
op: &str,
threshold: f64,
) -> Self
pub fn where_vector_distance( self, col: &str, embedding: &[f32], op: &str, threshold: f64, ) -> Self
WHERE {col} <-> '[…]'::vector {op} {threshold} (L2 distance filter).
Sourcepub fn where_inner_product(
self,
col: &str,
embedding: &[f32],
op: &str,
threshold: f64,
) -> Self
pub fn where_inner_product( self, col: &str, embedding: &[f32], op: &str, threshold: f64, ) -> Self
WHERE {col} <#> '[…]'::vector {op} {threshold} (negative inner product).
Sourcepub fn conditions(&self) -> &[(JoinOp, Condition)]
pub fn conditions(&self) -> &[(JoinOp, Condition)]
Expose the raw conditions (useful for callers that need to inspect them).
Sourcepub fn to_where_clause(&self) -> (String, Vec<SqlValue>)
pub fn to_where_clause(&self) -> (String, Vec<SqlValue>)
Build only the WHERE … fragment and its bound parameters.
Useful when you need to compose a raw UPDATE … SET … WHERE … or similar
statement while still leveraging the query builder’s condition logic.
Returns ("", vec![]) when there are no conditions.
Sourcepub fn to_aggregate_sql(&self, agg_expr: &str) -> (String, Vec<SqlValue>)
pub fn to_aggregate_sql(&self, agg_expr: &str) -> (String, Vec<SqlValue>)
Build SELECT <agg_expr> FROM … WHERE … for aggregates like MAX(col), SUM(col).
agg_expr is a raw SQL expression, e.g. "MAX(total)" or "SUM(price)".
Sourcepub fn upsert_sql(
table: &str,
data: &[(&str, SqlValue)],
conflict_cols: &[&str],
) -> (String, Vec<SqlValue>)
pub fn upsert_sql( table: &str, data: &[(&str, SqlValue)], conflict_cols: &[&str], ) -> (String, Vec<SqlValue>)
Build an INSERT INTO … ON CONFLICT (cols) DO UPDATE SET … statement (PostgreSQL).
data— column-value pairs to insertconflict_cols— the conflict target columnsupdate_cols— which columns to update on conflict (defaults to alldatacolumns that are not inconflict_colswhen empty)
Trait Implementations§
Source§impl<T: Clone> Clone for QueryBuilder<T>
impl<T: Clone> Clone for QueryBuilder<T>
Source§fn clone(&self) -> QueryBuilder<T>
fn clone(&self) -> QueryBuilder<T>
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more