use crate::*;
pub trait TableBuilder:
IndexBuilder + ForeignKeyBuilder + QuotedBuilder + TableRefBuilder + QueryBuilder
{
fn prepare_table_create_statement(
&self,
create: &TableCreateStatement,
sql: &mut dyn SqlWriter,
) {
write!(sql, "CREATE TABLE ").unwrap();
if create.if_not_exists {
write!(sql, "IF NOT EXISTS ").unwrap();
}
if let Some(table_ref) = &create.table {
self.prepare_table_ref_table_stmt(table_ref, sql);
}
write!(sql, " ( ").unwrap();
let mut count = 0;
for column_def in create.columns.iter() {
if count > 0 {
write!(sql, ", ").unwrap();
}
self.prepare_column_def(column_def, sql);
count += 1;
}
for index in create.indexes.iter() {
if count > 0 {
write!(sql, ", ").unwrap();
}
self.prepare_table_index_expression(index, sql);
count += 1;
}
for foreign_key in create.foreign_keys.iter() {
if count > 0 {
write!(sql, ", ").unwrap();
}
self.prepare_foreign_key_create_statement_internal(foreign_key, sql, Mode::Creation);
count += 1;
}
write!(sql, " )").unwrap();
for table_opt in create.options.iter() {
write!(sql, " ").unwrap();
self.prepare_table_opt(table_opt, sql);
}
}
fn prepare_table_ref_table_stmt(&self, table_ref: &TableRef, sql: &mut dyn SqlWriter) {
match table_ref {
TableRef::Table(_)
| TableRef::SchemaTable(_, _)
| TableRef::DatabaseSchemaTable(_, _, _) => self.prepare_table_ref_iden(table_ref, sql),
_ => panic!("Not supported"),
}
}
fn prepare_column_def(&self, column_def: &ColumnDef, sql: &mut dyn SqlWriter);
fn prepare_column_type(&self, column_type: &ColumnType, sql: &mut dyn SqlWriter);
fn prepare_column_spec(&self, column_spec: &ColumnSpec, sql: &mut dyn SqlWriter) {
match column_spec {
ColumnSpec::Null => write!(sql, "NULL").unwrap(),
ColumnSpec::NotNull => write!(sql, "NOT NULL").unwrap(),
ColumnSpec::Default(value) => {
write!(sql, "DEFAULT ").unwrap();
QueryBuilder::prepare_simple_expr(self, value, sql);
}
ColumnSpec::AutoIncrement => {
write!(sql, "{}", self.column_spec_auto_increment_keyword()).unwrap()
}
ColumnSpec::UniqueKey => write!(sql, "UNIQUE").unwrap(),
ColumnSpec::PrimaryKey => write!(sql, "PRIMARY KEY").unwrap(),
ColumnSpec::Extra(string) => write!(sql, "{}", string).unwrap(),
}
}
fn column_spec_auto_increment_keyword(&self) -> &str;
fn prepare_table_opt(&self, table_opt: &TableOpt, sql: &mut dyn SqlWriter) {
write!(
sql,
"{}",
match table_opt {
TableOpt::Engine(s) => format!("ENGINE={}", s),
TableOpt::Collate(s) => format!("COLLATE={}", s),
TableOpt::CharacterSet(s) => format!("DEFAULT CHARSET={}", s),
}
)
.unwrap()
}
fn prepare_table_partition(&self, _table_partition: &TablePartition, _sql: &mut dyn SqlWriter) {
}
fn prepare_table_drop_statement(&self, drop: &TableDropStatement, sql: &mut dyn SqlWriter) {
write!(sql, "DROP TABLE ").unwrap();
if drop.if_exists {
write!(sql, "IF EXISTS ").unwrap();
}
drop.tables.iter().fold(true, |first, table| {
if !first {
write!(sql, ", ").unwrap();
}
self.prepare_table_ref_table_stmt(table, sql);
false
});
for drop_opt in drop.options.iter() {
self.prepare_table_drop_opt(drop_opt, sql);
}
}
fn prepare_table_drop_opt(&self, drop_opt: &TableDropOpt, sql: &mut dyn SqlWriter) {
write!(
sql,
" {}",
match drop_opt {
TableDropOpt::Restrict => "RESTRICT",
TableDropOpt::Cascade => "CASCADE",
}
)
.unwrap();
}
fn prepare_table_truncate_statement(
&self,
truncate: &TableTruncateStatement,
sql: &mut dyn SqlWriter,
) {
write!(sql, "TRUNCATE TABLE ").unwrap();
if let Some(table) = &truncate.table {
self.prepare_table_ref_table_stmt(table, sql);
}
}
fn prepare_table_alter_statement(&self, alter: &TableAlterStatement, sql: &mut dyn SqlWriter);
fn prepare_table_rename_statement(
&self,
rename: &TableRenameStatement,
sql: &mut dyn SqlWriter,
);
}