use inherent::inherent;
use crate::{
backend::SchemaBuilder, foreign_key::*, index::*, types::*, ColumnDef, IntoColumnDef,
SchemaStatementBuilder, SimpleExpr,
};
#[derive(Default, Debug, Clone)]
pub struct TableCreateStatement {
pub(crate) table: Option<TableRef>,
pub(crate) columns: Vec<ColumnDef>,
pub(crate) options: Vec<TableOpt>,
pub(crate) partitions: Vec<TablePartition>,
pub(crate) indexes: Vec<IndexCreateStatement>,
pub(crate) foreign_keys: Vec<ForeignKeyCreateStatement>,
pub(crate) if_not_exists: bool,
pub(crate) check: Vec<SimpleExpr>,
pub(crate) comment: Option<String>,
pub(crate) extra: Option<String>,
pub(crate) temporary: bool,
}
#[derive(Debug, Clone)]
pub enum TableOpt {
Engine(String),
Collate(String),
CharacterSet(String),
}
#[derive(Debug, Clone)]
pub enum TablePartition {}
impl TableCreateStatement {
pub fn new() -> Self {
Self::default()
}
pub fn if_not_exists(&mut self) -> &mut Self {
self.if_not_exists = true;
self
}
pub fn table<T>(&mut self, table: T) -> &mut Self
where
T: IntoTableRef,
{
self.table = Some(table.into_table_ref());
self
}
pub fn comment<T>(&mut self, comment: T) -> &mut Self
where
T: Into<String>,
{
self.comment = Some(comment.into());
self
}
pub fn col<C: IntoColumnDef>(&mut self, column: C) -> &mut Self {
let mut column = column.into_column_def();
column.table.clone_from(&self.table);
self.columns.push(column);
self
}
pub fn check(&mut self, value: SimpleExpr) -> &mut Self {
self.check.push(value);
self
}
pub fn index(&mut self, index: &mut IndexCreateStatement) -> &mut Self {
self.indexes.push(index.take());
self
}
pub fn primary_key(&mut self, index: &mut IndexCreateStatement) -> &mut Self {
let mut index = index.take();
index.primary = true;
self.indexes.push(index);
self
}
pub fn foreign_key(&mut self, foreign_key: &mut ForeignKeyCreateStatement) -> &mut Self {
self.foreign_keys.push(foreign_key.take());
self
}
pub fn engine<T>(&mut self, string: T) -> &mut Self
where
T: Into<String>,
{
self.opt(TableOpt::Engine(string.into()));
self
}
pub fn collate<T>(&mut self, string: T) -> &mut Self
where
T: Into<String>,
{
self.opt(TableOpt::Collate(string.into()));
self
}
pub fn character_set<T>(&mut self, name: T) -> &mut Self
where
T: Into<String>,
{
self.opt(TableOpt::CharacterSet(name.into()));
self
}
fn opt(&mut self, option: TableOpt) -> &mut Self {
self.options.push(option);
self
}
#[allow(dead_code)]
fn partition(&mut self, partition: TablePartition) -> &mut Self {
self.partitions.push(partition);
self
}
pub fn get_table_name(&self) -> Option<&TableRef> {
self.table.as_ref()
}
pub fn get_columns(&self) -> &Vec<ColumnDef> {
self.columns.as_ref()
}
pub fn get_comment(&self) -> Option<&String> {
self.comment.as_ref()
}
pub fn get_foreign_key_create_stmts(&self) -> &Vec<ForeignKeyCreateStatement> {
self.foreign_keys.as_ref()
}
pub fn get_indexes(&self) -> &Vec<IndexCreateStatement> {
self.indexes.as_ref()
}
pub fn extra<T>(&mut self, extra: T) -> &mut Self
where
T: Into<String>,
{
self.extra = Some(extra.into());
self
}
pub fn get_extra(&self) -> Option<&String> {
self.extra.as_ref()
}
pub fn temporary(&mut self) -> &mut Self {
self.temporary = true;
self
}
pub fn take(&mut self) -> Self {
Self {
table: self.table.take(),
columns: std::mem::take(&mut self.columns),
options: std::mem::take(&mut self.options),
partitions: std::mem::take(&mut self.partitions),
indexes: std::mem::take(&mut self.indexes),
foreign_keys: std::mem::take(&mut self.foreign_keys),
if_not_exists: self.if_not_exists,
check: std::mem::take(&mut self.check),
comment: std::mem::take(&mut self.comment),
extra: std::mem::take(&mut self.extra),
temporary: self.temporary,
}
}
}
#[inherent]
impl SchemaStatementBuilder for TableCreateStatement {
pub fn build<T: SchemaBuilder>(&self, schema_builder: T) -> String {
let mut sql = String::with_capacity(256);
schema_builder.prepare_table_create_statement(self, &mut sql);
sql
}
pub fn build_any(&self, schema_builder: &dyn SchemaBuilder) -> String {
let mut sql = String::with_capacity(256);
schema_builder.prepare_table_create_statement(self, &mut sql);
sql
}
pub fn to_string<T: SchemaBuilder>(&self, schema_builder: T) -> String;
}