< 返回版块

github.com/shanliu/lsys 发表于 2022-04-28 21:40

[dependencies]
sqlx = {version = "~0.5.5",features = [ "mysql","runtime-tokio-native-tls","offline"]}
tokio = "1.*"
use std::str::FromStr;
use sqlx::{Transaction, MySql, Pool, pool::PoolOptions, mysql::MySqlConnectOptions};

pub async fn db() -> Pool<MySql> {
    let option = MySqlConnectOptions::from_str("mysql://root:@127.0.0.1:3306/test").unwrap();
    PoolOptions::<MySql>::new()
        .max_connections(5)
        .connect_with(option)
        .await.unwrap()
}


macro_rules! model_executor_option {
    ($block:block,$transaction:expr,$poll:expr,$execute:tt)=>{
        match $transaction {
            Some($execute)=>{
                $block
            }
            None=>{
                let $execute=$poll;
                $block
            }
        }
    };
}

pub async fn add_email<'t>(transaction:Option<&mut Transaction<'t,sqlx::MySql>>) {
    let poll=&db().await;
    model_executor_option!({
        let sql=format!("select 1");
        sqlx::query(sql.as_str()).execute(db).await.unwrap();
       // sqlx::query(sql.as_str()).execute(db).await.unwrap();//这会报错

    },transaction,poll,db);

    //目前生成应该是这样
    // match transaction {
    //     Some(db) => {
    //         let sql=format!("select 1");
    //         sqlx::query(sql.as_str()).execute(db).await.unwrap();
    //         sqlx::query(sql.as_str()).execute(db).await.unwrap();//因为 execute 参数为范型 导致db 不专为&mut *db 
    //     }
    //     None => {
    //         let db = poll;
    //         let sql=format!("select 1");
    //         sqlx::query(sql.as_str()).execute(db).await.unwrap();
    //         sqlx::query(sql.as_str()).execute(db).await.unwrap();
    //     }
    // }

    //期望生成
    // match transaction {
    //     Some(db) => {
    //         let sql=format!("select 1");
    //         sqlx::query(sql.as_str()).execute(&mut *db).await.unwrap();
    //         sqlx::query(sql.as_str()).execute(&mut *db).await.unwrap();
    //     }
    //     None => {
    //         let db = poll;
    //         let sql=format!("select 1");
    //         sqlx::query(sql.as_str()).execute(db).await.unwrap();
    //         sqlx::query(sql.as_str()).execute(db).await.unwrap();
    //     }
    // }
}

 fn main() {
    add_email(None);
}

评论区

写评论
作者 github.com/shanliu/lsys 2022-04-30 23:11

use trait 😂

--
👇
JohnnyZhao: 你好,请问是如何解决的哦?

--
👇
shanliu: 还有下面代码你可能没啥感觉 因为就一行query(&sql, db).await 当你业务需要十几二十个sql执行的时候,会有十几个二十行重复代码

--
👇
苦瓜小仔: 仅对这段代码:

用宏来简化处理 Option 简直是大材小用了,而且宏并不是绕过生命周期或者泛型的黑魔法。

你可以考虑泛型函数来抽象或者封装:

use sqlx::{
    database::HasArguments, mysql::MySqlConnectOptions, pool::PoolOptions, Executor, IntoArguments,
    MySql, Pool, Transaction,
};
use std::str::FromStr;

pub async fn db() -> Pool<MySql> {
    let option = MySqlConnectOptions::from_str("mysql://root:@127.0.0.1:3306/test").unwrap();
    PoolOptions::<MySql>::new().max_connections(5)
                               .connect_with(option)
                               .await
                               .unwrap()
}

pub async fn add_email<'t>(transaction: Option<&mut Transaction<'t, sqlx::MySql>>) {
    let sql = format!("select 1");
    if let Some(db) = transaction {
        query(&sql, db).await
    } else {
        query(&sql, &db().await).await
    };
}

async fn query<'e, 's: 'e, E: Executor<'e>>(sql: &'s str, db: E)
    where <E::Database as HasArguments<'e>>::Arguments: IntoArguments<'e, E::Database> {
    sqlx::query(sql).execute(db).await.unwrap();
}

fn main() { add_email(None); }
JohnnyZhao 2022-04-30 10:17

你好,请问是如何解决的哦?

--
👇
shanliu: 还有下面代码你可能没啥感觉 因为就一行query(&sql, db).await 当你业务需要十几二十个sql执行的时候,会有十几个二十行重复代码

--
👇
苦瓜小仔: 仅对这段代码:

用宏来简化处理 Option 简直是大材小用了,而且宏并不是绕过生命周期或者泛型的黑魔法。

你可以考虑泛型函数来抽象或者封装:

use sqlx::{
    database::HasArguments, mysql::MySqlConnectOptions, pool::PoolOptions, Executor, IntoArguments,
    MySql, Pool, Transaction,
};
use std::str::FromStr;

pub async fn db() -> Pool<MySql> {
    let option = MySqlConnectOptions::from_str("mysql://root:@127.0.0.1:3306/test").unwrap();
    PoolOptions::<MySql>::new().max_connections(5)
                               .connect_with(option)
                               .await
                               .unwrap()
}

pub async fn add_email<'t>(transaction: Option<&mut Transaction<'t, sqlx::MySql>>) {
    let sql = format!("select 1");
    if let Some(db) = transaction {
        query(&sql, db).await
    } else {
        query(&sql, &db().await).await
    };
}

