use std::{collections::BTreeMap, marker::PhantomData, ops::Deref, sync::Arc};
use super::{Identifier, TableColumn, TableConstraint};
#[derive(Clone, PartialEq, Eq, Debug,)]
pub struct DatabaseTableDefinition<T> {
data: Arc<DatabaseTableDefinitionData<T>>,
}
impl<T> Deref for DatabaseTableDefinition<T> {
type Target = DatabaseTableDefinitionData<T>;
fn deref(&self) -> &Self::Target {
&self.data
}
}
impl<T> DatabaseTableDefinition<T> {
#[allow(clippy::new_ret_no_self)]
pub fn new(table_name: &str) -> Result<DatabaseTableDefinitionData<T>, String> {
DatabaseTableDefinitionData::<T>::new(table_name)
}
}
#[derive(Clone, PartialEq, Eq, Debug)]
pub enum TableRelationship {
OneToMany(Identifier),
ManyToMany(Identifier),
OneToOne(Identifier),
}
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct DatabaseTableDefinitionData<T> {
pub table_name: Identifier,
pub columns: BTreeMap<Identifier, TableColumn>, pub child_tables: Vec<TableRelationship>, pub constraints: Vec<TableConstraint>,
pub _t: PhantomData<T>,
}
impl<T> From<DatabaseTableDefinitionData<T>> for DatabaseTableDefinition<T> {
fn from(val: DatabaseTableDefinitionData<T>) -> Self {
DatabaseTableDefinition {
data: Arc::new(val),
}
}
}
impl<T> DatabaseTableDefinitionData<T> {
pub fn new(table_name: &str) -> Result<Self, String> {
Ok(Self {
table_name: Identifier::new(table_name)?, columns: BTreeMap::new(),
child_tables: Default::default(),
constraints: Vec::new(),
_t: PhantomData,
})
}
pub fn column<C: Into<TableColumn>>(
mut self,
column: C,
) -> Self {
self.add_column(column);
self
}
pub fn add_column<C: Into<TableColumn>>(
&mut self,
column: C,
) {
let column = column.into();
self.columns.insert(column.column_name.clone(), column);
}
}
impl<T> DatabaseTableDefinitionData<T> {
pub fn with_string(
self,
col_name: &str,
) -> Result<Self, String> {
Ok(self.column(TableColumn::string(col_name)?))
}
pub fn with_bool(
self,
col_name: &str,
) -> Result<Self, String> {
Ok(self.column(TableColumn::bool(col_name)?))
}
pub fn with_float(
self,
col_name: &str,
) -> Result<Self, String> {
Ok(self.column(TableColumn::float(col_name)?))
}
pub fn with_int(
self,
col_name: &str,
) -> Result<Self, String> {
Ok(self.column(TableColumn::int(col_name)?))
}
pub fn with_timestamp(
self,
col_name: &str,
) -> Result<Self, String> {
Ok(self.column(TableColumn::timestamp(col_name)?))
}
pub fn with_uuid(
self,
col_name: &str,
) -> Result<Self, String> {
Ok(self.column(TableColumn::uuid(col_name)?))
}
}