diff options
author | Ben Marini <bmarini@gmail.com> | 2009-09-27 16:25:18 -0700 |
---|---|---|
committer | Jeremy Kemper <jeremy@bitsweat.net> | 2009-12-03 23:09:57 -0800 |
commit | e55284e8256461fc2440c41548ee9b4216f96b47 (patch) | |
tree | 1f70159ca25b71e1893adbfe55fdb8a327ca2842 | |
parent | 96e0638ce2a287eb5c43266fb4eb3e656e9968cf (diff) | |
download | rails-e55284e8256461fc2440c41548ee9b4216f96b47.tar.gz rails-e55284e8256461fc2440c41548ee9b4216f96b47.tar.bz2 rails-e55284e8256461fc2440c41548ee9b4216f96b47.zip |
Add support for Mysql column positioning via #add_column and #change_column
add_column and change_column in the Mysql adapter now accept some
additional options:
:first => true # Put the column in front of all the columns
:after => column_name # Put the colmn after 'column_name'
add_column :new_col, :string, :first => true
add_column :another_col, :integer, :default => 0, :after => :new_col
[#3286 state:committed]
Signed-off-by: Jeremy Kemper <jeremy@bitsweat.net>
-rw-r--r-- | activerecord/CHANGELOG | 2 | ||||
-rw-r--r-- | activerecord/lib/active_record/connection_adapters/mysql_adapter.rb | 15 | ||||
-rw-r--r-- | activerecord/test/cases/migration_test.rb | 47 |
3 files changed, 64 insertions, 0 deletions
diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG index d67b61dc07..d2aa44a23a 100644 --- a/activerecord/CHANGELOG +++ b/activerecord/CHANGELOG @@ -1,5 +1,7 @@ *Edge* +* MySQL: add_ and change_column support positioning. #3286 [Ben Marini] + * Reset your Active Record counter caches with the reset_counter_cache class method. #1211 [Mike Breen] * Remove support for SQLite 2. Please upgrade to SQLite 3+ or install the plugin from git://github.com/rails/sqlite2_adapter.git [Pratik Naik] diff --git a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb index ad36ff22e3..fa28bc64df 100644 --- a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb @@ -470,6 +470,13 @@ module ActiveRecord execute "RENAME TABLE #{quote_table_name(table_name)} TO #{quote_table_name(new_name)}" end + 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) + add_column_position!(add_column_sql, options) + execute(add_column_sql) + end + def change_column_default(table_name, column_name, default) #:nodoc: column = column_for(table_name, column_name) change_column table_name, column_name, column.sql_type, :default => default @@ -498,6 +505,7 @@ module ActiveRecord change_column_sql = "ALTER TABLE #{quote_table_name(table_name)} CHANGE #{quote_column_name(column_name)} #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}" add_column_options!(change_column_sql, options) + add_column_position!(change_column_sql, options) execute(change_column_sql) end @@ -529,6 +537,13 @@ module ActiveRecord end end + def add_column_position!(sql, options) + if options[:first] + sql << " FIRST" + elsif options[:after] + sql << " AFTER #{quote_column_name(options[:after])}" + end + end # SHOW VARIABLES LIKE 'name' def show_variable(name) diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb index 6d3f938799..0ef34e440a 100644 --- a/activerecord/test/cases/migration_test.rb +++ b/activerecord/test/cases/migration_test.rb @@ -527,6 +527,53 @@ if ActiveRecord::Base.connection.supports_migrations? assert !Person.column_methods_hash.include?(:last_name) end + if current_adapter?(:MysqlAdapter) + def testing_table_for_positioning + Person.connection.create_table :testings, :id => false do |t| + t.column :first, :integer + t.column :second, :integer + t.column :third, :integer + end + + yield Person.connection + ensure + Person.connection.drop_table :testings rescue nil + end + protected :testing_table_for_positioning + + def test_column_positioning + testing_table_for_positioning do |conn| + assert_equal %w(first second third), conn.columns(:testings).map {|c| c.name } + end + end + + def test_add_column_with_positioning + testing_table_for_positioning do |conn| + conn.add_column :testings, :new_col, :integer + assert_equal %w(first second third new_col), conn.columns(:testings).map {|c| c.name } + end + testing_table_for_positioning do |conn| + conn.add_column :testings, :new_col, :integer, :first => true + assert_equal %w(new_col first second third), conn.columns(:testings).map {|c| c.name } + end + testing_table_for_positioning do |conn| + conn.add_column :testings, :new_col, :integer, :after => :first + assert_equal %w(first new_col second third), conn.columns(:testings).map {|c| c.name } + end + end + + def test_change_column_with_positioning + testing_table_for_positioning do |conn| + conn.change_column :testings, :second, :integer, :first => true + assert_equal %w(second first third), conn.columns(:testings).map {|c| c.name } + end + testing_table_for_positioning do |conn| + conn.change_column :testings, :second, :integer, :after => :third + assert_equal %w(first third second), conn.columns(:testings).map {|c| c.name } + end + end + end + def test_add_rename Person.delete_all |