Skip to content

Refactor ComplianceFramework in to AR Model

Max Woolf requested to merge 251113-refactor_compliance_framework_fk into master

What does this MR do?

Refactor ComplianceFramework in to AR Model

  • Builds on this MR: !43301 (merged) to use the new table to represent compliance frameworks. This MR is reliant on !43301 (merged) being merged first. It contains the same commit, so should not be applied first!

  • Adds foreign key constraint and index between ComplianceManagement::ComplianceFramework:: and ComplianceManagement::Framework

  • Updates the use of the framework attribute to use the new foreign key relation. This commit is large due to the number of places that it is referenced throughout the codebase.

database review

RenameComplianceFrameworkColumn

Migrate

== 20200922094625 RenameComplianceFrameworkColumn: migrating ==================
-- column_exists?(:project_compliance_framework_settings, :project_id)
   -> 0.0025s
-- transaction_open?()
   -> 0.0000s
-- columns(:project_compliance_framework_settings)
   -> 0.0008s
-- add_column(:project_compliance_framework_settings, :framework_id, :integer, {:limit=>2, :precision=>nil, :scale=>nil})
   -> 0.0009s
-- transaction_open?()
   -> 0.0000s
-- exec_query("SELECT COUNT(*) AS count FROM \"project_compliance_framework_settings\"")
   -> 0.0006s
-- indexes(:project_compliance_framework_settings)
   -> 0.0024s
-- transaction_open?()
   -> 0.0000s
-- index_exists?(:project_compliance_framework_settings, ["framework_id"], {:unique=>false, :name=>"index_project_compliance_framework_id_settings_framework_id", :length=>{}, :order=>{}, :using=>:btree, :algorithm=>:concurrently})
   -> 0.0016s
-- execute("SET statement_timeout TO 0")
   -> 0.0001s
-- add_index(:project_compliance_framework_settings, ["framework_id"], {:unique=>false, :name=>"index_project_compliance_framework_id_settings_framework_id", :length=>{}, :order=>{}, :using=>:btree, :algorithm=>:concurrently})
   -> 0.0028s
-- execute("RESET ALL")
   -> 0.0001s
-- transaction_open?()
   -> 0.0000s
-- index_exists?(:project_compliance_framework_settings, ["framework_id"], {:unique=>false, :name=>"index_project_compliance_framework_id_settings_on_framework_id", :length=>{}, :order=>{}, :using=>:btree, :algorithm=>:concurrently})
   -> 0.0016s
-- add_index(:project_compliance_framework_settings, ["framework_id"], {:unique=>false, :name=>"index_project_compliance_framework_id_settings_on_framework_id", :length=>{}, :order=>{}, :using=>:btree, :algorithm=>:concurrently})
   -> 0.0027s
-- foreign_keys(:project_compliance_framework_settings)
   -> 0.0028s
-- quote_table_name(:project_compliance_framework_settings)
   -> 0.0000s
-- quote_column_name(:framework)
   -> 0.0000s
-- quote_column_name(:framework_id)
   -> 0.0000s
-- execute("CREATE OR REPLACE FUNCTION trigger_8b88fb98bb6e()\nRETURNS trigger AS\n$BODY$\nBEGIN\n  NEW.\"framework_id\" := NEW.\"framework\";\n  RETURN NEW;\nEND;\n$BODY$\nLANGUAGE 'plpgsql'\nVOLATILE\n")
   -> 0.0028s
-- execute("DROP TRIGGER IF EXISTS trigger_8b88fb98bb6e\nON \"project_compliance_framework_settings\"\n")
NOTICE:  trigger "trigger_8b88fb98bb6e" for relation "project_compliance_framework_settings" does not exist, skipping
   -> 0.0003s
-- execute("CREATE TRIGGER trigger_8b88fb98bb6e\nBEFORE INSERT OR UPDATE\nON \"project_compliance_framework_settings\"\nFOR EACH ROW\nEXECUTE FUNCTION trigger_8b88fb98bb6e()\n")
   -> 0.0005s
-- transaction_open?()
   -> 0.0000s
-- foreign_keys(:project_compliance_framework_settings)
   -> 0.0019s
-- execute("ALTER TABLE project_compliance_framework_settings\nADD CONSTRAINT fk_be413374a9\nFOREIGN KEY (framework_id)\nREFERENCES compliance_management_frameworks (id)\nON DELETE CASCADE\nNOT VALID;\n")
   -> 0.0018s
-- transaction_open?()
   -> 0.0000s
-- index_exists?(:project_compliance_framework_settings, :framework_id, {:name=>"index_project_compliance_framework_settings_framework_id", :algorithm=>:concurrently})
   -> 0.0019s
-- add_index(:project_compliance_framework_settings, :framework_id, {:name=>"index_project_compliance_framework_settings_framework_id", :algorithm=>:concurrently})
   -> 0.0020s
== 20200922094625 RenameComplianceFrameworkColumn: migrated (0.0419s) =========

Rollback

== 20200922094625 RenameComplianceFrameworkColumn: reverting ==================
-- transaction_open?()
   -> 0.0000s
-- index_exists?(:project_compliance_framework_settings, :framework_id, {:name=>"index_project_compliance_framework_settings_framework_id", :algorithm=>:concurrently})
   -> 0.0036s
-- execute("SET statement_timeout TO 0")
   -> 0.0002s
-- remove_index(:project_compliance_framework_settings, {:name=>"index_project_compliance_framework_settings_framework_id", :algorithm=>:concurrently, :column=>:framework_id})
   -> 0.0044s