async fn query<'e, 's: 'e, E: Executor<'e>>(sql: &'s str, db: E)
    where <E::Database as HasArguments<'e>>::Arguments: IntoArguments<'e, E::Database> {
    sqlx::query(sql).execute(db).await.unwrap();
}

fn main() { add_email(None); }
作者 github.com/shanliu/lsys 2022-04-29 20:43

还有下面代码你可能没啥感觉 因为就一行query(&sql, db).await 当你业务需要十几二十个sql执行的时候,会有十几个二十行重复代码

--
👇
苦瓜小仔: 仅对这段代码:

用宏来简化处理 Option 简直是大材小用了,而且宏并不是绕过生命周期或者泛型的黑魔法。

你可以考虑泛型函数来抽象或者封装:

use sqlx::{
    database::HasArguments, mysql::MySqlConnectOptions, pool::PoolOptions, Executor, IntoArguments,
    MySql, Pool, Transaction,
};
use std::str::FromStr;

pub async fn db() -> Pool<MySql> {
    let option = MySqlConnectOptions::from_str("mysql://root:@127.0.0.1:3306/test").unwrap();
    PoolOptions::<MySql>::new().max_connections(5)
                               .connect_with(option)
                               .await
                               .unwrap()
}

pub async fn add_email<'t>(transaction: Option<&mut Transaction<'t, sqlx::MySql>>) {
    let sql = format!("select 1");
    if let Some(db) = transaction {
        query(&sql, db).await
    } else {
        query(&sql, &db().await).await
    };
}

async fn query<'e, 's: 'e, E: Executor<'e>>(sql: &'s str, db: E)
    where <E::Database as HasArguments<'e>>::Arguments: IntoArguments<'e, E::Database> {
    sqlx::query(sql).execute(db).await.unwrap();
}

fn main() { add_email(None); }
作者 github.com/shanliu/lsys 2022-04-29 20:37

考虑过 1。 让上游传 db: E ,就是你写的这方法 但是这样写下来调用方其实是很不方便的 2. 把sql构造放到函数内,在把构造好的请求返回,因为sqlx::query(sql) 是引用,只能在里面执行,无解 3. 通过上面宏的方式解决,已经实现。【最方便的调用端实现】

--
👇
苦瓜小仔: 仅对这段代码:

用宏来简化处理 Option 简直是大材小用了,而且宏并不是绕过生命周期或者泛型的黑魔法。

你可以考虑泛型函数来抽象或者封装:

use sqlx::{
    database::HasArguments, mysql::MySqlConnectOptions, pool::PoolOptions, Executor, IntoArguments,
    MySql, Pool, Transaction,
};
use std::str::FromStr;

pub async fn db() -> Pool<MySql> {
    let option = MySqlConnectOptions::from_str("mysql://root:@127.0.0.1:3306/test").unwrap();
    PoolOptions::<MySql>::new().max_connections(5)
                               .connect_with(option)
                               .await
                               .unwrap()
}

pub async fn add_email<'t>(transaction: Option<&mut Transaction<'t, sqlx::MySql>>) {
    let sql = format!("select 1");
    if let Some(db) = transaction {
        query(&sql, db).await
    } else {
        query(&sql, &db().await).await
    };
}

async fn query<'e, 's: 'e, E: Executor<'e>>(sql: &'s str, db: E)
    where <E::Database as HasArguments<'e>>::Arguments: IntoArguments<'e, E::Database> {
    sqlx::query(sql).execute(db).await.unwrap();
}

fn main() { add_email(None); }
苦瓜小仔 2022-04-29 00:17

仅对这段代码:

用宏来简化处理 Option 简直是大材小用了,而且宏并不是绕过生命周期或者泛型的黑魔法。

你可以考虑泛型函数来抽象或者封装:

use sqlx::{
    database::HasArguments, mysql::MySqlConnectOptions, pool::PoolOptions, Executor, IntoArguments,
    MySql, Pool, Transaction,
};
use std::str::FromStr;

pub async fn db() -> Pool<MySql> {
    let option = MySqlConnectOptions::from_str("mysql://root:@127.0.0.1:3306/test").unwrap();
    PoolOptions::<MySql>::new().max_connections(5)
                               .connect_with(option)
                               .await
                               .unwrap()
}

pub async fn add_email<'t>(transaction: Option<&mut Transaction<'t, sqlx::MySql>>) {
    let sql = format!("select 1");
    if let Some(db) = transaction {
        query(&sql, db).await
    } else {
        query(&sql, &db().await).await
    };
}

async fn query<'e, 's: 'e, E: Executor<'e>>(sql: &'s str, db: E)
    where <E::Database as HasArguments<'e>>::Arguments: IntoArguments<'e, E::Database> {
    sqlx::query(sql).execute(db).await.unwrap();
}

fn main() { add_email(None); }
1 共 5 条评论, 1 页