Skip to content

Commit 99f2614

Browse files
committed
bigint migration - events table - step 1
1 parent f629077 commit 99f2614

File tree

9 files changed

+268
-2
lines changed

9 files changed

+268
-2
lines changed

.rubocop_cc.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,8 @@ Rails/DangerousColumnNames: # Disabled, in comparison to active_record we need t
136136
Rails/SkipsModelValidations: # We don`t want any model at all in migrations and migration specs
137137
Enabled: true
138138
Exclude:
139-
- db/migrations/*
140-
- spec/migrations/*
139+
- db/migrations/**/*
140+
- spec/migrations/**/*
141141

142142
#### ENABLED SECTION
143143
Gemspec/DeprecatedAttributeAssignment:

db/helpers/bigint_migration.rb

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
require 'tasks/rake_config'
2+
3+
# helpers
4+
def opt_out?
5+
opt_out = RakeConfig.config.get(:skip_bigint_id_migration)
6+
opt_out.nil? ? false : opt_out
7+
rescue VCAP::CloudController::Config::InvalidConfigPath
8+
false
9+
end
10+
11+
# DSL
12+
def empty?(table)
13+
raise unless is_a?(Sequel::Database)
14+
15+
self[table].count == 0
16+
end
17+
18+
def change_pk_to_bigint(table)
19+
raise unless is_a?(Sequel::Database)
20+
21+
set_column_type(table, :id, :Bignum) if column_type(self, table, :id) != BIGINT_TYPE
22+
end
23+
24+
def add_bigint_column(table)
25+
raise unless is_a?(Sequel::Database)
26+
27+
add_column(table, :id_bigint, :Bignum, if_not_exists: true)
28+
end
29+
30+
def revert_pk_to_integer(table)
31+
raise unless is_a?(Sequel::Database)
32+
33+
set_column_type(table, :id, :integer) if column_type(self, table, :id) == BIGINT_TYPE
34+
end
35+
36+
def drop_bigint_column(table)
37+
raise unless is_a?(Sequel::Database)
38+
39+
drop_column(table, :id_bigint, if_exists: true)
40+
end
41+
42+
# internal constants
43+
BIGINT_TYPE = 'bigint'.freeze
44+
45+
# internal helpers
46+
def column_type(db, table, column)
47+
db.schema(table).find { |col, _| col == column }&.dig(1, :db_type)
48+
end
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
require File.expand_path('../helpers/bigint_migration', __dir__)
2+
3+
Sequel.migration do
4+
up do
5+
# unless opt_out?
6+
# if empty?(:events)
7+
# change_pk_to_bigint(:events)
8+
# else
9+
# add_bigint_column(:events)
10+
# end
11+
# end
12+
end
13+
14+
down do
15+
# revert_pk_to_integer(:events)
16+
# drop_bigint_column(:events)
17+
end
18+
end

