use crate::{
error::Result,
model::TableSchema,
query::QueryBuilder,
value::{Row, Value},
};
use async_trait::async_trait;
#[async_trait]
pub trait DatabaseAdapter: Send + Sync + 'static {
fn name(&self) -> &'static str;
async fn ping(&self) -> Result<()>;
async fn close(&self) -> Result<()>;
async fn create_table(&self, schema: &TableSchema) -> Result<()>;
async fn drop_table(&self, table: &str) -> Result<()>;
async fn table_exists(&self, table: &str) -> Result<bool>;
async fn insert(&self, table: &str, row: Row) -> Result<Row>;
async fn insert_many(&self, table: &str, rows: Vec<Row>) -> Result<u64>;
async fn find(&self, query: &QueryBuilder) -> Result<Vec<Row>>;
async fn find_one(&self, query: &QueryBuilder) -> Result<Option<Row>>;
async fn update(&self, query: &QueryBuilder) -> Result<u64>;
async fn delete(&self, query: &QueryBuilder) -> Result<u64>;
async fn count(&self, query: &QueryBuilder) -> Result<u64>;
async fn execute_raw(&self, sql: &str, bindings: Vec<Value>) -> Result<u64>;
async fn query_raw(&self, sql: &str, bindings: Vec<Value>) -> Result<Vec<Row>>;
}
pub struct SyncAdapter<A: DatabaseAdapter> {
inner: A,
rt: tokio::runtime::Runtime,
}
impl<A: DatabaseAdapter> SyncAdapter<A> {
pub fn new(adapter: A) -> Result<Self> {
let rt = tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.map_err(|e: std::io::Error| crate::error::RusticxError::Unknown(e.to_string()))?;
Ok(Self { inner: adapter, rt })
}
pub fn ping(&self) -> Result<()> {
self.rt.block_on(self.inner.ping())
}
pub fn create_table(&self, schema: &TableSchema) -> Result<()> {
self.rt.block_on(self.inner.create_table(schema))
}
pub fn insert(&self, table: &str, row: Row) -> Result<Row> {
self.rt.block_on(self.inner.insert(table, row))
}
pub fn insert_many(&self, table: &str, rows: Vec<Row>) -> Result<u64> {
self.rt.block_on(self.inner.insert_many(table, rows))
}
pub fn find(&self, query: &QueryBuilder) -> Result<Vec<Row>> {
self.rt.block_on(self.inner.find(query))
}
pub fn find_one(&self, query: &QueryBuilder) -> Result<Option<Row>> {
self.rt.block_on(self.inner.find_one(query))
}
pub fn update(&self, query: &QueryBuilder) -> Result<u64> {
self.rt.block_on(self.inner.update(query))
}
pub fn delete(&self, query: &QueryBuilder) -> Result<u64> {
self.rt.block_on(self.inner.delete(query))
}
pub fn count(&self, query: &QueryBuilder) -> Result<u64> {
self.rt.block_on(self.inner.count(query))
}
pub fn execute_raw(&self, sql: &str, bindings: Vec<Value>) -> Result<u64> {
self.rt.block_on(self.inner.execute_raw(sql, bindings))
}
pub fn query_raw(&self, sql: &str, bindings: Vec<Value>) -> Result<Vec<Row>> {
self.rt.block_on(self.inner.query_raw(sql, bindings))
}
}