Skip to main content

SqlExecutor

Trait SqlExecutor 

Source
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§

Source

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。

Source

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,

查询多行。用户提供的值请走 SqlExecutor::query_with。

Source

fn dialect(&self) -> Dialect

本执行器背后的数据库方言。

Provided Methods§

Source

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,

参数化执行,防注入。无法绑定参数的后端返回错误。

Source

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,

参数化查询,防注入。无法绑定参数的后端返回错误。

Source

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;只有读写分离路由需要覆写, 否则写语句会被路由到从库。

Source

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".

Implementors§