lib/cloud_controller/config_schemas/base/api_schema.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ class ApiSchema < VCAP::Config
9999
optional(:max_migration_statement_runtime_in_seconds) => Integer,
100100
optional(:migration_psql_concurrent_statement_timeout_in_seconds) => Integer,
101101
optional(:migration_psql_worker_memory_kb) => Integer,
102+
optional(:skip_bigint_id_migration) => bool,
102103
db: {
103104
optional(:database) => Hash, # db connection hash for sequel
104105
max_connections: Integer, # max connections in the connection pool

lib/cloud_controller/config_schemas/base/migrate_schema.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ class MigrateSchema < VCAP::Config
1010
optional(:max_migration_statement_runtime_in_seconds) => Integer,
1111
optional(:migration_psql_concurrent_statement_timeout_in_seconds) => Integer,
1212
optional(:migration_psql_worker_memory_kb) => Integer,
13+
optional(:skip_bigint_id_migration) => bool,
1314

1415
db: {
1516
optional(:database) => Hash, # db connection hash for sequel
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
require 'spec_helper'
2+
require 'migrations/helpers/bigint_migration_step1_shared_context'
3+
4+
RSpec.describe 'bigint migration - events table - step1', isolation: :truncation, type: :migration do
5+
include_context 'bigint migration step1' do
6+
let(:migration_filename) { '20250327142351_bigint_migration_events_step1.rb' }
7+
let(:table) { :events }
8+
let(:insert_hash) do
9+
{
10+
guid: 'guid', timestamp: Time.now.utc, type: 'type',
11+
actor: 'actor', actor_type: 'actor_type',
12+
actee: 'actee', actee_type: 'actee_type'
13+
}
14+
end
15+
end
16+
end
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
require 'spec_helper'
2+
require_relative '../../db/helpers/bigint_migration'
3+
4+
RSpec.describe 'bigint migration helpers', isolation: :truncation, type: :migration do
5+
let(:skip_bigint_id_migration) { nil }
6+
7+
it 'works' do
8+
expect(true).to be_truthy
9+
end
10+
11+
# before do
12+
# allow_any_instance_of(VCAP::CloudController::Config).to receive(:get).and_call_original
13+
# allow_any_instance_of(VCAP::CloudController::Config).to receive(:get).with(:skip_bigint_id_migration).and_return(skip_bigint_id_migration)
14+
# end
15+
#
16+
# describe '#opt_out?' do
17+
# context 'when skip_bigint_id_migration is false' do
18+
# let(:skip_bigint_id_migration) { false }
19+
#
20+
# it 'returns false' do
21+
# expect(opt_out?).to be(false)
22+
# end
23+
# end
24+
#
25+
# context 'when skip_bigint_id_migration is true' do
26+
# let(:skip_bigint_id_migration) { true }
27+
#
28+
# it 'returns true' do
29+
# # expect(opt_out?).to be(true)
30+
# end
31+
# end
32+
#
33+
# context 'when skip_bigint_id_migration is nil' do
34+
# let(:skip_bigint_id_migration) { nil }
35+
#
36+
# it 'returns false' do
37+
# expect(opt_out?).to be(false)
38+
# end
39+
# end
40+
#
41+
# context 'when raising InvalidConfigPath error' do
42+
# before do
43+
# allow_any_instance_of(VCAP::CloudController::Config).to receive(:get).with(:skip_bigint_id_migration).and_raise(VCAP::CloudController::Config::InvalidConfigPath)
44+
# end
45+
#
46+
# it 'returns false' do
47+
# expect(opt_out?).to be(false)
48+
# end
49+
# end
50+
# end
51+
end
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
require 'migrations/helpers/migration_shared_context'
2+
3+
RSpec.shared_context 'bigint migration step1' do
4+
subject(:run_migration) { Sequel::Migrator.run(db, migrations_path, target: current_migration_index, allow_missing_migration_files: true) }
5+
6+
include_context 'migration'
7+
8+
it 'works' do
9+
run_migration
10+
expect(true).to be_truthy
11+
end
12+
13+
# let(:skip_bigint_id_migration) { nil }
14+
#
15+
# before do
16+
# # allow_any_instance_of(VCAP::CloudController::Config).to receive(:get).and_call_original
17+
# # allow_any_instance_of(VCAP::CloudController::Config).to receive(:get).with(:skip_bigint_id_migration).and_return(skip_bigint_id_migration)
18+
# end
19+
#
20+
# describe 'up' do
21+
# context 'when skip_bigint_id_migration is false' do
22+
# let(:skip_bigint_id_migration) { false }
23+
#
24+
# context 'when the table is empty' do
25+
# before do
26+
# db[table].delete
27+
# end
28+
#
29+
# it "changes the id column's type to bigint" do
30+
# expect(db).to have_table_with_column_and_type(table, :id, 'integer')
31+
#
32+
# run_migration
33+
#
34+
# expect(db).to have_table_with_column_and_type(table, :id, 'bigint')
35+
# end
36+
#
37+
# it 'does not add the id_bigint column' do
38+
# expect(db).not_to have_table_with_column(table, :id_bigint)
39+
#
40+
# run_migration
41+
#
42+
# expect(db).not_to have_table_with_column(table, :id_bigint)
43+
# end
44+
# end
45+
#
46+
# context 'when the table is not empty' do
47+
# before do
48+
# db[table].insert(insert_hash)
49+
# end
50+
#
51+
# it "does not change the id column's type" do
52+
# expect(db).to have_table_with_column_and_type(table, :id, 'integer')
53+
#
54+
# run_migration
55+
#
56+
# expect(db).to have_table_with_column_and_type(table, :id, 'integer')
57+
# end
58+
#
59+
# it 'adds the id_bigint column' do
60+
# expect(db).not_to have_table_with_column(table, :id_bigint)
61+
#
62+
# run_migration
63+
#
64+
# expect(db).to have_table_with_column_and_type(table, :id_bigint, 'bigint')
65+
# end
66+
# end
67+
# end
68+
#
69+
# context 'when skip_bigint_id_migration is true' do
70+
# let(:skip_bigint_id_migration) { true }
71+
#
72+
# it "neither changes the id column's type, nor adds the id_bigint column" do
73+
# # expect(db).to have_table_with_column_and_type(table, :id, 'integer')
74+
# # expect(db).not_to have_table_with_column(table, :id_bigint)
75+
# #
76+
# # run_migration
77+
# #
78+
# # expect(db).to have_table_with_column_and_type(table, :id, 'integer')
79+
# # expect(db).not_to have_table_with_column(table, :id_bigint)
80+
# end
81+
# end
82+
# end
83+
#
84+
# describe 'down' do
85+
# subject(:run_rollback) { Sequel::Migrator.run(db, migrations_path, target: current_migration_index - 1, allow_missing_migration_files: true) }
86+
#
87+
# context 'when the table is empty' do
88+
# before do
89+
# db[table].delete
90+
# run_migration
91+
# end
92+
#
93+
# it "reverts the id column's type to integer" do
94+
# expect(db).to have_table_with_column_and_type(table, :id, 'bigint')
95+
#
96+
# run_rollback
97+
#
98+
# expect(db).to have_table_with_column_and_type(table, :id, 'integer')
99+
# end
100+
# end
101+
#
102+
# context 'when the table is not empty' do
103+
# before do
104+
# db[table].insert(insert_hash)
105+
# run_migration
106+
# end
107+
#
108+
# it 'drops the id_bigint column' do
109+
# expect(db).to have_table_with_column(table, :id_bigint)
110+
#
111+
# run_rollback
112+
#
113+
# expect(db).not_to have_table_with_column(table, :id_bigint)
114+
# end
115+
# end
116+
# end
117+
end

spec/migrations/helpers/matchers.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,17 @@
1515
!options.delete(:name).nil? && (options - %i[if_exists concurrently]).empty?
1616
end
1717
end
18+
19+
RSpec::Matchers.define :have_table_with_column do |table, column|
20+
match do |db|
21+
db[table].columns.include?(column)
22+
end
23+
end
24+
25+
RSpec::Matchers.define :have_table_with_column_and_type do |table, column, type|
26+
match do |db|
27+
expect(db).to have_table_with_column(table, column)
28+
29+
db.schema(table).find { |col, _| col == column }&.dig(1, :db_type) == type
30+
end
31+
end

0 commit comments

Comments
 (0)