Introduction
Sibyl is an OCI-based interface (a.k.a. a driver) between Rust applications and Oracle databases. It supports both sync (blocking) and async (nonblocking) API.
Example
Assuming an HR sample schema is installed, the following example program would report median salaries for each country in the specified region.
Blocking Mode Version
fn main() -> sibyl::Result<()> {
let oracle = sibyl::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 c.country_name, Median(e.salary)
FROM hr.employees e
JOIN hr.departments d ON d.department_id = e.department_id
JOIN hr.locations l ON l.location_id = d.location_id
JOIN hr.countries c ON c.country_id = l.country_id
JOIN hr.regions r ON r.region_id = c.region_id
WHERE r.region_name = :REGION_NAME
GROUP BY c.country_name
")?;
let rows = stmt.query("Europe")?;
while let Some(row) = rows.next()? {
let country_name : &str = row.get(0)?;
let median_salary : u16 = row.get(1)?;
println!("{:25}: {:>5}", country_name, median_salary);
}
Ok(())
}
When executed it prints:
Germany : 10000
United Kingdom : 8800
Nonblocking (async) Mode Version
fn main() -> sibyl::Result<()> {
sibyl::block_on(async {
let oracle = sibyl::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 c.country_name, Median(e.salary)
FROM hr.employees e
JOIN hr.departments d ON d.department_id = e.department_id
JOIN hr.locations l ON l.location_id = d.location_id
JOIN hr.countries c ON c.country_id = l.country_id
JOIN hr.regions r ON r.region_id = c.region_id
WHERE r.region_name = :REGION_NAME
GROUP BY c.country_name
").await?;
let rows = stmt.query("Europe").await?;
while let Some(row) = rows.next().await? {
let country_name : &str = row.get(0)?;
let median_salary : u16 = row.get(1)?;
println!("{:25}: {:>5}", country_name, median_salary);
}
Ok(())
})
}
Note the only difference between this and the blocking mode program is that
async
method calls need to beawait
ed. Otherwise theasync
version of the program is a verbatim copy of the non-async one.