use crate::database_instance::DatabaseInstance;
use crate::db_type::{Error, Result};
use crate::table_definition::NativeModelOptions;
use crate::Models;
use crate::{upgrade, watch, Database, Model};
use std::collections::HashMap;
use std::path::Path;
use std::sync::atomic::AtomicU64;
use std::sync::{Arc, RwLock};
#[derive(Debug)]
pub(crate) struct Configuration {
pub(crate) cache_size_bytes: Option<usize>,
}
impl Configuration {
pub(crate) fn new_rdb_builder(&self) -> redb::Builder {
let mut redb_builder = redb::Builder::new();
if let Some(cache_size_bytes) = self.cache_size_bytes {
redb_builder.set_cache_size(cache_size_bytes);
}
redb_builder
}
}
#[cfg(feature = "redb1")]
impl Configuration {
pub(crate) fn redb1_new_rdb1_builder(&self) -> redb1::Builder {
let mut redb_builder = redb1::Builder::new();
if let Some(cache_size_bytes) = self.cache_size_bytes {
redb_builder.set_cache_size(cache_size_bytes);
}
redb_builder
}
}
#[derive(Debug)]
pub struct Builder {
database_configuration: Configuration,
}
impl Builder {
fn init<'a>(
&self,
database_instance: DatabaseInstance,
models: &'a Models,
) -> Result<Database<'a>> {
let mut database = Database {
instance: database_instance,
primary_table_definitions: HashMap::new(),
watchers: Arc::new(RwLock::new(watch::Watchers::new())),
watchers_counter_id: AtomicU64::new(0),
};
for (_, model_builder) in models.models_builder.iter() {
database.seed_model(&model_builder)?;
}
Ok(database)
}
}
impl Builder {
pub fn new() -> Self {
Self {
database_configuration: Configuration {
cache_size_bytes: None,
},
}
}
pub fn set_cache_size(&mut self, bytes: usize) -> &mut Self {
self.database_configuration.cache_size_bytes = Some(bytes);
self
}
pub fn create<'a>(&self, models: &'a Models, path: impl AsRef<Path>) -> Result<Database<'a>> {
let builder = self.database_configuration.new_rdb_builder();
let database_instance = DatabaseInstance::create_on_disk(builder, path)?;
self.init(database_instance, models)
}
pub fn open<'a>(&self, models: &'a Models, path: impl AsRef<Path>) -> Result<Database<'a>> {
let builder = self.database_configuration.new_rdb_builder();
let database_instance = match DatabaseInstance::open_on_disk(builder, &path) {
Err(Error::RedbDatabaseError(redb::DatabaseError::UpgradeRequired(_))) => {
upgrade::upgrade(&self.database_configuration, &path, &models.models_builder)
}
Err(error) => return Err(error),
Ok(database_instance) => Ok(database_instance),
}?;
self.init(database_instance, models)
}
pub fn create_in_memory<'a>(&self, models: &'a Models) -> Result<Database<'a>> {
let builder = self.database_configuration.new_rdb_builder();
let database_instance = DatabaseInstance::create_in_memory(builder)?;
self.init(database_instance, models)
}
}
#[derive(Debug)]
pub(crate) struct ModelBuilder {
pub(crate) model: Model,
pub(crate) native_model_options: NativeModelOptions,
}