use super::FieldNameCharsConsListItem;
use crate::{
sql::{FieldsConsListItem, IntoSqlType, SqlType},
statements::{
CreateTableStatement, DropTableStatement, EmptyDeleteStatement, EmptyUpdateStatement,
},
util::TypesEqual,
};
pub trait Table: Sized + 'static {
type Fields: FieldsConsListItem;
const FIELDS: &'static [TableField];
const UNIQUE_CONSTRAINTS: &'static [TableUniqueConstraint];
const TABLE_NAME: &'static str;
type IdColumn: Column;
}
pub struct TableField {
pub name: &'static str,
pub is_primary_key: bool,
pub is_unique: bool,
pub foreign_key_to_table_name: Option<&'static str>,
pub sql_type_name: &'static str,
pub is_null: bool,
}
pub struct TableUniqueConstraint {
pub fields: &'static [&'static str],
}
pub trait Column {
const COLUMN_NAME: &'static str;
type ColumnName: FieldNameCharsConsListItem;
type Table: Table;
type SqlType: SqlType;
type RustType: IntoSqlType<SqlType = Self::SqlType>;
}
pub trait ColumnIsForeignKey<T: Table>: Column
where
(
<Self::SqlType as SqlType>::NonNullSqlType,
<T::IdColumn as Column>::SqlType,
): TypesEqual,
{
}
pub trait TableMarker: Sized + 'static {
type Table: Table;
fn create(self) -> CreateTableStatement<Self::Table> {
CreateTableStatement::new()
}
fn drop(self) -> DropTableStatement<Self::Table> {
DropTableStatement::new()
}
fn delete(self) -> EmptyDeleteStatement<Self::Table> {
EmptyDeleteStatement::new()
}
fn update(self) -> EmptyUpdateStatement<Self::Table> {
EmptyUpdateStatement::new()
}
}
pub trait TableHasOneForeignKey<T: Table>: Table
where
(
<<Self::ForeignKeyColumn as Column>::SqlType as SqlType>::NonNullSqlType,
<T::IdColumn as Column>::SqlType,
): TypesEqual,
{
type ForeignKeyColumn: Column<Table = Self> + ColumnIsForeignKey<T>;
}