diff --git a/src/backend/postgres/types.rs b/src/backend/postgres/types.rs index db5a43b7..3ec126d5 100644 --- a/src/backend/postgres/types.rs +++ b/src/backend/postgres/types.rs @@ -88,22 +88,27 @@ impl PostgresQueryBuilder { fn prepare_alter_type_opt(&self, opt: &TypeAlterOpt, sql: &mut dyn SqlWriter) { match opt { - TypeAlterOpt::Add(value, placement) => { + TypeAlterOpt::Add { + value, + placement, + if_not_exists, + } => { write!(sql, " ADD VALUE ").unwrap(); - match placement { - Some(add_option) => match add_option { + if *if_not_exists { + write!(sql, "IF NOT EXISTS ").unwrap(); + } + self.prepare_value(&value.to_string().into(), sql); + if let Some(add_option) = placement { + match add_option { TypeAlterAddOpt::Before(before_value) => { - self.prepare_value(&value.to_string().into(), sql); write!(sql, " BEFORE ").unwrap(); self.prepare_value(&before_value.to_string().into(), sql); } TypeAlterAddOpt::After(after_value) => { - self.prepare_value(&value.to_string().into(), sql); write!(sql, " AFTER ").unwrap(); self.prepare_value(&after_value.to_string().into(), sql); } - }, - None => self.prepare_value(&value.to_string().into(), sql), + } } } TypeAlterOpt::Rename(new_name) => { diff --git a/src/extension/postgres/types.rs b/src/extension/postgres/types.rs index 3aff184d..29bda947 100644 --- a/src/extension/postgres/types.rs +++ b/src/extension/postgres/types.rs @@ -88,7 +88,11 @@ pub enum TypeDropOpt { #[derive(Debug, Clone)] pub enum TypeAlterOpt { - Add(DynIden, Option), + Add { + value: DynIden, + placement: Option, + if_not_exists: bool, + }, Rename(DynIden), RenameValue(DynIden, DynIden), } @@ -361,7 +365,11 @@ impl TypeAlterStatement { where T: IntoIden, { - self.alter_option(TypeAlterOpt::Add(value.into_iden(), None)) + self.alter_option(TypeAlterOpt::Add { + value: value.into_iden(), + placement: None, + if_not_exists: false, + }) } /// Add a enum value before an existing value @@ -398,6 +406,13 @@ impl TypeAlterStatement { self } + pub fn if_not_exists(mut self) -> Self { + if let Some(option) = self.option { + self.option = Some(option.if_not_exists()); + } + self + } + pub fn rename_to(self, name: T) -> Self where T: IntoIden, @@ -442,9 +457,15 @@ impl TypeAlterOpt { T: IntoIden, { match self { - TypeAlterOpt::Add(iden, _) => { - Self::Add(iden, Some(TypeAlterAddOpt::Before(value.into_iden()))) - } + TypeAlterOpt::Add { + value: iden, + if_not_exists, + .. + } => Self::Add { + value: iden, + if_not_exists, + placement: Some(TypeAlterAddOpt::Before(value.into_iden())), + }, _ => self, } } @@ -455,9 +476,29 @@ impl TypeAlterOpt { T: IntoIden, { match self { - TypeAlterOpt::Add(iden, _) => { - Self::Add(iden, Some(TypeAlterAddOpt::After(value.into_iden()))) - } + TypeAlterOpt::Add { + value: iden, + if_not_exists, + .. + } => Self::Add { + value: iden, + if_not_exists, + placement: Some(TypeAlterAddOpt::After(value.into_iden())), + }, + _ => self, + } + } + + /// Changes only `ADD VALUE x` options into `ADD VALUE IF NOT EXISTS x` options, does nothing otherwise + pub fn if_not_exists(self) -> Self { + match self { + TypeAlterOpt::Add { + value, placement, .. + } => Self::Add { + value, + placement, + if_not_exists: true, + }, _ => self, } }