#[macro_use]
mod macros;
pub mod db;
pub mod prelude;
pub mod utils;
pub use async_trait;
pub use chrono;
pub use inventory;
#[cfg(feature = "turso")]
pub use libsql;
pub use rusql_alchemy_derive as derive;
#[cfg(not(feature = "turso"))]
pub use sqlx;
pub type Error = Box<dyn std::error::Error + Send + Sync>;
type FutureResult<'fut, T, E = Error> =
std::pin::Pin<Box<dyn std::future::Future<Output = Result<T, E>> + Send + 'fut>>;
pub struct MigrationRegistrar {
pub up_fn: for<'m> fn(&'m db::Connection) -> FutureResult<'m, ()>,
pub down_fn: for<'m> fn(&'m db::Connection) -> FutureResult<'m, ()>,
}
inventory::collect!(MigrationRegistrar);
pub struct Database {
pub conn: db::Connection,
}
impl Database {
#[cfg(not(feature = "turso"))]
pub async fn new(database_url: &str) -> Result<Self, Error> {
sqlx::any::install_default_drivers();
let conn = sqlx::any::AnyPoolOptions::new()
.max_connections(5)
.connect(database_url)
.await?;
Ok(Self { conn })
}
#[cfg(feature = "turso")]
pub async fn new_local(path: &str) -> Result<Self, Error> {
let db = libsql::Builder::new_local(path).build().await?;
let conn = db.connect()?;
Ok(Self { conn })
}
#[cfg(feature = "turso")]
pub async fn new_remote_replica(
path: &str,
database_url: &str,
auth_token: &str,
) -> Result<Self, Error> {
let db = libsql::Builder::new_remote_replica(
path,
database_url.to_string(),
auth_token.to_string(),
)
.build()
.await?;
let conn = db.connect()?;
Ok(Self { conn })
}
#[cfg(feature = "turso")]
pub async fn new_remote(database_url: &str, auth_token: &str) -> Result<Self, Error> {
let db = libsql::Builder::new_remote(database_url.to_string(), auth_token.to_string())
.build()
.await?;
let conn = db.connect()?;
Ok(Self { conn })
}
pub async fn up(&self) -> Result<(), Error> {
for model in inventory::iter::<MigrationRegistrar> {
(model.up_fn)(&self.conn).await?;
}
Ok(())
}
pub async fn down(&self) -> Result<(), Error> {
for model in inventory::iter::<MigrationRegistrar> {
(model.down_fn)(&self.conn).await?;
}
Ok(())
}
}