Skip to content

Commit 214cd77

Browse files
authored
Merge pull request rails#45684 from adrianna-chang-shopify/ac-build-change-column-definition
Extract `#build_change_column_definition`
2 parents cefabdf + c59cbb5 commit 214cd77

File tree

6 files changed

+68
-41
lines changed

6 files changed

+68
-41
lines changed

activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ def aliased_types(name, fallback)
9292

9393
AddColumnDefinition = Struct.new(:column) # :nodoc:
9494

95-
ChangeColumnDefinition = Struct.new(:column, :name) # :nodoc:
95+
ChangeColumnDefinition = Struct.new(:column, :name, :ddl) # :nodoc:
9696

9797
CreateIndexDefinition = Struct.new(:index, :algorithm, :if_not_exists, :ddl) # :nodoc:
9898

activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb

Lines changed: 35 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,39 @@ def change_column(table_name, column_name, type, **options) # :nodoc:
371371
execute("ALTER TABLE #{quote_table_name(table_name)} #{change_column_for_alter(table_name, column_name, type, **options)}")
372372
end
373373

374+
# Builds a ChangeColumnDefinition object.
375+
#
376+
# This definition object contains information about the column change that would occur
377+
# if the same arguments were passed to #change_column. See #change_column for information about
378+
# passing a +table_name+, +column_name+, +type+ and other options that can be passed.
379+
def build_change_column_definition(table_name, column_name, type, **options) # :nodoc:
380+
column = column_for(table_name, column_name)
381+
type ||= column.sql_type
382+
383+
unless options.key?(:default)
384+
options[:default] = column.default
385+
end
386+
387+
unless options.key?(:null)
388+
options[:null] = column.null
389+
end
390+
391+
unless options.key?(:comment)
392+
options[:comment] = column.comment
393+
end
394+
395+
unless options.key?(:auto_increment)
396+
options[:auto_increment] = column.auto_increment?
397+
end
398+
399+
td = create_table_definition(table_name)
400+
cd = td.new_column_definition(column.name, type, **options)
401+
change_column_def = ChangeColumnDefinition.new(cd, column.name)
402+
schema_creation.accept(change_column_def)
403+
404+
change_column_def
405+
end
406+
374407
def rename_column(table_name, column_name, new_column_name) # :nodoc:
375408
execute("ALTER TABLE #{quote_table_name(table_name)} #{rename_column_for_alter(table_name, column_name, new_column_name)}")
376409
rename_column_indexes(table_name, column_name, new_column_name)
@@ -726,28 +759,8 @@ def translate_exception(exception, message:, sql:, binds:)
726759
end
727760

728761
def change_column_for_alter(table_name, column_name, type, **options)
729-
column = column_for(table_name, column_name)
730-
type ||= column.sql_type
731-
732-
unless options.key?(:default)
733-
options[:default] = column.default
734-
end
735-
736-
unless options.key?(:null)
737-
options[:null] = column.null
738-
end
739-
740-
unless options.key?(:comment)
741-
options[:comment] = column.comment
742-
end
743-
744-
unless options.key?(:auto_increment)
745-
options[:auto_increment] = column.auto_increment?
746-
end
747-
748-
td = create_table_definition(table_name)
749-
cd = td.new_column_definition(column.name, type, **options)
750-
schema_creation.accept(ChangeColumnDefinition.new(cd, column.name))
762+
cd = build_change_column_definition(table_name, column_name, type, **options)
763+
cd.ddl
751764
end
752765

753766
def rename_column_for_alter(table_name, column_name, new_column_name)

activerecord/lib/active_record/connection_adapters/mysql/schema_creation.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ def visit_AddColumnDefinition(o)
2121

2222
def visit_ChangeColumnDefinition(o)
2323
change_column_sql = +"CHANGE #{quote_column_name(o.name)} #{accept(o.column)}"
24-
add_column_position!(change_column_sql, column_options(o.column))
24+
o.ddl = add_column_position!(change_column_sql, column_options(o.column))
2525
end
2626

2727
def visit_CreateIndexDefinition(o)

activerecord/lib/active_record/connection_adapters/postgresql/schema_creation.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ def visit_ChangeColumnDefinition(o)
8484
change_column_sql << ", ALTER COLUMN #{quoted_column_name} #{options[:null] ? 'DROP' : 'SET'} NOT NULL"
8585
end
8686

87-
change_column_sql
87+
o.ddl = change_column_sql
8888
end
8989

9090
def add_column_options!(sql, options)

activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,20 @@ def change_column(table_name, column_name, type, **options) # :nodoc:
409409
procs.each(&:call)
410410
end
411411

412+
# Builds a ChangeColumnDefinition object.
413+
#
414+
# This definition object contains information about the column change that would occur
415+
# if the same arguments were passed to #change_column. See #change_column for information about
416+
# passing a +table_name+, +column_name+, +type+ and other options that can be passed.
417+
def build_change_column_definition(table_name, column_name, type, **options) # :nodoc:
418+
td = create_table_definition(table_name)
419+
cd = td.new_column_definition(column_name, type, **options)
420+
change_column_def = ChangeColumnDefinition.new(cd, column_name)
421+
schema_creation.accept(change_column_def)
422+
423+
change_column_def
424+
end
425+
412426
# Changes the default value of a table column.
413427
def change_column_default(table_name, column_name, default_or_changes) # :nodoc:
414428
execute "ALTER TABLE #{quote_table_name(table_name)} #{change_column_default_for_alter(table_name, column_name, default_or_changes)}"
@@ -835,9 +849,8 @@ def add_column_for_alter(table_name, column_name, type, **options)
835849
end
836850

837851
def change_column_for_alter(table_name, column_name, type, **options)
838-
td = create_table_definition(table_name)
839-
cd = td.new_column_definition(column_name, type, **options)
840-
sqls = [schema_creation.accept(ChangeColumnDefinition.new(cd, column_name))]
852+
change_col_def = build_change_column_definition(table_name, column_name, type, **options)
853+
sqls = [change_col_def.ddl]
841854
sqls << Proc.new { change_column_comment(table_name, column_name, options[:comment]) } if options.key?(:comment)
842855
sqls
843856
end

activerecord/test/cases/migration/schema_definitions_test.rb

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -62,21 +62,22 @@ def test_build_create_index_definition_for_existing_index
6262
end
6363
end
6464

65-
def test_build_add_column_definition
66-
connection.create_table(:test)
67-
add_col_td = connection.build_add_column_definition(:test, :foo, :string)
68-
69-
assert_match "ALTER TABLE", add_col_td.ddl
65+
unless current_adapter?(:SQLite3Adapter)
66+
def test_build_change_column_definition
67+
connection.create_table(:test) do |t|
68+
t.column :foo, :string
69+
end
7070

71-
add_cols = add_col_td.adds
72-
assert_equal 1, add_cols.size
71+
change_cd = connection.build_change_column_definition(:test, :foo, :integer)
72+
assert change_cd.ddl
7373

74-
add_col = add_cols.first.column
75-
assert_equal "foo", add_col.name
76-
assert add_col.type
77-
assert add_col.sql_type
78-
ensure
79-
connection.drop_table(:test) if connection.table_exists?(:test)
74+
change_col = change_cd.column
75+
assert_equal "foo", change_col.name.to_s
76+
assert change_col.type
77+
assert change_col.sql_type
78+
ensure
79+
connection.drop_table(:test) if connection.table_exists?(:test)
80+
end
8081
end
8182
end
8283
end

0 commit comments

Comments
 (0)