Skip to content

Commit 2177160

Browse files
authored
Add an index for user_id on all roles tables (#4268)
Currently there is only a combined index (space/org_id + user_id) which cannot be used when accessing the table via user_id. Multiple role queries could benefit from a dedicated index on user_id. MySQL already has this index (for the foreign key constraint).
1 parent cc72f07 commit 2177160

File tree

2 files changed

+116
-0
lines changed

2 files changed

+116
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
Sequel.migration do
2+
roles_tables = %w[
3+
organizations_auditors
4+
organizations_billing_managers
5+
organizations_managers
6+
organizations_users
7+
spaces_auditors
8+
spaces_developers
9+
spaces_managers
10+
spaces_supporters
11+
]
12+
13+
# adding an index concurrently cannot be done within a transaction
14+
no_transaction
15+
16+
up do
17+
roles_tables.each do |table|
18+
# MySQL already has an index on user_id (foreign key constraint)
19+
next unless database_type == :postgres
20+
21+
table_sym = table.to_sym
22+
index_sym = :"#{table}_user_id_index"
23+
VCAP::Migration.with_concurrent_timeout(self) do
24+
add_index table_sym, :user_id, name: index_sym, if_not_exists: true, concurrently: true
25+
end
26+
end
27+
end
28+
29+
down do
30+
roles_tables.each do |table|
31+
next unless database_type == :postgres
32+
33+
table_sym = table.to_sym
34+
index_sym = :"#{table}_user_id_index"
35+
VCAP::Migration.with_concurrent_timeout(self) do
36+
drop_index table_sym, :user_id, name: index_sym, if_exists: true, concurrently: true
37+
end
38+
end
39+
end
40+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
require 'spec_helper'
2+
require 'migrations/helpers/migration_shared_context'
3+
4+
RSpec.shared_examples 'adding an index for table' do |table|
5+
describe "#{table} table" do
6+
let(:table_sym) { table.to_sym }
7+
let(:index_sym) { :"#{table}_user_id_index" }
8+
9+
before do
10+
skip unless db.database_type == :postgres
11+
end
12+
13+
describe 'up migration' do
14+
context 'index does not exist' do
15+
it 'adds the index' do
16+
expect(db.indexes(table_sym)).not_to include(index_sym)
17+
expect { Sequel::Migrator.run(db, migrations_path, target: current_migration_index, allow_missing_migration_files: true) }.not_to raise_error
18+
expect(db.indexes(table_sym)).to include(index_sym)
19+
end
20+
end
21+
22+
context 'index already exists' do
23+
before do
24+
db.add_index table_sym, :user_id, name: index_sym
25+
end
26+
27+
it 'does not fail' do
28+
expect(db.indexes(table_sym)).to include(index_sym)
29+
expect { Sequel::Migrator.run(db, migrations_path, target: current_migration_index, allow_missing_migration_files: true) }.not_to raise_error
30+
expect(db.indexes(table_sym)).to include(index_sym)
31+
end
32+
end
33+
end
34+
35+
describe 'down migration' do
36+
before do
37+
Sequel::Migrator.run(db, migrations_path, target: current_migration_index, allow_missing_migration_files: true)
38+
end
39+
40+
context 'index exists' do
41+
it 'removes the index' do
42+
expect(db.indexes(table_sym)).to include(index_sym)
43+
expect { Sequel::Migrator.run(db, migrations_path, target: current_migration_index - 1, allow_missing_migration_files: true) }.not_to raise_error
44+
expect(db.indexes(table_sym)).not_to include(index_sym)
45+
end
46+
end
47+
48+
context 'index does not exist' do
49+
before do
50+
db.drop_index table_sym, :user_id, name: index_sym
51+
end
52+
53+
it 'does not fail' do
54+
expect(db.indexes(table_sym)).not_to include(index_sym)
55+
expect { Sequel::Migrator.run(db, migrations_path, target: current_migration_index - 1, allow_missing_migration_files: true) }.not_to raise_error
56+
expect(db.indexes(table_sym)).not_to include(index_sym)
57+
end
58+
end
59+
end
60+
end
61+
end
62+
63+
RSpec.describe 'migration to add an index for user_id on all roles tables', isolation: :truncation, type: :migration do
64+
include_context 'migration' do
65+
let(:migration_filename) { '20250318112800_add_user_id_index_to_roles_tables.rb' }
66+
end
67+
68+
include_examples 'adding an index for table', 'organizations_auditors'
69+
include_examples 'adding an index for table', 'organizations_billing_managers'
70+
include_examples 'adding an index for table', 'organizations_managers'
71+
include_examples 'adding an index for table', 'organizations_users'
72+
include_examples 'adding an index for table', 'spaces_auditors'
73+
include_examples 'adding an index for table', 'spaces_developers'
74+
include_examples 'adding an index for table', 'spaces_managers'
75+
include_examples 'adding an index for table', 'spaces_supporters'
76+
end

0 commit comments

Comments
 (0)