Skip to content

Commit

Permalink
issues-229 add column if not exists (#278)
Browse files Browse the repository at this point in the history
* issues-213 Add support for ADD COLUMN IF NOT EXISTS for postgres and mysql

* issues-229 Fix after review
  • Loading branch information
ikrivosheev authored Apr 3, 2022
1 parent cc928ac commit 822ebe1
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 8 deletions.
7 changes: 5 additions & 2 deletions src/backend/mysql/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,12 @@ impl TableBuilder for MysqlQueryBuilder {
write!(sql, ", ").unwrap();
};
match option {
TableAlterOption::AddColumn(column_def) => {
TableAlterOption::AddColumn(AddColumnOption {
column,
if_not_exists: _,
}) => {
write!(sql, "ADD COLUMN ").unwrap();
self.prepare_column_def(column_def, sql);
self.prepare_column_def(column, sql);
}
TableAlterOption::ModifyColumn(column_def) => {
write!(sql, "MODIFY COLUMN ").unwrap();
Expand Down
10 changes: 8 additions & 2 deletions src/backend/postgres/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,15 @@ impl TableBuilder for PostgresQueryBuilder {
write!(sql, ", ").unwrap();
};
match option {
TableAlterOption::AddColumn(column_def) => {
TableAlterOption::AddColumn(AddColumnOption {
column,
if_not_exists,
}) => {
write!(sql, "ADD COLUMN ").unwrap();
self.prepare_column_def(column_def, sql);
if *if_not_exists {
write!(sql, "IF NOT EXISTS ").unwrap();
}
self.prepare_column_def(column, sql);
}
TableAlterOption::ModifyColumn(column_def) => {
write!(sql, "ALTER COLUMN ").unwrap();
Expand Down
7 changes: 5 additions & 2 deletions src/backend/sqlite/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,12 @@ impl TableBuilder for SqliteQueryBuilder {
write!(sql, " ").unwrap();
}
match &alter.options[0] {
TableAlterOption::AddColumn(column_def) => {
TableAlterOption::AddColumn(AddColumnOption {
column,
if_not_exists: _,
}) => {
write!(sql, "ADD COLUMN ").unwrap();
self.prepare_column_def(column_def, sql);
self.prepare_column_def(column, sql);
}
TableAlterOption::ModifyColumn(_) => {
panic!("Sqlite not support modifying table column")
Expand Down
53 changes: 51 additions & 2 deletions src/table/alter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,17 @@ pub struct TableAlterStatement {
pub(crate) options: Vec<TableAlterOption>,
}

/// table alter add column options
#[derive(Debug, Clone)]
pub struct AddColumnOption {
pub(crate) column: ColumnDef,
pub(crate) if_not_exists: bool,
}

/// All available table alter options
#[derive(Debug, Clone)]
pub enum TableAlterOption {
AddColumn(ColumnDef),
AddColumn(AddColumnOption),
ModifyColumn(ColumnDef),
RenameColumn(DynIden, DynIden),
DropColumn(DynIden),
Expand Down Expand Up @@ -101,7 +108,49 @@ impl TableAlterStatement {
/// ```
pub fn add_column(&mut self, column_def: &mut ColumnDef) -> &mut Self {
self.options
.push(TableAlterOption::AddColumn(column_def.take()));
.push(TableAlterOption::AddColumn(AddColumnOption {
column: column_def.take(),
if_not_exists: false,
}));
self
}

/// Try add a column to an existing table if it does not exists
///
/// # Examples
///
/// ```
/// use sea_query::{tests_cfg::*, *};
///
/// let table = Table::alter()
/// .table(Font::Table)
/// .add_column_if_not_exists(
/// ColumnDef::new(Alias::new("new_col"))
/// .integer()
/// .not_null()
/// .default(100),
/// )
/// .to_owned();
///
/// assert_eq!(
/// table.to_string(MysqlQueryBuilder),
/// r#"ALTER TABLE `font` ADD COLUMN IF NOT EXISTS `new_col` int NOT NULL DEFAULT 100"#
/// );
/// assert_eq!(
/// table.to_string(PostgresQueryBuilder),
/// r#"ALTER TABLE "font" ADD COLUMN IF NOT EXISTS "new_col" integer NOT NULL DEFAULT 100"#
/// );
/// assert_eq!(
/// table.to_string(SqliteQueryBuilder),
/// r#"ALTER TABLE "font" ADD COLUMN "new_col" integer NOT NULL DEFAULT 100"#,
/// );
/// ```
pub fn add_column_if_not_exists(&mut self, column_def: &mut ColumnDef) -> &mut Self {
self.options
.push(TableAlterOption::AddColumn(AddColumnOption {
column: column_def.take(),
if_not_exists: true,
}));
self
}

Expand Down

0 comments on commit 822ebe1

Please sign in to comment.