Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extract #build_change_column_definition #45684

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -92,7 +92,7 @@ def aliased_types(name, fallback)

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:

Expand Down
Expand Up @@ -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)}")
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:
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)
Expand Down Expand Up @@ -726,28 +759,8 @@ def translate_exception(exception, message:, sql:, binds:)
end

def change_column_for_alter(table_name, column_name, type, **options)
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)
schema_creation.accept(ChangeColumnDefinition.new(cd, column.name))
cd = build_change_column_definition(table_name, column_name, type, **options)
cd.ddl
end

def rename_column_for_alter(table_name, column_name, new_column_name)
Expand Down
Expand Up @@ -21,7 +21,7 @@ def visit_AddColumnDefinition(o)

def visit_ChangeColumnDefinition(o)
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

def visit_CreateIndexDefinition(o)
Expand Down
Expand Up @@ -84,7 +84,7 @@ def visit_ChangeColumnDefinition(o)
change_column_sql << ", ALTER COLUMN #{quoted_column_name} #{options[:null] ? 'DROP' : 'SET'} NOT NULL"
end

change_column_sql
o.ddl = change_column_sql
end

def add_column_options!(sql, options)
Expand Down
Expand Up @@ -409,6 +409,20 @@ def change_column(table_name, column_name, type, **options) # :nodoc:
procs.each(&:call)
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.
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)}"
Expand Down Expand Up @@ -835,9 +849,8 @@ def add_column_for_alter(table_name, column_name, type, **options)
end

def change_column_for_alter(table_name, column_name, type, **options)
td = create_table_definition(table_name)
cd = td.new_column_definition(column_name, type, **options)
sqls = [schema_creation.accept(ChangeColumnDefinition.new(cd, column_name))]
change_col_def = build_change_column_definition(table_name, column_name, type, **options)
sqls = [change_col_def.ddl]
sqls << Proc.new { change_column_comment(table_name, column_name, options[:comment]) } if options.key?(:comment)
sqls
end
Expand Down
27 changes: 14 additions & 13 deletions activerecord/test/cases/migration/schema_definitions_test.rb
Expand Up @@ -62,21 +62,22 @@ def test_build_create_index_definition_for_existing_index
end
end

def test_build_add_column_definition
connection.create_table(:test)
add_col_td = connection.build_add_column_definition(:test, :foo, :string)

assert_match "ALTER TABLE", add_col_td.ddl
unless current_adapter?(:SQLite3Adapter)
def test_build_change_column_definition
connection.create_table(:test) do |t|
t.column :foo, :string
end

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

add_col = add_cols.first.column
assert_equal "foo", add_col.name
assert add_col.type
assert add_col.sql_type
ensure
connection.drop_table(:test) if connection.table_exists?(:test)
change_col = change_cd.column
assert_equal "foo", change_col.name.to_s
assert change_col.type
assert change_col.sql_type
ensure
connection.drop_table(:test) if connection.table_exists?(:test)
end
end
end
end
Expand Down