use serde::{Deserialize, Serialize};
use crate::dialect::Dialect;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum ColumnType {
Text,
Integer,
Real,
Blob,
Uuid,
Boolean,
Timestamp,
Date,
Time,
Json,
BigInt,
SmallInt,
Varchar(u32),
Serial,
BigSerial,
Jsonb,
Numeric,
Char(u32),
Array(Box<ColumnType>),
}
impl ColumnType {
pub fn as_sql(&self) -> String {
match self {
Self::Text | Self::Jsonb | Self::Char(_) | Self::Array(_) => "TEXT".to_owned(),
Self::Integer | Self::Serial | Self::BigSerial => "INTEGER".to_owned(),
Self::Real | Self::Numeric => "REAL".to_owned(),
Self::Blob => "BLOB".to_owned(),
Self::Uuid => "uuid".to_owned(),
Self::Boolean => "boolean".to_owned(),
Self::Timestamp => "timestamp".to_owned(),
Self::Date => "date".to_owned(),
Self::Time => "time".to_owned(),
Self::Json => "json".to_owned(),
Self::BigInt => "bigint".to_owned(),
Self::SmallInt => "smallint".to_owned(),
Self::Varchar(n) => format!("varchar({n})"),
}
}
pub fn as_compat_sql(&self) -> String {
match self {
Self::Text
| Self::Uuid
| Self::Date
| Self::Time
| Self::Json
| Self::Jsonb
| Self::Varchar(_)
| Self::Char(_)
| Self::Array(_) => "TEXT".to_owned(),
Self::Integer
| Self::BigInt
| Self::SmallInt
| Self::Timestamp
| Self::Boolean
| Self::Serial
| Self::BigSerial => "INTEGER".to_owned(),
Self::Real | Self::Numeric => "REAL".to_owned(),
Self::Blob => "BLOB".to_owned(),
}
}
pub fn as_ddl_sql(&self, dialect: Dialect) -> String {
match dialect {
Dialect::Sqlite => match self {
Self::Text
| Self::Uuid
| Self::Date
| Self::Time
| Self::Json
| Self::Jsonb
| Self::Varchar(_)
| Self::Char(_)
| Self::Array(_) => "TEXT".to_owned(),
Self::Integer
| Self::Boolean
| Self::Timestamp
| Self::BigInt
| Self::SmallInt
| Self::Serial
| Self::BigSerial => "INTEGER".to_owned(),
Self::Real | Self::Numeric => "REAL".to_owned(),
Self::Blob => "BLOB".to_owned(),
},
Dialect::Postgres => match self {
Self::Text => "TEXT".to_owned(),
Self::Integer => "INTEGER".to_owned(),
Self::Real => "DOUBLE PRECISION".to_owned(),
Self::Blob => "BYTEA".to_owned(),
Self::Uuid => "UUID".to_owned(),
Self::Boolean => "BOOLEAN".to_owned(),
Self::Timestamp => "TIMESTAMPTZ".to_owned(),
Self::Date => "DATE".to_owned(),
Self::Time => "TIME".to_owned(),
Self::Json => "JSON".to_owned(),
Self::Jsonb => "JSONB".to_owned(),
Self::BigInt => "BIGINT".to_owned(),
Self::SmallInt => "SMALLINT".to_owned(),
Self::Serial => "SERIAL".to_owned(),
Self::BigSerial => "BIGSERIAL".to_owned(),
Self::Numeric => "NUMERIC".to_owned(),
Self::Varchar(n) => format!("VARCHAR({n})"),
Self::Char(n) => format!("CHAR({n})"),
Self::Array(inner) => format!("{}[]", inner.as_ddl_sql(Dialect::Postgres)),
},
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum ForeignKeyAction {
Cascade,
SetNull,
SetDefault,
Restrict,
NoAction,
}
impl ForeignKeyAction {
pub fn as_sql(self) -> &'static str {
match self {
Self::Cascade => "CASCADE",
Self::SetNull => "SET NULL",
Self::SetDefault => "SET DEFAULT",
Self::Restrict => "RESTRICT",
Self::NoAction => "NO ACTION",
}
}
}
pub trait EnumSchema {
fn variants() -> &'static [&'static str];
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ColumnDef {
pub name: String,
pub column_type: ColumnType,
pub primary_key: bool,
pub not_null: bool,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub default: Option<String>,
pub unique: bool,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub references: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub on_delete: Option<ForeignKeyAction>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub on_update: Option<ForeignKeyAction>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub check: Option<String>,
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub unindexed: bool,
}
pub struct Text;
pub struct Integer;
pub struct Real;
pub struct Blob;
pub struct Uuid;
pub struct Boolean;
pub struct Timestamp;
pub struct Date;
pub struct Time;
pub struct Json;
pub struct BigInt;
pub struct SmallInt;
pub struct Varchar<const N: u32>;
pub struct Serial;
pub struct BigSerial;
pub struct Jsonb;
pub struct Numeric;
pub struct Char<const N: u32>;