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:
parent
575212a1ba
commit
b92ae61069
16 changed files with 74 additions and 75 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -19,3 +19,4 @@ pkg
|
||||||
/railties/doc
|
/railties/doc
|
||||||
/railties/tmp
|
/railties/tmp
|
||||||
/guides/output
|
/guides/output
|
||||||
|
/*/.byebug_history
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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 },
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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 = super
|
||||||
spec = { id: :bigint.inspect }
|
if column.type == :integer && !column.auto_increment?
|
||||||
spec[:default] = schema_default(column) || "nil" unless column.auto_increment?
|
spec[:default] = schema_default(column) || "nil"
|
||||||
else
|
|
||||||
spec = super
|
|
||||||
end
|
end
|
||||||
spec[:unsigned] = "true" if column.unsigned?
|
spec[:unsigned] = "true" if column.unsigned?
|
||||||
spec
|
spec
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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" },
|
||||||
|
|
|
@ -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
|
|
@ -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",
|
||||||
|
|
|
@ -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|
|
||||||
@connection.expect :add_column, nil, [:delete_me, :id, :primary_key, primary_key: true, first: true]
|
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]
|
||||||
|
end
|
||||||
|
|
||||||
t.primary_key :id, first: true
|
t.primary_key :id, first: true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -316,85 +316,62 @@ 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
|
||||||
|
|
||||||
class Widget < ActiveRecord::Base
|
class Widget < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
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)
|
end
|
||||||
else
|
|
||||||
@connection.create_table(:widgets, id: :bigint, force: true)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
teardown do
|
teardown do
|
||||||
@connection.drop_table :widgets, if_exists: true
|
@connection.drop_table :widgets, if_exists: true
|
||||||
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
|
column = @connection.columns(:widgets).find { |c| c.name == "id" }
|
||||||
@connection.create_table(:widgets, id: :primary_key, limit: 8, unsigned: true, force: true)
|
assert column.auto_increment?
|
||||||
column = @connection.columns(:widgets).find { |c| c.name == "id" }
|
|
||||||
assert column.auto_increment?
|
|
||||||
assert_equal :integer, column.type
|
|
||||||
assert_equal 8, column.limit
|
|
||||||
assert column.unsigned?
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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|
|
||||||
|
|
Loading…
Reference in a new issue