use crate::{
backend::SchemaBuilder, foreign_key::*, index::*, prepare::*, types::*, ColumnDef,
SchemaStatementBuilder,
};
#[derive(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,
}
#[derive(Debug, Clone)]
pub enum TableOpt {
Engine(String),
Collate(String),
CharacterSet(String),
}
#[derive(Debug, Clone)]
pub enum TablePartition {}
impl Default for TableCreateStatement {
fn default() -> Self {
Self::new()
}
}
impl TableCreateStatement {
pub fn new() -> Self {
Self {
table: None,
columns: Vec::new(),
options: Vec::new(),
partitions: Vec::new(),
indexes: Vec::new(),
foreign_keys: Vec::new(),
if_not_exists: false,
}
}
#[deprecated(
since = "0.9.6",
note = "Please use the [`TableCreateStatement::if_not_exists`]"
)]
pub fn create_if_not_exists(&mut self) -> &mut Self {
self.if_not_exists = true;
self
}
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 col(&mut self, column: &mut ColumnDef) -> &mut Self {
let mut column = column.take();
column.table = self.table.clone();
self.columns.push(column);
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(&mut self, string: &str) -> &mut Self {
self.opt(TableOpt::Engine(string.into()));
self
}
pub fn collate(&mut self, string: &str) -> &mut Self {
self.opt(TableOpt::Collate(string.into()));
self
}
pub fn character_set(&mut self, string: &str) -> &mut Self {
self.opt(TableOpt::CharacterSet(string.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_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 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,
}
}
}
impl SchemaStatementBuilder for TableCreateStatement {
fn build<T: SchemaBuilder>(&self, schema_builder: T) -> String {
let mut sql = SqlWriter::new();
schema_builder.prepare_table_create_statement(self, &mut sql);
sql.result()
}
fn build_any(&self, schema_builder: &dyn SchemaBuilder) -> String {
let mut sql = SqlWriter::new();
schema_builder.prepare_table_create_statement(self, &mut sql);
sql.result()
}
}