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§
Sourcefn query_many<T: Model + FromRow + Send + 'static>(
&self,
sql: &str,
params: Vec<FilterValue>,
) -> BoxFuture<'_, QueryResult<Vec<T>>>
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.
Sourcefn query_one<T: Model + FromRow + Send + 'static>(
&self,
sql: &str,
params: Vec<FilterValue>,
) -> BoxFuture<'_, QueryResult<T>>
fn query_one<T: Model + FromRow + Send + 'static>( &self, sql: &str, params: Vec<FilterValue>, ) -> BoxFuture<'_, QueryResult<T>>
Execute a SELECT query expecting one result.
Sourcefn query_optional<T: Model + FromRow + Send + 'static>(
&self,
sql: &str,
params: Vec<FilterValue>,
) -> BoxFuture<'_, QueryResult<Option<T>>>
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.
Sourcefn execute_insert<T: Model + FromRow + Send + 'static>(
&self,
sql: &str,
params: Vec<FilterValue>,
) -> BoxFuture<'_, QueryResult<T>>
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.
Sourcefn execute_update<T: Model + FromRow + Send + 'static>(
&self,
sql: &str,
params: Vec<FilterValue>,
) -> BoxFuture<'_, QueryResult<Vec<T>>>
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.
Sourcefn execute_delete(
&self,
sql: &str,
params: Vec<FilterValue>,
) -> BoxFuture<'_, QueryResult<u64>>
fn execute_delete( &self, sql: &str, params: Vec<FilterValue>, ) -> BoxFuture<'_, QueryResult<u64>>
Execute a DELETE query and return affected rows count.
Sourcefn execute_raw(
&self,
sql: &str,
params: Vec<FilterValue>,
) -> BoxFuture<'_, QueryResult<u64>>
fn execute_raw( &self, sql: &str, params: Vec<FilterValue>, ) -> BoxFuture<'_, QueryResult<u64>>
Execute a raw SQL query.
Sourcefn count(
&self,
sql: &str,
params: Vec<FilterValue>,
) -> BoxFuture<'_, QueryResult<u64>>
fn count( &self, sql: &str, params: Vec<FilterValue>, ) -> BoxFuture<'_, QueryResult<u64>>
Get a count of records.
Provided Methods§
Sourcefn dialect(&self) -> &dyn SqlDialect
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.
Sourcefn aggregate_query(
&self,
sql: &str,
params: Vec<FilterValue>,
) -> BoxFuture<'_, QueryResult<Vec<HashMap<String, FilterValue>>>>
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.
Sourcefn refresh_materialized_view(
&self,
view_name: &str,
concurrently: bool,
) -> BoxFuture<'_, QueryResult<()>>
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.
Sourcefn transaction<'a, R, Fut, F>(&'a self, f: F) -> BoxFuture<'a, QueryResult<R>>
fn transaction<'a, R, Fut, F>(&'a self, f: F) -> BoxFuture<'a, QueryResult<R>>
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.