use crate::SqliteConnectOptions;
use futures_core::future::BoxFuture;
use rbdc::db::{ConnectOptions, Connection, Driver, Placeholder};
use rbdc::Error;
use rbs::Value;
#[derive(Debug)]
pub struct SqliteDriver {}
impl Driver for SqliteDriver {
fn name(&self) -> &str {
"sqlite"
}
fn connect(&self, url: &str) -> BoxFuture<'_, Result<Box<dyn Connection>, Error>> {
let url = url.to_owned();
Box::pin(async move {
let mut opt = self.default_option();
opt.set_uri(&url)?;
if let Some(opt) = opt.downcast_ref::<SqliteConnectOptions>() {
let conn = opt.connect().await?;
Ok(Box::new(conn) as Box<dyn Connection>)
} else {
Err(Error::from("downcast_ref failure"))
}
})
}
fn connect_opt<'a>(
&'a self,
opt: &'a dyn ConnectOptions,
) -> BoxFuture<'a, Result<Box<dyn Connection>, Error>> {
let opt: &SqliteConnectOptions = opt.downcast_ref().expect(
"SqliteDriver::connect_opt requires SqliteConnectOptions, got a different ConnectOptions type",
);
Box::pin(async move {
let conn = opt.connect().await?;
Ok(Box::new(conn) as Box<dyn Connection>)
})
}
fn default_option(&self) -> Box<dyn ConnectOptions> {
Box::new(SqliteConnectOptions::default())
}
fn column_type(&self, val: &Value) -> String {
match val {
Value::Null => "NULL",
Value::Bool(_) => "BOOLEAN",
Value::I32(_) => "INTEGER",
Value::I64(_) => "INTEGER",
Value::U32(_) => "INTEGER",
Value::U64(_) => "INTEGER",
Value::F32(_) => "REAL",
Value::F64(_) => "REAL",
Value::String(_) => "TEXT",
Value::Binary(_) => "BLOB",
Value::Array(_) => "TEXT",
Value::Map(_) => "TEXT",
Value::Ext(t, _) => match *t {
"Date" => "TEXT",
"DateTime" => "TEXT",
"Time" => "TEXT",
"Timestamp" => "INTEGER",
"Decimal" => "NUMERIC",
"Json" => "BLOB",
"Uuid" => "TEXT",
_ => "NULL",
},
}
.to_string()
}
}
impl Placeholder for SqliteDriver {
fn exchange(&self, sql: &str) -> String {
sql.to_string()
}
}
#[cfg(test)]
mod test {
#[test]
fn test_default() {}
}