use turso_sql::{ColumnDef as SqlColumnDef, CreateIndex, CreateTable, Table};
use super::base_entity::EntityTrait;
use super::column::ColumnTrait;
use super::iden::{IdenStatic, Iterable};
use super::primary_key::{PrimaryKeyToColumn, PrimaryKeyTrait};
use super::relation::RelationTrait;
#[derive(Debug, Default)]
pub struct Schema {
strict: bool,
}
impl Schema {
pub fn new() -> Self {
Self::default()
}
#[must_use]
pub fn strict(mut self, strict: bool) -> Self {
self.strict = strict;
self
}
pub fn create_table_from_entity<E: EntityTrait>(&self, _: E) -> CreateTable {
let mut create = Table::create().table(E::TABLE_NAME);
let pks: Vec<E::PrimaryKey> = E::PrimaryKey::iter().collect();
let single_pk = pks.len() == 1;
for column in E::Column::iter() {
let def = column.def();
let mut col = SqlColumnDef::new(column.as_str(), def.ty);
if !def.nullable {
col = col.not_null();
}
if def.unique {
col = col.unique_key();
}
if let Some(d) = def.default {
col = col.default(d);
}
let is_pk = E::PrimaryKey::from_column(column).is_some();
if is_pk && single_pk {
col = col.primary_key();
if E::PrimaryKey::auto_increment() {
col = col.auto_increment();
}
}
create = create.col(col);
}
if !single_pk && !pks.is_empty() {
create = create.primary_key(pks.iter().map(IdenStatic::as_str));
}
for relation in E::Relation::iter() {
if let Some(fk) = relation.def().foreign_key() {
create = create.foreign_key(fk);
}
}
if self.strict {
create = create.strict();
}
create
}
pub fn create_index_from_entity<E: EntityTrait>(&self, _: E) -> Vec<CreateIndex> {
E::Column::iter()
.filter(|c| c.def().indexed)
.map(|c| {
CreateIndex::new()
.name(format!("idx-{}-{}", E::TABLE_NAME, c.as_str()))
.table(E::TABLE_NAME)
.col(c.as_str())
.if_not_exists()
})
.collect()
}
}