Skip to content

Commit

Permalink
Add change nullability statement (#1041)
Browse files Browse the repository at this point in the history
* Implement allow_nulls_for and forbid_nulls_for

* Remove leftover macro, fix ordering of change default with respect to change type
  • Loading branch information
davidepaolotua authored May 16, 2024
1 parent 52e7521 commit 1326a8e
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 1 deletion.
21 changes: 21 additions & 0 deletions spec/avram/migrator/alter_table_statement_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,27 @@ describe Avram::Migrator::AlterTableStatement do
built.statements[2].should eq "ALTER TABLE ONLY test_defaults ALTER COLUMN money SET DEFAULT '29.99';"
end

it "changes defaults after changing the type" do
built = Avram::Migrator::AlterTableStatement.new(:users).build do
change_type id : Int64
change_default id : Int64, default: 54
end
built.statements.size.should eq 2
built.statements[0].should eq "ALTER TABLE users ALTER COLUMN id SET DATA TYPE bigint;"
built.statements[1].should eq "ALTER TABLE ONLY users ALTER COLUMN id SET DEFAULT '54';"
end

it "can change column nullability" do
built = Avram::Migrator::AlterTableStatement.new(:users).build do
forbid_nulls_for :id
allow_nulls_for :age
end

built.statements.size.should eq 2
built.statements[0].should eq "ALTER TABLE users ALTER COLUMN id SET NOT NULL;"
built.statements[1].should eq "ALTER TABLE users ALTER COLUMN age DROP NOT NULL;"
end

describe "fill_existing_with" do
it "fills existing with value and sets column to be non-null for non-null types" do
built = Avram::Migrator::AlterTableStatement.new(:users).build do
Expand Down
27 changes: 26 additions & 1 deletion src/avram/migrator/alter_table_statement.cr
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class Avram::Migrator::AlterTableStatement
getter fill_existing_with_statements = [] of String
getter change_type_statements = [] of String
getter change_default_statements = [] of String
getter change_nullability_statements = [] of String
private getter? if_exists : Bool = false

def initialize(@table_name : TableName, *, @if_exists : Bool = false)
Expand Down Expand Up @@ -80,6 +81,30 @@ class Avram::Migrator::AlterTableStatement
add_change_default_statement %column
end

# Change the column's nullability from whatever it is currently to true.
# ```
# alter table_for(User) do
# allow_nulls_for :email
# end
# ```
macro allow_nulls_for(column_name)
change_nullability_statements << build_nullability_statement({{column_name.id.stringify}}, true)
end

# Change the column's nullability from whatever it is currently to false.
# ```
# alter table_for(User) do
# forbid_nulls_for :email
# end
# ```
macro forbid_nulls_for(column_name)
change_nullability_statements << build_nullability_statement({{column_name.id.stringify}}, false)
end

def build_nullability_statement(column_name, nullability)
"ALTER TABLE #{@table_name} ALTER COLUMN #{column_name} #{nullability ? "DROP" : "SET"} NOT NULL;"
end

def add_change_type_statement(column : ::Avram::Migrator::Columns::Base)
change_type_statements << column.build_change_type_statement(@table_name)
end
Expand Down Expand Up @@ -114,7 +139,7 @@ class Avram::Migrator::AlterTableStatement
end

def statements
alter_statements + change_default_statements + change_type_statements + index_statements + fill_existing_with_statements
alter_statements + change_type_statements + change_default_statements + change_nullability_statements + index_statements + fill_existing_with_statements
end

def if_exists_statement
Expand Down

0 comments on commit 1326a8e

Please sign in to comment.