use super::BuildableStatement;
use crate::errors::SqlBuilderError;
#[derive(Debug)]
pub enum ColumnType {
Integer,
Text,
Real,
Boolean,
Blob,
Numeric,
Date,
Time,
Datetime,
}
impl BuildableStatement for ColumnType {
fn build(&self) -> String {
String::from(match self {
Self::Integer => "INTEGER",
Self::Text => "TEXT",
Self::Real => "REAL",
Self::Boolean => "BOOLEAN",
Self::Blob => "BLOB",
Self::Numeric => "NUMERIC",
Self::Date => "DATE",
Self::Time => "TIME",
Self::Datetime => "DATETIME",
})
}
}
#[derive(Debug)]
pub enum ColumnOption {
NotNull,
Unique,
Default(String),
AutoIncrement,
PrimaryKey,
}
impl BuildableStatement for ColumnOption {
fn build(&self) -> String {
match self {
Self::NotNull => "NOT NULL".to_string(),
Self::Unique => "UNIQUE".to_string(),
Self::Default(s) => format!("DEFAULT {}", s),
Self::AutoIncrement => "AUTOINCREMENT".to_string(),
Self::PrimaryKey => "PRIMARY KEY".to_string(),
}
}
}
#[derive(Debug)]
pub struct Column {
name: String,
column_type: Option<ColumnType>,
options: Vec<ColumnOption>,
}
impl Column {
pub fn new(name: &str) -> Self {
Self {
name: name.to_string(),
column_type: None,
options: Vec::new(),
}
}
pub fn integer(mut self) -> Self {
self.column_type = Some(ColumnType::Integer);
self
}
pub fn text(mut self) -> Self {
self.column_type = Some(ColumnType::Text);
self
}
pub fn real(mut self) -> Self {
self.column_type = Some(ColumnType::Real);
self
}
pub fn boolean(mut self) -> Self {
self.column_type = Some(ColumnType::Boolean);
self
}
pub fn blob(mut self) -> Self {
self.column_type = Some(ColumnType::Blob);
self
}
pub fn numeric(mut self) -> Self {
self.column_type = Some(ColumnType::Numeric);
self
}
pub fn date(mut self) -> Self {
self.column_type = Some(ColumnType::Date);
self
}
pub fn time(mut self) -> Self {
self.column_type = Some(ColumnType::Time);
self
}
pub fn datetime(mut self) -> Self {
self.column_type = Some(ColumnType::Datetime);
self
}
pub fn not_null(mut self) -> Self {
self.options.push(ColumnOption::NotNull);
self
}
pub fn unique(mut self) -> Self {
self.options.push(ColumnOption::Unique);
self
}
pub fn default(mut self, value: &str) -> Self {
self.options.push(ColumnOption::Default(value.to_string()));
self
}
pub fn auto_increment(mut self) -> Self {
self.options.push(ColumnOption::AutoIncrement);
self
}
pub fn primary_key(mut self) -> Self {
self.options.push(ColumnOption::PrimaryKey);
self
}
pub fn build(&self) -> Result<String, SqlBuilderError> {
if self.name.is_empty() {
return Err(SqlBuilderError::EmptyColumnName);
}
let column_type = match &self.column_type {
Some(ct) => ct.build(),
None => return Err(SqlBuilderError::InvalidColumnType),
};
let options_str = self
.options
.iter()
.map(|opt| opt.build())
.collect::<Vec<String>>()
.join(" ");
Ok(format!("{} {} {}", self.name, column_type, options_str))
}
}
impl BuildableStatement for Column {
fn build(&self) -> String {
self.build().unwrap()
}
}