pub trait Executor {
// Required methods
fn dialect(&self) -> Dialect;
async fn fetch_all(
&self,
sql: &str,
params: Vec<Value>,
) -> Result<Vec<Box<dyn Row>>, Error>;
async fn execute(
&self,
sql: &str,
params: Vec<Value>,
) -> Result<ExecOutcome, Error>;
// Provided methods
fn shard_family(&self) -> Option<&str> { ... }
fn is_sharded(&self) -> bool { ... }
fn allocate_id(&self, _shard_key: u64) -> Option<u64> { ... }
async fn fetch_all_routed(
&self,
_route: ShardRoute,
sql: &str,
params: Vec<Value>,
) -> Result<Vec<Box<dyn Row>>, Error> { ... }
async fn execute_routed(
&self,
_route: ShardRoute,
sql: &str,
params: Vec<Value>,
) -> Result<ExecOutcome, Error> { ... }
}Expand description
A database backend. The single integration point: implement this and the generic CRUD layer works against your store unchanged.
async fn in trait (stable since Rust 1.75) keeps this dyn-free and
wasm-safe; callers hold a concrete executor and monomorphise.
The trait deliberately does not require Send + Sync. A multi-threaded
server’s concrete executors (SeaOrmExecutor, D1Executor<reqwest-transport>)
are Send + Sync, so state that holds them is too — the bound is provided
by the concrete type, not demanded by the trait. Leaving it off lets a
single-threaded Cloudflare Worker implement the trait over its !Send
native D1 binding, so the exact same generic services run there.
Required Methods§
Sourcefn dialect(&self) -> Dialect
fn dialect(&self) -> Dialect
The SQL dialect this backend speaks, so callers render matching SQL.
Sourceasync fn fetch_all(
&self,
sql: &str,
params: Vec<Value>,
) -> Result<Vec<Box<dyn Row>>, Error>
async fn fetch_all( &self, sql: &str, params: Vec<Value>, ) -> Result<Vec<Box<dyn Row>>, Error>
Run a query and return every row. Parameters are bound positionally in the order sea-query emitted them.
Sourceasync fn execute(
&self,
sql: &str,
params: Vec<Value>,
) -> Result<ExecOutcome, Error>
async fn execute( &self, sql: &str, params: Vec<Value>, ) -> Result<ExecOutcome, Error>
Run a write and report its ExecOutcome.
Provided Methods§
Sourcefn shard_family(&self) -> Option<&str>
fn shard_family(&self) -> Option<&str>
The shard family this connector routes within, or None for a
single, unsharded database.
This is the explicit “am I sharded, and as what?” marker: a Some(name)
connector uses sharded reasoning (ids are shard-encoded; operations
route within the named family), while None is a plain one-database
connector. Callers and migrations can branch on it without knowing the
concrete executor — and an entity’s shard_columns should match
the connector it runs on. Defaults to None.
Sourcefn is_sharded(&self) -> bool
fn is_sharded(&self) -> bool
true when this connector is sharded — sugar for
shard_family().is_some().
Sourcefn allocate_id(&self, _shard_key: u64) -> Option<u64>
fn allocate_id(&self, _shard_key: u64) -> Option<u64>
Mint a shard-encoded primary key for a row whose shard-key value is
shard_key (e.g. the owning user_id). repo::insert calls this when
an entity’s primary key is itself a shard key, is not auto-increment,
and is unset — so id assignment for the sharded data tier happens here,
in the connector, transparently, not in the service. The default is
None (no allocation: the caller’s id or the DB’s auto-increment stands)
so single, unsharded executors are unaffected.
Sourceasync fn fetch_all_routed(
&self,
_route: ShardRoute,
sql: &str,
params: Vec<Value>,
) -> Result<Vec<Box<dyn Row>>, Error>
async fn fetch_all_routed( &self, _route: ShardRoute, sql: &str, params: Vec<Value>, ) -> Result<Vec<Box<dyn Row>>, Error>
Run a query against the physical database the ShardRoute selects.
This is the sharding transparency seam. The repo/query layer
always calls the routed variants; a single-database executor inherits
the default below — which ignores the route and runs on its one
connection — so it needs no change and sharding stays invisible above.
A sharding executor overrides this to dispatch to the right shard.
Sourceasync fn execute_routed(
&self,
_route: ShardRoute,
sql: &str,
params: Vec<Value>,
) -> Result<ExecOutcome, Error>
async fn execute_routed( &self, _route: ShardRoute, sql: &str, params: Vec<Value>, ) -> Result<ExecOutcome, Error>
Routed counterpart of execute. Defaults to ignoring
the route — see fetch_all_routed.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".
Implementors§
impl Executor for Database
Implementing Executor is what keeps Rainier ORM’s whole surface available.
repo::insert, repo::query::<E>(), Cursor and Migrator::run are all
generic over X: Executor, so they accept a Database directly. Their
futures are !Send (see the module docs), so use them from a console
command, a migration, or a Worker — not from a request handler, which needs
the Send path above.