aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorYves Senn <yves.senn@gmail.com>2013-02-23 14:00:02 +0100
committerYves Senn <yves.senn@gmail.com>2013-02-23 15:23:28 +0100
commit8f6fa345e5c865acefa063c3e2cd62553fa9f2eb (patch)
tree6eeef63a41866e2571ccf4f5157d2abadd5e4e50 /activerecord
parent0c1558d32fe7f3198ef598ce552ea89a04ab7793 (diff)
downloadrails-8f6fa345e5c865acefa063c3e2cd62553fa9f2eb.tar.gz
rails-8f6fa345e5c865acefa063c3e2cd62553fa9f2eb.tar.bz2
rails-8f6fa345e5c865acefa063c3e2cd62553fa9f2eb.zip
Sqlite preserves primary keys when copying/altering tables.
Backport #2312. Fixes #9367. I also added a test-case to make sure that renaming or removing a column preserves the primary key.
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/CHANGELOG.md6
-rw-r--r--activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb8
-rw-r--r--activerecord/test/cases/adapters/sqlite3/copy_table_test.rb8
-rw-r--r--activerecord/test/cases/migration_test.rb14
4 files changed, 34 insertions, 2 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index cd105b8355..db4820b3d2 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -1,5 +1,11 @@
## unreleased ##
+* Sqlite now preserves custom primary keys when copying or altering tables.
+ Fixes #9367.
+ Backport #2312.
+
+ *Sean Scally + Yves Senn*
+
* Preloading `has_many :through` associations with conditions won't
cache the `:through` association. This will prevent invalid
subsets to be cached.
diff --git a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
index ca84c95bdc..455560aa55 100644
--- a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
@@ -490,7 +490,11 @@ module ActiveRecord
end
def copy_table(from, to, options = {}) #:nodoc:
- options = options.merge(:id => (!columns(from).detect{|c| c.name == 'id'}.nil? && 'id' == primary_key(from).to_s))
+ from_primary_key = primary_key(from)
+ options[:primary_key] = from_primary_key if from_primary_key != 'id'
+ unless options[:primary_key]
+ options[:id] = !columns(from).detect{|c| c.name == 'id'}.nil? && 'id' == from_primary_key
+ end
create_table(to, options) do |definition|
@definition = definition
columns(from).each do |column|
@@ -504,7 +508,7 @@ module ActiveRecord
:precision => column.precision, :scale => column.scale,
:null => column.null)
end
- @definition.primary_key(primary_key(from)) if primary_key(from)
+ @definition.primary_key(from_primary_key) if from_primary_key
yield @definition if block_given?
end
diff --git a/activerecord/test/cases/adapters/sqlite3/copy_table_test.rb b/activerecord/test/cases/adapters/sqlite3/copy_table_test.rb
index 575b4806c1..74288a98d1 100644
--- a/activerecord/test/cases/adapters/sqlite3/copy_table_test.rb
+++ b/activerecord/test/cases/adapters/sqlite3/copy_table_test.rb
@@ -57,6 +57,14 @@ class CopyTableTest < ActiveRecord::TestCase
end
end
+ def test_copy_table_with_unconventional_primary_key
+ test_copy_table('owners', 'owners_unconventional') do |from, to, options|
+ original_pk = @connection.primary_key('owners')
+ copied_pk = @connection.primary_key('owners_unconventional')
+ assert_equal original_pk, copied_pk
+ end
+ end
+
protected
def copy_table(from, to, options = {})
@connection.copy_table(from, to, {:temporary => true}.merge(options))
diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb
index 7bb71b7b6e..5b67d22c31 100644
--- a/activerecord/test/cases/migration_test.rb
+++ b/activerecord/test/cases/migration_test.rb
@@ -889,6 +889,20 @@ if ActiveRecord::Base.connection.supports_migrations?
ActiveRecord::Base.connection.drop_table(:hats) rescue nil
end
+ def test_removing_and_renaming_column_preserves_custom_primary_key
+ ActiveRecord::Base.connection.create_table "my_table", :primary_key => "my_table_id", :force => true do |t|
+ t.integer "col_one"
+ t.string "col_two", :limit => 128, :null => false
+ end
+
+ ActiveRecord::Base.connection.remove_column("my_table", "col_two")
+ ActiveRecord::Base.connection.rename_column("my_table", "col_one", "col_three")
+
+ assert_equal 'my_table_id', ActiveRecord::Base.connection.primary_key('my_table')
+ ensure
+ ActiveRecord::Base.connection.drop_table(:my_table) rescue nil
+ end
+
def test_change_type_of_not_null_column
assert_nothing_raised do
Topic.connection.change_column "topics", "written_on", :datetime, :null => false