Skip to content

Commit 3abe847

Browse files
committed
Do not try to create/drop check constraint on mysql < 8
1 parent c6dab85 commit 3abe847

File tree

2 files changed

+75
-33
lines changed

2 files changed

+75
-33
lines changed

db/migrations/20250225132929_add_apps_file_based_service_binding_feature_columns.rb

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@
1616
add_column :apps, :service_binding_k8s_enabled, :boolean, default: false, null: false unless schema(:apps).map(&:first).include?(:service_binding_k8s_enabled)
1717
add_column :apps, :file_based_vcap_services_enabled, :boolean, default: false, null: false unless schema(:apps).map(&:first).include?(:file_based_vcap_services_enabled)
1818

19-
unless check_constraint_exists?(self)
19+
if check_constraint_supported?(self) && !check_constraint_exists?(self)
2020
run('ALTER TABLE apps ADD CONSTRAINT only_one_sb_feature_enabled CHECK (NOT (service_binding_k8s_enabled AND file_based_vcap_services_enabled))')
2121
end
2222
end
2323
end
2424

2525
down do
2626
alter_table :apps do
27-
drop_constraint :only_one_sb_feature_enabled if check_constraint_exists?(@db)
27+
drop_constraint :only_one_sb_feature_enabled if check_constraint_supported?(@db) && check_constraint_exists?(@db)
2828
drop_column :service_binding_k8s_enabled if @db.schema(:apps).map(&:first).include?(:service_binding_k8s_enabled)
2929
drop_column :file_based_vcap_services_enabled if @db.schema(:apps).map(&:first).include?(:file_based_vcap_services_enabled)
3030
end
@@ -39,3 +39,9 @@ def check_constraint_exists?(database)
3939
CONSTRAINT_NAME: 'only_one_sb_feature_enabled').any?
4040
end
4141
end
42+
43+
# check constraints are not available in Mysql versions < 8
44+
# this is also enforced on application level, so it should be fine not to create it on that version
45+
def check_constraint_supported?(database)
46+
database.database_type == :postgres || (database.database_type == :mysql && database.server_version >= 80_000)
47+
end

spec/migrations/20250225132929_add_apps_file_based_service_binding_feature_columns_spec.rb

Lines changed: 67 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
require 'spec_helper'
22
require 'migrations/helpers/migration_shared_context'
33

4-
RSpec.describe 'migration to add service_binding_k8s_enabled column to apps table', isolation: :truncation, type: :migration do
4+
RSpec.describe 'migration to add file-based service binding feature columns to apps table', isolation: :truncation, type: :migration do
55
include_context 'migration' do
66
let(:migration_filename) { '20250225132929_add_apps_file_based_service_binding_feature_columns.rb' }
77
end
@@ -44,7 +44,7 @@
4444
expect { run_migration }.not_to raise_error
4545
expect(db[:apps].columns).to include(:service_binding_k8s_enabled)
4646
expect(db[:apps].columns).to include(:file_based_vcap_services_enabled)
47-
expect(check_constraint_exists?(db)).to be(true)
47+
expect(check_constraint_exists?(db)).to be(true) if check_constraint_supported?(db)
4848
end
4949
end
5050
end
@@ -83,38 +83,56 @@
8383
expect { run_migration }.not_to raise_error
8484
expect(db[:apps].columns).to include(:service_binding_k8s_enabled)
8585
expect(db[:apps].columns).to include(:file_based_vcap_services_enabled)
86-
expect(check_constraint_exists?(db)).to be(true)
86+
expect(check_constraint_exists?(db)).to be(true) if check_constraint_supported?(db)
8787
end
8888
end
8989
end
9090

9191
describe 'check constraint' do
92-
it 'adds the check constraint' do
93-
expect(check_constraint_exists?(db)).to be(false)
94-
run_migration
95-
expect(check_constraint_exists?(db)).to be(true)
96-
end
92+
context 'when supported' do
93+
before do
94+
skip 'check constraint not supported by db' unless check_constraint_supported?(db)
95+
end
9796

