Skip to main content

QueryEngine

Trait QueryEngine 

Source
pub trait QueryEngine:
    Send
    + Sync
    + Clone
    + 'static {
    // Required methods
    fn query_many<T: Model + FromRow + Send + 'static>(
        &self,
        sql: &str,
        params: Vec<FilterValue>,
    ) -> BoxFuture<'_, QueryResult<Vec<T>>>;
    fn query_one<T: Model + FromRow + Send + 'static>(
        &self,
        sql: &str,
        params: Vec<FilterValue>,
    ) -> BoxFuture<'_, QueryResult<T>>;
    fn query_optional<T: Model + FromRow + Send + 'static>(
        &self,
        sql: &str,
        params: Vec<FilterValue>,
    ) -> BoxFuture<'_, QueryResult<Option<T>>>;
    fn execute_insert<T: Model + FromRow + Send + 'static>(
        &self,
        sql: &str,
        params: Vec<FilterValue>,
    ) -> BoxFuture<'_, QueryResult<T>>;
    fn execute_update<T: Model + FromRow + Send + 'static>(
        &self,
        sql: &str,
        params: Vec<FilterValue>,
    ) -> BoxFuture<'_, QueryResult<Vec<T>>>;
    fn execute_delete(
        &self,
        sql: &str,
        params: Vec<FilterValue>,
    ) -> BoxFuture<'_, QueryResult<u64>>;
    fn execute_raw(
        &self,
        sql: &str,
        params: Vec<FilterValue>,
    ) -> BoxFuture<'_, QueryResult<u64>>;
    fn count(
        &self,
        sql: &str,
        params: Vec<FilterValue>,
    ) -> BoxFuture<'_, QueryResult<u64>>;

    // Provided methods
    fn dialect(&self) -> &dyn SqlDialect { ... }
    fn aggregate_query(
        &self,
        sql: &str,
        params: Vec<FilterValue>,
    ) -> BoxFuture<'_, QueryResult<Vec<HashMap<String, FilterValue>>>> { ... }
    fn refresh_materialized_view(
        &self,
        view_name: &str,
        concurrently: bool,
    ) -> BoxFuture<'_, QueryResult<()>> { ... }
    fn transaction<'a, R, Fut, F>(
        &'a self,
        f: F,
    ) -> BoxFuture<'a, QueryResult<R>>
       where F: FnOnce(Self) -> Fut + Send + 'a,
             Fut: Future<Output = QueryResult<R>> + Send + 'a,
             R: Send + 'a,
             Self: Clone { ... }
}
Expand description

The query engine abstraction.

This trait defines how queries are executed against a database. Different implementations can be provided for different databases (PostgreSQL, MySQL, SQLite, etc.).

Required Methods§

Source

fn query_many<T: Model + FromRow + Send + 'static>( &self, sql: &str, params: Vec<FilterValue>, ) -> BoxFuture<'_, QueryResult<Vec<T>>>

Execute a SELECT query and return rows.

Source

fn query_one<T: Model + FromRow + Send + 'static>( &self, sql: &str, params: Vec<FilterValue>, ) -> BoxFuture<'_, QueryResult<T>>

Execute a SELECT query expecting one result.

Source

fn query_optional<T: Model + FromRow + Send + 'static>( &self, sql: &str, params: Vec<FilterValue>, ) -> BoxFuture<'_, QueryResult<Option<T>>>

Execute a SELECT query expecting zero or one result.

Source

fn execute_insert<T: Model + FromRow + Send + 'static>( &self, sql: &str, params: Vec<FilterValue>, ) -> BoxFuture<'_, QueryResult<T>>

Execute an INSERT query and return the created row.

Source

fn execute_update<T: Model + FromRow + Send + 'static>( &self, sql: &str, params: Vec<FilterValue>, ) -> BoxFuture<'_, QueryResult<Vec<T>>>

Execute an UPDATE query and return affected rows.

Source

fn execute_delete( &self, sql: &str, params: Vec<FilterValue>, ) -> BoxFuture<'_, QueryResult<u64>>

Execute a DELETE query and return affected rows count.

Source

fn execute_raw( &self, sql: &str, params: Vec<FilterValue>, ) -> BoxFuture<'_, QueryResult<u64>>

Execute a raw SQL query.

Source

fn count( &self, sql: &str, params: Vec<FilterValue>, ) -> BoxFuture<'_, QueryResult<u64>>

Get a count of records.

Provided Methods§

Source

fn dialect(&self) -> &dyn SqlDialect

The SQL dialect this engine targets.

Drivers that emit SQL (Postgres, MySQL, SQLite, MSSQL) override this to return their matching dialect so the shared Operation builders emit dialect-appropriate placeholders, RETURNING clauses, identifier quoting, and upsert syntax.

The default returns &crate::dialect::NotSql, the inert dialect whose methods all panic if called. Non-SQL engines (MongoDB, document stores) can leave the default in place — their own operations never call SQL builders, so the panicking dialect is never invoked. If you implement QueryEngine for a SQL backend and forget to override this method, every attempt to build SQL through your engine will panic, which is the intended loud-failure mode.

Source

fn aggregate_query( &self, sql: &str, params: Vec<FilterValue>, ) -> BoxFuture<'_, QueryResult<Vec<HashMap<String, FilterValue>>>>

Execute an aggregate query (COUNT/SUM/AVG/MIN/MAX/GROUP BY) and return one map of column name → crate::filter::FilterValue per result row.

Used by crate::operations::AggregateOperation and crate::operations::GroupByOperation because aggregate result sets don’t fit a single Model schema: their columns are dialect-chosen aliases (_count, _sum_views, …) whose types depend on the aggregate function, and group-by queries also include the grouped columns themselves. Returning untyped column-value maps lets the aggregate builders adapt the shape without every driver needing to generate a fresh FromRow impl per query.

The default returns crate::error::QueryError::unsupported, so non-SQL engines (MongoDB, document stores) that never build aggregate queries through the SQL operation builders don’t have to implement this. SQL engines must override.

Source

fn refresh_materialized_view( &self, view_name: &str, concurrently: bool, ) -> BoxFuture<'_, QueryResult<()>>

Refresh a materialized view.

For PostgreSQL, this executes REFRESH MATERIALIZED VIEW. For MSSQL, this rebuilds the indexed view. For databases that don’t support materialized views, this returns an error.

Source

fn transaction<'a, R, Fut, F>(&'a self, f: F) -> BoxFuture<'a, QueryResult<R>>
where F: FnOnce(Self) -> Fut + Send + 'a, Fut: Future<Output = QueryResult<R>> + Send + 'a, R: Send + 'a, Self: Clone,

Run the closure inside a transaction.

Drivers that support real transactions override this to issue BEGIN / COMMIT / ROLLBACK and route every query emitted by the closure through the same underlying transaction. The default below simply hands the closure a clone of the current engine and executes it inline — it has no transactional semantics on its own, so drivers that care about atomicity must override. The default exists so non-SQL backends (MongoDB, document stores) don’t have to stub a method they don’t care about.

The Self: Clone bound lets the default clone the engine into the closure; every concrete QueryEngine already needs Clone for ModelAccessor routing, so it’s free in practice.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§