Merge pull request #45684 from adrianna-chang-shopify/ac-build-change-column-definition

Extract `#build_change_column_definition`
This commit is contained in:
Eileen M. Uchitelle 2022-07-29 13:38:06 -04:00 committed by GitHub
commit 214cd77d7f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 68 additions and 41 deletions

@ -92,7 +92,7 @@ def aliased_types(name, fallback)
AddColumnDefinition = Struct.new(:column) # :nodoc: AddColumnDefinition = Struct.new(:column) # :nodoc:
ChangeColumnDefinition = Struct.new(:column, :name) # :nodoc: ChangeColumnDefinition = Struct.new(:column, :name, :ddl) # :nodoc:
CreateIndexDefinition = Struct.new(:index, :algorithm, :if_not_exists, :ddl) # :nodoc: CreateIndexDefinition = Struct.new(:index, :algorithm, :if_not_exists, :ddl) # :nodoc:

@ -371,6 +371,39 @@ def change_column(table_name, column_name, type, **options) # :nodoc:
execute("ALTER TABLE #{quote_table_name(table_name)} #{change_column_for_alter(table_name, column_name, type, **options)}") execute("ALTER TABLE #{quote_table_name(table_name)} #{change_column_for_alter(table_name, column_name, type, **options)}")
end end
# Builds a ChangeColumnDefinition object.
#
# This definition object contains information about the column change that would occur
# if the same arguments were passed to #change_column. See #change_column for information about
# passing a +table_name+, +column_name+, +type+ and other options that can be passed.
def build_change_column_definition(table_name, column_name, type, **options) # :nodoc:
column = column_for(table_name, column_name)
type ||= column.sql_type
unless options.key?(:default)
options[:default] = column.default
end
unless options.key?(:null)
options[:null] = column.null
end
unless options.key?(:comment)
options[:comment] = column.comment
end
unless options.key?(:auto_increment)
options[:auto_increment] = column.auto_increment?
end
td = create_table_definition(table_name)
cd = td.new_column_definition(column.name, type, **options)
change_column_def = ChangeColumnDefinition.new(cd, column.name)
schema_creation.accept(change_column_def)
change_column_def
end
def rename_column(table_name, column_name, new_column_name) # :nodoc: def rename_column(table_name, column_name, new_column_name) # :nodoc:
execute("ALTER TABLE #{quote_table_name(table_name)} #{rename_column_for_alter(table_name, column_name, new_column_name)}") execute("ALTER TABLE #{quote_table_name(table_name)} #{rename_column_for_alter(table_name, column_name, new_column_name)}")
rename_column_indexes(table_name, column_name, new_column_name) rename_column_indexes(table_name, column_name, new_column_name)
@ -726,28 +759,8 @@ def translate_exception(exception, message:, sql:, binds:)
end end
def change_column_for_alter(table_name, column_name, type, **options) def change_column_for_alter(table_name, column_name, type, **options)
column = column_for(table_name, column_name) cd = build_change_column_definition(table_name, column_name, type, **options)
type ||= column.sql_type cd.ddl
unless options.key?(:default)
options[:default] = column.default
end
unless options.key?(:null)
options[:null] = column.null
end
unless options.key?(:comment)
options[:comment] = column.comment
end
unless options.key?(:auto_increment)
options[:auto_increment] = column.auto_increment?
end
td = create_table_definition(table_name)
cd = td.new_column_definition(column.name, type, **options)
schema_creation.accept(ChangeColumnDefinition.new(cd, column.name))
end end
def rename_column_for_alter(table_name, column_name, new_column_name) def rename_column_for_alter(table_name, column_name, new_column_name)

@ -21,7 +21,7 @@ def visit_AddColumnDefinition(o)
def visit_ChangeColumnDefinition(o) def visit_ChangeColumnDefinition(o)
change_column_sql = +"CHANGE #{quote_column_name(o.name)} #{accept(o.column)}" change_column_sql = +"CHANGE #{quote_column_name(o.name)} #{accept(o.column)}"
add_column_position!(change_column_sql, column_options(o.column)) o.ddl = add_column_position!(change_column_sql, column_options(o.column))
end end
def visit_CreateIndexDefinition(o) def visit_CreateIndexDefinition(o)

@ -84,7 +84,7 @@ def visit_ChangeColumnDefinition(o)
change_column_sql << ", ALTER COLUMN #{quoted_column_name} #{options[:null] ? 'DROP' : 'SET'} NOT NULL" change_column_sql << ", ALTER COLUMN #{quoted_column_name} #{options[:null] ? 'DROP' : 'SET'} NOT NULL"
end end
change_column_sql o.ddl = change_column_sql
end end
def add_column_options!(sql, options) def add_column_options!(sql, options)

@ -409,6 +409,20 @@ def change_column(table_name, column_name, type, **options) # :nodoc:
procs.each(&:call) procs.each(&:call)
end end
# Builds a ChangeColumnDefinition object.
#
# This definition object contains information about the column change that would occur
# if the same arguments were passed to #change_column. See #change_column for information about
# passing a +table_name+, +column_name+, +type+ and other options that can be passed.
def build_change_column_definition(table_name, column_name, type, **options) # :nodoc:
td = create_table_definition(table_name)
cd = td.new_column_definition(column_name, type, **options)
change_column_def = ChangeColumnDefinition.new(cd, column_name)
schema_creation.accept(change_column_def)
change_column_def
end
# Changes the default value of a table column. # Changes the default value of a table column.
def change_column_default(table_name, column_name, default_or_changes) # :nodoc: def change_column_default(table_name, column_name, default_or_changes) # :nodoc:
execute "ALTER TABLE #{quote_table_name(table_name)} #{change_column_default_for_alter(table_name, column_name, default_or_changes)}" 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)
end end
def change_column_for_alter(table_name, column_name, type, **options) def change_column_for_alter(table_name, column_name, type, **options)
td = create_table_definition(table_name) change_col_def = build_change_column_definition(table_name, column_name, type, **options)
cd = td.new_column_definition(column_name, type, **options) sqls = [change_col_def.ddl]
sqls = [schema_creation.accept(ChangeColumnDefinition.new(cd, column_name))]
sqls << Proc.new { change_column_comment(table_name, column_name, options[:comment]) } if options.key?(:comment) sqls << Proc.new { change_column_comment(table_name, column_name, options[:comment]) } if options.key?(:comment)
sqls sqls
end end

@ -62,21 +62,22 @@ def test_build_create_index_definition_for_existing_index
end end
end end
def test_build_add_column_definition unless current_adapter?(:SQLite3Adapter)
connection.create_table(:test) def test_build_change_column_definition
add_col_td = connection.build_add_column_definition(:test, :foo, :string) connection.create_table(:test) do |t|
t.column :foo, :string
end
assert_match "ALTER TABLE", add_col_td.ddl change_cd = connection.build_change_column_definition(:test, :foo, :integer)
assert change_cd.ddl
add_cols = add_col_td.adds change_col = change_cd.column
assert_equal 1, add_cols.size assert_equal "foo", change_col.name.to_s
assert change_col.type
add_col = add_cols.first.column assert change_col.sql_type
assert_equal "foo", add_col.name ensure
assert add_col.type connection.drop_table(:test) if connection.table_exists?(:test)
assert add_col.sql_type end
ensure
connection.drop_table(:test) if connection.table_exists?(:test)
end end
end end
end end