queryweave-sql 0.1.0

The SQL runtime of queryweave: database-agnostic sqlx query building (WHERE, ORDER BY, LIMIT/OFFSET, SET) from the data queryweave's derives generate.
Documentation
//! The `queryweave` runtime for the persistence layer: the traits and SQL the
//! code generated for entities and wrappers (`Columns`, `AppendToQuery`,
//! `AppendToQueryWithSeparator`) names, on top of the core runtime
//! (`queryweave`), which it re-exports so that code names only this crate.
//!
//! This is where the domain's database-agnostic filters, sorting and writes
//! (`queryweave::FilterCondition`, `queryweave::SortKey`,
//! `queryweave::FieldValue`) become SQL. They name domain fields; the
//! [`Columns`] of the entity storing them say which column each lives in, and
//! write the SQL against them.
//!
//! The SQL is portable across the databases sqlx supports: Postgres,
//! MySQL/MariaDB and SQLite (any [`BindValues`] database). What stays
//! database-specific is semantics, not syntax: `LIKE` is case-sensitive on
//! Postgres but case-insensitive on SQLite (for ASCII) and under MySQL's
//! default collations, and column names are written unquoted, so they must not
//! be reserved words of the database.

mod bind;
mod columns;
mod sql;

pub use queryweave::*;

pub use bind::BindValues;
pub use columns::{
    Columns, Message, column_for, first_field_without_column, missing_column_message,
};
pub use sql::{push_page, sql_direction, sql_operator};

/// The sqlx query builder the clauses are appended to, and the separated
/// builder `Columns::push_assignments` returns: re-exported so the generated
/// code (and its callers) name the same sqlx as this crate, whatever the user
/// calls their own sqlx dependency.
pub use sqlx::{QueryBuilder, query_builder::Separated};

/// Not public API: what the code generated by `queryweave-derive`
/// calls.
///
/// The inherent methods `#[derive(Columns)]` emits run the column check
/// themselves (so a missing column is reported at *their* caller, the line
/// writing the data, rather than inside the derive) and then call the
/// unchecked writers here, so the check is not reported twice.
#[doc(hidden)]
pub mod __private {
    pub use crate::columns::assert_model_columns;
    #[cfg(feature = "merge-patch")]
    pub use crate::sql::push_assignments;
    pub use crate::sql::{push_conditions, push_order_by};
    pub use queryweave::__private::*;
}

/// Append the filters query to the parent query.
pub trait AppendToQuery {
    /// Append the filters query to the parent query, for any [`BindValues`]
    /// database.
    fn append_to_query<DB, F>(
        &self,
        query_builder: &mut QueryBuilder<'_, DB>,
        privileged_guard_option: Option<F>,
    ) where
        DB: BindValues,
        F: FnOnce(&mut QueryBuilder<'_, DB>, &Self);
}

/// Append to query individual filters.
pub trait AppendToQueryWithSeparator {
    /// Append to query individual filters, for any [`BindValues`] database.
    fn append_to_query<DB: BindValues>(
        &self,
        query_builder: &mut QueryBuilder<'_, DB>,
        separator: &str,
    );
}