1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Change MySQL and Postgresql to use Bigint primary keys

This commit is contained in:
Jon McCartie 2016-08-21 09:50:24 -07:00
parent 575212a1ba
commit b92ae61069
16 changed files with 74 additions and 75 deletions

1
.gitignore vendored
View file

@ -19,3 +19,4 @@ pkg
/railties/doc /railties/doc
/railties/tmp /railties/tmp
/guides/output /guides/output
/*/.byebug_history

View file

@ -71,7 +71,7 @@ module ActiveRecord
polymorphic: false, polymorphic: false,
index: true, index: true,
foreign_key: false, foreign_key: false,
type: :integer, type: :bigint,
**options **options
) )
@name = name @name = name

View file

@ -56,7 +56,7 @@ module ActiveRecord
private private
def default_primary_key?(column) def default_primary_key?(column)
schema_type(column) == :integer schema_type(column) == :bigint
end end
def schema_type(column) def schema_type(column)

View file

@ -39,7 +39,7 @@ module ActiveRecord
self.emulate_booleans = true self.emulate_booleans = true
NATIVE_DATABASE_TYPES = { NATIVE_DATABASE_TYPES = {
primary_key: "int auto_increment PRIMARY KEY", primary_key: "BIGINT(8) UNSIGNED DEFAULT NULL auto_increment PRIMARY KEY",
string: { name: "varchar", limit: 255 }, string: { name: "varchar", limit: 255 },
text: { name: "text", limit: 65535 }, text: { name: "text", limit: 65535 },
integer: { name: "int", limit: 4 }, integer: { name: "int", limit: 4 },

View file

@ -3,7 +3,10 @@ module ActiveRecord
module MySQL module MySQL
module ColumnMethods module ColumnMethods
def primary_key(name, type = :primary_key, **options) def primary_key(name, type = :primary_key, **options)
options[:auto_increment] = true if type == :bigint && !options.key?(:default) if type == :primary_key && !options.key?(:default)
options[:auto_increment] = true
options[:limit] = 8
end
super super
end end

View file

@ -3,11 +3,9 @@ module ActiveRecord
module MySQL module MySQL
module ColumnDumper module ColumnDumper
def column_spec_for_primary_key(column) def column_spec_for_primary_key(column)
if column.bigint?
spec = { id: :bigint.inspect }
spec[:default] = schema_default(column) || "nil" unless column.auto_increment?
else
spec = super spec = super
if column.type == :integer && !column.auto_increment?
spec[:default] = schema_default(column) || "nil"
end end
spec[:unsigned] = "true" if column.unsigned? spec[:unsigned] = "true" if column.unsigned?
spec spec

View file

@ -25,7 +25,7 @@ module ActiveRecord
private private
def default_primary_key?(column) def default_primary_key?(column)
schema_type(column) == :serial schema_type(column) == :bigserial
end end
def schema_type(column) def schema_type(column)

View file

@ -70,7 +70,7 @@ module ActiveRecord
ADAPTER_NAME = "PostgreSQL".freeze ADAPTER_NAME = "PostgreSQL".freeze
NATIVE_DATABASE_TYPES = { NATIVE_DATABASE_TYPES = {
primary_key: "serial primary key", primary_key: "bigserial primary key",
string: { name: "character varying" }, string: { name: "character varying" },
text: { name: "text" }, text: { name: "text" },
integer: { name: "integer" }, integer: { name: "integer" },

View file

@ -0,0 +1,13 @@
module ActiveRecord
module ConnectionAdapters
module SQLite3
module ColumnDumper
private
def default_primary_key?(column)
schema_type(column) == :integer
end
end
end
end
end

View file

@ -4,6 +4,7 @@ require "active_record/connection_adapters/sqlite3/explain_pretty_printer"
require "active_record/connection_adapters/sqlite3/quoting" require "active_record/connection_adapters/sqlite3/quoting"
require "active_record/connection_adapters/sqlite3/schema_creation" require "active_record/connection_adapters/sqlite3/schema_creation"
require "active_record/connection_adapters/sqlite3/schema_definitions" require "active_record/connection_adapters/sqlite3/schema_definitions"
require "active_record/connection_adapters/sqlite3/schema_dumper"
gem "sqlite3", "~> 1.3.6" gem "sqlite3", "~> 1.3.6"
require "sqlite3" require "sqlite3"
@ -53,6 +54,7 @@ module ActiveRecord
ADAPTER_NAME = "SQLite".freeze ADAPTER_NAME = "SQLite".freeze
include SQLite3::Quoting include SQLite3::Quoting
include SQLite3::ColumnDumper
NATIVE_DATABASE_TYPES = { NATIVE_DATABASE_TYPES = {
primary_key: "INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL", primary_key: "INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL",

View file

@ -101,7 +101,12 @@ module ActiveRecord
def test_primary_key_creates_primary_key_column def test_primary_key_creates_primary_key_column
with_change_table do |t| with_change_table do |t|
if current_adapter?(:Mysql2Adapter)
@connection.expect :add_column, nil, [:delete_me, :id, :primary_key, { first: true, auto_increment: true, limit: 8, primary_key: true }]
else
@connection.expect :add_column, nil, [:delete_me, :id, :primary_key, primary_key: true, first: true] @connection.expect :add_column, nil, [:delete_me, :id, :primary_key, primary_key: true, first: true]
end
t.primary_key :id, first: true t.primary_key :id, first: true
end end
end end

View file

@ -76,7 +76,7 @@ if ActiveRecord::Base.connection.supports_foreign_keys?
end end
def test_add_foreign_key_with_non_standard_primary_key def test_add_foreign_key_with_non_standard_primary_key
with_example_table @connection, "space_shuttles", "pk integer PRIMARY KEY" do with_example_table @connection, "space_shuttles", "pk BIGINT PRIMARY KEY" do
@connection.add_foreign_key(:astronauts, :space_shuttles, @connection.add_foreign_key(:astronauts, :space_shuttles,
column: "rocket_id", primary_key: "pk", name: "custom_pk") column: "rocket_id", primary_key: "pk", name: "custom_pk")
@ -229,7 +229,7 @@ if ActiveRecord::Base.connection.supports_foreign_keys?
create_table("cities") { |t| } create_table("cities") { |t| }
create_table("houses") do |t| create_table("houses") do |t|
t.column :city_id, :integer t.column :city_id, :bigint
end end
add_foreign_key :houses, :cities, column: "city_id" add_foreign_key :houses, :cities, column: "city_id"
@ -261,7 +261,7 @@ if ActiveRecord::Base.connection.supports_foreign_keys?
create_table(:schools) create_table(:schools)
create_table(:classes) do |t| create_table(:classes) do |t|
t.column :school_id, :integer t.column :school_id, :bigint
end end
add_foreign_key :classes, :schools add_foreign_key :classes, :schools
end end

View file

@ -42,7 +42,7 @@ if ActiveRecord::Base.connection.supports_foreign_keys?
test "options hash can be passed" do test "options hash can be passed" do
@connection.change_table :testing_parents do |t| @connection.change_table :testing_parents do |t|
t.integer :other_id t.bigint :other_id
t.index :other_id, unique: true t.index :other_id, unique: true
end end
@connection.create_table :testings do |t| @connection.create_table :testings do |t|
@ -92,7 +92,7 @@ if ActiveRecord::Base.connection.supports_foreign_keys?
test "foreign keys accept options when changing the table" do test "foreign keys accept options when changing the table" do
@connection.change_table :testing_parents do |t| @connection.change_table :testing_parents do |t|
t.integer :other_id t.bigint :other_id
t.index :other_id, unique: true t.index :other_id, unique: true
end end
@connection.create_table :testings @connection.create_table :testings
@ -177,8 +177,8 @@ if ActiveRecord::Base.connection.supports_foreign_keys?
test "multiple foreign keys can be added to the same table" do test "multiple foreign keys can be added to the same table" do
@connection.create_table :testings do |t| @connection.create_table :testings do |t|
t.integer :col_1 t.bigint :col_1
t.integer :col_2 t.bigint :col_2
t.foreign_key :testing_parents, column: :col_1 t.foreign_key :testing_parents, column: :col_1
t.foreign_key :testing_parents, column: :col_2 t.foreign_key :testing_parents, column: :col_2

View file

@ -316,35 +316,34 @@ class CompositePrimaryKeyTest < ActiveRecord::TestCase
end end
if current_adapter?(:Mysql2Adapter) if current_adapter?(:Mysql2Adapter)
class PrimaryKeyBigintNilDefaultTest < ActiveRecord::TestCase class PrimaryKeyIntegerNilDefaultTest < ActiveRecord::TestCase
include SchemaDumpingHelper include SchemaDumpingHelper
self.use_transactional_tests = false self.use_transactional_tests = false
def setup def setup
@connection = ActiveRecord::Base.connection @connection = ActiveRecord::Base.connection
@connection.create_table(:bigint_defaults, id: :bigint, default: nil, force: true) @connection.create_table(:int_defaults, id: :integer, default: nil, force: true)
end end
def teardown def teardown
@connection.drop_table :bigint_defaults, if_exists: true @connection.drop_table :int_defaults, if_exists: true
end end
test "primary key with bigint allows default override via nil" do test "primary key with integer allows default override via nil" do
column = @connection.columns(:bigint_defaults).find { |c| c.name == "id" } column = @connection.columns(:int_defaults).find { |c| c.name == "id" }
assert column.bigint? assert_equal :integer, column.type
assert_not column.auto_increment? assert_not column.auto_increment?
end end
test "schema dump primary key with bigint default nil" do test "schema dump primary key with int default nil" do
schema = dump_table_schema "bigint_defaults" schema = dump_table_schema "int_defaults"
assert_match %r{create_table "bigint_defaults", id: :bigint, default: nil}, schema assert_match %r{create_table "int_defaults", id: :integer, default: nil}, schema
end end
end end
end end
if current_adapter?(:PostgreSQLAdapter, :Mysql2Adapter) class PrimaryKeyIntegerTest < ActiveRecord::TestCase
class PrimaryKeyBigSerialTest < ActiveRecord::TestCase
include SchemaDumpingHelper include SchemaDumpingHelper
self.use_transactional_tests = false self.use_transactional_tests = false
@ -354,11 +353,7 @@ if current_adapter?(:PostgreSQLAdapter, :Mysql2Adapter)
setup do setup do
@connection = ActiveRecord::Base.connection @connection = ActiveRecord::Base.connection
if current_adapter?(:PostgreSQLAdapter) @connection.create_table(:widgets, force: true)
@connection.create_table(:widgets, id: :bigserial, force: true)
else
@connection.create_table(:widgets, id: :bigint, force: true)
end
end end
teardown do teardown do
@ -366,35 +361,17 @@ if current_adapter?(:PostgreSQLAdapter, :Mysql2Adapter)
Widget.reset_column_information Widget.reset_column_information
end end
test "primary key column type with bigserial" do test "primary key column type" do
column_type = Widget.type_for_attribute(Widget.primary_key) column_type = Widget.type_for_attribute(Widget.primary_key)
assert_equal :integer, column_type.type assert_equal :integer, column_type.type
if current_adapter?(:PostgreSQLAdapter, :Mysql2Adapter)
assert_equal 8, column_type.limit assert_equal 8, column_type.limit
end end
test "primary key with bigserial are automatically numbered" do
widget = Widget.create!
assert_not_nil widget.id
end
test "schema dump primary key with bigserial" do
schema = dump_table_schema "widgets"
if current_adapter?(:PostgreSQLAdapter)
assert_match %r{create_table "widgets", id: :bigserial, force: :cascade}, schema
else
assert_match %r{create_table "widgets", id: :bigint, force: :cascade}, schema
end
end
if current_adapter?(:Mysql2Adapter) if current_adapter?(:Mysql2Adapter)
test "primary key column type with options" do
@connection.create_table(:widgets, id: :primary_key, limit: 8, unsigned: true, force: true)
column = @connection.columns(:widgets).find { |c| c.name == "id" } column = @connection.columns(:widgets).find { |c| c.name == "id" }
assert column.auto_increment? assert column.auto_increment?
assert_equal :integer, column.type
assert_equal 8, column.limit
assert column.unsigned?
end
end end
end end
end end

View file

@ -346,7 +346,7 @@ class SchemaDumperTest < ActiveRecord::TestCase
create_table("dogs") do |t| create_table("dogs") do |t|
t.column :name, :string t.column :name, :string
t.column :owner_id, :integer t.column :owner_id, :bigint
t.index [:name] t.index [:name]
t.foreign_key :dog_owners, column: "owner_id" if supports_foreign_keys? t.foreign_key :dog_owners, column: "owner_id" if supports_foreign_keys?
end end

View file

@ -54,7 +54,7 @@ ActiveRecord::Schema.define do
create_table :authors, force: true do |t| create_table :authors, force: true do |t|
t.string :name, null: false t.string :name, null: false
t.integer :author_address_id t.bigint :author_address_id
t.integer :author_address_extra_id t.integer :author_address_extra_id
t.string :organization_id t.string :organization_id
t.string :owned_essay_id t.string :owned_essay_id
@ -303,7 +303,7 @@ ActiveRecord::Schema.define do
end end
create_table :engines, force: true do |t| create_table :engines, force: true do |t|
t.integer :car_id t.bigint :car_id
end end
create_table :entrants, force: true do |t| create_table :entrants, force: true do |t|
@ -1004,7 +1004,7 @@ ActiveRecord::Schema.define do
if supports_foreign_keys? if supports_foreign_keys?
# fk_test_has_fk should be before fk_test_has_pk # fk_test_has_fk should be before fk_test_has_pk
create_table :fk_test_has_fk, force: true do |t| create_table :fk_test_has_fk, force: true do |t|
t.integer :fk_id, null: false t.bigint :fk_id, null: false
end end
create_table :fk_test_has_pk, force: true, primary_key: "pk_id" do |t| create_table :fk_test_has_pk, force: true, primary_key: "pk_id" do |t|