-- execute("RESET ALL")
   -> 0.0001s
-- foreign_keys(:project_compliance_framework_settings)
   -> 0.0026s
-- execute("DROP TRIGGER IF EXISTS trigger_8b88fb98bb6e ON project_compliance_framework_settings")
   -> 0.0004s
-- execute("DROP FUNCTION IF EXISTS trigger_8b88fb98bb6e()")
   -> 0.0003s
-- remove_column(:project_compliance_framework_settings, :framework_id)
   -> 0.0025s
== 20200922094625 RenameComplianceFrameworkColumn: reverted (0.0163s) =========

RenameComplianceFrameworkForeignKey (Post-Migration Cleanup)

Migrate

== 20200924091958 RenameComplianceFrameworkForeignKey: migrating ==============
-- execute("DROP TRIGGER IF EXISTS trigger_8b88fb98bb6e ON project_compliance_framework_settings")
   -> 0.0008s
-- execute("DROP FUNCTION IF EXISTS trigger_8b88fb98bb6e()")
   -> 0.0004s
-- remove_column(:project_compliance_framework_settings, :framework)
   -> 0.0029s
== 20200924091958 RenameComplianceFrameworkForeignKey: migrated (0.0056s) =====

Rollback

== 20200924091958 RenameComplianceFrameworkForeignKey: reverting ==============
-- column_exists?(:project_compliance_framework_settings, :project_id)
   -> 0.0021s
-- transaction_open?()
   -> 0.0000s
-- columns(:project_compliance_framework_settings)
   -> 0.0007s
-- add_column(:project_compliance_framework_settings, :framework, :integer, {:limit=>2, :precision=>nil, :scale=>nil})
   -> 0.0008s
-- transaction_open?()
   -> 0.0000s
-- exec_query("SELECT COUNT(*) AS count FROM \"project_compliance_framework_settings\"")
   -> 0.0040s
-- indexes(:project_compliance_framework_settings)
   -> 0.0024s
-- transaction_open?()
   -> 0.0000s
-- index_exists?(:project_compliance_framework_settings, ["framework"], {:unique=>false, :name=>"index_project_compliance_framework_settings_framework", :length=>{}, :order=>{}, :using=>:btree, :algorithm=>:concurrently})
   -> 0.0015s
-- execute("SET statement_timeout TO 0")
   -> 0.0001s
-- add_index(:project_compliance_framework_settings, ["framework"], {:unique=>false, :name=>"index_project_compliance_framework_settings_framework", :length=>{}, :order=>{}, :using=>:btree, :algorithm=>:concurrently})
   -> 0.0024s
-- execute("RESET ALL")
   -> 0.0001s
-- transaction_open?()
   -> 0.0000s
-- index_exists?(:project_compliance_framework_settings, ["framework"], {:unique=>false, :name=>"index_project_compliance_framework_settings_on_framework", :length=>{}, :order=>{}, :using=>:btree, :algorithm=>:concurrently})
   -> 0.0019s
-- add_index(:project_compliance_framework_settings, ["framework"], {:unique=>false, :name=>"index_project_compliance_framework_settings_on_framework", :length=>{}, :order=>{}, :using=>:btree, :algorithm=>:concurrently})
   -> 0.0020s
-- transaction_open?()
   -> 0.0000s
-- index_exists?(:project_compliance_framework_settings, ["framework"], {:unique=>false, :name=>"index_project_compliance_framework_settings_framework", :length=>{}, :order=>{}, :using=>:btree, :algorithm=>:concurrently})
   -> 0.0018s
-- foreign_keys(:project_compliance_framework_settings)
   -> 0.0023s
-- quote_table_name(:project_compliance_framework_settings)
   -> 0.0000s
-- quote_column_name(:framework)
   -> 0.0000s
-- quote_column_name(:framework_id)
   -> 0.0000s
-- execute("CREATE OR REPLACE FUNCTION trigger_8b88fb98bb6e()\nRETURNS trigger AS\n$BODY$\nBEGIN\n  NEW.\"framework_id\" := NEW.\"framework\";\n  RETURN NEW;\nEND;\n$BODY$\nLANGUAGE 'plpgsql'\nVOLATILE\n")
   -> 0.0042s
-- execute("DROP TRIGGER IF EXISTS trigger_8b88fb98bb6e\nON \"project_compliance_framework_settings\"\n")
NOTICE:  trigger "trigger_8b88fb98bb6e" for relation "project_compliance_framework_settings" does not exist, skipping
   -> 0.0002s
-- execute("CREATE TRIGGER trigger_8b88fb98bb6e\nBEFORE INSERT OR UPDATE\nON \"project_compliance_framework_settings\"\nFOR EACH ROW\nEXECUTE FUNCTION trigger_8b88fb98bb6e()\n")
   -> 0.0014s
== 20200924091958 RenameComplianceFrameworkForeignKey: reverted (0.0313s) =====

Does this MR meet the acceptance criteria?

Conformity

Availability and Testing

Security

If this MR contains changes to processing or storing of credentials or tokens, authorization and authentication methods and other items described in the security review guidelines:

  • Label as security and @ mention @gitlab-com/gl-security/appsec
  • The MR includes necessary changes to maintain consistency between UI, API, email, or other methods
  • Security reports checked/validated by a reviewer from the AppSec team

Mentions #251113 (closed)

Edited by Max Woolf

Merge request reports