pub trait Executor {
// Required methods
fn dialect(&self) -> Dialect;
async fn fetch_all(
&self,
sql: &str,
params: Vec<Value>,
) -> Result<Vec<Box<dyn Row>>>;
async fn execute(
&self,
sql: &str,
params: Vec<Value>,
) -> Result<ExecOutcome>;
// 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>>> { ... }
async fn execute_routed(
&self,
_route: ShardRoute,
sql: &str,
params: Vec<Value>,
) -> Result<ExecOutcome> { ... }
}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>>>
async fn fetch_all( &self, sql: &str, params: Vec<Value>, ) -> Result<Vec<Box<dyn Row>>>
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>
async fn execute(&self, sql: &str, params: Vec<Value>) -> Result<ExecOutcome>
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>>>
async fn fetch_all_routed( &self, _route: ShardRoute, sql: &str, params: Vec<Value>, ) -> Result<Vec<Box<dyn Row>>>
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>
async fn execute_routed( &self, _route: ShardRoute, sql: &str, params: Vec<Value>, ) -> Result<ExecOutcome>
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".