use crate::model::column_type::ColumnType;
use crate::model::types::BooleanMode;
#[derive(Debug, Clone)]
pub struct Column {
schema_name: Option<String>,
name: String,
column_type: ColumnType,
length: i32,
scale: i32,
required: bool,
check_constraint: Option<String>,
default_constraint: Option<String>,
generated: Option<String>,
min_value: Option<f64>,
max_value: Option<f64>,
enum_type: Option<String>,
element_type: Option<String>,
}
impl Column {
pub fn new<S: Into<String>>(
schema_name: Option<S>,
name: S,
column_type: ColumnType,
length: i32,
scale: i32,
required: bool,
) -> Self {
Self {
schema_name: schema_name.map(|s| s.into()),
name: name.into(),
column_type,
length,
scale,
required,
check_constraint: None,
default_constraint: None,
generated: None,
min_value: None,
max_value: None,
enum_type: None,
element_type: None,
}
}
pub fn new_all<S: Into<String>>(
schema_name: Option<S>,
name: S,
column_type: ColumnType,
length: i32,
scale: i32,
required: bool,
check_constraint: Option<String>,
default_constraint: Option<String>,
generated: Option<String>,
min_value: Option<f64>,
max_value: Option<f64>,
enum_type: Option<String>,
element_type: Option<String>,
) -> Self {
Self {
schema_name: schema_name.map(|s| s.into()),
name: name.into(),
column_type,
length,
scale,
required,
check_constraint,
default_constraint,
generated,
min_value,
max_value,
enum_type,
element_type,
}
}
pub fn schema_name(&self) -> Option<&str> {
self.schema_name.as_deref()
}
pub fn name(&self) -> &str {
&self.name
}
pub fn column_type(&self) -> ColumnType {
self.column_type
}
pub fn length(&self) -> i32 {
self.length
}
pub fn scale(&self) -> i32 {
self.scale
}
pub fn required(&self) -> bool {
self.required
}
pub fn is_required(&self) -> bool {
self.required
}
pub fn check_constraint(&self) -> Option<&str> {
self.check_constraint.as_deref()
}
pub fn default_constraint(&self) -> Option<&str> {
self.default_constraint.as_deref()
}
pub fn generated(&self) -> Option<&str> {
self.generated.as_deref()
}
pub fn min_value(&self) -> Option<f64> {
self.min_value
}
pub fn max_value(&self) -> Option<f64> {
self.max_value
}
pub fn enum_type(&self) -> Option<&str> {
self.enum_type.as_deref()
}
pub fn element_type(&self) -> Option<&str> {
self.element_type.as_deref()
}
pub fn has_min_or_max_value(&self) -> bool {
self.min_value.is_some() || self.max_value.is_some()
}
pub fn needs_check_constraints(&self, boolean_mode: BooleanMode) -> bool {
self.check_constraint.is_some()
|| self.min_value.is_some()
|| self.max_value.is_some()
|| self.enum_type.is_some()
|| (self.column_type == ColumnType::Boolean && boolean_mode != BooleanMode::Native)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::model::types::BooleanMode;
#[test]
fn constructor_and_getters() {
let c = Column::new(None, "name", ColumnType::Varchar, 255, 0, true);
assert_eq!(c.name(), "name");
assert_eq!(c.column_type(), ColumnType::Varchar);
assert_eq!(c.length(), 255);
assert_eq!(c.scale(), 0);
assert!(c.required());
assert!(c.is_required());
}
#[test]
fn needs_check_constraints_logic() {
let c = Column::new(None, "b", ColumnType::Boolean, 0, 0, false);
assert!(c.needs_check_constraints(BooleanMode::YesNo));
assert!(!c.needs_check_constraints(BooleanMode::Native));
}
#[test]
fn has_min_or_max_value() {
let c = Column::new(None, "n", ColumnType::Int, 0, 0, false);
assert!(!c.has_min_or_max_value());
}
}