Commit be090a5f authored by charlie ablett's avatar charlie ablett

Add constraint and separate out null column

parent 5927399c
...@@ -5,7 +5,7 @@ class AddIssueIndexToTestReport < ActiveRecord::Migration[6.1] ...@@ -5,7 +5,7 @@ class AddIssueIndexToTestReport < ActiveRecord::Migration[6.1]
disable_ddl_transaction! disable_ddl_transaction!
INDEX_NAME = 'index_test_reports_on_issue_id' INDEX_NAME = 'index_requirements_management_test_reports_on_issue_id'
def up def up
add_concurrent_index :requirements_management_test_reports, :issue_id, name: INDEX_NAME add_concurrent_index :requirements_management_test_reports, :issue_id, name: INDEX_NAME
......
...@@ -3,23 +3,15 @@ ...@@ -3,23 +3,15 @@
class ChangeColumnNullTestReportRequirement < ActiveRecord::Migration[6.1] class ChangeColumnNullTestReportRequirement < ActiveRecord::Migration[6.1]
include Gitlab::Database::MigrationHelpers include Gitlab::Database::MigrationHelpers
disable_ddl_transaction! TARGET_TABLE = :requirements_management_test_reports
def up def up
with_lock_retries do with_lock_retries do
change_column_null :requirements_management_test_reports, :requirement_id, true change_column_null TARGET_TABLE, :requirement_id, true
end end
add_concurrent_foreign_key :requirements_management_test_reports, :issues, column: :issue_id
end end
def down def down
with_lock_retries do # no-op as it's difficult to revert
remove_foreign_key_if_exists(:requirements_management_test_reports, column: :issue_id)
end
with_lock_retries do
change_column_null :requirements_management_test_reports, :requirement_id, false
end
end end
end end
# frozen_string_literal: true
class AddRequirementTestReportsForeignKey < ActiveRecord::Migration[6.1]
include Gitlab::Database::MigrationHelpers
disable_ddl_transaction!
TARGET_TABLE = :requirements_management_test_reports
CONSTRAINT_NAME = 'requirements_test_reports_requirement_id_xor_issue_id'
def up
add_concurrent_foreign_key TARGET_TABLE, :issues, column: :issue_id
add_check_constraint(TARGET_TABLE, 'num_nonnulls(requirement_id, issue_id) = 1', CONSTRAINT_NAME)
end
def down
remove_check_constraint TARGET_TABLE, CONSTRAINT_NAME
with_lock_retries do
remove_foreign_key_if_exists(TARGET_TABLE, column: :issue_id)
end
end
end
b84505713afce3bf0673329a3a4eaf85a00d4f8948f56d43d365d6cc47ef629c
\ No newline at end of file
...@@ -17464,7 +17464,8 @@ CREATE TABLE requirements_management_test_reports ( ...@@ -17464,7 +17464,8 @@ CREATE TABLE requirements_management_test_reports (
author_id bigint, author_id bigint,
state smallint NOT NULL, state smallint NOT NULL,
build_id bigint, build_id bigint,
issue_id bigint issue_id bigint,
CONSTRAINT requirements_test_reports_requirement_id_xor_issue_id CHECK ((num_nonnulls(requirement_id, issue_id) = 1))
); );
CREATE SEQUENCE requirements_management_test_reports_id_seq CREATE SEQUENCE requirements_management_test_reports_id_seq
...@@ -24426,6 +24427,8 @@ CREATE INDEX index_requirements_management_test_reports_on_author_id ON requirem ...@@ -24426,6 +24427,8 @@ CREATE INDEX index_requirements_management_test_reports_on_author_id ON requirem
CREATE INDEX index_requirements_management_test_reports_on_build_id ON requirements_management_test_reports USING btree (build_id); CREATE INDEX index_requirements_management_test_reports_on_build_id ON requirements_management_test_reports USING btree (build_id);
CREATE INDEX index_requirements_management_test_reports_on_issue_id ON requirements_management_test_reports USING btree (issue_id);
CREATE INDEX index_requirements_management_test_reports_on_requirement_id ON requirements_management_test_reports USING btree (requirement_id); CREATE INDEX index_requirements_management_test_reports_on_requirement_id ON requirements_management_test_reports USING btree (requirement_id);
CREATE INDEX index_requirements_on_author_id ON requirements USING btree (author_id); CREATE INDEX index_requirements_on_author_id ON requirements USING btree (author_id);
...@@ -24718,8 +24721,6 @@ CREATE UNIQUE INDEX index_terraform_states_on_uuid ON terraform_states USING btr ...@@ -24718,8 +24721,6 @@ CREATE UNIQUE INDEX index_terraform_states_on_uuid ON terraform_states USING btr
CREATE UNIQUE INDEX index_test_case_failures_unique_columns ON ci_test_case_failures USING btree (test_case_id, failed_at DESC, build_id); CREATE UNIQUE INDEX index_test_case_failures_unique_columns ON ci_test_case_failures USING btree (test_case_id, failed_at DESC, build_id);
CREATE INDEX index_test_reports_on_issue_id ON requirements_management_test_reports USING btree (issue_id);
CREATE INDEX index_timelogs_on_issue_id ON timelogs USING btree (issue_id); CREATE INDEX index_timelogs_on_issue_id ON timelogs USING btree (issue_id);
CREATE INDEX index_timelogs_on_merge_request_id ON timelogs USING btree (merge_request_id); CREATE INDEX index_timelogs_on_merge_request_id ON timelogs USING btree (merge_request_id);
...@@ -12,6 +12,7 @@ module RequirementsManagement ...@@ -12,6 +12,7 @@ module RequirementsManagement
validates :state, presence: true validates :state, presence: true
validate :only_one_requirement_association validate :only_one_requirement_association
validate :only_requirement_type_issue
enum state: { passed: 1, failed: 2 } enum state: { passed: 1, failed: 2 }
...@@ -69,7 +70,10 @@ module RequirementsManagement ...@@ -69,7 +70,10 @@ module RequirementsManagement
end end
def only_one_requirement_association def only_one_requirement_association
errors.add(:base, 'Must be associated with either a RequirementsManagement::Requirement and an Issue of type `requirement`, but not both') unless !!requirement ^ !!requirement_issue errors.add(:base, 'Must be associated with either a RequirementsManagement::Requirement OR an Issue of type `requirement`, but not both') unless !!requirement ^ !!requirement_issue
end
def only_requirement_type_issue
errors.add(:requirement_issue, 'must be an issue of type `Requirement`') if requirement_issue && !requirement_issue.requirement? errors.add(:requirement_issue, 'must be an issue of type `Requirement`') if requirement_issue && !requirement_issue.requirement?
end end
end end
......
...@@ -17,7 +17,7 @@ RSpec.describe RequirementsManagement::TestReport do ...@@ -17,7 +17,7 @@ RSpec.describe RequirementsManagement::TestReport do
let(:requirement) { build(:requirement) } let(:requirement) { build(:requirement) }
let(:requirement_issue) { build(:requirement_issue) } let(:requirement_issue) { build(:requirement_issue) }
let(:requirement_error) { /Must be associated with either a RequirementsManagement::Requirement and an Issue of type `requirement`, but not both/ } let(:requirement_error) { /Must be associated with either a RequirementsManagement::Requirement OR an Issue of type `requirement`, but not both/ }
it { is_expected.to validate_presence_of(:state) } it { is_expected.to validate_presence_of(:state) }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment