pub trait SqlExecutor: Send + Sync {
// Required methods
fn execute<'life0, 'life1, 'async_trait>(
&'life0 self,
sql: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<u64, RdbmsError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn query<'life0, 'life1, 'async_trait>(
&'life0 self,
sql: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Vec<Row>, RdbmsError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn dialect(&self) -> Dialect;
// Provided methods
fn execute_with<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_sql: &'life1 str,
_params: &'life2 [Value],
) -> Pin<Box<dyn Future<Output = Result<u64, RdbmsError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait { ... }
fn query_with<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_sql: &'life1 str,
_params: &'life2 [Value],
) -> Pin<Box<dyn Future<Output = Result<Vec<Row>, RdbmsError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait { ... }
fn query_write<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
sql: &'life1 str,
params: &'life2 [Value],
) -> Pin<Box<dyn Future<Output = Result<Vec<Row>, RdbmsError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait { ... }
fn execute_then_query<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
_first: &'life1 str,
_first_params: &'life2 [Value],
_second: &'life3 str,
) -> Pin<Box<dyn Future<Output = Result<Vec<Row>, RdbmsError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait { ... }
}Required Methods§
Sourcefn execute<'life0, 'life1, 'async_trait>(
&'life0 self,
sql: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<u64, RdbmsError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn execute<'life0, 'life1, 'async_trait>(
&'life0 self,
sql: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<u64, RdbmsError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
执行一条 SQL 语句,返回受影响行数。
用户提供的值请走 SqlExecutor::execute_with。
Provided Methods§
Sourcefn execute_with<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_sql: &'life1 str,
_params: &'life2 [Value],
) -> Pin<Box<dyn Future<Output = Result<u64, RdbmsError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn execute_with<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_sql: &'life1 str,
_params: &'life2 [Value],
) -> Pin<Box<dyn Future<Output = Result<u64, RdbmsError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
参数化执行,防注入。无法绑定参数的后端返回错误。
Sourcefn query_with<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_sql: &'life1 str,
_params: &'life2 [Value],
) -> Pin<Box<dyn Future<Output = Result<Vec<Row>, RdbmsError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn query_with<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_sql: &'life1 str,
_params: &'life2 [Value],
) -> Pin<Box<dyn Future<Output = Result<Vec<Row>, RdbmsError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
参数化查询,防注入。无法绑定参数的后端返回错误。
Sourcefn query_write<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
sql: &'life1 str,
params: &'life2 [Value],
) -> Pin<Box<dyn Future<Output = Result<Vec<Row>, RdbmsError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn query_write<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
sql: &'life1 str,
params: &'life2 [Value],
) -> Pin<Box<dyn Future<Output = Result<Vec<Row>, RdbmsError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
写路径且需要返回结果(INSERT ... RETURNING / OUTPUT INSERTED)。
默认委托给 SqlExecutor::query_with;只有读写分离路由需要覆写,
否则写语句会被路由到从库。
Sourcefn execute_then_query<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
_first: &'life1 str,
_first_params: &'life2 [Value],
_second: &'life3 str,
) -> Pin<Box<dyn Future<Output = Result<Vec<Row>, RdbmsError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
fn execute_then_query<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
_first: &'life1 str,
_first_params: &'life2 [Value],
_second: &'life3 str,
) -> Pin<Box<dyn Future<Output = Result<Vec<Row>, RdbmsError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
在同一条连接上先执行 first、再执行 second(查询),两者原子。
存在的理由:MySQL 的 LAST_INSERT_ID() 是连接作用域的 ——
池下两次独立取用可能落到不同连接、取回别的会话刚插入的值(静默错值),
所以 insert 的两步式主键回填必须落在同一条连接上。
默认实现返回「不支持」。三种覆写:
Transaction—— 直接在自己身上跑两条(它本来就在一条连接上的事务里)- 需要两步式的客户端(如
ecat-data-sqlx的SqlxClient)—— 开一个事务,跑完提交 - 一步式后端(MSSQL 的
OUTPUT INSERTED、PG/SQLite 的RETURNING)—— 用不到,不覆写
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".