#oracle #database-interface #async #sql #ffi

sibyl

基于OCI的(同步或异步)Rust应用程序和Oracle数据库之间的接口

27个版本

新版本 0.6.18 2024年8月20日
0.6.16 2023年2月6日
0.6.12 2022年10月17日
0.6.9 2022年7月26日
0.1.1 2019年6月11日

#51 in 数据库接口

Download history 37/week @ 2024-05-03 96/week @ 2024-05-10 71/week @ 2024-05-17 71/week @ 2024-05-24 53/week @ 2024-05-31 24/week @ 2024-06-07 61/week @ 2024-06-14 11/week @ 2024-06-21 22/week @ 2024-06-28 38/week @ 2024-07-05 26/week @ 2024-07-12 54/week @ 2024-07-19 246/week @ 2024-07-26 167/week @ 2024-08-02 140/week @ 2024-08-09 414/week @ 2024-08-16

979 每月下载量
2 crate 中使用

MIT 许可证

780KB
12K SLoC

Sibyl

Sibyl是Rust应用程序和Oracle数据库之间的基于OCI的接口。Sibyl支持阻塞(线程)和非阻塞(异步)API。

crates.io Documentation MIT

示例

阻塞模式

use sibyl as oracle; // pun intended :)

fn main() -> Result<(),Box<dyn std::error::Error>> {
    let oracle = oracle::env()?;

    let dbname = std::env::var("DBNAME").expect("database name");
    let dbuser = std::env::var("DBUSER").expect("user name");
    let dbpass = std::env::var("DBPASS").expect("password");

    let session = oracle.connect(&dbname, &dbuser, &dbpass)?;
    let stmt = session.prepare("
        SELECT first_name, last_name, hire_date
          FROM hr.employees
         WHERE hire_date >= :hire_date
      ORDER BY hire_date
    ")?;
    let date = oracle::Date::from_string("January 1, 2005", "MONTH DD, YYYY", &session)?;
    let rows = stmt.query(&date)?;
    while let Some( row ) = rows.next()? {
        let first_name : Option<&str>  = row.get(0)?;
        let last_name  : &str          = row.get(1)?;
        let hire_date  : oracle::Date  = row.get(2)?;

        let hire_date = hire_date.to_string("FMMonth DD, YYYY")?;
        if let Some(first_name) = first_name {
            println!("{}: {} {}", hire_date, first_name, last_name);
        } else {
            println!("{}: {}", hire_date, last_name);
        }
    }
    if stmt.row_count()? == 0 {
        println!("No one was hired after {}", date.to_string("FMMonth DD, YYYY")?);
    }
    Ok(())
}

非阻塞模式

use sibyl as oracle;

#[tokio::main]
async fn main() -> Result<(),Box<dyn std::error::Error>> {
    let oracle = oracle::env()?;

    let dbname = std::env::var("DBNAME").expect("database name");
    let dbuser = std::env::var("DBUSER").expect("user name");
    let dbpass = std::env::var("DBPASS").expect("password");

    let session = oracle.connect(&dbname, &dbuser, &dbpass).await?;
    let stmt = session.prepare("
        SELECT first_name, last_name, hire_date
          FROM hr.employees
         WHERE hire_date >= :hire_date
      ORDER BY hire_date
    ").await?;
    let date = oracle::Date::from_string("January 1, 2005", "MONTH DD, YYYY", &oracle)?;
    let rows = stmt.query(&date).await?;
    while let Some( row ) = rows.next().await? {
        let first_name : Option<&str>  = row.get(0)?;
        let last_name  : &str          = row.get(1)?;
        let hire_date  : oracle::Date  = row.get(2)?;

        let hire_date = hire_date.to_string("FMMonth DD, YYYY")?;
        if let Some(first_name) = first_name {
            println!("{}: {} {}", hire_date, first_name, last_name);
        } else {
            println!("{}: {}", hire_date, last_name);
        }
    }
    if stmt.row_count()? == 0 {
        println!("No one was hired after {}", date.to_string("FMMonth DD, YYYY")?);
    }
    Ok(())
}

注意

  • 非阻塞模式示例几乎与阻塞模式示例完全相同,只是添加了await
  • 异步示例使用并依赖于Tokio
  • 目前,Sibyl只能使用Tokio、Actix、async-std或async-global-executor作为异步执行器。

文档

依赖

~0.4–12MB
~132K SLoC