use crate::{
Db, Result,
db::{Connect, Pool, Shared},
engine::Engine,
};
use toasty_core::{
driver::Driver,
schema::{
self,
app::{self, ModelSet},
},
};
use std::sync::Arc;
#[derive(Default)]
pub struct Builder {
models: app::ModelSet,
core: schema::Builder,
}
impl Builder {
pub fn models(&mut self, models: ModelSet) -> &mut Self {
self.models = models;
self
}
pub fn table_name_prefix(&mut self, prefix: &str) -> &mut Self {
self.core.table_name_prefix(prefix);
self
}
pub fn build_app_schema(&self) -> Result<app::Schema> {
app::Schema::from_macro(self.models.clone())
}
pub async fn connect(&mut self, url: &str) -> Result<Db> {
let con = Connect::new(url).await?;
self.build(con).await
}
pub async fn build(&mut self, driver: impl Driver) -> Result<Db> {
tracing::info!(models = self.models.len(), "building database schema");
let capability = driver.capability();
capability.validate()?;
let schema = self.core.build(self.build_app_schema()?, capability)?;
tracing::info!(tables = schema.db.tables.len(), "schema built successfully");
let engine = Engine::new(Arc::new(schema), capability);
let pool = Pool::new(driver, engine.clone())?;
let shared = Arc::new(Shared { engine, pool });
let conn = shared.pool.get(shared.clone()).await?;
std::mem::drop(conn);
tracing::info!("database ready");
Ok(Db { shared })
}
}