98-
it 'forbids setting both features to true' do
99-
run_migration
100-
expect { db[:apps].insert(guid: 'some_app', file_based_vcap_services_enabled: true, service_binding_k8s_enabled: true) }.to(raise_error do |error|
101-
expect(error.inspect).to include('only_one_sb_feature_enabled', 'violate')
102-
end)
103-
end
97+
it 'adds the check constraint' do
98+
expect(check_constraint_exists?(db)).to be(false)
99+
run_migration
100+
expect(check_constraint_exists?(db)).to be(true)
101+
end
104102

105-
context 'when it already exists' do
106-
before do
107-
db.add_column :apps, :service_binding_k8s_enabled, :boolean, default: false, null: false, if_not_exists: true
108-
db.add_column :apps, :file_based_vcap_services_enabled, :boolean, default: false, null: false, if_not_exists: true
109-
db.alter_table :apps do
110-
add_constraint(name: :only_one_sb_feature_enabled) do
111-
Sequel.lit('NOT (service_binding_k8s_enabled AND file_based_vcap_services_enabled)')
103+
it 'forbids setting both features to true' do
104+
run_migration
105+
expect { db[:apps].insert(guid: 'some_app', file_based_vcap_services_enabled: true, service_binding_k8s_enabled: true) }.to(raise_error do |error|
106+
expect(error.inspect).to include('only_one_sb_feature_enabled', 'violate')
107+
end)
108+
end
109+
110+
context 'when it already exists' do
111+
before do
112+
db.add_column :apps, :service_binding_k8s_enabled, :boolean, default: false, null: false, if_not_exists: true
113+
db.add_column :apps, :file_based_vcap_services_enabled, :boolean, default: false, null: false, if_not_exists: true
114+
db.alter_table :apps do
115+
add_constraint(name: :only_one_sb_feature_enabled) do
116+
Sequel.lit('NOT (service_binding_k8s_enabled AND file_based_vcap_services_enabled)')
117+
end
112118
end
113119
end
120+
121+
it 'does not fail' do
122+
expect { run_migration }.not_to raise_error
123+
end
124+
end
125+
end
126+
127+
context 'when not supported' do
128+
before do
129+
skip 'check constraint supported by db' if check_constraint_supported?(db)
114130
end
115131

116132
it 'does not fail' do
117133
expect { run_migration }.not_to raise_error
134+
expect(db[:apps].columns).to include(:service_binding_k8s_enabled)
135+
expect(db[:apps].columns).to include(:file_based_vcap_services_enabled)
118136
end
119137
end
120138
end
@@ -178,25 +196,43 @@
178196
end
179197

180198
describe 'check constraint' do
181-
it 'removes the check constraint' do
182-
expect(check_constraint_exists?(db)).to be(true)
183-
run_rollback
184-
expect(check_constraint_exists?(db)).to be(false)
199+
context 'when supported' do
200+
before do
201+
skip 'check constraint not supported by db' unless check_constraint_supported?(db)
202+
end
203+
204+
it 'removes the check constraint' do
205+
expect(check_constraint_exists?(db)).to be(true)
206+
run_rollback
207+
expect(check_constraint_exists?(db)).to be(false)
208+
end
209+
210+
context 'when it does not exist' do
211+
before do
212+
db.alter_table :apps do
213+
drop_constraint :only_one_sb_feature_enabled
214+
end
215+
end
216+
217+
it 'does not fail' do
218+
expect(check_constraint_exists?(db)).to be(false)
219+
expect { run_rollback }.not_to raise_error
220+
expect(db[:apps].columns).not_to include(:service_binding_k8s_enabled)
221+
expect(db[:apps].columns).not_to include(:file_based_vcap_services_enabled)
222+
expect(check_constraint_exists?(db)).to be(false)
223+
end
224+
end
185225
end
186226

187-
context 'when it does not exist' do
227+
context 'when not supported' do
188228
before do
189-
db.alter_table :apps do
190-
drop_constraint :only_one_sb_feature_enabled
191-
end
229+
skip 'check constraint supported by db' if check_constraint_supported?(db)
192230
end
193231

194232
it 'does not fail' do
195-
expect(check_constraint_exists?(db)).to be(false)
196233
expect { run_rollback }.not_to raise_error
197234
expect(db[:apps].columns).not_to include(:service_binding_k8s_enabled)
198235
expect(db[:apps].columns).not_to include(:file_based_vcap_services_enabled)
199-
expect(check_constraint_exists?(db)).to be(false)
200236
end
201237
end
202238
end

0 commit comments

Comments
 (0)