use serde::{Deserialize, Serialize};
use crate::identifier::{Identifier, QualifiedName};
use crate::ir::column_type::ColumnType;
use crate::ir::default_expr::DefaultExpr;
use crate::ir::eq::DiffMacro;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, DiffMacro)]
pub struct Column {
pub name: Identifier,
#[diff(via_debug)]
pub ty: ColumnType,
pub nullable: bool,
#[diff(via_debug)]
pub default: Option<DefaultExpr>,
#[diff(via_debug)]
pub identity: Option<Identity>,
#[diff(via_debug)]
pub generated: Option<Generated>,
#[diff(via_debug)]
pub collation: Option<QualifiedName>,
#[diff(via_debug)]
pub storage: Option<StorageKind>,
#[diff(via_debug)]
pub compression: Option<Compression>,
#[diff(via_debug)]
pub comment: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Identity {
pub kind: IdentityKind,
pub sequence: SequenceOptions,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum IdentityKind {
Always,
ByDefault,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Generated {
pub kind: GeneratedKind,
pub expression: crate::ir::default_expr::NormalizedExpr,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum GeneratedKind {
Stored,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum StorageKind {
Plain,
External,
Extended,
Main,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum Compression {
Pglz,
Lz4,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SequenceOptions {
pub start: i64,
pub increment: i64,
pub min_value: Option<i64>,
pub max_value: Option<i64>,
pub cache: i64,
pub cycle: bool,
}
#[cfg(test)]
mod tests {
use super::*;
use crate::ir::eq::Diff;
fn id(s: &str) -> Identifier {
Identifier::from_unquoted(s).unwrap()
}
fn base() -> Column {
Column {
name: id("email"),
ty: ColumnType::Text,
nullable: false,
default: None,
identity: None,
generated: None,
collation: None,
storage: None,
compression: None,
comment: None,
}
}
#[test]
fn equal_columns_have_no_diff() {
assert!(base().canonical_eq(&base()));
}
#[test]
fn type_change_diffs() {
let mut b = base();
b.ty = ColumnType::Varchar { len: Some(255) };
assert!(base().diff(&b).iter().any(|x| x.path == "ty"));
}
#[test]
fn nullability_change_diffs() {
let mut b = base();
b.nullable = true;
assert!(base().diff(&b).iter().any(|x| x.path == "nullable"));
}
#[test]
fn identity_change_diffs() {
let mut b = base();
b.identity = Some(Identity {
kind: IdentityKind::ByDefault,
sequence: SequenceOptions {
start: 1,
increment: 1,
min_value: None,
max_value: None,
cache: 1,
cycle: false,
},
});
assert!(base().diff(&b).iter().any(|x| x.path == "identity"));
}
#[test]
fn storage_change_diffs() {
let mut b = base();
b.storage = Some(StorageKind::External);
assert!(base().diff(&b).iter().any(|x| x.path == "storage"));
}
#[test]
fn compression_change_diffs() {
let mut b = base();
b.compression = Some(Compression::Lz4);
assert!(base().diff(&b).iter().any(|x| x.path == "compression"));
}
}