pgsql_quick 2.0.2

postgres 数据库快速连接方法
Documentation
// 示例,set类方法同理。
pgupdate!("for_test", 56, {
    "content": "null", // 将更新 content 为 NULL
    "tatol": Some(200), // 将更新 tatol 为 200
    "uid": None, // 将忽略 uid 字段
}

PostgreSQL 数据库连接方法封装(异步)

use pgsql_quick::{PostgresQuick, pg_run_vec, pg_run_drop ...};

pub async fn postgres_conn() -> tokio_postgres::Client {
    let client = PostgresQuick::new("host=127.0.0.1 user=username password=xxx dbname=db")
        .await
        .unwrap()
        .client;
    client
}

let client = postgres_conn().await;

PostgreSQL 查询方法(异步)

运行sql 说明
pg_run_vec 异步执行sql,返回vec类型数据,无数据则返回vec![]
pg_run_drop 异步执行sql,无返回数据,最多返回id
pg_run_tran_vec 事务异步执行sql,有返回vec类型数据,无数据则返回vec![]
pg_run_tran_drop 事务异步执行sql,无返回数据,最多返回id
let id: u64 = pg_run_drop(&client, sql).await.unwrap();

// 异步执行 sql 语句
let data: Vec<serde_json::Value> = pg_run_vec(&client, sql).await.unwrap();

sql快捷生成

sql快捷生成方法 说明
pgcount 返回计数的sql
pgdel 删除一条数据的sql
pgdelmany 批量删除数据的sql
pgfind 查寻数据的sql
pgget 查寻一条数据的sql
pgset 新增一条数据的sql
pgsetmany 批量新增数据的sql
pgsetupdate 批量新增或更新数据的sql
pgsetupdatemany 批量新增或更新数据的sql
pgupdate 更新一条数据的sql
pgupdatemany 批量更新数据的sql
自定义 可以直接写自己的sql语句

以下内容,则为常用sql的快捷方法(异步示例)

// 异步函数中使用
async fn example() {
    let client = postgres_conn().await;

    // 新增一条数据
    let id = pg_run_drop(&client, pgset!("for_test", {
        "content": "ADFaadf",
        "uid": 9,
        "info": Some('a'),
    })).await.unwrap();

    // 删除一条数据
    pg_run_drop(&client, pgdel!("for_test", 50)).await.unwrap();

    // 更新一条数据
    pg_run_drop(&client, pgupdate!("for_test", 56, {
        "content": "更新后的内容",
        "tatol": Some(200),
    })).await.unwrap();

    // 批量 新增数据
    let msql_2 = pgsetmany!("for_test", vec![
        Item {uid: 1, content: "批量更新00adf"},
        Item {uid: 2, content: "2342341"},
        Item {uid: 3, content: "mmmmm"},
    ]);
    pg_run_drop(&client, msql_2).await.unwrap();

    // 批量 更新数据
    let sql = pgupdatemany!("for_test", "uid", vec![
        Item {uid: 1, content: "批量更新00adf"},
        Item {uid: 2, content: "2342341"},
    ]);
    pg_run_drop(&client, sql).await.unwrap();

    // 获取一条数据
    let sql1 = pgget!("for_test", 33, "id, content as cc");
    #[derive(Serialize, Deserialize, Debug)]
    struct Feedback {
        id: u64,
        cc: String
    }
    let res_get: Vec<Feedback> = pg_run_vec(&client, sql1).await.unwrap();

    // 查询数据
    let sql_f = pgfind!("for_test", {
        p0: ["uid", ">", 330],
        r: "p0",
        select: "*",
    });
    let res_find: Vec<Feedback> = pg_run_vec(&client, sql_f).await.unwrap();

    // 获取计数
    let res_count: Vec<PostgresQuickCount> = pg_run_vec(&client, pgcount!("for_test", {})).await.unwrap();

    // 自定义查询
    let list: Vec<serde_json::Value> =
        pg_run_vec(&client, "select distinct type_v3 from dishes".to_owned()).await.unwrap();
}

PostgreSQL 事务示例(异步)

pg_run_tran_vec、pg_run_tran_drop

use pgsql_quick::{PG_EXCLUSIVE_LOCK, PG_SHARED_LOCK};

async fn transaction_example() {
    let mut client = postgres_conn().await;
    // ---- 事务开始 ----
    let transaction = client.transaction().await.unwrap();
    let getsql = pgget!("for_test", 5, "id,title,content,price,total,uid") + PG_EXCLUSIVE_LOCK;
    let get_data: Vec<ForTestItem> = pg_run_tran_vec(&transaction, getsql).await.unwrap();
    let tmp = get_data;
    if tmp.len() == 0 {
        transaction.rollback().await.unwrap();
    } else {
        if tmp[0].total <= 0 {
            transaction.rollback().await.unwrap();
        } else {
            let sql2 = pgupdate!("for_test", 5, {"total": ["incr", -1]});
            pg_run_tran_drop(&transaction, sql2).await.unwrap();
            transaction.commit().await.unwrap();
        }
    }
    // ---- 事务结束 ----
}

组合查询

通过 Sql 包裹

use pgsql_quick::Sql;

let sql1 = pgfind!("hospital", {
    p0: ["hospital_name", "like", "信息%"],
    r: "p0",
    select: "hospital_id",
});
let sql2 = pgcount!("database.patient", { // 对其他库的表查询
    p0: ["investigation_id", "=", Sql("investigation.investigation_id")],
    r: "p0",
});

let sql = pgfind!("investigation", {
    j1: ["hospital_id", "inner", "hospital.hospital_id"],
    p0: ["hospital_id", "in", Sql(sql1)],
    p1: ["inv_type", "=", "门诊"],
    r: "p0 && p1",
    select: "investigation_id, hospital_id, (".to_string()
        + sql2.as_str() + ") as patient_count", // 如果自己写sql语句,要注意sql注入
});

println!("sql>>>>>  {} \n", sql);

重要变更说明

从 v2.0.0 开始,pgsql_quick 已经完全迁移到异步架构:

  1. 依赖变更

    • 移除了 postgres 同步库
    • 使用 tokio-postgres 异步库
    • 需要 tokio 运行时
  2. API 变更

    • 所有数据库操作函数现在都是异步的(async)
    • PostgresQuick::new() 现在是异步函数
    • pg_run_vecpg_run_droppg_run_tran_vecpg_run_tran_drop 都需要 .await
    • Client 参数从 &mut Client 改为 &Client(异步版本不需要可变引用)
  3. 使用要求

    • 需要在异步上下文中使用(async 函数或 tokio::main)
    • 项目需要添加 tokio 运行时依赖