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

sibyl

An OCI-based (synchronous or asynchronous) interface between Rust applications and Oracle databases

27 releases

0.6.18 Aug 20, 2024
0.6.16 Feb 6, 2023
0.6.12 Oct 17, 2022
0.6.9 Jul 26, 2022
0.1.1 Jun 11, 2019

#63 in Database interfaces

Download history 334/week @ 2024-08-21 171/week @ 2024-08-28 59/week @ 2024-09-04 110/week @ 2024-09-11 56/week @ 2024-09-18 95/week @ 2024-09-25 143/week @ 2024-10-02 75/week @ 2024-10-09 45/week @ 2024-10-16 11/week @ 2024-10-23 62/week @ 2024-10-30 82/week @ 2024-11-06 52/week @ 2024-11-13 37/week @ 2024-11-20 66/week @ 2024-11-27 30/week @ 2024-12-04

202 downloads per month
Used in 2 crates

MIT license

780KB
12K SLoC

Sibyl

Sibyl is an OCI-based interface between Rust applications and Oracle databases. Sibyl supports both blocking (threads) and nonblocking (async) API.

crates.io Documentation MIT

Example

Blocking Mode

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(())
}

Nonblocking Mode

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(())
}

Note that:

  • The nonblocking mode example is almost a verbatim copy of the blocking mode example with awaits added.
  • The async example uses and depends on Tokio
  • For the moment, Sibyl can use only Tokio, Actix, async-std or async-global-executor as an async executor.

Documentation

Dependencies

~0.4–11MB
~123K SLoC