diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb index 922a544e817a6cac36108e7f1a432f284878ae3e..7f0be28080590a4c4d727dd4277fc97b310cc3ec 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb @@ -262,12 +262,7 @@ def references(*args) end alias :belongs_to :references - private - def create_column_definition(name, type) - ColumnDefinition.new name, type - end - - def new_column_definition(name, type, options) + def new_column_definition(name, type, options) # :nodoc: column = create_column_definition name, type limit = options.fetch(:limit) do native[type][:limit] if native[type].is_a?(Hash) @@ -281,6 +276,11 @@ def new_column_definition(name, type, options) column end + private + def create_column_definition(name, type) + ColumnDefinition.new name, type + end + def primary_key_column_name primary_key_column = columns.detect { |c| c.primary_key? } primary_key_column && primary_key_column.name @@ -291,6 +291,23 @@ def native end end + class AlterTable # :nodoc: + attr_reader :add + + def initialize(td) + @td = td + @add = nil + end + + def name; @td.name; end + + def add_column(name, type, options) + name = name.to_s + type = type.to_sym + @add = @td.new_column_definition(name, type, options) + end + end + # Represents an SQL table in an abstract way for updating a table. # Also see TableDefinition and SchemaStatements#create_table # diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb index 08e8d3ca20e12c1992bb4665432d3b195396473e..6631a278ab2170fb7aa5befd256c842bed02a45b 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb @@ -355,9 +355,9 @@ def drop_table(table_name, options = {}) # Adds a new column to the named table. # See TableDefinition#column for details of the options you can use. def add_column(table_name, column_name, type, options = {}) - add_column_sql = "ALTER TABLE #{quote_table_name(table_name)} ADD #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}" - add_column_options!(add_column_sql, options) - execute(add_column_sql) + at = create_alter_table table_name + at.add_column(column_name, type, options) + execute schema_creation.accept at end # Removes the given columns from the table definition. @@ -829,6 +829,10 @@ def create_table_definition(name, temporary, options) TableDefinition.new native_database_types, name, temporary, options end + def create_alter_table(name) + AlterTable.new create_table_definition(name, false, {}) + end + def update_table_definition(table_name, base) Table.new(table_name, base) end diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb index b3c55dfbbb61a3ecb2521efbcdde263ea011ff4d..5d38b45a5b49a6bb5b40756951fad00ee9f326ca 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb @@ -113,14 +113,22 @@ def accept(o) private + def visit_AlterTable(o) + sql = "ALTER TABLE #{quote_table_name(o.name)} " + + if col = o.add + sql_type = type_to_sql(col.type.to_sym, col.limit, col.precision, col.scale) + sql << "ADD #{quote_column_name(col.name)} #{sql_type}" + add_column_options!(sql, column_options(col)) + end + + sql + end + def visit_ColumnDefinition(o) sql_type = type_to_sql(o.type.to_sym, o.limit, o.precision, o.scale) column_sql = "#{quote_column_name(o.name)} #{sql_type}" - column_options = {} - column_options[:null] = o.null unless o.null.nil? - column_options[:default] = o.default unless o.default.nil? - column_options[:column] = o - add_column_options!(column_sql, column_options) unless o.primary_key? + add_column_options!(column_sql, column_options(o)) unless o.primary_key? column_sql end @@ -132,6 +140,14 @@ def visit_TableDefinition(o) create_sql end + def column_options(o) + column_options = {} + column_options[:null] = o.null unless o.null.nil? + column_options[:default] = o.default unless o.default.nil? + column_options[:column] = o + column_options + end + def quote_column_name(name) @conn.quote_column_name name end