diff --git a/dojo/db_migrations/0304_archive_columns.py b/dojo/db_migrations/0304_archive_columns.py new file mode 100644 index 00000000000..c7f8d8eaef5 --- /dev/null +++ b/dojo/db_migrations/0304_archive_columns.py @@ -0,0 +1,3339 @@ +# Generated by Django 5.2.17 on 2026-10-22 19:48 + +import pgtrigger.compiler +import pgtrigger.migrations +from django.db import migrations, models + +# Generated with `manage.py sqlmigrate` from the operations below, then frozen. +FORWARD_SQL = r""" +-- +-- Remove trigger insert_insert from model endpoint +-- +DROP TRIGGER IF EXISTS pgtrigger_insert_insert_c7973 ON "dojo_endpoint"; +-- +-- Remove trigger update_update from model endpoint +-- +DROP TRIGGER IF EXISTS pgtrigger_update_update_2b19a ON "dojo_endpoint"; +-- +-- Remove trigger delete_delete from model endpoint +-- +DROP TRIGGER IF EXISTS pgtrigger_delete_delete_dd1f9 ON "dojo_endpoint"; +-- +-- Remove trigger insert_insert from model engagement +-- +DROP TRIGGER IF EXISTS pgtrigger_insert_insert_125f1 ON "dojo_engagement"; +-- +-- Remove trigger update_update from model engagement +-- +DROP TRIGGER IF EXISTS pgtrigger_update_update_65136 ON "dojo_engagement"; +-- +-- Remove trigger delete_delete from model engagement +-- +DROP TRIGGER IF EXISTS pgtrigger_delete_delete_9f4df ON "dojo_engagement"; +-- +-- Remove trigger insert_insert from model finding +-- +DROP TRIGGER IF EXISTS pgtrigger_insert_insert_2fbbb ON "dojo_finding"; +-- +-- Remove trigger update_update from model finding +-- +DROP TRIGGER IF EXISTS pgtrigger_update_update_92175 ON "dojo_finding"; +-- +-- Remove trigger delete_delete from model finding +-- +DROP TRIGGER IF EXISTS pgtrigger_delete_delete_72933 ON "dojo_finding"; +-- +-- Remove trigger insert_insert from model finding_group +-- +DROP TRIGGER IF EXISTS pgtrigger_insert_insert_94bd2 ON "dojo_finding_group"; +-- +-- Remove trigger update_update from model finding_group +-- +DROP TRIGGER IF EXISTS pgtrigger_update_update_37b5f ON "dojo_finding_group"; +-- +-- Remove trigger delete_delete from model finding_group +-- +DROP TRIGGER IF EXISTS pgtrigger_delete_delete_24b41 ON "dojo_finding_group"; +-- +-- Remove trigger insert_insert from model product +-- +DROP TRIGGER IF EXISTS pgtrigger_insert_insert_d5d32 ON "dojo_product"; +-- +-- Remove trigger update_update from model product +-- +DROP TRIGGER IF EXISTS pgtrigger_update_update_e7040 ON "dojo_product"; +-- +-- Remove trigger delete_delete from model product +-- +DROP TRIGGER IF EXISTS pgtrigger_delete_delete_064dd ON "dojo_product"; +-- +-- Remove trigger insert_insert from model product_type +-- +DROP TRIGGER IF EXISTS pgtrigger_insert_insert_2d109 ON "dojo_product_type"; +-- +-- Remove trigger update_update from model product_type +-- +DROP TRIGGER IF EXISTS pgtrigger_update_update_a0136 ON "dojo_product_type"; +-- +-- Remove trigger delete_delete from model product_type +-- +DROP TRIGGER IF EXISTS pgtrigger_delete_delete_66b18 ON "dojo_product_type"; +-- +-- Remove trigger insert_insert from model test +-- +DROP TRIGGER IF EXISTS pgtrigger_insert_insert_ecfc1 ON "dojo_test"; +-- +-- Remove trigger update_update from model test +-- +DROP TRIGGER IF EXISTS pgtrigger_update_update_c40f8 ON "dojo_test"; +-- +-- Remove trigger delete_delete from model test +-- +DROP TRIGGER IF EXISTS pgtrigger_delete_delete_66d18 ON "dojo_test"; +-- +-- Add field archive_batch to app_analysis +-- +ALTER TABLE "dojo_app_analysis" ADD COLUMN "archive_batch" uuid NULL; +-- +-- Add field archived_at to app_analysis +-- +ALTER TABLE "dojo_app_analysis" ADD COLUMN "archived_at" timestamp with time zone NULL; +-- +-- Add field archive_batch to dojometa +-- +ALTER TABLE "dojo_dojometa" ADD COLUMN "archive_batch" uuid NULL; +-- +-- Add field archived_at to dojometa +-- +ALTER TABLE "dojo_dojometa" ADD COLUMN "archived_at" timestamp with time zone NULL; +-- +-- Add field archive_batch to endpoint +-- +ALTER TABLE "dojo_endpoint" ADD COLUMN "archive_batch" uuid NULL; +-- +-- Add field archived_at to endpoint +-- +ALTER TABLE "dojo_endpoint" ADD COLUMN "archived_at" timestamp with time zone NULL; +-- +-- Add field archive_batch to endpoint_status +-- +ALTER TABLE "dojo_endpoint_status" ADD COLUMN "archive_batch" uuid NULL; +-- +-- Add field archived_at to endpoint_status +-- +ALTER TABLE "dojo_endpoint_status" ADD COLUMN "archived_at" timestamp with time zone NULL; +-- +-- Add field archive_batch to endpointevent +-- +ALTER TABLE "dojo_endpointevent" ADD COLUMN "archive_batch" uuid NULL; +-- +-- Add field archived_at to endpointevent +-- +ALTER TABLE "dojo_endpointevent" ADD COLUMN "archived_at" timestamp with time zone NULL; +-- +-- Add field archive_batch to engagement +-- +ALTER TABLE "dojo_engagement" ADD COLUMN "archive_batch" uuid NULL; +-- +-- Add field archived_at to engagement +-- +ALTER TABLE "dojo_engagement" ADD COLUMN "archived_at" timestamp with time zone NULL; +-- +-- Add field archive_batch to engagement_presets +-- +ALTER TABLE "dojo_engagement_presets" ADD COLUMN "archive_batch" uuid NULL; +-- +-- Add field archived_at to engagement_presets +-- +ALTER TABLE "dojo_engagement_presets" ADD COLUMN "archived_at" timestamp with time zone NULL; +-- +-- Add field archive_batch to engagementevent +-- +ALTER TABLE "dojo_engagementevent" ADD COLUMN "archive_batch" uuid NULL; +-- +-- Add field archived_at to engagementevent +-- +ALTER TABLE "dojo_engagementevent" ADD COLUMN "archived_at" timestamp with time zone NULL; +-- +-- Add field archive_batch to finding +-- +ALTER TABLE "dojo_finding" ADD COLUMN "archive_batch" uuid NULL; +-- +-- Add field archived_at to finding +-- +ALTER TABLE "dojo_finding" ADD COLUMN "archived_at" timestamp with time zone NULL; +-- +-- Add field archive_batch to finding_group +-- +ALTER TABLE "dojo_finding_group" ADD COLUMN "archive_batch" uuid NULL; +-- +-- Add field archived_at to finding_group +-- +ALTER TABLE "dojo_finding_group" ADD COLUMN "archived_at" timestamp with time zone NULL; +-- +-- Add field archive_batch to finding_groupevent +-- +ALTER TABLE "dojo_finding_groupevent" ADD COLUMN "archive_batch" uuid NULL; +-- +-- Add field archived_at to finding_groupevent +-- +ALTER TABLE "dojo_finding_groupevent" ADD COLUMN "archived_at" timestamp with time zone NULL; +-- +-- Add field archive_batch to findingevent +-- +ALTER TABLE "dojo_findingevent" ADD COLUMN "archive_batch" uuid NULL; +-- +-- Add field archived_at to findingevent +-- +ALTER TABLE "dojo_findingevent" ADD COLUMN "archived_at" timestamp with time zone NULL; +-- +-- Add field archive_batch to findingvulnerabilityreference +-- +ALTER TABLE "dojo_findingvulnerabilityreference" ADD COLUMN "archive_batch" uuid NULL; +-- +-- Add field archived_at to findingvulnerabilityreference +-- +ALTER TABLE "dojo_findingvulnerabilityreference" ADD COLUMN "archived_at" timestamp with time zone NULL; +-- +-- Add field archive_batch to jira_issue +-- +ALTER TABLE "dojo_jira_issue" ADD COLUMN "archive_batch" uuid NULL; +-- +-- Add field archived_at to jira_issue +-- +ALTER TABLE "dojo_jira_issue" ADD COLUMN "archived_at" timestamp with time zone NULL; +-- +-- Add field archive_batch to jira_project +-- +ALTER TABLE "dojo_jira_project" ADD COLUMN "archive_batch" uuid NULL; +-- +-- Add field archived_at to jira_project +-- +ALTER TABLE "dojo_jira_project" ADD COLUMN "archived_at" timestamp with time zone NULL; +-- +-- Add field archive_batch to languages +-- +ALTER TABLE "dojo_languages" ADD COLUMN "archive_batch" uuid NULL; +-- +-- Add field archived_at to languages +-- +ALTER TABLE "dojo_languages" ADD COLUMN "archived_at" timestamp with time zone NULL; +-- +-- Add field archive_batch to locationfindingreference +-- +ALTER TABLE "dojo_locationfindingreference" ADD COLUMN "archive_batch" uuid NULL; +-- +-- Add field archived_at to locationfindingreference +-- +ALTER TABLE "dojo_locationfindingreference" ADD COLUMN "archived_at" timestamp with time zone NULL; +-- +-- Add field archive_batch to locationproductreference +-- +ALTER TABLE "dojo_locationproductreference" ADD COLUMN "archive_batch" uuid NULL; +-- +-- Add field archived_at to locationproductreference +-- +ALTER TABLE "dojo_locationproductreference" ADD COLUMN "archived_at" timestamp with time zone NULL; +-- +-- Add field archive_batch to objects_product +-- +ALTER TABLE "dojo_objects_product" ADD COLUMN "archive_batch" uuid NULL; +-- +-- Add field archived_at to objects_product +-- +ALTER TABLE "dojo_objects_product" ADD COLUMN "archived_at" timestamp with time zone NULL; +-- +-- Add field archive_batch to product +-- +ALTER TABLE "dojo_product" ADD COLUMN "archive_batch" uuid NULL; +-- +-- Add field archived_at to product +-- +ALTER TABLE "dojo_product" ADD COLUMN "archived_at" timestamp with time zone NULL; +-- +-- Add field archive_batch to product_api_scan_configuration +-- +ALTER TABLE "dojo_product_api_scan_configuration" ADD COLUMN "archive_batch" uuid NULL; +-- +-- Add field archived_at to product_api_scan_configuration +-- +ALTER TABLE "dojo_product_api_scan_configuration" ADD COLUMN "archived_at" timestamp with time zone NULL; +-- +-- Add field archive_batch to product_type +-- +ALTER TABLE "dojo_product_type" ADD COLUMN "archive_batch" uuid NULL; +-- +-- Add field archived_at to product_type +-- +ALTER TABLE "dojo_product_type" ADD COLUMN "archived_at" timestamp with time zone NULL; +-- +-- Add field archive_batch to product_typeevent +-- +ALTER TABLE "dojo_product_typeevent" ADD COLUMN "archive_batch" uuid NULL; +-- +-- Add field archived_at to product_typeevent +-- +ALTER TABLE "dojo_product_typeevent" ADD COLUMN "archived_at" timestamp with time zone NULL; +-- +-- Add field archive_batch to productevent +-- +ALTER TABLE "dojo_productevent" ADD COLUMN "archive_batch" uuid NULL; +-- +-- Add field archived_at to productevent +-- +ALTER TABLE "dojo_productevent" ADD COLUMN "archived_at" timestamp with time zone NULL; +-- +-- Add field archive_batch to test +-- +ALTER TABLE "dojo_test" ADD COLUMN "archive_batch" uuid NULL; +-- +-- Add field archived_at to test +-- +ALTER TABLE "dojo_test" ADD COLUMN "archived_at" timestamp with time zone NULL; +-- +-- Add field archive_batch to test_import +-- +ALTER TABLE "dojo_test_import" ADD COLUMN "archive_batch" uuid NULL; +-- +-- Add field archived_at to test_import +-- +ALTER TABLE "dojo_test_import" ADD COLUMN "archived_at" timestamp with time zone NULL; +-- +-- Add field archive_batch to test_import_finding_action +-- +ALTER TABLE "dojo_test_import_finding_action" ADD COLUMN "archive_batch" uuid NULL; +-- +-- Add field archived_at to test_import_finding_action +-- +ALTER TABLE "dojo_test_import_finding_action" ADD COLUMN "archived_at" timestamp with time zone NULL; +-- +-- Add field archive_batch to testevent +-- +ALTER TABLE "dojo_testevent" ADD COLUMN "archive_batch" uuid NULL; +-- +-- Add field archived_at to testevent +-- +ALTER TABLE "dojo_testevent" ADD COLUMN "archived_at" timestamp with time zone NULL; +-- +-- Add field archive_batch to tool_product_settings +-- +ALTER TABLE "dojo_tool_product_settings" ADD COLUMN "archive_batch" uuid NULL; +-- +-- Add field archived_at to tool_product_settings +-- +ALTER TABLE "dojo_tool_product_settings" ADD COLUMN "archived_at" timestamp with time zone NULL; +-- +-- Add field archive_batch to vulnerability_id +-- +ALTER TABLE "dojo_vulnerability_id" ADD COLUMN "archive_batch" uuid NULL; +-- +-- Add field archived_at to vulnerability_id +-- +ALTER TABLE "dojo_vulnerability_id" ADD COLUMN "archived_at" timestamp with time zone NULL; +-- +-- Create trigger insert_insert on model endpoint +-- + + CREATE OR REPLACE FUNCTION "public"._pgtrigger_should_ignore( + trigger_name NAME + ) + RETURNS BOOLEAN AS $$ + DECLARE + _pgtrigger_ignore TEXT[]; + _result BOOLEAN; + BEGIN + BEGIN + SELECT INTO _pgtrigger_ignore + CURRENT_SETTING('pgtrigger.ignore'); + EXCEPTION WHEN OTHERS THEN + END; + IF _pgtrigger_ignore IS NOT NULL THEN + SELECT trigger_name = ANY(_pgtrigger_ignore) + INTO _result; + RETURN _result; + ELSE + RETURN FALSE; + END IF; + END; + $$ LANGUAGE plpgsql; + + CREATE OR REPLACE FUNCTION pgtrigger_insert_insert_c7973() + RETURNS TRIGGER AS $$ + + BEGIN + IF ("public"._pgtrigger_should_ignore(TG_NAME) IS TRUE) THEN + IF (TG_OP = 'DELETE') THEN + RETURN OLD; + ELSE + RETURN NEW; + END IF; + END IF; + INSERT INTO "dojo_endpointevent" ("archive_batch", "archived_at", "fragment", "host", "id", "path", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "port", "product_id", "protocol", "query", "userinfo") VALUES (NEW."archive_batch", NEW."archived_at", NEW."fragment", NEW."host", NEW."id", NEW."path", _pgh_attach_context(), NOW(), 'insert', NEW."id", NEW."port", NEW."product_id", NEW."protocol", NEW."query", NEW."userinfo"); RETURN NULL; + END; + $$ LANGUAGE plpgsql; + + DROP TRIGGER IF EXISTS pgtrigger_insert_insert_c7973 ON "dojo_endpoint"; + CREATE TRIGGER pgtrigger_insert_insert_c7973 + AFTER INSERT ON "dojo_endpoint" + + + FOR EACH ROW + EXECUTE PROCEDURE pgtrigger_insert_insert_c7973(); + + COMMENT ON TRIGGER pgtrigger_insert_insert_c7973 ON "dojo_endpoint" IS '4aa86c99a53e2afc8a2e7bbc9dce7e87cfe93c99'; + +-- +-- Create trigger update_update on model endpoint +-- + + CREATE OR REPLACE FUNCTION "public"._pgtrigger_should_ignore( + trigger_name NAME + ) + RETURNS BOOLEAN AS $$ + DECLARE + _pgtrigger_ignore TEXT[]; + _result BOOLEAN; + BEGIN + BEGIN + SELECT INTO _pgtrigger_ignore + CURRENT_SETTING('pgtrigger.ignore'); + EXCEPTION WHEN OTHERS THEN + END; + IF _pgtrigger_ignore IS NOT NULL THEN + SELECT trigger_name = ANY(_pgtrigger_ignore) + INTO _result; + RETURN _result; + ELSE + RETURN FALSE; + END IF; + END; + $$ LANGUAGE plpgsql; + + CREATE OR REPLACE FUNCTION pgtrigger_update_update_2b19a() + RETURNS TRIGGER AS $$ + + BEGIN + IF ("public"._pgtrigger_should_ignore(TG_NAME) IS TRUE) THEN + IF (TG_OP = 'DELETE') THEN + RETURN OLD; + ELSE + RETURN NEW; + END IF; + END IF; + INSERT INTO "dojo_endpointevent" ("archive_batch", "archived_at", "fragment", "host", "id", "path", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "port", "product_id", "protocol", "query", "userinfo") VALUES (NEW."archive_batch", NEW."archived_at", NEW."fragment", NEW."host", NEW."id", NEW."path", _pgh_attach_context(), NOW(), 'update', NEW."id", NEW."port", NEW."product_id", NEW."protocol", NEW."query", NEW."userinfo"); RETURN NULL; + END; + $$ LANGUAGE plpgsql; + + DROP TRIGGER IF EXISTS pgtrigger_update_update_2b19a ON "dojo_endpoint"; + CREATE TRIGGER pgtrigger_update_update_2b19a + AFTER UPDATE ON "dojo_endpoint" + + + FOR EACH ROW WHEN (OLD.* IS DISTINCT FROM NEW.*) + EXECUTE PROCEDURE pgtrigger_update_update_2b19a(); + + COMMENT ON TRIGGER pgtrigger_update_update_2b19a ON "dojo_endpoint" IS '187a4d67775847794459c2d4249fe13e333b2118'; + +-- +-- Create trigger delete_delete on model endpoint +-- + + CREATE OR REPLACE FUNCTION "public"._pgtrigger_should_ignore( + trigger_name NAME + ) + RETURNS BOOLEAN AS $$ + DECLARE + _pgtrigger_ignore TEXT[]; + _result BOOLEAN; + BEGIN + BEGIN + SELECT INTO _pgtrigger_ignore + CURRENT_SETTING('pgtrigger.ignore'); + EXCEPTION WHEN OTHERS THEN + END; + IF _pgtrigger_ignore IS NOT NULL THEN + SELECT trigger_name = ANY(_pgtrigger_ignore) + INTO _result; + RETURN _result; + ELSE + RETURN FALSE; + END IF; + END; + $$ LANGUAGE plpgsql; + + CREATE OR REPLACE FUNCTION pgtrigger_delete_delete_dd1f9() + RETURNS TRIGGER AS $$ + + BEGIN + IF ("public"._pgtrigger_should_ignore(TG_NAME) IS TRUE) THEN + IF (TG_OP = 'DELETE') THEN + RETURN OLD; + ELSE + RETURN NEW; + END IF; + END IF; + INSERT INTO "dojo_endpointevent" ("archive_batch", "archived_at", "fragment", "host", "id", "path", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "port", "product_id", "protocol", "query", "userinfo") VALUES (OLD."archive_batch", OLD."archived_at", OLD."fragment", OLD."host", OLD."id", OLD."path", _pgh_attach_context(), NOW(), 'delete', OLD."id", OLD."port", OLD."product_id", OLD."protocol", OLD."query", OLD."userinfo"); RETURN NULL; + END; + $$ LANGUAGE plpgsql; + + DROP TRIGGER IF EXISTS pgtrigger_delete_delete_dd1f9 ON "dojo_endpoint"; + CREATE TRIGGER pgtrigger_delete_delete_dd1f9 + AFTER DELETE ON "dojo_endpoint" + + + FOR EACH ROW + EXECUTE PROCEDURE pgtrigger_delete_delete_dd1f9(); + + COMMENT ON TRIGGER pgtrigger_delete_delete_dd1f9 ON "dojo_endpoint" IS 'c30fc33fac55999df702b7c9c249f64513bf7497'; + +-- +-- Create trigger insert_insert on model engagement +-- + + CREATE OR REPLACE FUNCTION "public"._pgtrigger_should_ignore( + trigger_name NAME + ) + RETURNS BOOLEAN AS $$ + DECLARE + _pgtrigger_ignore TEXT[]; + _result BOOLEAN; + BEGIN + BEGIN + SELECT INTO _pgtrigger_ignore + CURRENT_SETTING('pgtrigger.ignore'); + EXCEPTION WHEN OTHERS THEN + END; + IF _pgtrigger_ignore IS NOT NULL THEN + SELECT trigger_name = ANY(_pgtrigger_ignore) + INTO _result; + RETURN _result; + ELSE + RETURN FALSE; + END IF; + END; + $$ LANGUAGE plpgsql; + + CREATE OR REPLACE FUNCTION pgtrigger_insert_insert_125f1() + RETURNS TRIGGER AS $$ + + BEGIN + IF ("public"._pgtrigger_should_ignore(TG_NAME) IS TRUE) THEN + IF (TG_OP = 'DELETE') THEN + RETURN OLD; + ELSE + RETURN NEW; + END IF; + END IF; + INSERT INTO "dojo_engagementevent" ("active", "api_test", "archive_batch", "archived_at", "branch_tag", "build_id", "check_list", "cicd_build_server_id", "cicd_orchestration_engine_id", "cicd_scm_server_id", "commit_hash", "created", "deduplication_on_engagement", "description", "done_testing", "engagement_type", "first_contacted", "id", "lead_id", "name", "pen_test", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "preset_id", "product_id", "progress", "reason", "report_type_id", "requester_id", "source_code_management_uri", "status", "target_end", "target_start", "test_strategy", "threat_model", "tmodel_path", "tracker", "updated", "version") VALUES (NEW."active", NEW."api_test", NEW."archive_batch", NEW."archived_at", NEW."branch_tag", NEW."build_id", NEW."check_list", NEW."cicd_build_server_id", NEW."cicd_orchestration_engine_id", NEW."cicd_scm_server_id", NEW."commit_hash", NEW."created", NEW."deduplication_on_engagement", NEW."description", NEW."done_testing", NEW."engagement_type", NEW."first_contacted", NEW."id", NEW."lead_id", NEW."name", NEW."pen_test", _pgh_attach_context(), NOW(), 'insert', NEW."id", NEW."preset_id", NEW."product_id", NEW."progress", NEW."reason", NEW."report_type_id", NEW."requester_id", NEW."source_code_management_uri", NEW."status", NEW."target_end", NEW."target_start", NEW."test_strategy", NEW."threat_model", NEW."tmodel_path", NEW."tracker", NEW."updated", NEW."version"); RETURN NULL; + END; + $$ LANGUAGE plpgsql; + + DROP TRIGGER IF EXISTS pgtrigger_insert_insert_125f1 ON "dojo_engagement"; + CREATE TRIGGER pgtrigger_insert_insert_125f1 + AFTER INSERT ON "dojo_engagement" + + + FOR EACH ROW + EXECUTE PROCEDURE pgtrigger_insert_insert_125f1(); + + COMMENT ON TRIGGER pgtrigger_insert_insert_125f1 ON "dojo_engagement" IS '5b48232cfe7dc67a91eebfd023a4ccb6eb920c39'; + +-- +-- Create trigger update_update on model engagement +-- + + CREATE OR REPLACE FUNCTION "public"._pgtrigger_should_ignore( + trigger_name NAME + ) + RETURNS BOOLEAN AS $$ + DECLARE + _pgtrigger_ignore TEXT[]; + _result BOOLEAN; + BEGIN + BEGIN + SELECT INTO _pgtrigger_ignore + CURRENT_SETTING('pgtrigger.ignore'); + EXCEPTION WHEN OTHERS THEN + END; + IF _pgtrigger_ignore IS NOT NULL THEN + SELECT trigger_name = ANY(_pgtrigger_ignore) + INTO _result; + RETURN _result; + ELSE + RETURN FALSE; + END IF; + END; + $$ LANGUAGE plpgsql; + + CREATE OR REPLACE FUNCTION pgtrigger_update_update_65136() + RETURNS TRIGGER AS $$ + + BEGIN + IF ("public"._pgtrigger_should_ignore(TG_NAME) IS TRUE) THEN + IF (TG_OP = 'DELETE') THEN + RETURN OLD; + ELSE + RETURN NEW; + END IF; + END IF; + INSERT INTO "dojo_engagementevent" ("active", "api_test", "archive_batch", "archived_at", "branch_tag", "build_id", "check_list", "cicd_build_server_id", "cicd_orchestration_engine_id", "cicd_scm_server_id", "commit_hash", "created", "deduplication_on_engagement", "description", "done_testing", "engagement_type", "first_contacted", "id", "lead_id", "name", "pen_test", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "preset_id", "product_id", "progress", "reason", "report_type_id", "requester_id", "source_code_management_uri", "status", "target_end", "target_start", "test_strategy", "threat_model", "tmodel_path", "tracker", "updated", "version") VALUES (NEW."active", NEW."api_test", NEW."archive_batch", NEW."archived_at", NEW."branch_tag", NEW."build_id", NEW."check_list", NEW."cicd_build_server_id", NEW."cicd_orchestration_engine_id", NEW."cicd_scm_server_id", NEW."commit_hash", NEW."created", NEW."deduplication_on_engagement", NEW."description", NEW."done_testing", NEW."engagement_type", NEW."first_contacted", NEW."id", NEW."lead_id", NEW."name", NEW."pen_test", _pgh_attach_context(), NOW(), 'update', NEW."id", NEW."preset_id", NEW."product_id", NEW."progress", NEW."reason", NEW."report_type_id", NEW."requester_id", NEW."source_code_management_uri", NEW."status", NEW."target_end", NEW."target_start", NEW."test_strategy", NEW."threat_model", NEW."tmodel_path", NEW."tracker", NEW."updated", NEW."version"); RETURN NULL; + END; + $$ LANGUAGE plpgsql; + + DROP TRIGGER IF EXISTS pgtrigger_update_update_65136 ON "dojo_engagement"; + CREATE TRIGGER pgtrigger_update_update_65136 + AFTER UPDATE ON "dojo_engagement" + + + FOR EACH ROW WHEN (OLD."active" IS DISTINCT FROM (NEW."active") OR OLD."api_test" IS DISTINCT FROM (NEW."api_test") OR OLD."archive_batch" IS DISTINCT FROM (NEW."archive_batch") OR OLD."archived_at" IS DISTINCT FROM (NEW."archived_at") OR OLD."branch_tag" IS DISTINCT FROM (NEW."branch_tag") OR OLD."build_id" IS DISTINCT FROM (NEW."build_id") OR OLD."check_list" IS DISTINCT FROM (NEW."check_list") OR OLD."cicd_build_server_id" IS DISTINCT FROM (NEW."cicd_build_server_id") OR OLD."cicd_orchestration_engine_id" IS DISTINCT FROM (NEW."cicd_orchestration_engine_id") OR OLD."cicd_scm_server_id" IS DISTINCT FROM (NEW."cicd_scm_server_id") OR OLD."commit_hash" IS DISTINCT FROM (NEW."commit_hash") OR OLD."deduplication_on_engagement" IS DISTINCT FROM (NEW."deduplication_on_engagement") OR OLD."description" IS DISTINCT FROM (NEW."description") OR OLD."done_testing" IS DISTINCT FROM (NEW."done_testing") OR OLD."engagement_type" IS DISTINCT FROM (NEW."engagement_type") OR OLD."first_contacted" IS DISTINCT FROM (NEW."first_contacted") OR OLD."id" IS DISTINCT FROM (NEW."id") OR OLD."lead_id" IS DISTINCT FROM (NEW."lead_id") OR OLD."name" IS DISTINCT FROM (NEW."name") OR OLD."pen_test" IS DISTINCT FROM (NEW."pen_test") OR OLD."preset_id" IS DISTINCT FROM (NEW."preset_id") OR OLD."product_id" IS DISTINCT FROM (NEW."product_id") OR OLD."progress" IS DISTINCT FROM (NEW."progress") OR OLD."reason" IS DISTINCT FROM (NEW."reason") OR OLD."report_type_id" IS DISTINCT FROM (NEW."report_type_id") OR OLD."requester_id" IS DISTINCT FROM (NEW."requester_id") OR OLD."source_code_management_uri" IS DISTINCT FROM (NEW."source_code_management_uri") OR OLD."status" IS DISTINCT FROM (NEW."status") OR OLD."target_end" IS DISTINCT FROM (NEW."target_end") OR OLD."target_start" IS DISTINCT FROM (NEW."target_start") OR OLD."test_strategy" IS DISTINCT FROM (NEW."test_strategy") OR OLD."threat_model" IS DISTINCT FROM (NEW."threat_model") OR OLD."tmodel_path" IS DISTINCT FROM (NEW."tmodel_path") OR OLD."tracker" IS DISTINCT FROM (NEW."tracker") OR OLD."version" IS DISTINCT FROM (NEW."version")) + EXECUTE PROCEDURE pgtrigger_update_update_65136(); + + COMMENT ON TRIGGER pgtrigger_update_update_65136 ON "dojo_engagement" IS '8990b78ab9370e3cd1ec2b85dd89d52834d5aaf6'; + +-- +-- Create trigger delete_delete on model engagement +-- + + CREATE OR REPLACE FUNCTION "public"._pgtrigger_should_ignore( + trigger_name NAME + ) + RETURNS BOOLEAN AS $$ + DECLARE + _pgtrigger_ignore TEXT[]; + _result BOOLEAN; + BEGIN + BEGIN + SELECT INTO _pgtrigger_ignore + CURRENT_SETTING('pgtrigger.ignore'); + EXCEPTION WHEN OTHERS THEN + END; + IF _pgtrigger_ignore IS NOT NULL THEN + SELECT trigger_name = ANY(_pgtrigger_ignore) + INTO _result; + RETURN _result; + ELSE + RETURN FALSE; + END IF; + END; + $$ LANGUAGE plpgsql; + + CREATE OR REPLACE FUNCTION pgtrigger_delete_delete_9f4df() + RETURNS TRIGGER AS $$ + + BEGIN + IF ("public"._pgtrigger_should_ignore(TG_NAME) IS TRUE) THEN + IF (TG_OP = 'DELETE') THEN + RETURN OLD; + ELSE + RETURN NEW; + END IF; + END IF; + INSERT INTO "dojo_engagementevent" ("active", "api_test", "archive_batch", "archived_at", "branch_tag", "build_id", "check_list", "cicd_build_server_id", "cicd_orchestration_engine_id", "cicd_scm_server_id", "commit_hash", "created", "deduplication_on_engagement", "description", "done_testing", "engagement_type", "first_contacted", "id", "lead_id", "name", "pen_test", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "preset_id", "product_id", "progress", "reason", "report_type_id", "requester_id", "source_code_management_uri", "status", "target_end", "target_start", "test_strategy", "threat_model", "tmodel_path", "tracker", "updated", "version") VALUES (OLD."active", OLD."api_test", OLD."archive_batch", OLD."archived_at", OLD."branch_tag", OLD."build_id", OLD."check_list", OLD."cicd_build_server_id", OLD."cicd_orchestration_engine_id", OLD."cicd_scm_server_id", OLD."commit_hash", OLD."created", OLD."deduplication_on_engagement", OLD."description", OLD."done_testing", OLD."engagement_type", OLD."first_contacted", OLD."id", OLD."lead_id", OLD."name", OLD."pen_test", _pgh_attach_context(), NOW(), 'delete', OLD."id", OLD."preset_id", OLD."product_id", OLD."progress", OLD."reason", OLD."report_type_id", OLD."requester_id", OLD."source_code_management_uri", OLD."status", OLD."target_end", OLD."target_start", OLD."test_strategy", OLD."threat_model", OLD."tmodel_path", OLD."tracker", OLD."updated", OLD."version"); RETURN NULL; + END; + $$ LANGUAGE plpgsql; + + DROP TRIGGER IF EXISTS pgtrigger_delete_delete_9f4df ON "dojo_engagement"; + CREATE TRIGGER pgtrigger_delete_delete_9f4df + AFTER DELETE ON "dojo_engagement" + + + FOR EACH ROW + EXECUTE PROCEDURE pgtrigger_delete_delete_9f4df(); + + COMMENT ON TRIGGER pgtrigger_delete_delete_9f4df ON "dojo_engagement" IS '0de881cdff9409808f24eb0258bdd61ae9ddc60e'; + +-- +-- Create trigger insert_insert on model finding +-- + + CREATE OR REPLACE FUNCTION "public"._pgtrigger_should_ignore( + trigger_name NAME + ) + RETURNS BOOLEAN AS $$ + DECLARE + _pgtrigger_ignore TEXT[]; + _result BOOLEAN; + BEGIN + BEGIN + SELECT INTO _pgtrigger_ignore + CURRENT_SETTING('pgtrigger.ignore'); + EXCEPTION WHEN OTHERS THEN + END; + IF _pgtrigger_ignore IS NOT NULL THEN + SELECT trigger_name = ANY(_pgtrigger_ignore) + INTO _result; + RETURN _result; + ELSE + RETURN FALSE; + END IF; + END; + $$ LANGUAGE plpgsql; + + CREATE OR REPLACE FUNCTION pgtrigger_insert_insert_2fbbb() + RETURNS TRIGGER AS $$ + + BEGIN + IF ("public"._pgtrigger_should_ignore(TG_NAME) IS TRUE) THEN + IF (TG_OP = 'DELETE') THEN + RETURN OLD; + ELSE + RETURN NEW; + END IF; + END IF; + INSERT INTO "dojo_findingevent" ("active", "archive_batch", "archived_at", "component_name", "component_version", "created", "cve", "cvssv3", "cvssv3_score", "cvssv4", "cvssv4_score", "cwe", "date", "defect_review_requested_by_id", "description", "duplicate", "duplicate_finding_id", "dynamic_finding", "effort_for_fixing", "epss_percentile", "epss_score", "false_p", "file_path", "fix_available", "fix_version", "hash_code", "id", "impact", "is_mitigated", "kev_date", "known_exploited", "last_reviewed", "last_reviewed_by_id", "last_status_update", "line", "mitigated", "mitigated_by_id", "mitigation", "nb_occurences", "numerical_severity", "out_of_scope", "param", "payload", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "planned_remediation_date", "planned_remediation_version", "publish_date", "ransomware_used", "refs", "reporter_id", "review_requested_by_id", "risk_accepted", "sast_sink_object", "sast_source_file_path", "sast_source_line", "sast_source_object", "scanner_confidence", "service", "severity", "severity_justification", "sla_expiration_date", "sla_start_date", "sonarqube_issue_id", "static_finding", "steps_to_reproduce", "test_id", "thread_id", "title", "under_defect_review", "under_review", "unique_id_from_tool", "updated", "url", "verified", "vuln_id_from_tool") VALUES (NEW."active", NEW."archive_batch", NEW."archived_at", NEW."component_name", NEW."component_version", NEW."created", NEW."cve", NEW."cvssv3", NEW."cvssv3_score", NEW."cvssv4", NEW."cvssv4_score", NEW."cwe", NEW."date", NEW."defect_review_requested_by_id", NEW."description", NEW."duplicate", NEW."duplicate_finding_id", NEW."dynamic_finding", NEW."effort_for_fixing", NEW."epss_percentile", NEW."epss_score", NEW."false_p", NEW."file_path", NEW."fix_available", NEW."fix_version", NEW."hash_code", NEW."id", NEW."impact", NEW."is_mitigated", NEW."kev_date", NEW."known_exploited", NEW."last_reviewed", NEW."last_reviewed_by_id", NEW."last_status_update", NEW."line", NEW."mitigated", NEW."mitigated_by_id", NEW."mitigation", NEW."nb_occurences", NEW."numerical_severity", NEW."out_of_scope", NEW."param", NEW."payload", _pgh_attach_context(), NOW(), 'insert', NEW."id", NEW."planned_remediation_date", NEW."planned_remediation_version", NEW."publish_date", NEW."ransomware_used", NEW."refs", NEW."reporter_id", NEW."review_requested_by_id", NEW."risk_accepted", NEW."sast_sink_object", NEW."sast_source_file_path", NEW."sast_source_line", NEW."sast_source_object", NEW."scanner_confidence", NEW."service", NEW."severity", NEW."severity_justification", NEW."sla_expiration_date", NEW."sla_start_date", NEW."sonarqube_issue_id", NEW."static_finding", NEW."steps_to_reproduce", NEW."test_id", NEW."thread_id", NEW."title", NEW."under_defect_review", NEW."under_review", NEW."unique_id_from_tool", NEW."updated", NEW."url", NEW."verified", NEW."vuln_id_from_tool"); RETURN NULL; + END; + $$ LANGUAGE plpgsql; + + DROP TRIGGER IF EXISTS pgtrigger_insert_insert_2fbbb ON "dojo_finding"; + CREATE TRIGGER pgtrigger_insert_insert_2fbbb + AFTER INSERT ON "dojo_finding" + + + FOR EACH ROW + EXECUTE PROCEDURE pgtrigger_insert_insert_2fbbb(); + + COMMENT ON TRIGGER pgtrigger_insert_insert_2fbbb ON "dojo_finding" IS 'bfca827e3bf9d38085346f34984b62bfc9efa036'; + +-- +-- Create trigger update_update on model finding +-- + + CREATE OR REPLACE FUNCTION "public"._pgtrigger_should_ignore( + trigger_name NAME + ) + RETURNS BOOLEAN AS $$ + DECLARE + _pgtrigger_ignore TEXT[]; + _result BOOLEAN; + BEGIN + BEGIN + SELECT INTO _pgtrigger_ignore + CURRENT_SETTING('pgtrigger.ignore'); + EXCEPTION WHEN OTHERS THEN + END; + IF _pgtrigger_ignore IS NOT NULL THEN + SELECT trigger_name = ANY(_pgtrigger_ignore) + INTO _result; + RETURN _result; + ELSE + RETURN FALSE; + END IF; + END; + $$ LANGUAGE plpgsql; + + CREATE OR REPLACE FUNCTION pgtrigger_update_update_92175() + RETURNS TRIGGER AS $$ + + BEGIN + IF ("public"._pgtrigger_should_ignore(TG_NAME) IS TRUE) THEN + IF (TG_OP = 'DELETE') THEN + RETURN OLD; + ELSE + RETURN NEW; + END IF; + END IF; + INSERT INTO "dojo_findingevent" ("active", "archive_batch", "archived_at", "component_name", "component_version", "created", "cve", "cvssv3", "cvssv3_score", "cvssv4", "cvssv4_score", "cwe", "date", "defect_review_requested_by_id", "description", "duplicate", "duplicate_finding_id", "dynamic_finding", "effort_for_fixing", "epss_percentile", "epss_score", "false_p", "file_path", "fix_available", "fix_version", "hash_code", "id", "impact", "is_mitigated", "kev_date", "known_exploited", "last_reviewed", "last_reviewed_by_id", "last_status_update", "line", "mitigated", "mitigated_by_id", "mitigation", "nb_occurences", "numerical_severity", "out_of_scope", "param", "payload", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "planned_remediation_date", "planned_remediation_version", "publish_date", "ransomware_used", "refs", "reporter_id", "review_requested_by_id", "risk_accepted", "sast_sink_object", "sast_source_file_path", "sast_source_line", "sast_source_object", "scanner_confidence", "service", "severity", "severity_justification", "sla_expiration_date", "sla_start_date", "sonarqube_issue_id", "static_finding", "steps_to_reproduce", "test_id", "thread_id", "title", "under_defect_review", "under_review", "unique_id_from_tool", "updated", "url", "verified", "vuln_id_from_tool") VALUES (NEW."active", NEW."archive_batch", NEW."archived_at", NEW."component_name", NEW."component_version", NEW."created", NEW."cve", NEW."cvssv3", NEW."cvssv3_score", NEW."cvssv4", NEW."cvssv4_score", NEW."cwe", NEW."date", NEW."defect_review_requested_by_id", NEW."description", NEW."duplicate", NEW."duplicate_finding_id", NEW."dynamic_finding", NEW."effort_for_fixing", NEW."epss_percentile", NEW."epss_score", NEW."false_p", NEW."file_path", NEW."fix_available", NEW."fix_version", NEW."hash_code", NEW."id", NEW."impact", NEW."is_mitigated", NEW."kev_date", NEW."known_exploited", NEW."last_reviewed", NEW."last_reviewed_by_id", NEW."last_status_update", NEW."line", NEW."mitigated", NEW."mitigated_by_id", NEW."mitigation", NEW."nb_occurences", NEW."numerical_severity", NEW."out_of_scope", NEW."param", NEW."payload", _pgh_attach_context(), NOW(), 'update', NEW."id", NEW."planned_remediation_date", NEW."planned_remediation_version", NEW."publish_date", NEW."ransomware_used", NEW."refs", NEW."reporter_id", NEW."review_requested_by_id", NEW."risk_accepted", NEW."sast_sink_object", NEW."sast_source_file_path", NEW."sast_source_line", NEW."sast_source_object", NEW."scanner_confidence", NEW."service", NEW."severity", NEW."severity_justification", NEW."sla_expiration_date", NEW."sla_start_date", NEW."sonarqube_issue_id", NEW."static_finding", NEW."steps_to_reproduce", NEW."test_id", NEW."thread_id", NEW."title", NEW."under_defect_review", NEW."under_review", NEW."unique_id_from_tool", NEW."updated", NEW."url", NEW."verified", NEW."vuln_id_from_tool"); RETURN NULL; + END; + $$ LANGUAGE plpgsql; + + DROP TRIGGER IF EXISTS pgtrigger_update_update_92175 ON "dojo_finding"; + CREATE TRIGGER pgtrigger_update_update_92175 + AFTER UPDATE ON "dojo_finding" + + + FOR EACH ROW WHEN (OLD."active" IS DISTINCT FROM (NEW."active") OR OLD."archive_batch" IS DISTINCT FROM (NEW."archive_batch") OR OLD."archived_at" IS DISTINCT FROM (NEW."archived_at") OR OLD."component_name" IS DISTINCT FROM (NEW."component_name") OR OLD."component_version" IS DISTINCT FROM (NEW."component_version") OR OLD."cve" IS DISTINCT FROM (NEW."cve") OR OLD."cvssv3" IS DISTINCT FROM (NEW."cvssv3") OR OLD."cvssv3_score" IS DISTINCT FROM (NEW."cvssv3_score") OR OLD."cvssv4" IS DISTINCT FROM (NEW."cvssv4") OR OLD."cvssv4_score" IS DISTINCT FROM (NEW."cvssv4_score") OR OLD."cwe" IS DISTINCT FROM (NEW."cwe") OR OLD."date" IS DISTINCT FROM (NEW."date") OR OLD."defect_review_requested_by_id" IS DISTINCT FROM (NEW."defect_review_requested_by_id") OR OLD."description" IS DISTINCT FROM (NEW."description") OR OLD."duplicate" IS DISTINCT FROM (NEW."duplicate") OR OLD."duplicate_finding_id" IS DISTINCT FROM (NEW."duplicate_finding_id") OR OLD."dynamic_finding" IS DISTINCT FROM (NEW."dynamic_finding") OR OLD."effort_for_fixing" IS DISTINCT FROM (NEW."effort_for_fixing") OR OLD."epss_percentile" IS DISTINCT FROM (NEW."epss_percentile") OR OLD."epss_score" IS DISTINCT FROM (NEW."epss_score") OR OLD."false_p" IS DISTINCT FROM (NEW."false_p") OR OLD."file_path" IS DISTINCT FROM (NEW."file_path") OR OLD."fix_available" IS DISTINCT FROM (NEW."fix_available") OR OLD."fix_version" IS DISTINCT FROM (NEW."fix_version") OR OLD."hash_code" IS DISTINCT FROM (NEW."hash_code") OR OLD."id" IS DISTINCT FROM (NEW."id") OR OLD."impact" IS DISTINCT FROM (NEW."impact") OR OLD."is_mitigated" IS DISTINCT FROM (NEW."is_mitigated") OR OLD."kev_date" IS DISTINCT FROM (NEW."kev_date") OR OLD."known_exploited" IS DISTINCT FROM (NEW."known_exploited") OR OLD."last_reviewed" IS DISTINCT FROM (NEW."last_reviewed") OR OLD."last_reviewed_by_id" IS DISTINCT FROM (NEW."last_reviewed_by_id") OR OLD."line" IS DISTINCT FROM (NEW."line") OR OLD."mitigated" IS DISTINCT FROM (NEW."mitigated") OR OLD."mitigated_by_id" IS DISTINCT FROM (NEW."mitigated_by_id") OR OLD."mitigation" IS DISTINCT FROM (NEW."mitigation") OR OLD."nb_occurences" IS DISTINCT FROM (NEW."nb_occurences") OR OLD."numerical_severity" IS DISTINCT FROM (NEW."numerical_severity") OR OLD."out_of_scope" IS DISTINCT FROM (NEW."out_of_scope") OR OLD."param" IS DISTINCT FROM (NEW."param") OR OLD."payload" IS DISTINCT FROM (NEW."payload") OR OLD."planned_remediation_date" IS DISTINCT FROM (NEW."planned_remediation_date") OR OLD."planned_remediation_version" IS DISTINCT FROM (NEW."planned_remediation_version") OR OLD."publish_date" IS DISTINCT FROM (NEW."publish_date") OR OLD."ransomware_used" IS DISTINCT FROM (NEW."ransomware_used") OR OLD."refs" IS DISTINCT FROM (NEW."refs") OR OLD."reporter_id" IS DISTINCT FROM (NEW."reporter_id") OR OLD."review_requested_by_id" IS DISTINCT FROM (NEW."review_requested_by_id") OR OLD."risk_accepted" IS DISTINCT FROM (NEW."risk_accepted") OR OLD."sast_sink_object" IS DISTINCT FROM (NEW."sast_sink_object") OR OLD."sast_source_file_path" IS DISTINCT FROM (NEW."sast_source_file_path") OR OLD."sast_source_line" IS DISTINCT FROM (NEW."sast_source_line") OR OLD."sast_source_object" IS DISTINCT FROM (NEW."sast_source_object") OR OLD."scanner_confidence" IS DISTINCT FROM (NEW."scanner_confidence") OR OLD."service" IS DISTINCT FROM (NEW."service") OR OLD."severity" IS DISTINCT FROM (NEW."severity") OR OLD."severity_justification" IS DISTINCT FROM (NEW."severity_justification") OR OLD."sla_expiration_date" IS DISTINCT FROM (NEW."sla_expiration_date") OR OLD."sla_start_date" IS DISTINCT FROM (NEW."sla_start_date") OR OLD."sonarqube_issue_id" IS DISTINCT FROM (NEW."sonarqube_issue_id") OR OLD."static_finding" IS DISTINCT FROM (NEW."static_finding") OR OLD."steps_to_reproduce" IS DISTINCT FROM (NEW."steps_to_reproduce") OR OLD."test_id" IS DISTINCT FROM (NEW."test_id") OR OLD."thread_id" IS DISTINCT FROM (NEW."thread_id") OR OLD."title" IS DISTINCT FROM (NEW."title") OR OLD."under_defect_review" IS DISTINCT FROM (NEW."under_defect_review") OR OLD."under_review" IS DISTINCT FROM (NEW."under_review") OR OLD."unique_id_from_tool" IS DISTINCT FROM (NEW."unique_id_from_tool") OR OLD."url" IS DISTINCT FROM (NEW."url") OR OLD."verified" IS DISTINCT FROM (NEW."verified") OR OLD."vuln_id_from_tool" IS DISTINCT FROM (NEW."vuln_id_from_tool")) + EXECUTE PROCEDURE pgtrigger_update_update_92175(); + + COMMENT ON TRIGGER pgtrigger_update_update_92175 ON "dojo_finding" IS '7b1c5da1fc67ea4d10b0d6e9ec42fbf428ad6d47'; + +-- +-- Create trigger delete_delete on model finding +-- + + CREATE OR REPLACE FUNCTION "public"._pgtrigger_should_ignore( + trigger_name NAME + ) + RETURNS BOOLEAN AS $$ + DECLARE + _pgtrigger_ignore TEXT[]; + _result BOOLEAN; + BEGIN + BEGIN + SELECT INTO _pgtrigger_ignore + CURRENT_SETTING('pgtrigger.ignore'); + EXCEPTION WHEN OTHERS THEN + END; + IF _pgtrigger_ignore IS NOT NULL THEN + SELECT trigger_name = ANY(_pgtrigger_ignore) + INTO _result; + RETURN _result; + ELSE + RETURN FALSE; + END IF; + END; + $$ LANGUAGE plpgsql; + + CREATE OR REPLACE FUNCTION pgtrigger_delete_delete_72933() + RETURNS TRIGGER AS $$ + + BEGIN + IF ("public"._pgtrigger_should_ignore(TG_NAME) IS TRUE) THEN + IF (TG_OP = 'DELETE') THEN + RETURN OLD; + ELSE + RETURN NEW; + END IF; + END IF; + INSERT INTO "dojo_findingevent" ("active", "archive_batch", "archived_at", "component_name", "component_version", "created", "cve", "cvssv3", "cvssv3_score", "cvssv4", "cvssv4_score", "cwe", "date", "defect_review_requested_by_id", "description", "duplicate", "duplicate_finding_id", "dynamic_finding", "effort_for_fixing", "epss_percentile", "epss_score", "false_p", "file_path", "fix_available", "fix_version", "hash_code", "id", "impact", "is_mitigated", "kev_date", "known_exploited", "last_reviewed", "last_reviewed_by_id", "last_status_update", "line", "mitigated", "mitigated_by_id", "mitigation", "nb_occurences", "numerical_severity", "out_of_scope", "param", "payload", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "planned_remediation_date", "planned_remediation_version", "publish_date", "ransomware_used", "refs", "reporter_id", "review_requested_by_id", "risk_accepted", "sast_sink_object", "sast_source_file_path", "sast_source_line", "sast_source_object", "scanner_confidence", "service", "severity", "severity_justification", "sla_expiration_date", "sla_start_date", "sonarqube_issue_id", "static_finding", "steps_to_reproduce", "test_id", "thread_id", "title", "under_defect_review", "under_review", "unique_id_from_tool", "updated", "url", "verified", "vuln_id_from_tool") VALUES (OLD."active", OLD."archive_batch", OLD."archived_at", OLD."component_name", OLD."component_version", OLD."created", OLD."cve", OLD."cvssv3", OLD."cvssv3_score", OLD."cvssv4", OLD."cvssv4_score", OLD."cwe", OLD."date", OLD."defect_review_requested_by_id", OLD."description", OLD."duplicate", OLD."duplicate_finding_id", OLD."dynamic_finding", OLD."effort_for_fixing", OLD."epss_percentile", OLD."epss_score", OLD."false_p", OLD."file_path", OLD."fix_available", OLD."fix_version", OLD."hash_code", OLD."id", OLD."impact", OLD."is_mitigated", OLD."kev_date", OLD."known_exploited", OLD."last_reviewed", OLD."last_reviewed_by_id", OLD."last_status_update", OLD."line", OLD."mitigated", OLD."mitigated_by_id", OLD."mitigation", OLD."nb_occurences", OLD."numerical_severity", OLD."out_of_scope", OLD."param", OLD."payload", _pgh_attach_context(), NOW(), 'delete', OLD."id", OLD."planned_remediation_date", OLD."planned_remediation_version", OLD."publish_date", OLD."ransomware_used", OLD."refs", OLD."reporter_id", OLD."review_requested_by_id", OLD."risk_accepted", OLD."sast_sink_object", OLD."sast_source_file_path", OLD."sast_source_line", OLD."sast_source_object", OLD."scanner_confidence", OLD."service", OLD."severity", OLD."severity_justification", OLD."sla_expiration_date", OLD."sla_start_date", OLD."sonarqube_issue_id", OLD."static_finding", OLD."steps_to_reproduce", OLD."test_id", OLD."thread_id", OLD."title", OLD."under_defect_review", OLD."under_review", OLD."unique_id_from_tool", OLD."updated", OLD."url", OLD."verified", OLD."vuln_id_from_tool"); RETURN NULL; + END; + $$ LANGUAGE plpgsql; + + DROP TRIGGER IF EXISTS pgtrigger_delete_delete_72933 ON "dojo_finding"; + CREATE TRIGGER pgtrigger_delete_delete_72933 + AFTER DELETE ON "dojo_finding" + + + FOR EACH ROW + EXECUTE PROCEDURE pgtrigger_delete_delete_72933(); + + COMMENT ON TRIGGER pgtrigger_delete_delete_72933 ON "dojo_finding" IS '0b0ae774839868caab7908236804d2b14393a699'; + +-- +-- Create trigger insert_insert on model finding_group +-- + + CREATE OR REPLACE FUNCTION "public"._pgtrigger_should_ignore( + trigger_name NAME + ) + RETURNS BOOLEAN AS $$ + DECLARE + _pgtrigger_ignore TEXT[]; + _result BOOLEAN; + BEGIN + BEGIN + SELECT INTO _pgtrigger_ignore + CURRENT_SETTING('pgtrigger.ignore'); + EXCEPTION WHEN OTHERS THEN + END; + IF _pgtrigger_ignore IS NOT NULL THEN + SELECT trigger_name = ANY(_pgtrigger_ignore) + INTO _result; + RETURN _result; + ELSE + RETURN FALSE; + END IF; + END; + $$ LANGUAGE plpgsql; + + CREATE OR REPLACE FUNCTION pgtrigger_insert_insert_94bd2() + RETURNS TRIGGER AS $$ + + BEGIN + IF ("public"._pgtrigger_should_ignore(TG_NAME) IS TRUE) THEN + IF (TG_OP = 'DELETE') THEN + RETURN OLD; + ELSE + RETURN NEW; + END IF; + END IF; + INSERT INTO "dojo_finding_groupevent" ("archive_batch", "archived_at", "created", "creator_id", "id", "modified", "name", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "test_id") VALUES (NEW."archive_batch", NEW."archived_at", NEW."created", NEW."creator_id", NEW."id", NEW."modified", NEW."name", _pgh_attach_context(), NOW(), 'insert', NEW."id", NEW."test_id"); RETURN NULL; + END; + $$ LANGUAGE plpgsql; + + DROP TRIGGER IF EXISTS pgtrigger_insert_insert_94bd2 ON "dojo_finding_group"; + CREATE TRIGGER pgtrigger_insert_insert_94bd2 + AFTER INSERT ON "dojo_finding_group" + + + FOR EACH ROW + EXECUTE PROCEDURE pgtrigger_insert_insert_94bd2(); + + COMMENT ON TRIGGER pgtrigger_insert_insert_94bd2 ON "dojo_finding_group" IS 'bcad4bd5b2d4c90eede0665d18169e85f5f14257'; + +-- +-- Create trigger update_update on model finding_group +-- + + CREATE OR REPLACE FUNCTION "public"._pgtrigger_should_ignore( + trigger_name NAME + ) + RETURNS BOOLEAN AS $$ + DECLARE + _pgtrigger_ignore TEXT[]; + _result BOOLEAN; + BEGIN + BEGIN + SELECT INTO _pgtrigger_ignore + CURRENT_SETTING('pgtrigger.ignore'); + EXCEPTION WHEN OTHERS THEN + END; + IF _pgtrigger_ignore IS NOT NULL THEN + SELECT trigger_name = ANY(_pgtrigger_ignore) + INTO _result; + RETURN _result; + ELSE + RETURN FALSE; + END IF; + END; + $$ LANGUAGE plpgsql; + + CREATE OR REPLACE FUNCTION pgtrigger_update_update_37b5f() + RETURNS TRIGGER AS $$ + + BEGIN + IF ("public"._pgtrigger_should_ignore(TG_NAME) IS TRUE) THEN + IF (TG_OP = 'DELETE') THEN + RETURN OLD; + ELSE + RETURN NEW; + END IF; + END IF; + INSERT INTO "dojo_finding_groupevent" ("archive_batch", "archived_at", "created", "creator_id", "id", "modified", "name", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "test_id") VALUES (NEW."archive_batch", NEW."archived_at", NEW."created", NEW."creator_id", NEW."id", NEW."modified", NEW."name", _pgh_attach_context(), NOW(), 'update', NEW."id", NEW."test_id"); RETURN NULL; + END; + $$ LANGUAGE plpgsql; + + DROP TRIGGER IF EXISTS pgtrigger_update_update_37b5f ON "dojo_finding_group"; + CREATE TRIGGER pgtrigger_update_update_37b5f + AFTER UPDATE ON "dojo_finding_group" + + + FOR EACH ROW WHEN (OLD."archive_batch" IS DISTINCT FROM (NEW."archive_batch") OR OLD."archived_at" IS DISTINCT FROM (NEW."archived_at") OR OLD."creator_id" IS DISTINCT FROM (NEW."creator_id") OR OLD."id" IS DISTINCT FROM (NEW."id") OR OLD."name" IS DISTINCT FROM (NEW."name") OR OLD."test_id" IS DISTINCT FROM (NEW."test_id")) + EXECUTE PROCEDURE pgtrigger_update_update_37b5f(); + + COMMENT ON TRIGGER pgtrigger_update_update_37b5f ON "dojo_finding_group" IS 'bc709885f7ae1a3e00bb01e453bfd461ea3ac298'; + +-- +-- Create trigger delete_delete on model finding_group +-- + + CREATE OR REPLACE FUNCTION "public"._pgtrigger_should_ignore( + trigger_name NAME + ) + RETURNS BOOLEAN AS $$ + DECLARE + _pgtrigger_ignore TEXT[]; + _result BOOLEAN; + BEGIN + BEGIN + SELECT INTO _pgtrigger_ignore + CURRENT_SETTING('pgtrigger.ignore'); + EXCEPTION WHEN OTHERS THEN + END; + IF _pgtrigger_ignore IS NOT NULL THEN + SELECT trigger_name = ANY(_pgtrigger_ignore) + INTO _result; + RETURN _result; + ELSE + RETURN FALSE; + END IF; + END; + $$ LANGUAGE plpgsql; + + CREATE OR REPLACE FUNCTION pgtrigger_delete_delete_24b41() + RETURNS TRIGGER AS $$ + + BEGIN + IF ("public"._pgtrigger_should_ignore(TG_NAME) IS TRUE) THEN + IF (TG_OP = 'DELETE') THEN + RETURN OLD; + ELSE + RETURN NEW; + END IF; + END IF; + INSERT INTO "dojo_finding_groupevent" ("archive_batch", "archived_at", "created", "creator_id", "id", "modified", "name", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "test_id") VALUES (OLD."archive_batch", OLD."archived_at", OLD."created", OLD."creator_id", OLD."id", OLD."modified", OLD."name", _pgh_attach_context(), NOW(), 'delete', OLD."id", OLD."test_id"); RETURN NULL; + END; + $$ LANGUAGE plpgsql; + + DROP TRIGGER IF EXISTS pgtrigger_delete_delete_24b41 ON "dojo_finding_group"; + CREATE TRIGGER pgtrigger_delete_delete_24b41 + AFTER DELETE ON "dojo_finding_group" + + + FOR EACH ROW + EXECUTE PROCEDURE pgtrigger_delete_delete_24b41(); + + COMMENT ON TRIGGER pgtrigger_delete_delete_24b41 ON "dojo_finding_group" IS 'e573c51b932f142bef508cc995f8f4e6657c1d62'; + +-- +-- Create trigger insert_insert on model product +-- + + CREATE OR REPLACE FUNCTION "public"._pgtrigger_should_ignore( + trigger_name NAME + ) + RETURNS BOOLEAN AS $$ + DECLARE + _pgtrigger_ignore TEXT[]; + _result BOOLEAN; + BEGIN + BEGIN + SELECT INTO _pgtrigger_ignore + CURRENT_SETTING('pgtrigger.ignore'); + EXCEPTION WHEN OTHERS THEN + END; + IF _pgtrigger_ignore IS NOT NULL THEN + SELECT trigger_name = ANY(_pgtrigger_ignore) + INTO _result; + RETURN _result; + ELSE + RETURN FALSE; + END IF; + END; + $$ LANGUAGE plpgsql; + + CREATE OR REPLACE FUNCTION pgtrigger_insert_insert_d5d32() + RETURNS TRIGGER AS $$ + + BEGIN + IF ("public"._pgtrigger_should_ignore(TG_NAME) IS TRUE) THEN + IF (TG_OP = 'DELETE') THEN + RETURN OLD; + ELSE + RETURN NEW; + END IF; + END IF; + INSERT INTO "dojo_productevent" ("archive_batch", "archived_at", "async_updating", "business_criticality", "created", "description", "disable_sla_breach_notifications", "enable_full_risk_acceptance", "enable_product_tag_inheritance", "enable_simple_risk_acceptance", "external_audience", "id", "internet_accessible", "lifecycle_id", "name", "origin_id", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "platform_id", "prod_numeric_grade", "prod_type_id", "product_manager_id", "revenue", "sla_configuration_id", "team_manager_id", "technical_contact_id", "tid", "updated", "user_records") VALUES (NEW."archive_batch", NEW."archived_at", NEW."async_updating", NEW."business_criticality", NEW."created", NEW."description", NEW."disable_sla_breach_notifications", NEW."enable_full_risk_acceptance", NEW."enable_product_tag_inheritance", NEW."enable_simple_risk_acceptance", NEW."external_audience", NEW."id", NEW."internet_accessible", NEW."lifecycle_id", NEW."name", NEW."origin_id", _pgh_attach_context(), NOW(), 'insert', NEW."id", NEW."platform_id", NEW."prod_numeric_grade", NEW."prod_type_id", NEW."product_manager_id", NEW."revenue", NEW."sla_configuration_id", NEW."team_manager_id", NEW."technical_contact_id", NEW."tid", NEW."updated", NEW."user_records"); RETURN NULL; + END; + $$ LANGUAGE plpgsql; + + DROP TRIGGER IF EXISTS pgtrigger_insert_insert_d5d32 ON "dojo_product"; + CREATE TRIGGER pgtrigger_insert_insert_d5d32 + AFTER INSERT ON "dojo_product" + + + FOR EACH ROW + EXECUTE PROCEDURE pgtrigger_insert_insert_d5d32(); + + COMMENT ON TRIGGER pgtrigger_insert_insert_d5d32 ON "dojo_product" IS 'b5851c1970f7b7c91e09d80dc365cbe2579c1220'; + +-- +-- Create trigger update_update on model product +-- + + CREATE OR REPLACE FUNCTION "public"._pgtrigger_should_ignore( + trigger_name NAME + ) + RETURNS BOOLEAN AS $$ + DECLARE + _pgtrigger_ignore TEXT[]; + _result BOOLEAN; + BEGIN + BEGIN + SELECT INTO _pgtrigger_ignore + CURRENT_SETTING('pgtrigger.ignore'); + EXCEPTION WHEN OTHERS THEN + END; + IF _pgtrigger_ignore IS NOT NULL THEN + SELECT trigger_name = ANY(_pgtrigger_ignore) + INTO _result; + RETURN _result; + ELSE + RETURN FALSE; + END IF; + END; + $$ LANGUAGE plpgsql; + + CREATE OR REPLACE FUNCTION pgtrigger_update_update_e7040() + RETURNS TRIGGER AS $$ + + BEGIN + IF ("public"._pgtrigger_should_ignore(TG_NAME) IS TRUE) THEN + IF (TG_OP = 'DELETE') THEN + RETURN OLD; + ELSE + RETURN NEW; + END IF; + END IF; + INSERT INTO "dojo_productevent" ("archive_batch", "archived_at", "async_updating", "business_criticality", "created", "description", "disable_sla_breach_notifications", "enable_full_risk_acceptance", "enable_product_tag_inheritance", "enable_simple_risk_acceptance", "external_audience", "id", "internet_accessible", "lifecycle_id", "name", "origin_id", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "platform_id", "prod_numeric_grade", "prod_type_id", "product_manager_id", "revenue", "sla_configuration_id", "team_manager_id", "technical_contact_id", "tid", "updated", "user_records") VALUES (NEW."archive_batch", NEW."archived_at", NEW."async_updating", NEW."business_criticality", NEW."created", NEW."description", NEW."disable_sla_breach_notifications", NEW."enable_full_risk_acceptance", NEW."enable_product_tag_inheritance", NEW."enable_simple_risk_acceptance", NEW."external_audience", NEW."id", NEW."internet_accessible", NEW."lifecycle_id", NEW."name", NEW."origin_id", _pgh_attach_context(), NOW(), 'update', NEW."id", NEW."platform_id", NEW."prod_numeric_grade", NEW."prod_type_id", NEW."product_manager_id", NEW."revenue", NEW."sla_configuration_id", NEW."team_manager_id", NEW."technical_contact_id", NEW."tid", NEW."updated", NEW."user_records"); RETURN NULL; + END; + $$ LANGUAGE plpgsql; + + DROP TRIGGER IF EXISTS pgtrigger_update_update_e7040 ON "dojo_product"; + CREATE TRIGGER pgtrigger_update_update_e7040 + AFTER UPDATE ON "dojo_product" + + + FOR EACH ROW WHEN (OLD."archive_batch" IS DISTINCT FROM (NEW."archive_batch") OR OLD."archived_at" IS DISTINCT FROM (NEW."archived_at") OR OLD."async_updating" IS DISTINCT FROM (NEW."async_updating") OR OLD."business_criticality" IS DISTINCT FROM (NEW."business_criticality") OR OLD."description" IS DISTINCT FROM (NEW."description") OR OLD."disable_sla_breach_notifications" IS DISTINCT FROM (NEW."disable_sla_breach_notifications") OR OLD."enable_full_risk_acceptance" IS DISTINCT FROM (NEW."enable_full_risk_acceptance") OR OLD."enable_product_tag_inheritance" IS DISTINCT FROM (NEW."enable_product_tag_inheritance") OR OLD."enable_simple_risk_acceptance" IS DISTINCT FROM (NEW."enable_simple_risk_acceptance") OR OLD."external_audience" IS DISTINCT FROM (NEW."external_audience") OR OLD."id" IS DISTINCT FROM (NEW."id") OR OLD."internet_accessible" IS DISTINCT FROM (NEW."internet_accessible") OR OLD."lifecycle_id" IS DISTINCT FROM (NEW."lifecycle_id") OR OLD."name" IS DISTINCT FROM (NEW."name") OR OLD."origin_id" IS DISTINCT FROM (NEW."origin_id") OR OLD."platform_id" IS DISTINCT FROM (NEW."platform_id") OR OLD."prod_numeric_grade" IS DISTINCT FROM (NEW."prod_numeric_grade") OR OLD."prod_type_id" IS DISTINCT FROM (NEW."prod_type_id") OR OLD."product_manager_id" IS DISTINCT FROM (NEW."product_manager_id") OR OLD."revenue" IS DISTINCT FROM (NEW."revenue") OR OLD."sla_configuration_id" IS DISTINCT FROM (NEW."sla_configuration_id") OR OLD."team_manager_id" IS DISTINCT FROM (NEW."team_manager_id") OR OLD."technical_contact_id" IS DISTINCT FROM (NEW."technical_contact_id") OR OLD."tid" IS DISTINCT FROM (NEW."tid") OR OLD."user_records" IS DISTINCT FROM (NEW."user_records")) + EXECUTE PROCEDURE pgtrigger_update_update_e7040(); + + COMMENT ON TRIGGER pgtrigger_update_update_e7040 ON "dojo_product" IS 'b5793f361239e1329aea5ee48f4b68ba6d9c5f0f'; + +-- +-- Create trigger delete_delete on model product +-- + + CREATE OR REPLACE FUNCTION "public"._pgtrigger_should_ignore( + trigger_name NAME + ) + RETURNS BOOLEAN AS $$ + DECLARE + _pgtrigger_ignore TEXT[]; + _result BOOLEAN; + BEGIN + BEGIN + SELECT INTO _pgtrigger_ignore + CURRENT_SETTING('pgtrigger.ignore'); + EXCEPTION WHEN OTHERS THEN + END; + IF _pgtrigger_ignore IS NOT NULL THEN + SELECT trigger_name = ANY(_pgtrigger_ignore) + INTO _result; + RETURN _result; + ELSE + RETURN FALSE; + END IF; + END; + $$ LANGUAGE plpgsql; + + CREATE OR REPLACE FUNCTION pgtrigger_delete_delete_064dd() + RETURNS TRIGGER AS $$ + + BEGIN + IF ("public"._pgtrigger_should_ignore(TG_NAME) IS TRUE) THEN + IF (TG_OP = 'DELETE') THEN + RETURN OLD; + ELSE + RETURN NEW; + END IF; + END IF; + INSERT INTO "dojo_productevent" ("archive_batch", "archived_at", "async_updating", "business_criticality", "created", "description", "disable_sla_breach_notifications", "enable_full_risk_acceptance", "enable_product_tag_inheritance", "enable_simple_risk_acceptance", "external_audience", "id", "internet_accessible", "lifecycle_id", "name", "origin_id", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "platform_id", "prod_numeric_grade", "prod_type_id", "product_manager_id", "revenue", "sla_configuration_id", "team_manager_id", "technical_contact_id", "tid", "updated", "user_records") VALUES (OLD."archive_batch", OLD."archived_at", OLD."async_updating", OLD."business_criticality", OLD."created", OLD."description", OLD."disable_sla_breach_notifications", OLD."enable_full_risk_acceptance", OLD."enable_product_tag_inheritance", OLD."enable_simple_risk_acceptance", OLD."external_audience", OLD."id", OLD."internet_accessible", OLD."lifecycle_id", OLD."name", OLD."origin_id", _pgh_attach_context(), NOW(), 'delete', OLD."id", OLD."platform_id", OLD."prod_numeric_grade", OLD."prod_type_id", OLD."product_manager_id", OLD."revenue", OLD."sla_configuration_id", OLD."team_manager_id", OLD."technical_contact_id", OLD."tid", OLD."updated", OLD."user_records"); RETURN NULL; + END; + $$ LANGUAGE plpgsql; + + DROP TRIGGER IF EXISTS pgtrigger_delete_delete_064dd ON "dojo_product"; + CREATE TRIGGER pgtrigger_delete_delete_064dd + AFTER DELETE ON "dojo_product" + + + FOR EACH ROW + EXECUTE PROCEDURE pgtrigger_delete_delete_064dd(); + + COMMENT ON TRIGGER pgtrigger_delete_delete_064dd ON "dojo_product" IS 'b680a761758c22da5777b8b70f718169dfaf58b5'; + +-- +-- Create trigger insert_insert on model product_type +-- + + CREATE OR REPLACE FUNCTION "public"._pgtrigger_should_ignore( + trigger_name NAME + ) + RETURNS BOOLEAN AS $$ + DECLARE + _pgtrigger_ignore TEXT[]; + _result BOOLEAN; + BEGIN + BEGIN + SELECT INTO _pgtrigger_ignore + CURRENT_SETTING('pgtrigger.ignore'); + EXCEPTION WHEN OTHERS THEN + END; + IF _pgtrigger_ignore IS NOT NULL THEN + SELECT trigger_name = ANY(_pgtrigger_ignore) + INTO _result; + RETURN _result; + ELSE + RETURN FALSE; + END IF; + END; + $$ LANGUAGE plpgsql; + + CREATE OR REPLACE FUNCTION pgtrigger_insert_insert_2d109() + RETURNS TRIGGER AS $$ + + BEGIN + IF ("public"._pgtrigger_should_ignore(TG_NAME) IS TRUE) THEN + IF (TG_OP = 'DELETE') THEN + RETURN OLD; + ELSE + RETURN NEW; + END IF; + END IF; + INSERT INTO "dojo_product_typeevent" ("archive_batch", "archived_at", "created", "critical_product", "description", "id", "key_product", "name", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "updated") VALUES (NEW."archive_batch", NEW."archived_at", NEW."created", NEW."critical_product", NEW."description", NEW."id", NEW."key_product", NEW."name", _pgh_attach_context(), NOW(), 'insert', NEW."id", NEW."updated"); RETURN NULL; + END; + $$ LANGUAGE plpgsql; + + DROP TRIGGER IF EXISTS pgtrigger_insert_insert_2d109 ON "dojo_product_type"; + CREATE TRIGGER pgtrigger_insert_insert_2d109 + AFTER INSERT ON "dojo_product_type" + + + FOR EACH ROW + EXECUTE PROCEDURE pgtrigger_insert_insert_2d109(); + + COMMENT ON TRIGGER pgtrigger_insert_insert_2d109 ON "dojo_product_type" IS 'c22c7686452daedc2b9216ac67df591501e319f2'; + +-- +-- Create trigger update_update on model product_type +-- + + CREATE OR REPLACE FUNCTION "public"._pgtrigger_should_ignore( + trigger_name NAME + ) + RETURNS BOOLEAN AS $$ + DECLARE + _pgtrigger_ignore TEXT[]; + _result BOOLEAN; + BEGIN + BEGIN + SELECT INTO _pgtrigger_ignore + CURRENT_SETTING('pgtrigger.ignore'); + EXCEPTION WHEN OTHERS THEN + END; + IF _pgtrigger_ignore IS NOT NULL THEN + SELECT trigger_name = ANY(_pgtrigger_ignore) + INTO _result; + RETURN _result; + ELSE + RETURN FALSE; + END IF; + END; + $$ LANGUAGE plpgsql; + + CREATE OR REPLACE FUNCTION pgtrigger_update_update_a0136() + RETURNS TRIGGER AS $$ + + BEGIN + IF ("public"._pgtrigger_should_ignore(TG_NAME) IS TRUE) THEN + IF (TG_OP = 'DELETE') THEN + RETURN OLD; + ELSE + RETURN NEW; + END IF; + END IF; + INSERT INTO "dojo_product_typeevent" ("archive_batch", "archived_at", "created", "critical_product", "description", "id", "key_product", "name", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "updated") VALUES (NEW."archive_batch", NEW."archived_at", NEW."created", NEW."critical_product", NEW."description", NEW."id", NEW."key_product", NEW."name", _pgh_attach_context(), NOW(), 'update', NEW."id", NEW."updated"); RETURN NULL; + END; + $$ LANGUAGE plpgsql; + + DROP TRIGGER IF EXISTS pgtrigger_update_update_a0136 ON "dojo_product_type"; + CREATE TRIGGER pgtrigger_update_update_a0136 + AFTER UPDATE ON "dojo_product_type" + + + FOR EACH ROW WHEN (OLD."archive_batch" IS DISTINCT FROM (NEW."archive_batch") OR OLD."archived_at" IS DISTINCT FROM (NEW."archived_at") OR OLD."critical_product" IS DISTINCT FROM (NEW."critical_product") OR OLD."description" IS DISTINCT FROM (NEW."description") OR OLD."id" IS DISTINCT FROM (NEW."id") OR OLD."key_product" IS DISTINCT FROM (NEW."key_product") OR OLD."name" IS DISTINCT FROM (NEW."name")) + EXECUTE PROCEDURE pgtrigger_update_update_a0136(); + + COMMENT ON TRIGGER pgtrigger_update_update_a0136 ON "dojo_product_type" IS 'f0b2de3b71e7b546d0efe2cb7950638c095d85fd'; + +-- +-- Create trigger delete_delete on model product_type +-- + + CREATE OR REPLACE FUNCTION "public"._pgtrigger_should_ignore( + trigger_name NAME + ) + RETURNS BOOLEAN AS $$ + DECLARE + _pgtrigger_ignore TEXT[]; + _result BOOLEAN; + BEGIN + BEGIN + SELECT INTO _pgtrigger_ignore + CURRENT_SETTING('pgtrigger.ignore'); + EXCEPTION WHEN OTHERS THEN + END; + IF _pgtrigger_ignore IS NOT NULL THEN + SELECT trigger_name = ANY(_pgtrigger_ignore) + INTO _result; + RETURN _result; + ELSE + RETURN FALSE; + END IF; + END; + $$ LANGUAGE plpgsql; + + CREATE OR REPLACE FUNCTION pgtrigger_delete_delete_66b18() + RETURNS TRIGGER AS $$ + + BEGIN + IF ("public"._pgtrigger_should_ignore(TG_NAME) IS TRUE) THEN + IF (TG_OP = 'DELETE') THEN + RETURN OLD; + ELSE + RETURN NEW; + END IF; + END IF; + INSERT INTO "dojo_product_typeevent" ("archive_batch", "archived_at", "created", "critical_product", "description", "id", "key_product", "name", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "updated") VALUES (OLD."archive_batch", OLD."archived_at", OLD."created", OLD."critical_product", OLD."description", OLD."id", OLD."key_product", OLD."name", _pgh_attach_context(), NOW(), 'delete', OLD."id", OLD."updated"); RETURN NULL; + END; + $$ LANGUAGE plpgsql; + + DROP TRIGGER IF EXISTS pgtrigger_delete_delete_66b18 ON "dojo_product_type"; + CREATE TRIGGER pgtrigger_delete_delete_66b18 + AFTER DELETE ON "dojo_product_type" + + + FOR EACH ROW + EXECUTE PROCEDURE pgtrigger_delete_delete_66b18(); + + COMMENT ON TRIGGER pgtrigger_delete_delete_66b18 ON "dojo_product_type" IS '7d8aada72ff77dd0e91e25d2324c57b8d8500509'; + +-- +-- Create trigger insert_insert on model test +-- + + CREATE OR REPLACE FUNCTION "public"._pgtrigger_should_ignore( + trigger_name NAME + ) + RETURNS BOOLEAN AS $$ + DECLARE + _pgtrigger_ignore TEXT[]; + _result BOOLEAN; + BEGIN + BEGIN + SELECT INTO _pgtrigger_ignore + CURRENT_SETTING('pgtrigger.ignore'); + EXCEPTION WHEN OTHERS THEN + END; + IF _pgtrigger_ignore IS NOT NULL THEN + SELECT trigger_name = ANY(_pgtrigger_ignore) + INTO _result; + RETURN _result; + ELSE + RETURN FALSE; + END IF; + END; + $$ LANGUAGE plpgsql; + + CREATE OR REPLACE FUNCTION pgtrigger_insert_insert_ecfc1() + RETURNS TRIGGER AS $$ + + BEGIN + IF ("public"._pgtrigger_should_ignore(TG_NAME) IS TRUE) THEN + IF (TG_OP = 'DELETE') THEN + RETURN OLD; + ELSE + RETURN NEW; + END IF; + END IF; + INSERT INTO "dojo_testevent" ("api_scan_configuration_id", "archive_batch", "archived_at", "branch_tag", "build_id", "commit_hash", "created", "description", "engagement_id", "environment_id", "id", "lead_id", "percent_complete", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "scan_type", "target_end", "target_start", "test_type_id", "title", "updated", "version") VALUES (NEW."api_scan_configuration_id", NEW."archive_batch", NEW."archived_at", NEW."branch_tag", NEW."build_id", NEW."commit_hash", NEW."created", NEW."description", NEW."engagement_id", NEW."environment_id", NEW."id", NEW."lead_id", NEW."percent_complete", _pgh_attach_context(), NOW(), 'insert', NEW."id", NEW."scan_type", NEW."target_end", NEW."target_start", NEW."test_type_id", NEW."title", NEW."updated", NEW."version"); RETURN NULL; + END; + $$ LANGUAGE plpgsql; + + DROP TRIGGER IF EXISTS pgtrigger_insert_insert_ecfc1 ON "dojo_test"; + CREATE TRIGGER pgtrigger_insert_insert_ecfc1 + AFTER INSERT ON "dojo_test" + + + FOR EACH ROW + EXECUTE PROCEDURE pgtrigger_insert_insert_ecfc1(); + + COMMENT ON TRIGGER pgtrigger_insert_insert_ecfc1 ON "dojo_test" IS '477f6a297658d54b13ef83b4f4b19b0e76f2bb27'; + +-- +-- Create trigger update_update on model test +-- + + CREATE OR REPLACE FUNCTION "public"._pgtrigger_should_ignore( + trigger_name NAME + ) + RETURNS BOOLEAN AS $$ + DECLARE + _pgtrigger_ignore TEXT[]; + _result BOOLEAN; + BEGIN + BEGIN + SELECT INTO _pgtrigger_ignore + CURRENT_SETTING('pgtrigger.ignore'); + EXCEPTION WHEN OTHERS THEN + END; + IF _pgtrigger_ignore IS NOT NULL THEN + SELECT trigger_name = ANY(_pgtrigger_ignore) + INTO _result; + RETURN _result; + ELSE + RETURN FALSE; + END IF; + END; + $$ LANGUAGE plpgsql; + + CREATE OR REPLACE FUNCTION pgtrigger_update_update_c40f8() + RETURNS TRIGGER AS $$ + + BEGIN + IF ("public"._pgtrigger_should_ignore(TG_NAME) IS TRUE) THEN + IF (TG_OP = 'DELETE') THEN + RETURN OLD; + ELSE + RETURN NEW; + END IF; + END IF; + INSERT INTO "dojo_testevent" ("api_scan_configuration_id", "archive_batch", "archived_at", "branch_tag", "build_id", "commit_hash", "created", "description", "engagement_id", "environment_id", "id", "lead_id", "percent_complete", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "scan_type", "target_end", "target_start", "test_type_id", "title", "updated", "version") VALUES (NEW."api_scan_configuration_id", NEW."archive_batch", NEW."archived_at", NEW."branch_tag", NEW."build_id", NEW."commit_hash", NEW."created", NEW."description", NEW."engagement_id", NEW."environment_id", NEW."id", NEW."lead_id", NEW."percent_complete", _pgh_attach_context(), NOW(), 'update', NEW."id", NEW."scan_type", NEW."target_end", NEW."target_start", NEW."test_type_id", NEW."title", NEW."updated", NEW."version"); RETURN NULL; + END; + $$ LANGUAGE plpgsql; + + DROP TRIGGER IF EXISTS pgtrigger_update_update_c40f8 ON "dojo_test"; + CREATE TRIGGER pgtrigger_update_update_c40f8 + AFTER UPDATE ON "dojo_test" + + + FOR EACH ROW WHEN (OLD."api_scan_configuration_id" IS DISTINCT FROM (NEW."api_scan_configuration_id") OR OLD."archive_batch" IS DISTINCT FROM (NEW."archive_batch") OR OLD."archived_at" IS DISTINCT FROM (NEW."archived_at") OR OLD."branch_tag" IS DISTINCT FROM (NEW."branch_tag") OR OLD."build_id" IS DISTINCT FROM (NEW."build_id") OR OLD."commit_hash" IS DISTINCT FROM (NEW."commit_hash") OR OLD."description" IS DISTINCT FROM (NEW."description") OR OLD."engagement_id" IS DISTINCT FROM (NEW."engagement_id") OR OLD."environment_id" IS DISTINCT FROM (NEW."environment_id") OR OLD."id" IS DISTINCT FROM (NEW."id") OR OLD."lead_id" IS DISTINCT FROM (NEW."lead_id") OR OLD."percent_complete" IS DISTINCT FROM (NEW."percent_complete") OR OLD."scan_type" IS DISTINCT FROM (NEW."scan_type") OR OLD."target_end" IS DISTINCT FROM (NEW."target_end") OR OLD."target_start" IS DISTINCT FROM (NEW."target_start") OR OLD."test_type_id" IS DISTINCT FROM (NEW."test_type_id") OR OLD."title" IS DISTINCT FROM (NEW."title") OR OLD."version" IS DISTINCT FROM (NEW."version")) + EXECUTE PROCEDURE pgtrigger_update_update_c40f8(); + + COMMENT ON TRIGGER pgtrigger_update_update_c40f8 ON "dojo_test" IS '50e41edef10c98f5e20b9c43a324c49f5b897f88'; + +-- +-- Create trigger delete_delete on model test +-- + + CREATE OR REPLACE FUNCTION "public"._pgtrigger_should_ignore( + trigger_name NAME + ) + RETURNS BOOLEAN AS $$ + DECLARE + _pgtrigger_ignore TEXT[]; + _result BOOLEAN; + BEGIN + BEGIN + SELECT INTO _pgtrigger_ignore + CURRENT_SETTING('pgtrigger.ignore'); + EXCEPTION WHEN OTHERS THEN + END; + IF _pgtrigger_ignore IS NOT NULL THEN + SELECT trigger_name = ANY(_pgtrigger_ignore) + INTO _result; + RETURN _result; + ELSE + RETURN FALSE; + END IF; + END; + $$ LANGUAGE plpgsql; + + CREATE OR REPLACE FUNCTION pgtrigger_delete_delete_66d18() + RETURNS TRIGGER AS $$ + + BEGIN + IF ("public"._pgtrigger_should_ignore(TG_NAME) IS TRUE) THEN + IF (TG_OP = 'DELETE') THEN + RETURN OLD; + ELSE + RETURN NEW; + END IF; + END IF; + INSERT INTO "dojo_testevent" ("api_scan_configuration_id", "archive_batch", "archived_at", "branch_tag", "build_id", "commit_hash", "created", "description", "engagement_id", "environment_id", "id", "lead_id", "percent_complete", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "scan_type", "target_end", "target_start", "test_type_id", "title", "updated", "version") VALUES (OLD."api_scan_configuration_id", OLD."archive_batch", OLD."archived_at", OLD."branch_tag", OLD."build_id", OLD."commit_hash", OLD."created", OLD."description", OLD."engagement_id", OLD."environment_id", OLD."id", OLD."lead_id", OLD."percent_complete", _pgh_attach_context(), NOW(), 'delete', OLD."id", OLD."scan_type", OLD."target_end", OLD."target_start", OLD."test_type_id", OLD."title", OLD."updated", OLD."version"); RETURN NULL; + END; + $$ LANGUAGE plpgsql; + + DROP TRIGGER IF EXISTS pgtrigger_delete_delete_66d18 ON "dojo_test"; + CREATE TRIGGER pgtrigger_delete_delete_66d18 + AFTER DELETE ON "dojo_test" + + + FOR EACH ROW + EXECUTE PROCEDURE pgtrigger_delete_delete_66d18(); + + COMMENT ON TRIGGER pgtrigger_delete_delete_66d18 ON "dojo_test" IS '0b9eda2793d6208cb855751dc6c39f8d6819cd2d'; +""" + +BACKWARD_SQL = r""" +-- +-- Create trigger delete_delete on model test +-- +DROP TRIGGER IF EXISTS pgtrigger_delete_delete_66d18 ON "dojo_test"; +-- +-- Create trigger update_update on model test +-- +DROP TRIGGER IF EXISTS pgtrigger_update_update_c40f8 ON "dojo_test"; +-- +-- Create trigger insert_insert on model test +-- +DROP TRIGGER IF EXISTS pgtrigger_insert_insert_ecfc1 ON "dojo_test"; +-- +-- Create trigger delete_delete on model product_type +-- +DROP TRIGGER IF EXISTS pgtrigger_delete_delete_66b18 ON "dojo_product_type"; +-- +-- Create trigger update_update on model product_type +-- +DROP TRIGGER IF EXISTS pgtrigger_update_update_a0136 ON "dojo_product_type"; +-- +-- Create trigger insert_insert on model product_type +-- +DROP TRIGGER IF EXISTS pgtrigger_insert_insert_2d109 ON "dojo_product_type"; +-- +-- Create trigger delete_delete on model product +-- +DROP TRIGGER IF EXISTS pgtrigger_delete_delete_064dd ON "dojo_product"; +-- +-- Create trigger update_update on model product +-- +DROP TRIGGER IF EXISTS pgtrigger_update_update_e7040 ON "dojo_product"; +-- +-- Create trigger insert_insert on model product +-- +DROP TRIGGER IF EXISTS pgtrigger_insert_insert_d5d32 ON "dojo_product"; +-- +-- Create trigger delete_delete on model finding_group +-- +DROP TRIGGER IF EXISTS pgtrigger_delete_delete_24b41 ON "dojo_finding_group"; +-- +-- Create trigger update_update on model finding_group +-- +DROP TRIGGER IF EXISTS pgtrigger_update_update_37b5f ON "dojo_finding_group"; +-- +-- Create trigger insert_insert on model finding_group +-- +DROP TRIGGER IF EXISTS pgtrigger_insert_insert_94bd2 ON "dojo_finding_group"; +-- +-- Create trigger delete_delete on model finding +-- +DROP TRIGGER IF EXISTS pgtrigger_delete_delete_72933 ON "dojo_finding"; +-- +-- Create trigger update_update on model finding +-- +DROP TRIGGER IF EXISTS pgtrigger_update_update_92175 ON "dojo_finding"; +-- +-- Create trigger insert_insert on model finding +-- +DROP TRIGGER IF EXISTS pgtrigger_insert_insert_2fbbb ON "dojo_finding"; +-- +-- Create trigger delete_delete on model engagement +-- +DROP TRIGGER IF EXISTS pgtrigger_delete_delete_9f4df ON "dojo_engagement"; +-- +-- Create trigger update_update on model engagement +-- +DROP TRIGGER IF EXISTS pgtrigger_update_update_65136 ON "dojo_engagement"; +-- +-- Create trigger insert_insert on model engagement +-- +DROP TRIGGER IF EXISTS pgtrigger_insert_insert_125f1 ON "dojo_engagement"; +-- +-- Create trigger delete_delete on model endpoint +-- +DROP TRIGGER IF EXISTS pgtrigger_delete_delete_dd1f9 ON "dojo_endpoint"; +-- +-- Create trigger update_update on model endpoint +-- +DROP TRIGGER IF EXISTS pgtrigger_update_update_2b19a ON "dojo_endpoint"; +-- +-- Create trigger insert_insert on model endpoint +-- +DROP TRIGGER IF EXISTS pgtrigger_insert_insert_c7973 ON "dojo_endpoint"; +-- +-- Add field archived_at to vulnerability_id +-- +ALTER TABLE "dojo_vulnerability_id" DROP COLUMN "archived_at" CASCADE; +-- +-- Add field archive_batch to vulnerability_id +-- +ALTER TABLE "dojo_vulnerability_id" DROP COLUMN "archive_batch" CASCADE; +-- +-- Add field archived_at to tool_product_settings +-- +ALTER TABLE "dojo_tool_product_settings" DROP COLUMN "archived_at" CASCADE; +-- +-- Add field archive_batch to tool_product_settings +-- +ALTER TABLE "dojo_tool_product_settings" DROP COLUMN "archive_batch" CASCADE; +-- +-- Add field archived_at to testevent +-- +ALTER TABLE "dojo_testevent" DROP COLUMN "archived_at" CASCADE; +-- +-- Add field archive_batch to testevent +-- +ALTER TABLE "dojo_testevent" DROP COLUMN "archive_batch" CASCADE; +-- +-- Add field archived_at to test_import_finding_action +-- +ALTER TABLE "dojo_test_import_finding_action" DROP COLUMN "archived_at" CASCADE; +-- +-- Add field archive_batch to test_import_finding_action +-- +ALTER TABLE "dojo_test_import_finding_action" DROP COLUMN "archive_batch" CASCADE; +-- +-- Add field archived_at to test_import +-- +ALTER TABLE "dojo_test_import" DROP COLUMN "archived_at" CASCADE; +-- +-- Add field archive_batch to test_import +-- +ALTER TABLE "dojo_test_import" DROP COLUMN "archive_batch" CASCADE; +-- +-- Add field archived_at to test +-- +ALTER TABLE "dojo_test" DROP COLUMN "archived_at" CASCADE; +-- +-- Add field archive_batch to test +-- +ALTER TABLE "dojo_test" DROP COLUMN "archive_batch" CASCADE; +-- +-- Add field archived_at to productevent +-- +ALTER TABLE "dojo_productevent" DROP COLUMN "archived_at" CASCADE; +-- +-- Add field archive_batch to productevent +-- +ALTER TABLE "dojo_productevent" DROP COLUMN "archive_batch" CASCADE; +-- +-- Add field archived_at to product_typeevent +-- +ALTER TABLE "dojo_product_typeevent" DROP COLUMN "archived_at" CASCADE; +-- +-- Add field archive_batch to product_typeevent +-- +ALTER TABLE "dojo_product_typeevent" DROP COLUMN "archive_batch" CASCADE; +-- +-- Add field archived_at to product_type +-- +ALTER TABLE "dojo_product_type" DROP COLUMN "archived_at" CASCADE; +-- +-- Add field archive_batch to product_type +-- +ALTER TABLE "dojo_product_type" DROP COLUMN "archive_batch" CASCADE; +-- +-- Add field archived_at to product_api_scan_configuration +-- +ALTER TABLE "dojo_product_api_scan_configuration" DROP COLUMN "archived_at" CASCADE; +-- +-- Add field archive_batch to product_api_scan_configuration +-- +ALTER TABLE "dojo_product_api_scan_configuration" DROP COLUMN "archive_batch" CASCADE; +-- +-- Add field archived_at to product +-- +ALTER TABLE "dojo_product" DROP COLUMN "archived_at" CASCADE; +-- +-- Add field archive_batch to product +-- +ALTER TABLE "dojo_product" DROP COLUMN "archive_batch" CASCADE; +-- +-- Add field archived_at to objects_product +-- +ALTER TABLE "dojo_objects_product" DROP COLUMN "archived_at" CASCADE; +-- +-- Add field archive_batch to objects_product +-- +ALTER TABLE "dojo_objects_product" DROP COLUMN "archive_batch" CASCADE; +-- +-- Add field archived_at to locationproductreference +-- +ALTER TABLE "dojo_locationproductreference" DROP COLUMN "archived_at" CASCADE; +-- +-- Add field archive_batch to locationproductreference +-- +ALTER TABLE "dojo_locationproductreference" DROP COLUMN "archive_batch" CASCADE; +-- +-- Add field archived_at to locationfindingreference +-- +ALTER TABLE "dojo_locationfindingreference" DROP COLUMN "archived_at" CASCADE; +-- +-- Add field archive_batch to locationfindingreference +-- +ALTER TABLE "dojo_locationfindingreference" DROP COLUMN "archive_batch" CASCADE; +-- +-- Add field archived_at to languages +-- +ALTER TABLE "dojo_languages" DROP COLUMN "archived_at" CASCADE; +-- +-- Add field archive_batch to languages +-- +ALTER TABLE "dojo_languages" DROP COLUMN "archive_batch" CASCADE; +-- +-- Add field archived_at to jira_project +-- +ALTER TABLE "dojo_jira_project" DROP COLUMN "archived_at" CASCADE; +-- +-- Add field archive_batch to jira_project +-- +ALTER TABLE "dojo_jira_project" DROP COLUMN "archive_batch" CASCADE; +-- +-- Add field archived_at to jira_issue +-- +ALTER TABLE "dojo_jira_issue" DROP COLUMN "archived_at" CASCADE; +-- +-- Add field archive_batch to jira_issue +-- +ALTER TABLE "dojo_jira_issue" DROP COLUMN "archive_batch" CASCADE; +-- +-- Add field archived_at to findingvulnerabilityreference +-- +ALTER TABLE "dojo_findingvulnerabilityreference" DROP COLUMN "archived_at" CASCADE; +-- +-- Add field archive_batch to findingvulnerabilityreference +-- +ALTER TABLE "dojo_findingvulnerabilityreference" DROP COLUMN "archive_batch" CASCADE; +-- +-- Add field archived_at to findingevent +-- +ALTER TABLE "dojo_findingevent" DROP COLUMN "archived_at" CASCADE; +-- +-- Add field archive_batch to findingevent +-- +ALTER TABLE "dojo_findingevent" DROP COLUMN "archive_batch" CASCADE; +-- +-- Add field archived_at to finding_groupevent +-- +ALTER TABLE "dojo_finding_groupevent" DROP COLUMN "archived_at" CASCADE; +-- +-- Add field archive_batch to finding_groupevent +-- +ALTER TABLE "dojo_finding_groupevent" DROP COLUMN "archive_batch" CASCADE; +-- +-- Add field archived_at to finding_group +-- +ALTER TABLE "dojo_finding_group" DROP COLUMN "archived_at" CASCADE; +-- +-- Add field archive_batch to finding_group +-- +ALTER TABLE "dojo_finding_group" DROP COLUMN "archive_batch" CASCADE; +-- +-- Add field archived_at to finding +-- +ALTER TABLE "dojo_finding" DROP COLUMN "archived_at" CASCADE; +-- +-- Add field archive_batch to finding +-- +ALTER TABLE "dojo_finding" DROP COLUMN "archive_batch" CASCADE; +-- +-- Add field archived_at to engagementevent +-- +ALTER TABLE "dojo_engagementevent" DROP COLUMN "archived_at" CASCADE; +-- +-- Add field archive_batch to engagementevent +-- +ALTER TABLE "dojo_engagementevent" DROP COLUMN "archive_batch" CASCADE; +-- +-- Add field archived_at to engagement_presets +-- +ALTER TABLE "dojo_engagement_presets" DROP COLUMN "archived_at" CASCADE; +-- +-- Add field archive_batch to engagement_presets +-- +ALTER TABLE "dojo_engagement_presets" DROP COLUMN "archive_batch" CASCADE; +-- +-- Add field archived_at to engagement +-- +ALTER TABLE "dojo_engagement" DROP COLUMN "archived_at" CASCADE; +-- +-- Add field archive_batch to engagement +-- +ALTER TABLE "dojo_engagement" DROP COLUMN "archive_batch" CASCADE; +-- +-- Add field archived_at to endpointevent +-- +ALTER TABLE "dojo_endpointevent" DROP COLUMN "archived_at" CASCADE; +-- +-- Add field archive_batch to endpointevent +-- +ALTER TABLE "dojo_endpointevent" DROP COLUMN "archive_batch" CASCADE; +-- +-- Add field archived_at to endpoint_status +-- +ALTER TABLE "dojo_endpoint_status" DROP COLUMN "archived_at" CASCADE; +-- +-- Add field archive_batch to endpoint_status +-- +ALTER TABLE "dojo_endpoint_status" DROP COLUMN "archive_batch" CASCADE; +-- +-- Add field archived_at to endpoint +-- +ALTER TABLE "dojo_endpoint" DROP COLUMN "archived_at" CASCADE; +-- +-- Add field archive_batch to endpoint +-- +ALTER TABLE "dojo_endpoint" DROP COLUMN "archive_batch" CASCADE; +-- +-- Add field archived_at to dojometa +-- +ALTER TABLE "dojo_dojometa" DROP COLUMN "archived_at" CASCADE; +-- +-- Add field archive_batch to dojometa +-- +ALTER TABLE "dojo_dojometa" DROP COLUMN "archive_batch" CASCADE; +-- +-- Add field archived_at to app_analysis +-- +ALTER TABLE "dojo_app_analysis" DROP COLUMN "archived_at" CASCADE; +-- +-- Add field archive_batch to app_analysis +-- +ALTER TABLE "dojo_app_analysis" DROP COLUMN "archive_batch" CASCADE; +-- +-- Remove trigger delete_delete from model test +-- + + CREATE OR REPLACE FUNCTION "public"._pgtrigger_should_ignore( + trigger_name NAME + ) + RETURNS BOOLEAN AS $$ + DECLARE + _pgtrigger_ignore TEXT[]; + _result BOOLEAN; + BEGIN + BEGIN + SELECT INTO _pgtrigger_ignore + CURRENT_SETTING('pgtrigger.ignore'); + EXCEPTION WHEN OTHERS THEN + END; + IF _pgtrigger_ignore IS NOT NULL THEN + SELECT trigger_name = ANY(_pgtrigger_ignore) + INTO _result; + RETURN _result; + ELSE + RETURN FALSE; + END IF; + END; + $$ LANGUAGE plpgsql; + + CREATE OR REPLACE FUNCTION pgtrigger_delete_delete_66d18() + RETURNS TRIGGER AS $$ + + BEGIN + IF ("public"._pgtrigger_should_ignore(TG_NAME) IS TRUE) THEN + IF (TG_OP = 'DELETE') THEN + RETURN OLD; + ELSE + RETURN NEW; + END IF; + END IF; + INSERT INTO "dojo_testevent" ("api_scan_configuration_id", "branch_tag", "build_id", "commit_hash", "created", "description", "engagement_id", "environment_id", "id", "lead_id", "percent_complete", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "scan_type", "target_end", "target_start", "test_type_id", "title", "updated", "version") VALUES (OLD."api_scan_configuration_id", OLD."branch_tag", OLD."build_id", OLD."commit_hash", OLD."created", OLD."description", OLD."engagement_id", OLD."environment_id", OLD."id", OLD."lead_id", OLD."percent_complete", _pgh_attach_context(), NOW(), 'delete', OLD."id", OLD."scan_type", OLD."target_end", OLD."target_start", OLD."test_type_id", OLD."title", OLD."updated", OLD."version"); RETURN NULL; + END; + $$ LANGUAGE plpgsql; + + DROP TRIGGER IF EXISTS pgtrigger_delete_delete_66d18 ON "dojo_test"; + CREATE TRIGGER pgtrigger_delete_delete_66d18 + AFTER DELETE ON "dojo_test" + + + FOR EACH ROW + EXECUTE PROCEDURE pgtrigger_delete_delete_66d18(); + + COMMENT ON TRIGGER pgtrigger_delete_delete_66d18 ON "dojo_test" IS '51bce27193221308adc41e62f1faff5122bbbceb'; + +-- +-- Remove trigger update_update from model test +-- + + CREATE OR REPLACE FUNCTION "public"._pgtrigger_should_ignore( + trigger_name NAME + ) + RETURNS BOOLEAN AS $$ + DECLARE + _pgtrigger_ignore TEXT[]; + _result BOOLEAN; + BEGIN + BEGIN + SELECT INTO _pgtrigger_ignore + CURRENT_SETTING('pgtrigger.ignore'); + EXCEPTION WHEN OTHERS THEN + END; + IF _pgtrigger_ignore IS NOT NULL THEN + SELECT trigger_name = ANY(_pgtrigger_ignore) + INTO _result; + RETURN _result; + ELSE + RETURN FALSE; + END IF; + END; + $$ LANGUAGE plpgsql; + + CREATE OR REPLACE FUNCTION pgtrigger_update_update_c40f8() + RETURNS TRIGGER AS $$ + + BEGIN + IF ("public"._pgtrigger_should_ignore(TG_NAME) IS TRUE) THEN + IF (TG_OP = 'DELETE') THEN + RETURN OLD; + ELSE + RETURN NEW; + END IF; + END IF; + INSERT INTO "dojo_testevent" ("api_scan_configuration_id", "branch_tag", "build_id", "commit_hash", "created", "description", "engagement_id", "environment_id", "id", "lead_id", "percent_complete", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "scan_type", "target_end", "target_start", "test_type_id", "title", "updated", "version") VALUES (NEW."api_scan_configuration_id", NEW."branch_tag", NEW."build_id", NEW."commit_hash", NEW."created", NEW."description", NEW."engagement_id", NEW."environment_id", NEW."id", NEW."lead_id", NEW."percent_complete", _pgh_attach_context(), NOW(), 'update', NEW."id", NEW."scan_type", NEW."target_end", NEW."target_start", NEW."test_type_id", NEW."title", NEW."updated", NEW."version"); RETURN NULL; + END; + $$ LANGUAGE plpgsql; + + DROP TRIGGER IF EXISTS pgtrigger_update_update_c40f8 ON "dojo_test"; + CREATE TRIGGER pgtrigger_update_update_c40f8 + AFTER UPDATE ON "dojo_test" + + + FOR EACH ROW WHEN (OLD."api_scan_configuration_id" IS DISTINCT FROM (NEW."api_scan_configuration_id") OR OLD."branch_tag" IS DISTINCT FROM (NEW."branch_tag") OR OLD."build_id" IS DISTINCT FROM (NEW."build_id") OR OLD."commit_hash" IS DISTINCT FROM (NEW."commit_hash") OR OLD."description" IS DISTINCT FROM (NEW."description") OR OLD."engagement_id" IS DISTINCT FROM (NEW."engagement_id") OR OLD."environment_id" IS DISTINCT FROM (NEW."environment_id") OR OLD."id" IS DISTINCT FROM (NEW."id") OR OLD."lead_id" IS DISTINCT FROM (NEW."lead_id") OR OLD."percent_complete" IS DISTINCT FROM (NEW."percent_complete") OR OLD."scan_type" IS DISTINCT FROM (NEW."scan_type") OR OLD."target_end" IS DISTINCT FROM (NEW."target_end") OR OLD."target_start" IS DISTINCT FROM (NEW."target_start") OR OLD."test_type_id" IS DISTINCT FROM (NEW."test_type_id") OR OLD."title" IS DISTINCT FROM (NEW."title") OR OLD."version" IS DISTINCT FROM (NEW."version")) + EXECUTE PROCEDURE pgtrigger_update_update_c40f8(); + + COMMENT ON TRIGGER pgtrigger_update_update_c40f8 ON "dojo_test" IS '777c92a16d48f7e590e50cb8fb6c0d77c9afa1b6'; + +-- +-- Remove trigger insert_insert from model test +-- + + CREATE OR REPLACE FUNCTION "public"._pgtrigger_should_ignore( + trigger_name NAME + ) + RETURNS BOOLEAN AS $$ + DECLARE + _pgtrigger_ignore TEXT[]; + _result BOOLEAN; + BEGIN + BEGIN + SELECT INTO _pgtrigger_ignore + CURRENT_SETTING('pgtrigger.ignore'); + EXCEPTION WHEN OTHERS THEN + END; + IF _pgtrigger_ignore IS NOT NULL THEN + SELECT trigger_name = ANY(_pgtrigger_ignore) + INTO _result; + RETURN _result; + ELSE + RETURN FALSE; + END IF; + END; + $$ LANGUAGE plpgsql; + + CREATE OR REPLACE FUNCTION pgtrigger_insert_insert_ecfc1() + RETURNS TRIGGER AS $$ + + BEGIN + IF ("public"._pgtrigger_should_ignore(TG_NAME) IS TRUE) THEN + IF (TG_OP = 'DELETE') THEN + RETURN OLD; + ELSE + RETURN NEW; + END IF; + END IF; + INSERT INTO "dojo_testevent" ("api_scan_configuration_id", "branch_tag", "build_id", "commit_hash", "created", "description", "engagement_id", "environment_id", "id", "lead_id", "percent_complete", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "scan_type", "target_end", "target_start", "test_type_id", "title", "updated", "version") VALUES (NEW."api_scan_configuration_id", NEW."branch_tag", NEW."build_id", NEW."commit_hash", NEW."created", NEW."description", NEW."engagement_id", NEW."environment_id", NEW."id", NEW."lead_id", NEW."percent_complete", _pgh_attach_context(), NOW(), 'insert', NEW."id", NEW."scan_type", NEW."target_end", NEW."target_start", NEW."test_type_id", NEW."title", NEW."updated", NEW."version"); RETURN NULL; + END; + $$ LANGUAGE plpgsql; + + DROP TRIGGER IF EXISTS pgtrigger_insert_insert_ecfc1 ON "dojo_test"; + CREATE TRIGGER pgtrigger_insert_insert_ecfc1 + AFTER INSERT ON "dojo_test" + + + FOR EACH ROW + EXECUTE PROCEDURE pgtrigger_insert_insert_ecfc1(); + + COMMENT ON TRIGGER pgtrigger_insert_insert_ecfc1 ON "dojo_test" IS '0b6ec21ca35b61b1abcc0b2f8629cb4d1cc92930'; + +-- +-- Remove trigger delete_delete from model product_type +-- + + CREATE OR REPLACE FUNCTION "public"._pgtrigger_should_ignore( + trigger_name NAME + ) + RETURNS BOOLEAN AS $$ + DECLARE + _pgtrigger_ignore TEXT[]; + _result BOOLEAN; + BEGIN + BEGIN + SELECT INTO _pgtrigger_ignore + CURRENT_SETTING('pgtrigger.ignore'); + EXCEPTION WHEN OTHERS THEN + END; + IF _pgtrigger_ignore IS NOT NULL THEN + SELECT trigger_name = ANY(_pgtrigger_ignore) + INTO _result; + RETURN _result; + ELSE + RETURN FALSE; + END IF; + END; + $$ LANGUAGE plpgsql; + + CREATE OR REPLACE FUNCTION pgtrigger_delete_delete_66b18() + RETURNS TRIGGER AS $$ + + BEGIN + IF ("public"._pgtrigger_should_ignore(TG_NAME) IS TRUE) THEN + IF (TG_OP = 'DELETE') THEN + RETURN OLD; + ELSE + RETURN NEW; + END IF; + END IF; + INSERT INTO "dojo_product_typeevent" ("created", "critical_product", "description", "id", "key_product", "name", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "updated") VALUES (OLD."created", OLD."critical_product", OLD."description", OLD."id", OLD."key_product", OLD."name", _pgh_attach_context(), NOW(), 'delete', OLD."id", OLD."updated"); RETURN NULL; + END; + $$ LANGUAGE plpgsql; + + DROP TRIGGER IF EXISTS pgtrigger_delete_delete_66b18 ON "dojo_product_type"; + CREATE TRIGGER pgtrigger_delete_delete_66b18 + AFTER DELETE ON "dojo_product_type" + + + FOR EACH ROW + EXECUTE PROCEDURE pgtrigger_delete_delete_66b18(); + + COMMENT ON TRIGGER pgtrigger_delete_delete_66b18 ON "dojo_product_type" IS '1b3bb470de18c3270ba2a1d4453d276b34f650dc'; + +-- +-- Remove trigger update_update from model product_type +-- + + CREATE OR REPLACE FUNCTION "public"._pgtrigger_should_ignore( + trigger_name NAME + ) + RETURNS BOOLEAN AS $$ + DECLARE + _pgtrigger_ignore TEXT[]; + _result BOOLEAN; + BEGIN + BEGIN + SELECT INTO _pgtrigger_ignore + CURRENT_SETTING('pgtrigger.ignore'); + EXCEPTION WHEN OTHERS THEN + END; + IF _pgtrigger_ignore IS NOT NULL THEN + SELECT trigger_name = ANY(_pgtrigger_ignore) + INTO _result; + RETURN _result; + ELSE + RETURN FALSE; + END IF; + END; + $$ LANGUAGE plpgsql; + + CREATE OR REPLACE FUNCTION pgtrigger_update_update_a0136() + RETURNS TRIGGER AS $$ + + BEGIN + IF ("public"._pgtrigger_should_ignore(TG_NAME) IS TRUE) THEN + IF (TG_OP = 'DELETE') THEN + RETURN OLD; + ELSE + RETURN NEW; + END IF; + END IF; + INSERT INTO "dojo_product_typeevent" ("created", "critical_product", "description", "id", "key_product", "name", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "updated") VALUES (NEW."created", NEW."critical_product", NEW."description", NEW."id", NEW."key_product", NEW."name", _pgh_attach_context(), NOW(), 'update', NEW."id", NEW."updated"); RETURN NULL; + END; + $$ LANGUAGE plpgsql; + + DROP TRIGGER IF EXISTS pgtrigger_update_update_a0136 ON "dojo_product_type"; + CREATE TRIGGER pgtrigger_update_update_a0136 + AFTER UPDATE ON "dojo_product_type" + + + FOR EACH ROW WHEN (OLD."critical_product" IS DISTINCT FROM (NEW."critical_product") OR OLD."description" IS DISTINCT FROM (NEW."description") OR OLD."id" IS DISTINCT FROM (NEW."id") OR OLD."key_product" IS DISTINCT FROM (NEW."key_product") OR OLD."name" IS DISTINCT FROM (NEW."name")) + EXECUTE PROCEDURE pgtrigger_update_update_a0136(); + + COMMENT ON TRIGGER pgtrigger_update_update_a0136 ON "dojo_product_type" IS '97c18814aec2e06d73b89e3eb65e0cfbf832dda5'; + +-- +-- Remove trigger insert_insert from model product_type +-- + + CREATE OR REPLACE FUNCTION "public"._pgtrigger_should_ignore( + trigger_name NAME + ) + RETURNS BOOLEAN AS $$ + DECLARE + _pgtrigger_ignore TEXT[]; + _result BOOLEAN; + BEGIN + BEGIN + SELECT INTO _pgtrigger_ignore + CURRENT_SETTING('pgtrigger.ignore'); + EXCEPTION WHEN OTHERS THEN + END; + IF _pgtrigger_ignore IS NOT NULL THEN + SELECT trigger_name = ANY(_pgtrigger_ignore) + INTO _result; + RETURN _result; + ELSE + RETURN FALSE; + END IF; + END; + $$ LANGUAGE plpgsql; + + CREATE OR REPLACE FUNCTION pgtrigger_insert_insert_2d109() + RETURNS TRIGGER AS $$ + + BEGIN + IF ("public"._pgtrigger_should_ignore(TG_NAME) IS TRUE) THEN + IF (TG_OP = 'DELETE') THEN + RETURN OLD; + ELSE + RETURN NEW; + END IF; + END IF; + INSERT INTO "dojo_product_typeevent" ("created", "critical_product", "description", "id", "key_product", "name", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "updated") VALUES (NEW."created", NEW."critical_product", NEW."description", NEW."id", NEW."key_product", NEW."name", _pgh_attach_context(), NOW(), 'insert', NEW."id", NEW."updated"); RETURN NULL; + END; + $$ LANGUAGE plpgsql; + + DROP TRIGGER IF EXISTS pgtrigger_insert_insert_2d109 ON "dojo_product_type"; + CREATE TRIGGER pgtrigger_insert_insert_2d109 + AFTER INSERT ON "dojo_product_type" + + + FOR EACH ROW + EXECUTE PROCEDURE pgtrigger_insert_insert_2d109(); + + COMMENT ON TRIGGER pgtrigger_insert_insert_2d109 ON "dojo_product_type" IS '3f3d8e8a68a63bc86ff3557f8fc5f54d950e9d6d'; + +-- +-- Remove trigger delete_delete from model product +-- + + CREATE OR REPLACE FUNCTION "public"._pgtrigger_should_ignore( + trigger_name NAME + ) + RETURNS BOOLEAN AS $$ + DECLARE + _pgtrigger_ignore TEXT[]; + _result BOOLEAN; + BEGIN + BEGIN + SELECT INTO _pgtrigger_ignore + CURRENT_SETTING('pgtrigger.ignore'); + EXCEPTION WHEN OTHERS THEN + END; + IF _pgtrigger_ignore IS NOT NULL THEN + SELECT trigger_name = ANY(_pgtrigger_ignore) + INTO _result; + RETURN _result; + ELSE + RETURN FALSE; + END IF; + END; + $$ LANGUAGE plpgsql; + + CREATE OR REPLACE FUNCTION pgtrigger_delete_delete_064dd() + RETURNS TRIGGER AS $$ + + BEGIN + IF ("public"._pgtrigger_should_ignore(TG_NAME) IS TRUE) THEN + IF (TG_OP = 'DELETE') THEN + RETURN OLD; + ELSE + RETURN NEW; + END IF; + END IF; + INSERT INTO "dojo_productevent" ("async_updating", "business_criticality", "created", "description", "disable_sla_breach_notifications", "enable_full_risk_acceptance", "enable_product_tag_inheritance", "enable_simple_risk_acceptance", "external_audience", "id", "internet_accessible", "lifecycle_id", "name", "origin_id", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "platform_id", "prod_numeric_grade", "prod_type_id", "product_manager_id", "revenue", "sla_configuration_id", "team_manager_id", "technical_contact_id", "tid", "updated", "user_records") VALUES (OLD."async_updating", OLD."business_criticality", OLD."created", OLD."description", OLD."disable_sla_breach_notifications", OLD."enable_full_risk_acceptance", OLD."enable_product_tag_inheritance", OLD."enable_simple_risk_acceptance", OLD."external_audience", OLD."id", OLD."internet_accessible", OLD."lifecycle_id", OLD."name", OLD."origin_id", _pgh_attach_context(), NOW(), 'delete', OLD."id", OLD."platform_id", OLD."prod_numeric_grade", OLD."prod_type_id", OLD."product_manager_id", OLD."revenue", OLD."sla_configuration_id", OLD."team_manager_id", OLD."technical_contact_id", OLD."tid", OLD."updated", OLD."user_records"); RETURN NULL; + END; + $$ LANGUAGE plpgsql; + + DROP TRIGGER IF EXISTS pgtrigger_delete_delete_064dd ON "dojo_product"; + CREATE TRIGGER pgtrigger_delete_delete_064dd + AFTER DELETE ON "dojo_product" + + + FOR EACH ROW + EXECUTE PROCEDURE pgtrigger_delete_delete_064dd(); + + COMMENT ON TRIGGER pgtrigger_delete_delete_064dd ON "dojo_product" IS 'fb5075dda22c29fcfbf16c799b636b5dbf993777'; + +-- +-- Remove trigger update_update from model product +-- + + CREATE OR REPLACE FUNCTION "public"._pgtrigger_should_ignore( + trigger_name NAME + ) + RETURNS BOOLEAN AS $$ + DECLARE + _pgtrigger_ignore TEXT[]; + _result BOOLEAN; + BEGIN + BEGIN + SELECT INTO _pgtrigger_ignore + CURRENT_SETTING('pgtrigger.ignore'); + EXCEPTION WHEN OTHERS THEN + END; + IF _pgtrigger_ignore IS NOT NULL THEN + SELECT trigger_name = ANY(_pgtrigger_ignore) + INTO _result; + RETURN _result; + ELSE + RETURN FALSE; + END IF; + END; + $$ LANGUAGE plpgsql; + + CREATE OR REPLACE FUNCTION pgtrigger_update_update_e7040() + RETURNS TRIGGER AS $$ + + BEGIN + IF ("public"._pgtrigger_should_ignore(TG_NAME) IS TRUE) THEN + IF (TG_OP = 'DELETE') THEN + RETURN OLD; + ELSE + RETURN NEW; + END IF; + END IF; + INSERT INTO "dojo_productevent" ("async_updating", "business_criticality", "created", "description", "disable_sla_breach_notifications", "enable_full_risk_acceptance", "enable_product_tag_inheritance", "enable_simple_risk_acceptance", "external_audience", "id", "internet_accessible", "lifecycle_id", "name", "origin_id", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "platform_id", "prod_numeric_grade", "prod_type_id", "product_manager_id", "revenue", "sla_configuration_id", "team_manager_id", "technical_contact_id", "tid", "updated", "user_records") VALUES (NEW."async_updating", NEW."business_criticality", NEW."created", NEW."description", NEW."disable_sla_breach_notifications", NEW."enable_full_risk_acceptance", NEW."enable_product_tag_inheritance", NEW."enable_simple_risk_acceptance", NEW."external_audience", NEW."id", NEW."internet_accessible", NEW."lifecycle_id", NEW."name", NEW."origin_id", _pgh_attach_context(), NOW(), 'update', NEW."id", NEW."platform_id", NEW."prod_numeric_grade", NEW."prod_type_id", NEW."product_manager_id", NEW."revenue", NEW."sla_configuration_id", NEW."team_manager_id", NEW."technical_contact_id", NEW."tid", NEW."updated", NEW."user_records"); RETURN NULL; + END; + $$ LANGUAGE plpgsql; + + DROP TRIGGER IF EXISTS pgtrigger_update_update_e7040 ON "dojo_product"; + CREATE TRIGGER pgtrigger_update_update_e7040 + AFTER UPDATE ON "dojo_product" + + + FOR EACH ROW WHEN (OLD."async_updating" IS DISTINCT FROM (NEW."async_updating") OR OLD."business_criticality" IS DISTINCT FROM (NEW."business_criticality") OR OLD."description" IS DISTINCT FROM (NEW."description") OR OLD."disable_sla_breach_notifications" IS DISTINCT FROM (NEW."disable_sla_breach_notifications") OR OLD."enable_full_risk_acceptance" IS DISTINCT FROM (NEW."enable_full_risk_acceptance") OR OLD."enable_product_tag_inheritance" IS DISTINCT FROM (NEW."enable_product_tag_inheritance") OR OLD."enable_simple_risk_acceptance" IS DISTINCT FROM (NEW."enable_simple_risk_acceptance") OR OLD."external_audience" IS DISTINCT FROM (NEW."external_audience") OR OLD."id" IS DISTINCT FROM (NEW."id") OR OLD."internet_accessible" IS DISTINCT FROM (NEW."internet_accessible") OR OLD."lifecycle_id" IS DISTINCT FROM (NEW."lifecycle_id") OR OLD."name" IS DISTINCT FROM (NEW."name") OR OLD."origin_id" IS DISTINCT FROM (NEW."origin_id") OR OLD."platform_id" IS DISTINCT FROM (NEW."platform_id") OR OLD."prod_numeric_grade" IS DISTINCT FROM (NEW."prod_numeric_grade") OR OLD."prod_type_id" IS DISTINCT FROM (NEW."prod_type_id") OR OLD."product_manager_id" IS DISTINCT FROM (NEW."product_manager_id") OR OLD."revenue" IS DISTINCT FROM (NEW."revenue") OR OLD."sla_configuration_id" IS DISTINCT FROM (NEW."sla_configuration_id") OR OLD."team_manager_id" IS DISTINCT FROM (NEW."team_manager_id") OR OLD."technical_contact_id" IS DISTINCT FROM (NEW."technical_contact_id") OR OLD."tid" IS DISTINCT FROM (NEW."tid") OR OLD."user_records" IS DISTINCT FROM (NEW."user_records")) + EXECUTE PROCEDURE pgtrigger_update_update_e7040(); + + COMMENT ON TRIGGER pgtrigger_update_update_e7040 ON "dojo_product" IS '49923bd314b57154a13024be447d70ff62dda123'; + +-- +-- Remove trigger insert_insert from model product +-- + + CREATE OR REPLACE FUNCTION "public"._pgtrigger_should_ignore( + trigger_name NAME + ) + RETURNS BOOLEAN AS $$ + DECLARE + _pgtrigger_ignore TEXT[]; + _result BOOLEAN; + BEGIN + BEGIN + SELECT INTO _pgtrigger_ignore + CURRENT_SETTING('pgtrigger.ignore'); + EXCEPTION WHEN OTHERS THEN + END; + IF _pgtrigger_ignore IS NOT NULL THEN + SELECT trigger_name = ANY(_pgtrigger_ignore) + INTO _result; + RETURN _result; + ELSE + RETURN FALSE; + END IF; + END; + $$ LANGUAGE plpgsql; + + CREATE OR REPLACE FUNCTION pgtrigger_insert_insert_d5d32() + RETURNS TRIGGER AS $$ + + BEGIN + IF ("public"._pgtrigger_should_ignore(TG_NAME) IS TRUE) THEN + IF (TG_OP = 'DELETE') THEN + RETURN OLD; + ELSE + RETURN NEW; + END IF; + END IF; + INSERT INTO "dojo_productevent" ("async_updating", "business_criticality", "created", "description", "disable_sla_breach_notifications", "enable_full_risk_acceptance", "enable_product_tag_inheritance", "enable_simple_risk_acceptance", "external_audience", "id", "internet_accessible", "lifecycle_id", "name", "origin_id", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "platform_id", "prod_numeric_grade", "prod_type_id", "product_manager_id", "revenue", "sla_configuration_id", "team_manager_id", "technical_contact_id", "tid", "updated", "user_records") VALUES (NEW."async_updating", NEW."business_criticality", NEW."created", NEW."description", NEW."disable_sla_breach_notifications", NEW."enable_full_risk_acceptance", NEW."enable_product_tag_inheritance", NEW."enable_simple_risk_acceptance", NEW."external_audience", NEW."id", NEW."internet_accessible", NEW."lifecycle_id", NEW."name", NEW."origin_id", _pgh_attach_context(), NOW(), 'insert', NEW."id", NEW."platform_id", NEW."prod_numeric_grade", NEW."prod_type_id", NEW."product_manager_id", NEW."revenue", NEW."sla_configuration_id", NEW."team_manager_id", NEW."technical_contact_id", NEW."tid", NEW."updated", NEW."user_records"); RETURN NULL; + END; + $$ LANGUAGE plpgsql; + + DROP TRIGGER IF EXISTS pgtrigger_insert_insert_d5d32 ON "dojo_product"; + CREATE TRIGGER pgtrigger_insert_insert_d5d32 + AFTER INSERT ON "dojo_product" + + + FOR EACH ROW + EXECUTE PROCEDURE pgtrigger_insert_insert_d5d32(); + + COMMENT ON TRIGGER pgtrigger_insert_insert_d5d32 ON "dojo_product" IS '56d7d4e2ec7a3c855444408a7cd6be18e2e9ab02'; + +-- +-- Remove trigger delete_delete from model finding_group +-- + + CREATE OR REPLACE FUNCTION "public"._pgtrigger_should_ignore( + trigger_name NAME + ) + RETURNS BOOLEAN AS $$ + DECLARE + _pgtrigger_ignore TEXT[]; + _result BOOLEAN; + BEGIN + BEGIN + SELECT INTO _pgtrigger_ignore + CURRENT_SETTING('pgtrigger.ignore'); + EXCEPTION WHEN OTHERS THEN + END; + IF _pgtrigger_ignore IS NOT NULL THEN + SELECT trigger_name = ANY(_pgtrigger_ignore) + INTO _result; + RETURN _result; + ELSE + RETURN FALSE; + END IF; + END; + $$ LANGUAGE plpgsql; + + CREATE OR REPLACE FUNCTION pgtrigger_delete_delete_24b41() + RETURNS TRIGGER AS $$ + + BEGIN + IF ("public"._pgtrigger_should_ignore(TG_NAME) IS TRUE) THEN + IF (TG_OP = 'DELETE') THEN + RETURN OLD; + ELSE + RETURN NEW; + END IF; + END IF; + INSERT INTO "dojo_finding_groupevent" ("created", "creator_id", "id", "modified", "name", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "test_id") VALUES (OLD."created", OLD."creator_id", OLD."id", OLD."modified", OLD."name", _pgh_attach_context(), NOW(), 'delete', OLD."id", OLD."test_id"); RETURN NULL; + END; + $$ LANGUAGE plpgsql; + + DROP TRIGGER IF EXISTS pgtrigger_delete_delete_24b41 ON "dojo_finding_group"; + CREATE TRIGGER pgtrigger_delete_delete_24b41 + AFTER DELETE ON "dojo_finding_group" + + + FOR EACH ROW + EXECUTE PROCEDURE pgtrigger_delete_delete_24b41(); + + COMMENT ON TRIGGER pgtrigger_delete_delete_24b41 ON "dojo_finding_group" IS '4d7241855d22804d01d455fb4228e750c5b11497'; + +-- +-- Remove trigger update_update from model finding_group +-- + + CREATE OR REPLACE FUNCTION "public"._pgtrigger_should_ignore( + trigger_name NAME + ) + RETURNS BOOLEAN AS $$ + DECLARE + _pgtrigger_ignore TEXT[]; + _result BOOLEAN; + BEGIN + BEGIN + SELECT INTO _pgtrigger_ignore + CURRENT_SETTING('pgtrigger.ignore'); + EXCEPTION WHEN OTHERS THEN + END; + IF _pgtrigger_ignore IS NOT NULL THEN + SELECT trigger_name = ANY(_pgtrigger_ignore) + INTO _result; + RETURN _result; + ELSE + RETURN FALSE; + END IF; + END; + $$ LANGUAGE plpgsql; + + CREATE OR REPLACE FUNCTION pgtrigger_update_update_37b5f() + RETURNS TRIGGER AS $$ + + BEGIN + IF ("public"._pgtrigger_should_ignore(TG_NAME) IS TRUE) THEN + IF (TG_OP = 'DELETE') THEN + RETURN OLD; + ELSE + RETURN NEW; + END IF; + END IF; + INSERT INTO "dojo_finding_groupevent" ("created", "creator_id", "id", "modified", "name", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "test_id") VALUES (NEW."created", NEW."creator_id", NEW."id", NEW."modified", NEW."name", _pgh_attach_context(), NOW(), 'update', NEW."id", NEW."test_id"); RETURN NULL; + END; + $$ LANGUAGE plpgsql; + + DROP TRIGGER IF EXISTS pgtrigger_update_update_37b5f ON "dojo_finding_group"; + CREATE TRIGGER pgtrigger_update_update_37b5f + AFTER UPDATE ON "dojo_finding_group" + + + FOR EACH ROW WHEN (OLD."creator_id" IS DISTINCT FROM (NEW."creator_id") OR OLD."id" IS DISTINCT FROM (NEW."id") OR OLD."name" IS DISTINCT FROM (NEW."name") OR OLD."test_id" IS DISTINCT FROM (NEW."test_id")) + EXECUTE PROCEDURE pgtrigger_update_update_37b5f(); + + COMMENT ON TRIGGER pgtrigger_update_update_37b5f ON "dojo_finding_group" IS 'd5d94d19b54079f6c284d9448666eb408b20f245'; + +-- +-- Remove trigger insert_insert from model finding_group +-- + + CREATE OR REPLACE FUNCTION "public"._pgtrigger_should_ignore( + trigger_name NAME + ) + RETURNS BOOLEAN AS $$ + DECLARE + _pgtrigger_ignore TEXT[]; + _result BOOLEAN; + BEGIN + BEGIN + SELECT INTO _pgtrigger_ignore + CURRENT_SETTING('pgtrigger.ignore'); + EXCEPTION WHEN OTHERS THEN + END; + IF _pgtrigger_ignore IS NOT NULL THEN + SELECT trigger_name = ANY(_pgtrigger_ignore) + INTO _result; + RETURN _result; + ELSE + RETURN FALSE; + END IF; + END; + $$ LANGUAGE plpgsql; + + CREATE OR REPLACE FUNCTION pgtrigger_insert_insert_94bd2() + RETURNS TRIGGER AS $$ + + BEGIN + IF ("public"._pgtrigger_should_ignore(TG_NAME) IS TRUE) THEN + IF (TG_OP = 'DELETE') THEN + RETURN OLD; + ELSE + RETURN NEW; + END IF; + END IF; + INSERT INTO "dojo_finding_groupevent" ("created", "creator_id", "id", "modified", "name", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "test_id") VALUES (NEW."created", NEW."creator_id", NEW."id", NEW."modified", NEW."name", _pgh_attach_context(), NOW(), 'insert', NEW."id", NEW."test_id"); RETURN NULL; + END; + $$ LANGUAGE plpgsql; + + DROP TRIGGER IF EXISTS pgtrigger_insert_insert_94bd2 ON "dojo_finding_group"; + CREATE TRIGGER pgtrigger_insert_insert_94bd2 + AFTER INSERT ON "dojo_finding_group" + + + FOR EACH ROW + EXECUTE PROCEDURE pgtrigger_insert_insert_94bd2(); + + COMMENT ON TRIGGER pgtrigger_insert_insert_94bd2 ON "dojo_finding_group" IS 'ccce37d431a0be588c20aa39b570893c63be9b4b'; + +-- +-- Remove trigger delete_delete from model finding +-- + + CREATE OR REPLACE FUNCTION "public"._pgtrigger_should_ignore( + trigger_name NAME + ) + RETURNS BOOLEAN AS $$ + DECLARE + _pgtrigger_ignore TEXT[]; + _result BOOLEAN; + BEGIN + BEGIN + SELECT INTO _pgtrigger_ignore + CURRENT_SETTING('pgtrigger.ignore'); + EXCEPTION WHEN OTHERS THEN + END; + IF _pgtrigger_ignore IS NOT NULL THEN + SELECT trigger_name = ANY(_pgtrigger_ignore) + INTO _result; + RETURN _result; + ELSE + RETURN FALSE; + END IF; + END; + $$ LANGUAGE plpgsql; + + CREATE OR REPLACE FUNCTION pgtrigger_delete_delete_72933() + RETURNS TRIGGER AS $$ + + BEGIN + IF ("public"._pgtrigger_should_ignore(TG_NAME) IS TRUE) THEN + IF (TG_OP = 'DELETE') THEN + RETURN OLD; + ELSE + RETURN NEW; + END IF; + END IF; + INSERT INTO "dojo_findingevent" ("active", "component_name", "component_version", "created", "cve", "cvssv3", "cvssv3_score", "cvssv4", "cvssv4_score", "cwe", "date", "defect_review_requested_by_id", "description", "duplicate", "duplicate_finding_id", "dynamic_finding", "effort_for_fixing", "epss_percentile", "epss_score", "false_p", "file_path", "fix_available", "fix_version", "hash_code", "id", "impact", "is_mitigated", "kev_date", "known_exploited", "last_reviewed", "last_reviewed_by_id", "last_status_update", "line", "mitigated", "mitigated_by_id", "mitigation", "nb_occurences", "numerical_severity", "out_of_scope", "param", "payload", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "planned_remediation_date", "planned_remediation_version", "publish_date", "ransomware_used", "refs", "reporter_id", "review_requested_by_id", "risk_accepted", "sast_sink_object", "sast_source_file_path", "sast_source_line", "sast_source_object", "scanner_confidence", "service", "severity", "severity_justification", "sla_expiration_date", "sla_start_date", "sonarqube_issue_id", "static_finding", "steps_to_reproduce", "test_id", "thread_id", "title", "under_defect_review", "under_review", "unique_id_from_tool", "updated", "url", "verified", "vuln_id_from_tool") VALUES (OLD."active", OLD."component_name", OLD."component_version", OLD."created", OLD."cve", OLD."cvssv3", OLD."cvssv3_score", OLD."cvssv4", OLD."cvssv4_score", OLD."cwe", OLD."date", OLD."defect_review_requested_by_id", OLD."description", OLD."duplicate", OLD."duplicate_finding_id", OLD."dynamic_finding", OLD."effort_for_fixing", OLD."epss_percentile", OLD."epss_score", OLD."false_p", OLD."file_path", OLD."fix_available", OLD."fix_version", OLD."hash_code", OLD."id", OLD."impact", OLD."is_mitigated", OLD."kev_date", OLD."known_exploited", OLD."last_reviewed", OLD."last_reviewed_by_id", OLD."last_status_update", OLD."line", OLD."mitigated", OLD."mitigated_by_id", OLD."mitigation", OLD."nb_occurences", OLD."numerical_severity", OLD."out_of_scope", OLD."param", OLD."payload", _pgh_attach_context(), NOW(), 'delete', OLD."id", OLD."planned_remediation_date", OLD."planned_remediation_version", OLD."publish_date", OLD."ransomware_used", OLD."refs", OLD."reporter_id", OLD."review_requested_by_id", OLD."risk_accepted", OLD."sast_sink_object", OLD."sast_source_file_path", OLD."sast_source_line", OLD."sast_source_object", OLD."scanner_confidence", OLD."service", OLD."severity", OLD."severity_justification", OLD."sla_expiration_date", OLD."sla_start_date", OLD."sonarqube_issue_id", OLD."static_finding", OLD."steps_to_reproduce", OLD."test_id", OLD."thread_id", OLD."title", OLD."under_defect_review", OLD."under_review", OLD."unique_id_from_tool", OLD."updated", OLD."url", OLD."verified", OLD."vuln_id_from_tool"); RETURN NULL; + END; + $$ LANGUAGE plpgsql; + + DROP TRIGGER IF EXISTS pgtrigger_delete_delete_72933 ON "dojo_finding"; + CREATE TRIGGER pgtrigger_delete_delete_72933 + AFTER DELETE ON "dojo_finding" + + + FOR EACH ROW + EXECUTE PROCEDURE pgtrigger_delete_delete_72933(); + + COMMENT ON TRIGGER pgtrigger_delete_delete_72933 ON "dojo_finding" IS 'dd1240d046d5292ab4e6ce9cd193d921c9c2d309'; + +-- +-- Remove trigger update_update from model finding +-- + + CREATE OR REPLACE FUNCTION "public"._pgtrigger_should_ignore( + trigger_name NAME + ) + RETURNS BOOLEAN AS $$ + DECLARE + _pgtrigger_ignore TEXT[]; + _result BOOLEAN; + BEGIN + BEGIN + SELECT INTO _pgtrigger_ignore + CURRENT_SETTING('pgtrigger.ignore'); + EXCEPTION WHEN OTHERS THEN + END; + IF _pgtrigger_ignore IS NOT NULL THEN + SELECT trigger_name = ANY(_pgtrigger_ignore) + INTO _result; + RETURN _result; + ELSE + RETURN FALSE; + END IF; + END; + $$ LANGUAGE plpgsql; + + CREATE OR REPLACE FUNCTION pgtrigger_update_update_92175() + RETURNS TRIGGER AS $$ + + BEGIN + IF ("public"._pgtrigger_should_ignore(TG_NAME) IS TRUE) THEN + IF (TG_OP = 'DELETE') THEN + RETURN OLD; + ELSE + RETURN NEW; + END IF; + END IF; + INSERT INTO "dojo_findingevent" ("active", "component_name", "component_version", "created", "cve", "cvssv3", "cvssv3_score", "cvssv4", "cvssv4_score", "cwe", "date", "defect_review_requested_by_id", "description", "duplicate", "duplicate_finding_id", "dynamic_finding", "effort_for_fixing", "epss_percentile", "epss_score", "false_p", "file_path", "fix_available", "fix_version", "hash_code", "id", "impact", "is_mitigated", "kev_date", "known_exploited", "last_reviewed", "last_reviewed_by_id", "last_status_update", "line", "mitigated", "mitigated_by_id", "mitigation", "nb_occurences", "numerical_severity", "out_of_scope", "param", "payload", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "planned_remediation_date", "planned_remediation_version", "publish_date", "ransomware_used", "refs", "reporter_id", "review_requested_by_id", "risk_accepted", "sast_sink_object", "sast_source_file_path", "sast_source_line", "sast_source_object", "scanner_confidence", "service", "severity", "severity_justification", "sla_expiration_date", "sla_start_date", "sonarqube_issue_id", "static_finding", "steps_to_reproduce", "test_id", "thread_id", "title", "under_defect_review", "under_review", "unique_id_from_tool", "updated", "url", "verified", "vuln_id_from_tool") VALUES (NEW."active", NEW."component_name", NEW."component_version", NEW."created", NEW."cve", NEW."cvssv3", NEW."cvssv3_score", NEW."cvssv4", NEW."cvssv4_score", NEW."cwe", NEW."date", NEW."defect_review_requested_by_id", NEW."description", NEW."duplicate", NEW."duplicate_finding_id", NEW."dynamic_finding", NEW."effort_for_fixing", NEW."epss_percentile", NEW."epss_score", NEW."false_p", NEW."file_path", NEW."fix_available", NEW."fix_version", NEW."hash_code", NEW."id", NEW."impact", NEW."is_mitigated", NEW."kev_date", NEW."known_exploited", NEW."last_reviewed", NEW."last_reviewed_by_id", NEW."last_status_update", NEW."line", NEW."mitigated", NEW."mitigated_by_id", NEW."mitigation", NEW."nb_occurences", NEW."numerical_severity", NEW."out_of_scope", NEW."param", NEW."payload", _pgh_attach_context(), NOW(), 'update', NEW."id", NEW."planned_remediation_date", NEW."planned_remediation_version", NEW."publish_date", NEW."ransomware_used", NEW."refs", NEW."reporter_id", NEW."review_requested_by_id", NEW."risk_accepted", NEW."sast_sink_object", NEW."sast_source_file_path", NEW."sast_source_line", NEW."sast_source_object", NEW."scanner_confidence", NEW."service", NEW."severity", NEW."severity_justification", NEW."sla_expiration_date", NEW."sla_start_date", NEW."sonarqube_issue_id", NEW."static_finding", NEW."steps_to_reproduce", NEW."test_id", NEW."thread_id", NEW."title", NEW."under_defect_review", NEW."under_review", NEW."unique_id_from_tool", NEW."updated", NEW."url", NEW."verified", NEW."vuln_id_from_tool"); RETURN NULL; + END; + $$ LANGUAGE plpgsql; + + DROP TRIGGER IF EXISTS pgtrigger_update_update_92175 ON "dojo_finding"; + CREATE TRIGGER pgtrigger_update_update_92175 + AFTER UPDATE ON "dojo_finding" + + + FOR EACH ROW WHEN (OLD."active" IS DISTINCT FROM (NEW."active") OR OLD."component_name" IS DISTINCT FROM (NEW."component_name") OR OLD."component_version" IS DISTINCT FROM (NEW."component_version") OR OLD."cve" IS DISTINCT FROM (NEW."cve") OR OLD."cvssv3" IS DISTINCT FROM (NEW."cvssv3") OR OLD."cvssv3_score" IS DISTINCT FROM (NEW."cvssv3_score") OR OLD."cvssv4" IS DISTINCT FROM (NEW."cvssv4") OR OLD."cvssv4_score" IS DISTINCT FROM (NEW."cvssv4_score") OR OLD."cwe" IS DISTINCT FROM (NEW."cwe") OR OLD."date" IS DISTINCT FROM (NEW."date") OR OLD."defect_review_requested_by_id" IS DISTINCT FROM (NEW."defect_review_requested_by_id") OR OLD."description" IS DISTINCT FROM (NEW."description") OR OLD."duplicate" IS DISTINCT FROM (NEW."duplicate") OR OLD."duplicate_finding_id" IS DISTINCT FROM (NEW."duplicate_finding_id") OR OLD."dynamic_finding" IS DISTINCT FROM (NEW."dynamic_finding") OR OLD."effort_for_fixing" IS DISTINCT FROM (NEW."effort_for_fixing") OR OLD."epss_percentile" IS DISTINCT FROM (NEW."epss_percentile") OR OLD."epss_score" IS DISTINCT FROM (NEW."epss_score") OR OLD."false_p" IS DISTINCT FROM (NEW."false_p") OR OLD."file_path" IS DISTINCT FROM (NEW."file_path") OR OLD."fix_available" IS DISTINCT FROM (NEW."fix_available") OR OLD."fix_version" IS DISTINCT FROM (NEW."fix_version") OR OLD."hash_code" IS DISTINCT FROM (NEW."hash_code") OR OLD."id" IS DISTINCT FROM (NEW."id") OR OLD."impact" IS DISTINCT FROM (NEW."impact") OR OLD."is_mitigated" IS DISTINCT FROM (NEW."is_mitigated") OR OLD."kev_date" IS DISTINCT FROM (NEW."kev_date") OR OLD."known_exploited" IS DISTINCT FROM (NEW."known_exploited") OR OLD."last_reviewed" IS DISTINCT FROM (NEW."last_reviewed") OR OLD."last_reviewed_by_id" IS DISTINCT FROM (NEW."last_reviewed_by_id") OR OLD."line" IS DISTINCT FROM (NEW."line") OR OLD."mitigated" IS DISTINCT FROM (NEW."mitigated") OR OLD."mitigated_by_id" IS DISTINCT FROM (NEW."mitigated_by_id") OR OLD."mitigation" IS DISTINCT FROM (NEW."mitigation") OR OLD."nb_occurences" IS DISTINCT FROM (NEW."nb_occurences") OR OLD."numerical_severity" IS DISTINCT FROM (NEW."numerical_severity") OR OLD."out_of_scope" IS DISTINCT FROM (NEW."out_of_scope") OR OLD."param" IS DISTINCT FROM (NEW."param") OR OLD."payload" IS DISTINCT FROM (NEW."payload") OR OLD."planned_remediation_date" IS DISTINCT FROM (NEW."planned_remediation_date") OR OLD."planned_remediation_version" IS DISTINCT FROM (NEW."planned_remediation_version") OR OLD."publish_date" IS DISTINCT FROM (NEW."publish_date") OR OLD."ransomware_used" IS DISTINCT FROM (NEW."ransomware_used") OR OLD."refs" IS DISTINCT FROM (NEW."refs") OR OLD."reporter_id" IS DISTINCT FROM (NEW."reporter_id") OR OLD."review_requested_by_id" IS DISTINCT FROM (NEW."review_requested_by_id") OR OLD."risk_accepted" IS DISTINCT FROM (NEW."risk_accepted") OR OLD."sast_sink_object" IS DISTINCT FROM (NEW."sast_sink_object") OR OLD."sast_source_file_path" IS DISTINCT FROM (NEW."sast_source_file_path") OR OLD."sast_source_line" IS DISTINCT FROM (NEW."sast_source_line") OR OLD."sast_source_object" IS DISTINCT FROM (NEW."sast_source_object") OR OLD."scanner_confidence" IS DISTINCT FROM (NEW."scanner_confidence") OR OLD."service" IS DISTINCT FROM (NEW."service") OR OLD."severity" IS DISTINCT FROM (NEW."severity") OR OLD."severity_justification" IS DISTINCT FROM (NEW."severity_justification") OR OLD."sla_expiration_date" IS DISTINCT FROM (NEW."sla_expiration_date") OR OLD."sla_start_date" IS DISTINCT FROM (NEW."sla_start_date") OR OLD."sonarqube_issue_id" IS DISTINCT FROM (NEW."sonarqube_issue_id") OR OLD."static_finding" IS DISTINCT FROM (NEW."static_finding") OR OLD."steps_to_reproduce" IS DISTINCT FROM (NEW."steps_to_reproduce") OR OLD."test_id" IS DISTINCT FROM (NEW."test_id") OR OLD."thread_id" IS DISTINCT FROM (NEW."thread_id") OR OLD."title" IS DISTINCT FROM (NEW."title") OR OLD."under_defect_review" IS DISTINCT FROM (NEW."under_defect_review") OR OLD."under_review" IS DISTINCT FROM (NEW."under_review") OR OLD."unique_id_from_tool" IS DISTINCT FROM (NEW."unique_id_from_tool") OR OLD."url" IS DISTINCT FROM (NEW."url") OR OLD."verified" IS DISTINCT FROM (NEW."verified") OR OLD."vuln_id_from_tool" IS DISTINCT FROM (NEW."vuln_id_from_tool")) + EXECUTE PROCEDURE pgtrigger_update_update_92175(); + + COMMENT ON TRIGGER pgtrigger_update_update_92175 ON "dojo_finding" IS '3a8608f3269631a51e32dffe79021258c6c4af33'; + +-- +-- Remove trigger insert_insert from model finding +-- + + CREATE OR REPLACE FUNCTION "public"._pgtrigger_should_ignore( + trigger_name NAME + ) + RETURNS BOOLEAN AS $$ + DECLARE + _pgtrigger_ignore TEXT[]; + _result BOOLEAN; + BEGIN + BEGIN + SELECT INTO _pgtrigger_ignore + CURRENT_SETTING('pgtrigger.ignore'); + EXCEPTION WHEN OTHERS THEN + END; + IF _pgtrigger_ignore IS NOT NULL THEN + SELECT trigger_name = ANY(_pgtrigger_ignore) + INTO _result; + RETURN _result; + ELSE + RETURN FALSE; + END IF; + END; + $$ LANGUAGE plpgsql; + + CREATE OR REPLACE FUNCTION pgtrigger_insert_insert_2fbbb() + RETURNS TRIGGER AS $$ + + BEGIN + IF ("public"._pgtrigger_should_ignore(TG_NAME) IS TRUE) THEN + IF (TG_OP = 'DELETE') THEN + RETURN OLD; + ELSE + RETURN NEW; + END IF; + END IF; + INSERT INTO "dojo_findingevent" ("active", "component_name", "component_version", "created", "cve", "cvssv3", "cvssv3_score", "cvssv4", "cvssv4_score", "cwe", "date", "defect_review_requested_by_id", "description", "duplicate", "duplicate_finding_id", "dynamic_finding", "effort_for_fixing", "epss_percentile", "epss_score", "false_p", "file_path", "fix_available", "fix_version", "hash_code", "id", "impact", "is_mitigated", "kev_date", "known_exploited", "last_reviewed", "last_reviewed_by_id", "last_status_update", "line", "mitigated", "mitigated_by_id", "mitigation", "nb_occurences", "numerical_severity", "out_of_scope", "param", "payload", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "planned_remediation_date", "planned_remediation_version", "publish_date", "ransomware_used", "refs", "reporter_id", "review_requested_by_id", "risk_accepted", "sast_sink_object", "sast_source_file_path", "sast_source_line", "sast_source_object", "scanner_confidence", "service", "severity", "severity_justification", "sla_expiration_date", "sla_start_date", "sonarqube_issue_id", "static_finding", "steps_to_reproduce", "test_id", "thread_id", "title", "under_defect_review", "under_review", "unique_id_from_tool", "updated", "url", "verified", "vuln_id_from_tool") VALUES (NEW."active", NEW."component_name", NEW."component_version", NEW."created", NEW."cve", NEW."cvssv3", NEW."cvssv3_score", NEW."cvssv4", NEW."cvssv4_score", NEW."cwe", NEW."date", NEW."defect_review_requested_by_id", NEW."description", NEW."duplicate", NEW."duplicate_finding_id", NEW."dynamic_finding", NEW."effort_for_fixing", NEW."epss_percentile", NEW."epss_score", NEW."false_p", NEW."file_path", NEW."fix_available", NEW."fix_version", NEW."hash_code", NEW."id", NEW."impact", NEW."is_mitigated", NEW."kev_date", NEW."known_exploited", NEW."last_reviewed", NEW."last_reviewed_by_id", NEW."last_status_update", NEW."line", NEW."mitigated", NEW."mitigated_by_id", NEW."mitigation", NEW."nb_occurences", NEW."numerical_severity", NEW."out_of_scope", NEW."param", NEW."payload", _pgh_attach_context(), NOW(), 'insert', NEW."id", NEW."planned_remediation_date", NEW."planned_remediation_version", NEW."publish_date", NEW."ransomware_used", NEW."refs", NEW."reporter_id", NEW."review_requested_by_id", NEW."risk_accepted", NEW."sast_sink_object", NEW."sast_source_file_path", NEW."sast_source_line", NEW."sast_source_object", NEW."scanner_confidence", NEW."service", NEW."severity", NEW."severity_justification", NEW."sla_expiration_date", NEW."sla_start_date", NEW."sonarqube_issue_id", NEW."static_finding", NEW."steps_to_reproduce", NEW."test_id", NEW."thread_id", NEW."title", NEW."under_defect_review", NEW."under_review", NEW."unique_id_from_tool", NEW."updated", NEW."url", NEW."verified", NEW."vuln_id_from_tool"); RETURN NULL; + END; + $$ LANGUAGE plpgsql; + + DROP TRIGGER IF EXISTS pgtrigger_insert_insert_2fbbb ON "dojo_finding"; + CREATE TRIGGER pgtrigger_insert_insert_2fbbb + AFTER INSERT ON "dojo_finding" + + + FOR EACH ROW + EXECUTE PROCEDURE pgtrigger_insert_insert_2fbbb(); + + COMMENT ON TRIGGER pgtrigger_insert_insert_2fbbb ON "dojo_finding" IS 'b8eea714d4e92bd779ff82939552ad55346d949f'; + +-- +-- Remove trigger delete_delete from model engagement +-- + + CREATE OR REPLACE FUNCTION "public"._pgtrigger_should_ignore( + trigger_name NAME + ) + RETURNS BOOLEAN AS $$ + DECLARE + _pgtrigger_ignore TEXT[]; + _result BOOLEAN; + BEGIN + BEGIN + SELECT INTO _pgtrigger_ignore + CURRENT_SETTING('pgtrigger.ignore'); + EXCEPTION WHEN OTHERS THEN + END; + IF _pgtrigger_ignore IS NOT NULL THEN + SELECT trigger_name = ANY(_pgtrigger_ignore) + INTO _result; + RETURN _result; + ELSE + RETURN FALSE; + END IF; + END; + $$ LANGUAGE plpgsql; + + CREATE OR REPLACE FUNCTION pgtrigger_delete_delete_9f4df() + RETURNS TRIGGER AS $$ + + BEGIN + IF ("public"._pgtrigger_should_ignore(TG_NAME) IS TRUE) THEN + IF (TG_OP = 'DELETE') THEN + RETURN OLD; + ELSE + RETURN NEW; + END IF; + END IF; + INSERT INTO "dojo_engagementevent" ("active", "api_test", "branch_tag", "build_id", "check_list", "cicd_build_server_id", "cicd_orchestration_engine_id", "cicd_scm_server_id", "commit_hash", "created", "deduplication_on_engagement", "description", "done_testing", "engagement_type", "first_contacted", "id", "lead_id", "name", "pen_test", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "preset_id", "product_id", "progress", "reason", "report_type_id", "requester_id", "source_code_management_uri", "status", "target_end", "target_start", "test_strategy", "threat_model", "tmodel_path", "tracker", "updated", "version") VALUES (OLD."active", OLD."api_test", OLD."branch_tag", OLD."build_id", OLD."check_list", OLD."cicd_build_server_id", OLD."cicd_orchestration_engine_id", OLD."cicd_scm_server_id", OLD."commit_hash", OLD."created", OLD."deduplication_on_engagement", OLD."description", OLD."done_testing", OLD."engagement_type", OLD."first_contacted", OLD."id", OLD."lead_id", OLD."name", OLD."pen_test", _pgh_attach_context(), NOW(), 'delete', OLD."id", OLD."preset_id", OLD."product_id", OLD."progress", OLD."reason", OLD."report_type_id", OLD."requester_id", OLD."source_code_management_uri", OLD."status", OLD."target_end", OLD."target_start", OLD."test_strategy", OLD."threat_model", OLD."tmodel_path", OLD."tracker", OLD."updated", OLD."version"); RETURN NULL; + END; + $$ LANGUAGE plpgsql; + + DROP TRIGGER IF EXISTS pgtrigger_delete_delete_9f4df ON "dojo_engagement"; + CREATE TRIGGER pgtrigger_delete_delete_9f4df + AFTER DELETE ON "dojo_engagement" + + + FOR EACH ROW + EXECUTE PROCEDURE pgtrigger_delete_delete_9f4df(); + + COMMENT ON TRIGGER pgtrigger_delete_delete_9f4df ON "dojo_engagement" IS 'de64abfdac94fadfbe7a8cd33212b1dc26ad9600'; + +-- +-- Remove trigger update_update from model engagement +-- + + CREATE OR REPLACE FUNCTION "public"._pgtrigger_should_ignore( + trigger_name NAME + ) + RETURNS BOOLEAN AS $$ + DECLARE + _pgtrigger_ignore TEXT[]; + _result BOOLEAN; + BEGIN + BEGIN + SELECT INTO _pgtrigger_ignore + CURRENT_SETTING('pgtrigger.ignore'); + EXCEPTION WHEN OTHERS THEN + END; + IF _pgtrigger_ignore IS NOT NULL THEN + SELECT trigger_name = ANY(_pgtrigger_ignore) + INTO _result; + RETURN _result; + ELSE + RETURN FALSE; + END IF; + END; + $$ LANGUAGE plpgsql; + + CREATE OR REPLACE FUNCTION pgtrigger_update_update_65136() + RETURNS TRIGGER AS $$ + + BEGIN + IF ("public"._pgtrigger_should_ignore(TG_NAME) IS TRUE) THEN + IF (TG_OP = 'DELETE') THEN + RETURN OLD; + ELSE + RETURN NEW; + END IF; + END IF; + INSERT INTO "dojo_engagementevent" ("active", "api_test", "branch_tag", "build_id", "check_list", "cicd_build_server_id", "cicd_orchestration_engine_id", "cicd_scm_server_id", "commit_hash", "created", "deduplication_on_engagement", "description", "done_testing", "engagement_type", "first_contacted", "id", "lead_id", "name", "pen_test", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "preset_id", "product_id", "progress", "reason", "report_type_id", "requester_id", "source_code_management_uri", "status", "target_end", "target_start", "test_strategy", "threat_model", "tmodel_path", "tracker", "updated", "version") VALUES (NEW."active", NEW."api_test", NEW."branch_tag", NEW."build_id", NEW."check_list", NEW."cicd_build_server_id", NEW."cicd_orchestration_engine_id", NEW."cicd_scm_server_id", NEW."commit_hash", NEW."created", NEW."deduplication_on_engagement", NEW."description", NEW."done_testing", NEW."engagement_type", NEW."first_contacted", NEW."id", NEW."lead_id", NEW."name", NEW."pen_test", _pgh_attach_context(), NOW(), 'update', NEW."id", NEW."preset_id", NEW."product_id", NEW."progress", NEW."reason", NEW."report_type_id", NEW."requester_id", NEW."source_code_management_uri", NEW."status", NEW."target_end", NEW."target_start", NEW."test_strategy", NEW."threat_model", NEW."tmodel_path", NEW."tracker", NEW."updated", NEW."version"); RETURN NULL; + END; + $$ LANGUAGE plpgsql; + + DROP TRIGGER IF EXISTS pgtrigger_update_update_65136 ON "dojo_engagement"; + CREATE TRIGGER pgtrigger_update_update_65136 + AFTER UPDATE ON "dojo_engagement" + + + FOR EACH ROW WHEN (OLD."active" IS DISTINCT FROM (NEW."active") OR OLD."api_test" IS DISTINCT FROM (NEW."api_test") OR OLD."branch_tag" IS DISTINCT FROM (NEW."branch_tag") OR OLD."build_id" IS DISTINCT FROM (NEW."build_id") OR OLD."check_list" IS DISTINCT FROM (NEW."check_list") OR OLD."cicd_build_server_id" IS DISTINCT FROM (NEW."cicd_build_server_id") OR OLD."cicd_orchestration_engine_id" IS DISTINCT FROM (NEW."cicd_orchestration_engine_id") OR OLD."cicd_scm_server_id" IS DISTINCT FROM (NEW."cicd_scm_server_id") OR OLD."commit_hash" IS DISTINCT FROM (NEW."commit_hash") OR OLD."deduplication_on_engagement" IS DISTINCT FROM (NEW."deduplication_on_engagement") OR OLD."description" IS DISTINCT FROM (NEW."description") OR OLD."done_testing" IS DISTINCT FROM (NEW."done_testing") OR OLD."engagement_type" IS DISTINCT FROM (NEW."engagement_type") OR OLD."first_contacted" IS DISTINCT FROM (NEW."first_contacted") OR OLD."id" IS DISTINCT FROM (NEW."id") OR OLD."lead_id" IS DISTINCT FROM (NEW."lead_id") OR OLD."name" IS DISTINCT FROM (NEW."name") OR OLD."pen_test" IS DISTINCT FROM (NEW."pen_test") OR OLD."preset_id" IS DISTINCT FROM (NEW."preset_id") OR OLD."product_id" IS DISTINCT FROM (NEW."product_id") OR OLD."progress" IS DISTINCT FROM (NEW."progress") OR OLD."reason" IS DISTINCT FROM (NEW."reason") OR OLD."report_type_id" IS DISTINCT FROM (NEW."report_type_id") OR OLD."requester_id" IS DISTINCT FROM (NEW."requester_id") OR OLD."source_code_management_uri" IS DISTINCT FROM (NEW."source_code_management_uri") OR OLD."status" IS DISTINCT FROM (NEW."status") OR OLD."target_end" IS DISTINCT FROM (NEW."target_end") OR OLD."target_start" IS DISTINCT FROM (NEW."target_start") OR OLD."test_strategy" IS DISTINCT FROM (NEW."test_strategy") OR OLD."threat_model" IS DISTINCT FROM (NEW."threat_model") OR OLD."tmodel_path" IS DISTINCT FROM (NEW."tmodel_path") OR OLD."tracker" IS DISTINCT FROM (NEW."tracker") OR OLD."version" IS DISTINCT FROM (NEW."version")) + EXECUTE PROCEDURE pgtrigger_update_update_65136(); + + COMMENT ON TRIGGER pgtrigger_update_update_65136 ON "dojo_engagement" IS '6a9569fa21d5d7ad16eb018bc4e6236e8401bced'; + +-- +-- Remove trigger insert_insert from model engagement +-- + + CREATE OR REPLACE FUNCTION "public"._pgtrigger_should_ignore( + trigger_name NAME + ) + RETURNS BOOLEAN AS $$ + DECLARE + _pgtrigger_ignore TEXT[]; + _result BOOLEAN; + BEGIN + BEGIN + SELECT INTO _pgtrigger_ignore + CURRENT_SETTING('pgtrigger.ignore'); + EXCEPTION WHEN OTHERS THEN + END; + IF _pgtrigger_ignore IS NOT NULL THEN + SELECT trigger_name = ANY(_pgtrigger_ignore) + INTO _result; + RETURN _result; + ELSE + RETURN FALSE; + END IF; + END; + $$ LANGUAGE plpgsql; + + CREATE OR REPLACE FUNCTION pgtrigger_insert_insert_125f1() + RETURNS TRIGGER AS $$ + + BEGIN + IF ("public"._pgtrigger_should_ignore(TG_NAME) IS TRUE) THEN + IF (TG_OP = 'DELETE') THEN + RETURN OLD; + ELSE + RETURN NEW; + END IF; + END IF; + INSERT INTO "dojo_engagementevent" ("active", "api_test", "branch_tag", "build_id", "check_list", "cicd_build_server_id", "cicd_orchestration_engine_id", "cicd_scm_server_id", "commit_hash", "created", "deduplication_on_engagement", "description", "done_testing", "engagement_type", "first_contacted", "id", "lead_id", "name", "pen_test", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "preset_id", "product_id", "progress", "reason", "report_type_id", "requester_id", "source_code_management_uri", "status", "target_end", "target_start", "test_strategy", "threat_model", "tmodel_path", "tracker", "updated", "version") VALUES (NEW."active", NEW."api_test", NEW."branch_tag", NEW."build_id", NEW."check_list", NEW."cicd_build_server_id", NEW."cicd_orchestration_engine_id", NEW."cicd_scm_server_id", NEW."commit_hash", NEW."created", NEW."deduplication_on_engagement", NEW."description", NEW."done_testing", NEW."engagement_type", NEW."first_contacted", NEW."id", NEW."lead_id", NEW."name", NEW."pen_test", _pgh_attach_context(), NOW(), 'insert', NEW."id", NEW."preset_id", NEW."product_id", NEW."progress", NEW."reason", NEW."report_type_id", NEW."requester_id", NEW."source_code_management_uri", NEW."status", NEW."target_end", NEW."target_start", NEW."test_strategy", NEW."threat_model", NEW."tmodel_path", NEW."tracker", NEW."updated", NEW."version"); RETURN NULL; + END; + $$ LANGUAGE plpgsql; + + DROP TRIGGER IF EXISTS pgtrigger_insert_insert_125f1 ON "dojo_engagement"; + CREATE TRIGGER pgtrigger_insert_insert_125f1 + AFTER INSERT ON "dojo_engagement" + + + FOR EACH ROW + EXECUTE PROCEDURE pgtrigger_insert_insert_125f1(); + + COMMENT ON TRIGGER pgtrigger_insert_insert_125f1 ON "dojo_engagement" IS 'a217ec77b975020749afc350ee463c5867cfea27'; + +-- +-- Remove trigger delete_delete from model endpoint +-- + + CREATE OR REPLACE FUNCTION "public"._pgtrigger_should_ignore( + trigger_name NAME + ) + RETURNS BOOLEAN AS $$ + DECLARE + _pgtrigger_ignore TEXT[]; + _result BOOLEAN; + BEGIN + BEGIN + SELECT INTO _pgtrigger_ignore + CURRENT_SETTING('pgtrigger.ignore'); + EXCEPTION WHEN OTHERS THEN + END; + IF _pgtrigger_ignore IS NOT NULL THEN + SELECT trigger_name = ANY(_pgtrigger_ignore) + INTO _result; + RETURN _result; + ELSE + RETURN FALSE; + END IF; + END; + $$ LANGUAGE plpgsql; + + CREATE OR REPLACE FUNCTION pgtrigger_delete_delete_dd1f9() + RETURNS TRIGGER AS $$ + + BEGIN + IF ("public"._pgtrigger_should_ignore(TG_NAME) IS TRUE) THEN + IF (TG_OP = 'DELETE') THEN + RETURN OLD; + ELSE + RETURN NEW; + END IF; + END IF; + INSERT INTO "dojo_endpointevent" ("fragment", "host", "id", "path", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "port", "product_id", "protocol", "query", "userinfo") VALUES (OLD."fragment", OLD."host", OLD."id", OLD."path", _pgh_attach_context(), NOW(), 'delete', OLD."id", OLD."port", OLD."product_id", OLD."protocol", OLD."query", OLD."userinfo"); RETURN NULL; + END; + $$ LANGUAGE plpgsql; + + DROP TRIGGER IF EXISTS pgtrigger_delete_delete_dd1f9 ON "dojo_endpoint"; + CREATE TRIGGER pgtrigger_delete_delete_dd1f9 + AFTER DELETE ON "dojo_endpoint" + + + FOR EACH ROW + EXECUTE PROCEDURE pgtrigger_delete_delete_dd1f9(); + + COMMENT ON TRIGGER pgtrigger_delete_delete_dd1f9 ON "dojo_endpoint" IS '5e88416165d3e62cc6717b7d7f5d82933929de32'; + +-- +-- Remove trigger update_update from model endpoint +-- + + CREATE OR REPLACE FUNCTION "public"._pgtrigger_should_ignore( + trigger_name NAME + ) + RETURNS BOOLEAN AS $$ + DECLARE + _pgtrigger_ignore TEXT[]; + _result BOOLEAN; + BEGIN + BEGIN + SELECT INTO _pgtrigger_ignore + CURRENT_SETTING('pgtrigger.ignore'); + EXCEPTION WHEN OTHERS THEN + END; + IF _pgtrigger_ignore IS NOT NULL THEN + SELECT trigger_name = ANY(_pgtrigger_ignore) + INTO _result; + RETURN _result; + ELSE + RETURN FALSE; + END IF; + END; + $$ LANGUAGE plpgsql; + + CREATE OR REPLACE FUNCTION pgtrigger_update_update_2b19a() + RETURNS TRIGGER AS $$ + + BEGIN + IF ("public"._pgtrigger_should_ignore(TG_NAME) IS TRUE) THEN + IF (TG_OP = 'DELETE') THEN + RETURN OLD; + ELSE + RETURN NEW; + END IF; + END IF; + INSERT INTO "dojo_endpointevent" ("fragment", "host", "id", "path", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "port", "product_id", "protocol", "query", "userinfo") VALUES (NEW."fragment", NEW."host", NEW."id", NEW."path", _pgh_attach_context(), NOW(), 'update', NEW."id", NEW."port", NEW."product_id", NEW."protocol", NEW."query", NEW."userinfo"); RETURN NULL; + END; + $$ LANGUAGE plpgsql; + + DROP TRIGGER IF EXISTS pgtrigger_update_update_2b19a ON "dojo_endpoint"; + CREATE TRIGGER pgtrigger_update_update_2b19a + AFTER UPDATE ON "dojo_endpoint" + + + FOR EACH ROW WHEN (OLD.* IS DISTINCT FROM NEW.*) + EXECUTE PROCEDURE pgtrigger_update_update_2b19a(); + + COMMENT ON TRIGGER pgtrigger_update_update_2b19a ON "dojo_endpoint" IS 'fce28bcbd64850a383950a720a72f134da7989d9'; + +-- +-- Remove trigger insert_insert from model endpoint +-- + + CREATE OR REPLACE FUNCTION "public"._pgtrigger_should_ignore( + trigger_name NAME + ) + RETURNS BOOLEAN AS $$ + DECLARE + _pgtrigger_ignore TEXT[]; + _result BOOLEAN; + BEGIN + BEGIN + SELECT INTO _pgtrigger_ignore + CURRENT_SETTING('pgtrigger.ignore'); + EXCEPTION WHEN OTHERS THEN + END; + IF _pgtrigger_ignore IS NOT NULL THEN + SELECT trigger_name = ANY(_pgtrigger_ignore) + INTO _result; + RETURN _result; + ELSE + RETURN FALSE; + END IF; + END; + $$ LANGUAGE plpgsql; + + CREATE OR REPLACE FUNCTION pgtrigger_insert_insert_c7973() + RETURNS TRIGGER AS $$ + + BEGIN + IF ("public"._pgtrigger_should_ignore(TG_NAME) IS TRUE) THEN + IF (TG_OP = 'DELETE') THEN + RETURN OLD; + ELSE + RETURN NEW; + END IF; + END IF; + INSERT INTO "dojo_endpointevent" ("fragment", "host", "id", "path", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "port", "product_id", "protocol", "query", "userinfo") VALUES (NEW."fragment", NEW."host", NEW."id", NEW."path", _pgh_attach_context(), NOW(), 'insert', NEW."id", NEW."port", NEW."product_id", NEW."protocol", NEW."query", NEW."userinfo"); RETURN NULL; + END; + $$ LANGUAGE plpgsql; + + DROP TRIGGER IF EXISTS pgtrigger_insert_insert_c7973 ON "dojo_endpoint"; + CREATE TRIGGER pgtrigger_insert_insert_c7973 + AFTER INSERT ON "dojo_endpoint" + + + FOR EACH ROW + EXECUTE PROCEDURE pgtrigger_insert_insert_c7973(); + + COMMENT ON TRIGGER pgtrigger_insert_insert_c7973 ON "dojo_endpoint" IS '68e589c514e437831f4da3e802ca18e4cced175d'; +""" + + +class Migration(migrations.Migration): + + """ + Archive columns on the hierarchy and its child rows, with their audit triggers. + + The operations are applied to the migration state only; the database work is the + frozen SQL they generate, run as one statement batch at the end. Django rebuilds its + model state after every operation, which takes most of a minute for these, and in a + plain migration each table's ACCESS EXCLUSIVE lock is taken by its ALTER and held + through all the rebuilding that follows. On 10 million findings that blocked every + read of dojo_finding for about 40 seconds. Done this way the locks are held only for + the SQL itself. + """ + + dependencies = [ + ("dojo", "0303_system_settings_install_id"), + ] + + operations = [ + migrations.SeparateDatabaseAndState( + state_operations=[ + pgtrigger.migrations.RemoveTrigger( + model_name="endpoint", + name="insert_insert", + ), + pgtrigger.migrations.RemoveTrigger( + model_name="endpoint", + name="update_update", + ), + pgtrigger.migrations.RemoveTrigger( + model_name="endpoint", + name="delete_delete", + ), + pgtrigger.migrations.RemoveTrigger( + model_name="engagement", + name="insert_insert", + ), + pgtrigger.migrations.RemoveTrigger( + model_name="engagement", + name="update_update", + ), + pgtrigger.migrations.RemoveTrigger( + model_name="engagement", + name="delete_delete", + ), + pgtrigger.migrations.RemoveTrigger( + model_name="finding", + name="insert_insert", + ), + pgtrigger.migrations.RemoveTrigger( + model_name="finding", + name="update_update", + ), + pgtrigger.migrations.RemoveTrigger( + model_name="finding", + name="delete_delete", + ), + pgtrigger.migrations.RemoveTrigger( + model_name="finding_group", + name="insert_insert", + ), + pgtrigger.migrations.RemoveTrigger( + model_name="finding_group", + name="update_update", + ), + pgtrigger.migrations.RemoveTrigger( + model_name="finding_group", + name="delete_delete", + ), + pgtrigger.migrations.RemoveTrigger( + model_name="product", + name="insert_insert", + ), + pgtrigger.migrations.RemoveTrigger( + model_name="product", + name="update_update", + ), + pgtrigger.migrations.RemoveTrigger( + model_name="product", + name="delete_delete", + ), + pgtrigger.migrations.RemoveTrigger( + model_name="product_type", + name="insert_insert", + ), + pgtrigger.migrations.RemoveTrigger( + model_name="product_type", + name="update_update", + ), + pgtrigger.migrations.RemoveTrigger( + model_name="product_type", + name="delete_delete", + ), + pgtrigger.migrations.RemoveTrigger( + model_name="test", + name="insert_insert", + ), + pgtrigger.migrations.RemoveTrigger( + model_name="test", + name="update_update", + ), + pgtrigger.migrations.RemoveTrigger( + model_name="test", + name="delete_delete", + ), + migrations.AddField( + model_name="app_analysis", + name="archive_batch", + field=models.UUIDField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="app_analysis", + name="archived_at", + field=models.DateTimeField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="dojometa", + name="archive_batch", + field=models.UUIDField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="dojometa", + name="archived_at", + field=models.DateTimeField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="endpoint", + name="archive_batch", + field=models.UUIDField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="endpoint", + name="archived_at", + field=models.DateTimeField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="endpoint_status", + name="archive_batch", + field=models.UUIDField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="endpoint_status", + name="archived_at", + field=models.DateTimeField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="endpointevent", + name="archive_batch", + field=models.UUIDField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="endpointevent", + name="archived_at", + field=models.DateTimeField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="engagement", + name="archive_batch", + field=models.UUIDField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="engagement", + name="archived_at", + field=models.DateTimeField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="engagement_presets", + name="archive_batch", + field=models.UUIDField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="engagement_presets", + name="archived_at", + field=models.DateTimeField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="engagementevent", + name="archive_batch", + field=models.UUIDField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="engagementevent", + name="archived_at", + field=models.DateTimeField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="finding", + name="archive_batch", + field=models.UUIDField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="finding", + name="archived_at", + field=models.DateTimeField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="finding_group", + name="archive_batch", + field=models.UUIDField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="finding_group", + name="archived_at", + field=models.DateTimeField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="finding_groupevent", + name="archive_batch", + field=models.UUIDField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="finding_groupevent", + name="archived_at", + field=models.DateTimeField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="findingevent", + name="archive_batch", + field=models.UUIDField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="findingevent", + name="archived_at", + field=models.DateTimeField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="findingvulnerabilityreference", + name="archive_batch", + field=models.UUIDField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="findingvulnerabilityreference", + name="archived_at", + field=models.DateTimeField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="jira_issue", + name="archive_batch", + field=models.UUIDField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="jira_issue", + name="archived_at", + field=models.DateTimeField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="jira_project", + name="archive_batch", + field=models.UUIDField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="jira_project", + name="archived_at", + field=models.DateTimeField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="languages", + name="archive_batch", + field=models.UUIDField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="languages", + name="archived_at", + field=models.DateTimeField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="locationfindingreference", + name="archive_batch", + field=models.UUIDField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="locationfindingreference", + name="archived_at", + field=models.DateTimeField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="locationproductreference", + name="archive_batch", + field=models.UUIDField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="locationproductreference", + name="archived_at", + field=models.DateTimeField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="objects_product", + name="archive_batch", + field=models.UUIDField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="objects_product", + name="archived_at", + field=models.DateTimeField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="product", + name="archive_batch", + field=models.UUIDField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="product", + name="archived_at", + field=models.DateTimeField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="product_api_scan_configuration", + name="archive_batch", + field=models.UUIDField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="product_api_scan_configuration", + name="archived_at", + field=models.DateTimeField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="product_type", + name="archive_batch", + field=models.UUIDField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="product_type", + name="archived_at", + field=models.DateTimeField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="product_typeevent", + name="archive_batch", + field=models.UUIDField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="product_typeevent", + name="archived_at", + field=models.DateTimeField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="productevent", + name="archive_batch", + field=models.UUIDField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="productevent", + name="archived_at", + field=models.DateTimeField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="test", + name="archive_batch", + field=models.UUIDField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="test", + name="archived_at", + field=models.DateTimeField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="test_import", + name="archive_batch", + field=models.UUIDField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="test_import", + name="archived_at", + field=models.DateTimeField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="test_import_finding_action", + name="archive_batch", + field=models.UUIDField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="test_import_finding_action", + name="archived_at", + field=models.DateTimeField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="testevent", + name="archive_batch", + field=models.UUIDField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="testevent", + name="archived_at", + field=models.DateTimeField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="tool_product_settings", + name="archive_batch", + field=models.UUIDField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="tool_product_settings", + name="archived_at", + field=models.DateTimeField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="vulnerability_id", + name="archive_batch", + field=models.UUIDField(blank=True, editable=False, null=True), + ), + migrations.AddField( + model_name="vulnerability_id", + name="archived_at", + field=models.DateTimeField(blank=True, editable=False, null=True), + ), + pgtrigger.migrations.AddTrigger( + model_name="endpoint", + trigger=pgtrigger.compiler.Trigger(name="insert_insert", sql=pgtrigger.compiler.UpsertTriggerSql(func='INSERT INTO "dojo_endpointevent" ("archive_batch", "archived_at", "fragment", "host", "id", "path", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "port", "product_id", "protocol", "query", "userinfo") VALUES (NEW."archive_batch", NEW."archived_at", NEW."fragment", NEW."host", NEW."id", NEW."path", _pgh_attach_context(), NOW(), \'insert\', NEW."id", NEW."port", NEW."product_id", NEW."protocol", NEW."query", NEW."userinfo"); RETURN NULL;', hash="4aa86c99a53e2afc8a2e7bbc9dce7e87cfe93c99", operation="INSERT", pgid="pgtrigger_insert_insert_c7973", table="dojo_endpoint", when="AFTER")), + ), + pgtrigger.migrations.AddTrigger( + model_name="endpoint", + trigger=pgtrigger.compiler.Trigger(name="update_update", sql=pgtrigger.compiler.UpsertTriggerSql(condition="WHEN (OLD.* IS DISTINCT FROM NEW.*)", func='INSERT INTO "dojo_endpointevent" ("archive_batch", "archived_at", "fragment", "host", "id", "path", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "port", "product_id", "protocol", "query", "userinfo") VALUES (NEW."archive_batch", NEW."archived_at", NEW."fragment", NEW."host", NEW."id", NEW."path", _pgh_attach_context(), NOW(), \'update\', NEW."id", NEW."port", NEW."product_id", NEW."protocol", NEW."query", NEW."userinfo"); RETURN NULL;', hash="187a4d67775847794459c2d4249fe13e333b2118", operation="UPDATE", pgid="pgtrigger_update_update_2b19a", table="dojo_endpoint", when="AFTER")), + ), + pgtrigger.migrations.AddTrigger( + model_name="endpoint", + trigger=pgtrigger.compiler.Trigger(name="delete_delete", sql=pgtrigger.compiler.UpsertTriggerSql(func='INSERT INTO "dojo_endpointevent" ("archive_batch", "archived_at", "fragment", "host", "id", "path", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "port", "product_id", "protocol", "query", "userinfo") VALUES (OLD."archive_batch", OLD."archived_at", OLD."fragment", OLD."host", OLD."id", OLD."path", _pgh_attach_context(), NOW(), \'delete\', OLD."id", OLD."port", OLD."product_id", OLD."protocol", OLD."query", OLD."userinfo"); RETURN NULL;', hash="c30fc33fac55999df702b7c9c249f64513bf7497", operation="DELETE", pgid="pgtrigger_delete_delete_dd1f9", table="dojo_endpoint", when="AFTER")), + ), + pgtrigger.migrations.AddTrigger( + model_name="engagement", + trigger=pgtrigger.compiler.Trigger(name="insert_insert", sql=pgtrigger.compiler.UpsertTriggerSql(func='INSERT INTO "dojo_engagementevent" ("active", "api_test", "archive_batch", "archived_at", "branch_tag", "build_id", "check_list", "cicd_build_server_id", "cicd_orchestration_engine_id", "cicd_scm_server_id", "commit_hash", "created", "deduplication_on_engagement", "description", "done_testing", "engagement_type", "first_contacted", "id", "lead_id", "name", "pen_test", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "preset_id", "product_id", "progress", "reason", "report_type_id", "requester_id", "source_code_management_uri", "status", "target_end", "target_start", "test_strategy", "threat_model", "tmodel_path", "tracker", "updated", "version") VALUES (NEW."active", NEW."api_test", NEW."archive_batch", NEW."archived_at", NEW."branch_tag", NEW."build_id", NEW."check_list", NEW."cicd_build_server_id", NEW."cicd_orchestration_engine_id", NEW."cicd_scm_server_id", NEW."commit_hash", NEW."created", NEW."deduplication_on_engagement", NEW."description", NEW."done_testing", NEW."engagement_type", NEW."first_contacted", NEW."id", NEW."lead_id", NEW."name", NEW."pen_test", _pgh_attach_context(), NOW(), \'insert\', NEW."id", NEW."preset_id", NEW."product_id", NEW."progress", NEW."reason", NEW."report_type_id", NEW."requester_id", NEW."source_code_management_uri", NEW."status", NEW."target_end", NEW."target_start", NEW."test_strategy", NEW."threat_model", NEW."tmodel_path", NEW."tracker", NEW."updated", NEW."version"); RETURN NULL;', hash="5b48232cfe7dc67a91eebfd023a4ccb6eb920c39", operation="INSERT", pgid="pgtrigger_insert_insert_125f1", table="dojo_engagement", when="AFTER")), + ), + pgtrigger.migrations.AddTrigger( + model_name="engagement", + trigger=pgtrigger.compiler.Trigger(name="update_update", sql=pgtrigger.compiler.UpsertTriggerSql(condition='WHEN (OLD."active" IS DISTINCT FROM (NEW."active") OR OLD."api_test" IS DISTINCT FROM (NEW."api_test") OR OLD."archive_batch" IS DISTINCT FROM (NEW."archive_batch") OR OLD."archived_at" IS DISTINCT FROM (NEW."archived_at") OR OLD."branch_tag" IS DISTINCT FROM (NEW."branch_tag") OR OLD."build_id" IS DISTINCT FROM (NEW."build_id") OR OLD."check_list" IS DISTINCT FROM (NEW."check_list") OR OLD."cicd_build_server_id" IS DISTINCT FROM (NEW."cicd_build_server_id") OR OLD."cicd_orchestration_engine_id" IS DISTINCT FROM (NEW."cicd_orchestration_engine_id") OR OLD."cicd_scm_server_id" IS DISTINCT FROM (NEW."cicd_scm_server_id") OR OLD."commit_hash" IS DISTINCT FROM (NEW."commit_hash") OR OLD."deduplication_on_engagement" IS DISTINCT FROM (NEW."deduplication_on_engagement") OR OLD."description" IS DISTINCT FROM (NEW."description") OR OLD."done_testing" IS DISTINCT FROM (NEW."done_testing") OR OLD."engagement_type" IS DISTINCT FROM (NEW."engagement_type") OR OLD."first_contacted" IS DISTINCT FROM (NEW."first_contacted") OR OLD."id" IS DISTINCT FROM (NEW."id") OR OLD."lead_id" IS DISTINCT FROM (NEW."lead_id") OR OLD."name" IS DISTINCT FROM (NEW."name") OR OLD."pen_test" IS DISTINCT FROM (NEW."pen_test") OR OLD."preset_id" IS DISTINCT FROM (NEW."preset_id") OR OLD."product_id" IS DISTINCT FROM (NEW."product_id") OR OLD."progress" IS DISTINCT FROM (NEW."progress") OR OLD."reason" IS DISTINCT FROM (NEW."reason") OR OLD."report_type_id" IS DISTINCT FROM (NEW."report_type_id") OR OLD."requester_id" IS DISTINCT FROM (NEW."requester_id") OR OLD."source_code_management_uri" IS DISTINCT FROM (NEW."source_code_management_uri") OR OLD."status" IS DISTINCT FROM (NEW."status") OR OLD."target_end" IS DISTINCT FROM (NEW."target_end") OR OLD."target_start" IS DISTINCT FROM (NEW."target_start") OR OLD."test_strategy" IS DISTINCT FROM (NEW."test_strategy") OR OLD."threat_model" IS DISTINCT FROM (NEW."threat_model") OR OLD."tmodel_path" IS DISTINCT FROM (NEW."tmodel_path") OR OLD."tracker" IS DISTINCT FROM (NEW."tracker") OR OLD."version" IS DISTINCT FROM (NEW."version"))', func='INSERT INTO "dojo_engagementevent" ("active", "api_test", "archive_batch", "archived_at", "branch_tag", "build_id", "check_list", "cicd_build_server_id", "cicd_orchestration_engine_id", "cicd_scm_server_id", "commit_hash", "created", "deduplication_on_engagement", "description", "done_testing", "engagement_type", "first_contacted", "id", "lead_id", "name", "pen_test", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "preset_id", "product_id", "progress", "reason", "report_type_id", "requester_id", "source_code_management_uri", "status", "target_end", "target_start", "test_strategy", "threat_model", "tmodel_path", "tracker", "updated", "version") VALUES (NEW."active", NEW."api_test", NEW."archive_batch", NEW."archived_at", NEW."branch_tag", NEW."build_id", NEW."check_list", NEW."cicd_build_server_id", NEW."cicd_orchestration_engine_id", NEW."cicd_scm_server_id", NEW."commit_hash", NEW."created", NEW."deduplication_on_engagement", NEW."description", NEW."done_testing", NEW."engagement_type", NEW."first_contacted", NEW."id", NEW."lead_id", NEW."name", NEW."pen_test", _pgh_attach_context(), NOW(), \'update\', NEW."id", NEW."preset_id", NEW."product_id", NEW."progress", NEW."reason", NEW."report_type_id", NEW."requester_id", NEW."source_code_management_uri", NEW."status", NEW."target_end", NEW."target_start", NEW."test_strategy", NEW."threat_model", NEW."tmodel_path", NEW."tracker", NEW."updated", NEW."version"); RETURN NULL;', hash="8990b78ab9370e3cd1ec2b85dd89d52834d5aaf6", operation="UPDATE", pgid="pgtrigger_update_update_65136", table="dojo_engagement", when="AFTER")), + ), + pgtrigger.migrations.AddTrigger( + model_name="engagement", + trigger=pgtrigger.compiler.Trigger(name="delete_delete", sql=pgtrigger.compiler.UpsertTriggerSql(func='INSERT INTO "dojo_engagementevent" ("active", "api_test", "archive_batch", "archived_at", "branch_tag", "build_id", "check_list", "cicd_build_server_id", "cicd_orchestration_engine_id", "cicd_scm_server_id", "commit_hash", "created", "deduplication_on_engagement", "description", "done_testing", "engagement_type", "first_contacted", "id", "lead_id", "name", "pen_test", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "preset_id", "product_id", "progress", "reason", "report_type_id", "requester_id", "source_code_management_uri", "status", "target_end", "target_start", "test_strategy", "threat_model", "tmodel_path", "tracker", "updated", "version") VALUES (OLD."active", OLD."api_test", OLD."archive_batch", OLD."archived_at", OLD."branch_tag", OLD."build_id", OLD."check_list", OLD."cicd_build_server_id", OLD."cicd_orchestration_engine_id", OLD."cicd_scm_server_id", OLD."commit_hash", OLD."created", OLD."deduplication_on_engagement", OLD."description", OLD."done_testing", OLD."engagement_type", OLD."first_contacted", OLD."id", OLD."lead_id", OLD."name", OLD."pen_test", _pgh_attach_context(), NOW(), \'delete\', OLD."id", OLD."preset_id", OLD."product_id", OLD."progress", OLD."reason", OLD."report_type_id", OLD."requester_id", OLD."source_code_management_uri", OLD."status", OLD."target_end", OLD."target_start", OLD."test_strategy", OLD."threat_model", OLD."tmodel_path", OLD."tracker", OLD."updated", OLD."version"); RETURN NULL;', hash="0de881cdff9409808f24eb0258bdd61ae9ddc60e", operation="DELETE", pgid="pgtrigger_delete_delete_9f4df", table="dojo_engagement", when="AFTER")), + ), + pgtrigger.migrations.AddTrigger( + model_name="finding", + trigger=pgtrigger.compiler.Trigger(name="insert_insert", sql=pgtrigger.compiler.UpsertTriggerSql(func='INSERT INTO "dojo_findingevent" ("active", "archive_batch", "archived_at", "component_name", "component_version", "created", "cve", "cvssv3", "cvssv3_score", "cvssv4", "cvssv4_score", "cwe", "date", "defect_review_requested_by_id", "description", "duplicate", "duplicate_finding_id", "dynamic_finding", "effort_for_fixing", "epss_percentile", "epss_score", "false_p", "file_path", "fix_available", "fix_version", "hash_code", "id", "impact", "is_mitigated", "kev_date", "known_exploited", "last_reviewed", "last_reviewed_by_id", "last_status_update", "line", "mitigated", "mitigated_by_id", "mitigation", "nb_occurences", "numerical_severity", "out_of_scope", "param", "payload", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "planned_remediation_date", "planned_remediation_version", "publish_date", "ransomware_used", "refs", "reporter_id", "review_requested_by_id", "risk_accepted", "sast_sink_object", "sast_source_file_path", "sast_source_line", "sast_source_object", "scanner_confidence", "service", "severity", "severity_justification", "sla_expiration_date", "sla_start_date", "sonarqube_issue_id", "static_finding", "steps_to_reproduce", "test_id", "thread_id", "title", "under_defect_review", "under_review", "unique_id_from_tool", "updated", "url", "verified", "vuln_id_from_tool") VALUES (NEW."active", NEW."archive_batch", NEW."archived_at", NEW."component_name", NEW."component_version", NEW."created", NEW."cve", NEW."cvssv3", NEW."cvssv3_score", NEW."cvssv4", NEW."cvssv4_score", NEW."cwe", NEW."date", NEW."defect_review_requested_by_id", NEW."description", NEW."duplicate", NEW."duplicate_finding_id", NEW."dynamic_finding", NEW."effort_for_fixing", NEW."epss_percentile", NEW."epss_score", NEW."false_p", NEW."file_path", NEW."fix_available", NEW."fix_version", NEW."hash_code", NEW."id", NEW."impact", NEW."is_mitigated", NEW."kev_date", NEW."known_exploited", NEW."last_reviewed", NEW."last_reviewed_by_id", NEW."last_status_update", NEW."line", NEW."mitigated", NEW."mitigated_by_id", NEW."mitigation", NEW."nb_occurences", NEW."numerical_severity", NEW."out_of_scope", NEW."param", NEW."payload", _pgh_attach_context(), NOW(), \'insert\', NEW."id", NEW."planned_remediation_date", NEW."planned_remediation_version", NEW."publish_date", NEW."ransomware_used", NEW."refs", NEW."reporter_id", NEW."review_requested_by_id", NEW."risk_accepted", NEW."sast_sink_object", NEW."sast_source_file_path", NEW."sast_source_line", NEW."sast_source_object", NEW."scanner_confidence", NEW."service", NEW."severity", NEW."severity_justification", NEW."sla_expiration_date", NEW."sla_start_date", NEW."sonarqube_issue_id", NEW."static_finding", NEW."steps_to_reproduce", NEW."test_id", NEW."thread_id", NEW."title", NEW."under_defect_review", NEW."under_review", NEW."unique_id_from_tool", NEW."updated", NEW."url", NEW."verified", NEW."vuln_id_from_tool"); RETURN NULL;', hash="bfca827e3bf9d38085346f34984b62bfc9efa036", operation="INSERT", pgid="pgtrigger_insert_insert_2fbbb", table="dojo_finding", when="AFTER")), + ), + pgtrigger.migrations.AddTrigger( + model_name="finding", + trigger=pgtrigger.compiler.Trigger(name="update_update", sql=pgtrigger.compiler.UpsertTriggerSql(condition='WHEN (OLD."active" IS DISTINCT FROM (NEW."active") OR OLD."archive_batch" IS DISTINCT FROM (NEW."archive_batch") OR OLD."archived_at" IS DISTINCT FROM (NEW."archived_at") OR OLD."component_name" IS DISTINCT FROM (NEW."component_name") OR OLD."component_version" IS DISTINCT FROM (NEW."component_version") OR OLD."cve" IS DISTINCT FROM (NEW."cve") OR OLD."cvssv3" IS DISTINCT FROM (NEW."cvssv3") OR OLD."cvssv3_score" IS DISTINCT FROM (NEW."cvssv3_score") OR OLD."cvssv4" IS DISTINCT FROM (NEW."cvssv4") OR OLD."cvssv4_score" IS DISTINCT FROM (NEW."cvssv4_score") OR OLD."cwe" IS DISTINCT FROM (NEW."cwe") OR OLD."date" IS DISTINCT FROM (NEW."date") OR OLD."defect_review_requested_by_id" IS DISTINCT FROM (NEW."defect_review_requested_by_id") OR OLD."description" IS DISTINCT FROM (NEW."description") OR OLD."duplicate" IS DISTINCT FROM (NEW."duplicate") OR OLD."duplicate_finding_id" IS DISTINCT FROM (NEW."duplicate_finding_id") OR OLD."dynamic_finding" IS DISTINCT FROM (NEW."dynamic_finding") OR OLD."effort_for_fixing" IS DISTINCT FROM (NEW."effort_for_fixing") OR OLD."epss_percentile" IS DISTINCT FROM (NEW."epss_percentile") OR OLD."epss_score" IS DISTINCT FROM (NEW."epss_score") OR OLD."false_p" IS DISTINCT FROM (NEW."false_p") OR OLD."file_path" IS DISTINCT FROM (NEW."file_path") OR OLD."fix_available" IS DISTINCT FROM (NEW."fix_available") OR OLD."fix_version" IS DISTINCT FROM (NEW."fix_version") OR OLD."hash_code" IS DISTINCT FROM (NEW."hash_code") OR OLD."id" IS DISTINCT FROM (NEW."id") OR OLD."impact" IS DISTINCT FROM (NEW."impact") OR OLD."is_mitigated" IS DISTINCT FROM (NEW."is_mitigated") OR OLD."kev_date" IS DISTINCT FROM (NEW."kev_date") OR OLD."known_exploited" IS DISTINCT FROM (NEW."known_exploited") OR OLD."last_reviewed" IS DISTINCT FROM (NEW."last_reviewed") OR OLD."last_reviewed_by_id" IS DISTINCT FROM (NEW."last_reviewed_by_id") OR OLD."line" IS DISTINCT FROM (NEW."line") OR OLD."mitigated" IS DISTINCT FROM (NEW."mitigated") OR OLD."mitigated_by_id" IS DISTINCT FROM (NEW."mitigated_by_id") OR OLD."mitigation" IS DISTINCT FROM (NEW."mitigation") OR OLD."nb_occurences" IS DISTINCT FROM (NEW."nb_occurences") OR OLD."numerical_severity" IS DISTINCT FROM (NEW."numerical_severity") OR OLD."out_of_scope" IS DISTINCT FROM (NEW."out_of_scope") OR OLD."param" IS DISTINCT FROM (NEW."param") OR OLD."payload" IS DISTINCT FROM (NEW."payload") OR OLD."planned_remediation_date" IS DISTINCT FROM (NEW."planned_remediation_date") OR OLD."planned_remediation_version" IS DISTINCT FROM (NEW."planned_remediation_version") OR OLD."publish_date" IS DISTINCT FROM (NEW."publish_date") OR OLD."ransomware_used" IS DISTINCT FROM (NEW."ransomware_used") OR OLD."refs" IS DISTINCT FROM (NEW."refs") OR OLD."reporter_id" IS DISTINCT FROM (NEW."reporter_id") OR OLD."review_requested_by_id" IS DISTINCT FROM (NEW."review_requested_by_id") OR OLD."risk_accepted" IS DISTINCT FROM (NEW."risk_accepted") OR OLD."sast_sink_object" IS DISTINCT FROM (NEW."sast_sink_object") OR OLD."sast_source_file_path" IS DISTINCT FROM (NEW."sast_source_file_path") OR OLD."sast_source_line" IS DISTINCT FROM (NEW."sast_source_line") OR OLD."sast_source_object" IS DISTINCT FROM (NEW."sast_source_object") OR OLD."scanner_confidence" IS DISTINCT FROM (NEW."scanner_confidence") OR OLD."service" IS DISTINCT FROM (NEW."service") OR OLD."severity" IS DISTINCT FROM (NEW."severity") OR OLD."severity_justification" IS DISTINCT FROM (NEW."severity_justification") OR OLD."sla_expiration_date" IS DISTINCT FROM (NEW."sla_expiration_date") OR OLD."sla_start_date" IS DISTINCT FROM (NEW."sla_start_date") OR OLD."sonarqube_issue_id" IS DISTINCT FROM (NEW."sonarqube_issue_id") OR OLD."static_finding" IS DISTINCT FROM (NEW."static_finding") OR OLD."steps_to_reproduce" IS DISTINCT FROM (NEW."steps_to_reproduce") OR OLD."test_id" IS DISTINCT FROM (NEW."test_id") OR OLD."thread_id" IS DISTINCT FROM (NEW."thread_id") OR OLD."title" IS DISTINCT FROM (NEW."title") OR OLD."under_defect_review" IS DISTINCT FROM (NEW."under_defect_review") OR OLD."under_review" IS DISTINCT FROM (NEW."under_review") OR OLD."unique_id_from_tool" IS DISTINCT FROM (NEW."unique_id_from_tool") OR OLD."url" IS DISTINCT FROM (NEW."url") OR OLD."verified" IS DISTINCT FROM (NEW."verified") OR OLD."vuln_id_from_tool" IS DISTINCT FROM (NEW."vuln_id_from_tool"))', func='INSERT INTO "dojo_findingevent" ("active", "archive_batch", "archived_at", "component_name", "component_version", "created", "cve", "cvssv3", "cvssv3_score", "cvssv4", "cvssv4_score", "cwe", "date", "defect_review_requested_by_id", "description", "duplicate", "duplicate_finding_id", "dynamic_finding", "effort_for_fixing", "epss_percentile", "epss_score", "false_p", "file_path", "fix_available", "fix_version", "hash_code", "id", "impact", "is_mitigated", "kev_date", "known_exploited", "last_reviewed", "last_reviewed_by_id", "last_status_update", "line", "mitigated", "mitigated_by_id", "mitigation", "nb_occurences", "numerical_severity", "out_of_scope", "param", "payload", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "planned_remediation_date", "planned_remediation_version", "publish_date", "ransomware_used", "refs", "reporter_id", "review_requested_by_id", "risk_accepted", "sast_sink_object", "sast_source_file_path", "sast_source_line", "sast_source_object", "scanner_confidence", "service", "severity", "severity_justification", "sla_expiration_date", "sla_start_date", "sonarqube_issue_id", "static_finding", "steps_to_reproduce", "test_id", "thread_id", "title", "under_defect_review", "under_review", "unique_id_from_tool", "updated", "url", "verified", "vuln_id_from_tool") VALUES (NEW."active", NEW."archive_batch", NEW."archived_at", NEW."component_name", NEW."component_version", NEW."created", NEW."cve", NEW."cvssv3", NEW."cvssv3_score", NEW."cvssv4", NEW."cvssv4_score", NEW."cwe", NEW."date", NEW."defect_review_requested_by_id", NEW."description", NEW."duplicate", NEW."duplicate_finding_id", NEW."dynamic_finding", NEW."effort_for_fixing", NEW."epss_percentile", NEW."epss_score", NEW."false_p", NEW."file_path", NEW."fix_available", NEW."fix_version", NEW."hash_code", NEW."id", NEW."impact", NEW."is_mitigated", NEW."kev_date", NEW."known_exploited", NEW."last_reviewed", NEW."last_reviewed_by_id", NEW."last_status_update", NEW."line", NEW."mitigated", NEW."mitigated_by_id", NEW."mitigation", NEW."nb_occurences", NEW."numerical_severity", NEW."out_of_scope", NEW."param", NEW."payload", _pgh_attach_context(), NOW(), \'update\', NEW."id", NEW."planned_remediation_date", NEW."planned_remediation_version", NEW."publish_date", NEW."ransomware_used", NEW."refs", NEW."reporter_id", NEW."review_requested_by_id", NEW."risk_accepted", NEW."sast_sink_object", NEW."sast_source_file_path", NEW."sast_source_line", NEW."sast_source_object", NEW."scanner_confidence", NEW."service", NEW."severity", NEW."severity_justification", NEW."sla_expiration_date", NEW."sla_start_date", NEW."sonarqube_issue_id", NEW."static_finding", NEW."steps_to_reproduce", NEW."test_id", NEW."thread_id", NEW."title", NEW."under_defect_review", NEW."under_review", NEW."unique_id_from_tool", NEW."updated", NEW."url", NEW."verified", NEW."vuln_id_from_tool"); RETURN NULL;', hash="7b1c5da1fc67ea4d10b0d6e9ec42fbf428ad6d47", operation="UPDATE", pgid="pgtrigger_update_update_92175", table="dojo_finding", when="AFTER")), + ), + pgtrigger.migrations.AddTrigger( + model_name="finding", + trigger=pgtrigger.compiler.Trigger(name="delete_delete", sql=pgtrigger.compiler.UpsertTriggerSql(func='INSERT INTO "dojo_findingevent" ("active", "archive_batch", "archived_at", "component_name", "component_version", "created", "cve", "cvssv3", "cvssv3_score", "cvssv4", "cvssv4_score", "cwe", "date", "defect_review_requested_by_id", "description", "duplicate", "duplicate_finding_id", "dynamic_finding", "effort_for_fixing", "epss_percentile", "epss_score", "false_p", "file_path", "fix_available", "fix_version", "hash_code", "id", "impact", "is_mitigated", "kev_date", "known_exploited", "last_reviewed", "last_reviewed_by_id", "last_status_update", "line", "mitigated", "mitigated_by_id", "mitigation", "nb_occurences", "numerical_severity", "out_of_scope", "param", "payload", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "planned_remediation_date", "planned_remediation_version", "publish_date", "ransomware_used", "refs", "reporter_id", "review_requested_by_id", "risk_accepted", "sast_sink_object", "sast_source_file_path", "sast_source_line", "sast_source_object", "scanner_confidence", "service", "severity", "severity_justification", "sla_expiration_date", "sla_start_date", "sonarqube_issue_id", "static_finding", "steps_to_reproduce", "test_id", "thread_id", "title", "under_defect_review", "under_review", "unique_id_from_tool", "updated", "url", "verified", "vuln_id_from_tool") VALUES (OLD."active", OLD."archive_batch", OLD."archived_at", OLD."component_name", OLD."component_version", OLD."created", OLD."cve", OLD."cvssv3", OLD."cvssv3_score", OLD."cvssv4", OLD."cvssv4_score", OLD."cwe", OLD."date", OLD."defect_review_requested_by_id", OLD."description", OLD."duplicate", OLD."duplicate_finding_id", OLD."dynamic_finding", OLD."effort_for_fixing", OLD."epss_percentile", OLD."epss_score", OLD."false_p", OLD."file_path", OLD."fix_available", OLD."fix_version", OLD."hash_code", OLD."id", OLD."impact", OLD."is_mitigated", OLD."kev_date", OLD."known_exploited", OLD."last_reviewed", OLD."last_reviewed_by_id", OLD."last_status_update", OLD."line", OLD."mitigated", OLD."mitigated_by_id", OLD."mitigation", OLD."nb_occurences", OLD."numerical_severity", OLD."out_of_scope", OLD."param", OLD."payload", _pgh_attach_context(), NOW(), \'delete\', OLD."id", OLD."planned_remediation_date", OLD."planned_remediation_version", OLD."publish_date", OLD."ransomware_used", OLD."refs", OLD."reporter_id", OLD."review_requested_by_id", OLD."risk_accepted", OLD."sast_sink_object", OLD."sast_source_file_path", OLD."sast_source_line", OLD."sast_source_object", OLD."scanner_confidence", OLD."service", OLD."severity", OLD."severity_justification", OLD."sla_expiration_date", OLD."sla_start_date", OLD."sonarqube_issue_id", OLD."static_finding", OLD."steps_to_reproduce", OLD."test_id", OLD."thread_id", OLD."title", OLD."under_defect_review", OLD."under_review", OLD."unique_id_from_tool", OLD."updated", OLD."url", OLD."verified", OLD."vuln_id_from_tool"); RETURN NULL;', hash="0b0ae774839868caab7908236804d2b14393a699", operation="DELETE", pgid="pgtrigger_delete_delete_72933", table="dojo_finding", when="AFTER")), + ), + pgtrigger.migrations.AddTrigger( + model_name="finding_group", + trigger=pgtrigger.compiler.Trigger(name="insert_insert", sql=pgtrigger.compiler.UpsertTriggerSql(func='INSERT INTO "dojo_finding_groupevent" ("archive_batch", "archived_at", "created", "creator_id", "id", "modified", "name", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "test_id") VALUES (NEW."archive_batch", NEW."archived_at", NEW."created", NEW."creator_id", NEW."id", NEW."modified", NEW."name", _pgh_attach_context(), NOW(), \'insert\', NEW."id", NEW."test_id"); RETURN NULL;', hash="bcad4bd5b2d4c90eede0665d18169e85f5f14257", operation="INSERT", pgid="pgtrigger_insert_insert_94bd2", table="dojo_finding_group", when="AFTER")), + ), + pgtrigger.migrations.AddTrigger( + model_name="finding_group", + trigger=pgtrigger.compiler.Trigger(name="update_update", sql=pgtrigger.compiler.UpsertTriggerSql(condition='WHEN (OLD."archive_batch" IS DISTINCT FROM (NEW."archive_batch") OR OLD."archived_at" IS DISTINCT FROM (NEW."archived_at") OR OLD."creator_id" IS DISTINCT FROM (NEW."creator_id") OR OLD."id" IS DISTINCT FROM (NEW."id") OR OLD."name" IS DISTINCT FROM (NEW."name") OR OLD."test_id" IS DISTINCT FROM (NEW."test_id"))', func='INSERT INTO "dojo_finding_groupevent" ("archive_batch", "archived_at", "created", "creator_id", "id", "modified", "name", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "test_id") VALUES (NEW."archive_batch", NEW."archived_at", NEW."created", NEW."creator_id", NEW."id", NEW."modified", NEW."name", _pgh_attach_context(), NOW(), \'update\', NEW."id", NEW."test_id"); RETURN NULL;', hash="bc709885f7ae1a3e00bb01e453bfd461ea3ac298", operation="UPDATE", pgid="pgtrigger_update_update_37b5f", table="dojo_finding_group", when="AFTER")), + ), + pgtrigger.migrations.AddTrigger( + model_name="finding_group", + trigger=pgtrigger.compiler.Trigger(name="delete_delete", sql=pgtrigger.compiler.UpsertTriggerSql(func='INSERT INTO "dojo_finding_groupevent" ("archive_batch", "archived_at", "created", "creator_id", "id", "modified", "name", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "test_id") VALUES (OLD."archive_batch", OLD."archived_at", OLD."created", OLD."creator_id", OLD."id", OLD."modified", OLD."name", _pgh_attach_context(), NOW(), \'delete\', OLD."id", OLD."test_id"); RETURN NULL;', hash="e573c51b932f142bef508cc995f8f4e6657c1d62", operation="DELETE", pgid="pgtrigger_delete_delete_24b41", table="dojo_finding_group", when="AFTER")), + ), + pgtrigger.migrations.AddTrigger( + model_name="product", + trigger=pgtrigger.compiler.Trigger(name="insert_insert", sql=pgtrigger.compiler.UpsertTriggerSql(func='INSERT INTO "dojo_productevent" ("archive_batch", "archived_at", "async_updating", "business_criticality", "created", "description", "disable_sla_breach_notifications", "enable_full_risk_acceptance", "enable_product_tag_inheritance", "enable_simple_risk_acceptance", "external_audience", "id", "internet_accessible", "lifecycle_id", "name", "origin_id", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "platform_id", "prod_numeric_grade", "prod_type_id", "product_manager_id", "revenue", "sla_configuration_id", "team_manager_id", "technical_contact_id", "tid", "updated", "user_records") VALUES (NEW."archive_batch", NEW."archived_at", NEW."async_updating", NEW."business_criticality", NEW."created", NEW."description", NEW."disable_sla_breach_notifications", NEW."enable_full_risk_acceptance", NEW."enable_product_tag_inheritance", NEW."enable_simple_risk_acceptance", NEW."external_audience", NEW."id", NEW."internet_accessible", NEW."lifecycle_id", NEW."name", NEW."origin_id", _pgh_attach_context(), NOW(), \'insert\', NEW."id", NEW."platform_id", NEW."prod_numeric_grade", NEW."prod_type_id", NEW."product_manager_id", NEW."revenue", NEW."sla_configuration_id", NEW."team_manager_id", NEW."technical_contact_id", NEW."tid", NEW."updated", NEW."user_records"); RETURN NULL;', hash="b5851c1970f7b7c91e09d80dc365cbe2579c1220", operation="INSERT", pgid="pgtrigger_insert_insert_d5d32", table="dojo_product", when="AFTER")), + ), + pgtrigger.migrations.AddTrigger( + model_name="product", + trigger=pgtrigger.compiler.Trigger(name="update_update", sql=pgtrigger.compiler.UpsertTriggerSql(condition='WHEN (OLD."archive_batch" IS DISTINCT FROM (NEW."archive_batch") OR OLD."archived_at" IS DISTINCT FROM (NEW."archived_at") OR OLD."async_updating" IS DISTINCT FROM (NEW."async_updating") OR OLD."business_criticality" IS DISTINCT FROM (NEW."business_criticality") OR OLD."description" IS DISTINCT FROM (NEW."description") OR OLD."disable_sla_breach_notifications" IS DISTINCT FROM (NEW."disable_sla_breach_notifications") OR OLD."enable_full_risk_acceptance" IS DISTINCT FROM (NEW."enable_full_risk_acceptance") OR OLD."enable_product_tag_inheritance" IS DISTINCT FROM (NEW."enable_product_tag_inheritance") OR OLD."enable_simple_risk_acceptance" IS DISTINCT FROM (NEW."enable_simple_risk_acceptance") OR OLD."external_audience" IS DISTINCT FROM (NEW."external_audience") OR OLD."id" IS DISTINCT FROM (NEW."id") OR OLD."internet_accessible" IS DISTINCT FROM (NEW."internet_accessible") OR OLD."lifecycle_id" IS DISTINCT FROM (NEW."lifecycle_id") OR OLD."name" IS DISTINCT FROM (NEW."name") OR OLD."origin_id" IS DISTINCT FROM (NEW."origin_id") OR OLD."platform_id" IS DISTINCT FROM (NEW."platform_id") OR OLD."prod_numeric_grade" IS DISTINCT FROM (NEW."prod_numeric_grade") OR OLD."prod_type_id" IS DISTINCT FROM (NEW."prod_type_id") OR OLD."product_manager_id" IS DISTINCT FROM (NEW."product_manager_id") OR OLD."revenue" IS DISTINCT FROM (NEW."revenue") OR OLD."sla_configuration_id" IS DISTINCT FROM (NEW."sla_configuration_id") OR OLD."team_manager_id" IS DISTINCT FROM (NEW."team_manager_id") OR OLD."technical_contact_id" IS DISTINCT FROM (NEW."technical_contact_id") OR OLD."tid" IS DISTINCT FROM (NEW."tid") OR OLD."user_records" IS DISTINCT FROM (NEW."user_records"))', func='INSERT INTO "dojo_productevent" ("archive_batch", "archived_at", "async_updating", "business_criticality", "created", "description", "disable_sla_breach_notifications", "enable_full_risk_acceptance", "enable_product_tag_inheritance", "enable_simple_risk_acceptance", "external_audience", "id", "internet_accessible", "lifecycle_id", "name", "origin_id", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "platform_id", "prod_numeric_grade", "prod_type_id", "product_manager_id", "revenue", "sla_configuration_id", "team_manager_id", "technical_contact_id", "tid", "updated", "user_records") VALUES (NEW."archive_batch", NEW."archived_at", NEW."async_updating", NEW."business_criticality", NEW."created", NEW."description", NEW."disable_sla_breach_notifications", NEW."enable_full_risk_acceptance", NEW."enable_product_tag_inheritance", NEW."enable_simple_risk_acceptance", NEW."external_audience", NEW."id", NEW."internet_accessible", NEW."lifecycle_id", NEW."name", NEW."origin_id", _pgh_attach_context(), NOW(), \'update\', NEW."id", NEW."platform_id", NEW."prod_numeric_grade", NEW."prod_type_id", NEW."product_manager_id", NEW."revenue", NEW."sla_configuration_id", NEW."team_manager_id", NEW."technical_contact_id", NEW."tid", NEW."updated", NEW."user_records"); RETURN NULL;', hash="b5793f361239e1329aea5ee48f4b68ba6d9c5f0f", operation="UPDATE", pgid="pgtrigger_update_update_e7040", table="dojo_product", when="AFTER")), + ), + pgtrigger.migrations.AddTrigger( + model_name="product", + trigger=pgtrigger.compiler.Trigger(name="delete_delete", sql=pgtrigger.compiler.UpsertTriggerSql(func='INSERT INTO "dojo_productevent" ("archive_batch", "archived_at", "async_updating", "business_criticality", "created", "description", "disable_sla_breach_notifications", "enable_full_risk_acceptance", "enable_product_tag_inheritance", "enable_simple_risk_acceptance", "external_audience", "id", "internet_accessible", "lifecycle_id", "name", "origin_id", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "platform_id", "prod_numeric_grade", "prod_type_id", "product_manager_id", "revenue", "sla_configuration_id", "team_manager_id", "technical_contact_id", "tid", "updated", "user_records") VALUES (OLD."archive_batch", OLD."archived_at", OLD."async_updating", OLD."business_criticality", OLD."created", OLD."description", OLD."disable_sla_breach_notifications", OLD."enable_full_risk_acceptance", OLD."enable_product_tag_inheritance", OLD."enable_simple_risk_acceptance", OLD."external_audience", OLD."id", OLD."internet_accessible", OLD."lifecycle_id", OLD."name", OLD."origin_id", _pgh_attach_context(), NOW(), \'delete\', OLD."id", OLD."platform_id", OLD."prod_numeric_grade", OLD."prod_type_id", OLD."product_manager_id", OLD."revenue", OLD."sla_configuration_id", OLD."team_manager_id", OLD."technical_contact_id", OLD."tid", OLD."updated", OLD."user_records"); RETURN NULL;', hash="b680a761758c22da5777b8b70f718169dfaf58b5", operation="DELETE", pgid="pgtrigger_delete_delete_064dd", table="dojo_product", when="AFTER")), + ), + pgtrigger.migrations.AddTrigger( + model_name="product_type", + trigger=pgtrigger.compiler.Trigger(name="insert_insert", sql=pgtrigger.compiler.UpsertTriggerSql(func='INSERT INTO "dojo_product_typeevent" ("archive_batch", "archived_at", "created", "critical_product", "description", "id", "key_product", "name", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "updated") VALUES (NEW."archive_batch", NEW."archived_at", NEW."created", NEW."critical_product", NEW."description", NEW."id", NEW."key_product", NEW."name", _pgh_attach_context(), NOW(), \'insert\', NEW."id", NEW."updated"); RETURN NULL;', hash="c22c7686452daedc2b9216ac67df591501e319f2", operation="INSERT", pgid="pgtrigger_insert_insert_2d109", table="dojo_product_type", when="AFTER")), + ), + pgtrigger.migrations.AddTrigger( + model_name="product_type", + trigger=pgtrigger.compiler.Trigger(name="update_update", sql=pgtrigger.compiler.UpsertTriggerSql(condition='WHEN (OLD."archive_batch" IS DISTINCT FROM (NEW."archive_batch") OR OLD."archived_at" IS DISTINCT FROM (NEW."archived_at") OR OLD."critical_product" IS DISTINCT FROM (NEW."critical_product") OR OLD."description" IS DISTINCT FROM (NEW."description") OR OLD."id" IS DISTINCT FROM (NEW."id") OR OLD."key_product" IS DISTINCT FROM (NEW."key_product") OR OLD."name" IS DISTINCT FROM (NEW."name"))', func='INSERT INTO "dojo_product_typeevent" ("archive_batch", "archived_at", "created", "critical_product", "description", "id", "key_product", "name", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "updated") VALUES (NEW."archive_batch", NEW."archived_at", NEW."created", NEW."critical_product", NEW."description", NEW."id", NEW."key_product", NEW."name", _pgh_attach_context(), NOW(), \'update\', NEW."id", NEW."updated"); RETURN NULL;', hash="f0b2de3b71e7b546d0efe2cb7950638c095d85fd", operation="UPDATE", pgid="pgtrigger_update_update_a0136", table="dojo_product_type", when="AFTER")), + ), + pgtrigger.migrations.AddTrigger( + model_name="product_type", + trigger=pgtrigger.compiler.Trigger(name="delete_delete", sql=pgtrigger.compiler.UpsertTriggerSql(func='INSERT INTO "dojo_product_typeevent" ("archive_batch", "archived_at", "created", "critical_product", "description", "id", "key_product", "name", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "updated") VALUES (OLD."archive_batch", OLD."archived_at", OLD."created", OLD."critical_product", OLD."description", OLD."id", OLD."key_product", OLD."name", _pgh_attach_context(), NOW(), \'delete\', OLD."id", OLD."updated"); RETURN NULL;', hash="7d8aada72ff77dd0e91e25d2324c57b8d8500509", operation="DELETE", pgid="pgtrigger_delete_delete_66b18", table="dojo_product_type", when="AFTER")), + ), + pgtrigger.migrations.AddTrigger( + model_name="test", + trigger=pgtrigger.compiler.Trigger(name="insert_insert", sql=pgtrigger.compiler.UpsertTriggerSql(func='INSERT INTO "dojo_testevent" ("api_scan_configuration_id", "archive_batch", "archived_at", "branch_tag", "build_id", "commit_hash", "created", "description", "engagement_id", "environment_id", "id", "lead_id", "percent_complete", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "scan_type", "target_end", "target_start", "test_type_id", "title", "updated", "version") VALUES (NEW."api_scan_configuration_id", NEW."archive_batch", NEW."archived_at", NEW."branch_tag", NEW."build_id", NEW."commit_hash", NEW."created", NEW."description", NEW."engagement_id", NEW."environment_id", NEW."id", NEW."lead_id", NEW."percent_complete", _pgh_attach_context(), NOW(), \'insert\', NEW."id", NEW."scan_type", NEW."target_end", NEW."target_start", NEW."test_type_id", NEW."title", NEW."updated", NEW."version"); RETURN NULL;', hash="477f6a297658d54b13ef83b4f4b19b0e76f2bb27", operation="INSERT", pgid="pgtrigger_insert_insert_ecfc1", table="dojo_test", when="AFTER")), + ), + pgtrigger.migrations.AddTrigger( + model_name="test", + trigger=pgtrigger.compiler.Trigger(name="update_update", sql=pgtrigger.compiler.UpsertTriggerSql(condition='WHEN (OLD."api_scan_configuration_id" IS DISTINCT FROM (NEW."api_scan_configuration_id") OR OLD."archive_batch" IS DISTINCT FROM (NEW."archive_batch") OR OLD."archived_at" IS DISTINCT FROM (NEW."archived_at") OR OLD."branch_tag" IS DISTINCT FROM (NEW."branch_tag") OR OLD."build_id" IS DISTINCT FROM (NEW."build_id") OR OLD."commit_hash" IS DISTINCT FROM (NEW."commit_hash") OR OLD."description" IS DISTINCT FROM (NEW."description") OR OLD."engagement_id" IS DISTINCT FROM (NEW."engagement_id") OR OLD."environment_id" IS DISTINCT FROM (NEW."environment_id") OR OLD."id" IS DISTINCT FROM (NEW."id") OR OLD."lead_id" IS DISTINCT FROM (NEW."lead_id") OR OLD."percent_complete" IS DISTINCT FROM (NEW."percent_complete") OR OLD."scan_type" IS DISTINCT FROM (NEW."scan_type") OR OLD."target_end" IS DISTINCT FROM (NEW."target_end") OR OLD."target_start" IS DISTINCT FROM (NEW."target_start") OR OLD."test_type_id" IS DISTINCT FROM (NEW."test_type_id") OR OLD."title" IS DISTINCT FROM (NEW."title") OR OLD."version" IS DISTINCT FROM (NEW."version"))', func='INSERT INTO "dojo_testevent" ("api_scan_configuration_id", "archive_batch", "archived_at", "branch_tag", "build_id", "commit_hash", "created", "description", "engagement_id", "environment_id", "id", "lead_id", "percent_complete", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "scan_type", "target_end", "target_start", "test_type_id", "title", "updated", "version") VALUES (NEW."api_scan_configuration_id", NEW."archive_batch", NEW."archived_at", NEW."branch_tag", NEW."build_id", NEW."commit_hash", NEW."created", NEW."description", NEW."engagement_id", NEW."environment_id", NEW."id", NEW."lead_id", NEW."percent_complete", _pgh_attach_context(), NOW(), \'update\', NEW."id", NEW."scan_type", NEW."target_end", NEW."target_start", NEW."test_type_id", NEW."title", NEW."updated", NEW."version"); RETURN NULL;', hash="50e41edef10c98f5e20b9c43a324c49f5b897f88", operation="UPDATE", pgid="pgtrigger_update_update_c40f8", table="dojo_test", when="AFTER")), + ), + pgtrigger.migrations.AddTrigger( + model_name="test", + trigger=pgtrigger.compiler.Trigger(name="delete_delete", sql=pgtrigger.compiler.UpsertTriggerSql(func='INSERT INTO "dojo_testevent" ("api_scan_configuration_id", "archive_batch", "archived_at", "branch_tag", "build_id", "commit_hash", "created", "description", "engagement_id", "environment_id", "id", "lead_id", "percent_complete", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "scan_type", "target_end", "target_start", "test_type_id", "title", "updated", "version") VALUES (OLD."api_scan_configuration_id", OLD."archive_batch", OLD."archived_at", OLD."branch_tag", OLD."build_id", OLD."commit_hash", OLD."created", OLD."description", OLD."engagement_id", OLD."environment_id", OLD."id", OLD."lead_id", OLD."percent_complete", _pgh_attach_context(), NOW(), \'delete\', OLD."id", OLD."scan_type", OLD."target_end", OLD."target_start", OLD."test_type_id", OLD."title", OLD."updated", OLD."version"); RETURN NULL;', hash="0b9eda2793d6208cb855751dc6c39f8d6819cd2d", operation="DELETE", pgid="pgtrigger_delete_delete_66d18", table="dojo_test", when="AFTER")), + ), + ], + database_operations=[ + migrations.RunSQL(sql=[FORWARD_SQL], reverse_sql=[BACKWARD_SQL]), + ], + ), + ] diff --git a/dojo/db_migrations/0305_archive_batch_indexes.py b/dojo/db_migrations/0305_archive_batch_indexes.py new file mode 100644 index 00000000000..16919c925a6 --- /dev/null +++ b/dojo/db_migrations/0305_archive_batch_indexes.py @@ -0,0 +1,60 @@ +from django.contrib.postgres.operations import AddIndexConcurrently +from django.db import migrations, models + + +class Migration(migrations.Migration): + + # CREATE INDEX CONCURRENTLY cannot run inside a transaction, and a plain + # CREATE INDEX would lock dojo_finding and dojo_endpoint_status for the whole build. + atomic = False + + dependencies = [ + ("dojo", "0304_archive_columns"), + ] + + operations = [ + AddIndexConcurrently( + model_name="findingvulnerabilityreference", + index=models.Index(condition=models.Q(("archive_batch__isnull", False)), fields=["archive_batch"], name="dojo_findvulnref_archive_batch"), + ), + AddIndexConcurrently( + model_name="endpoint_status", + index=models.Index(condition=models.Q(("archive_batch__isnull", False)), fields=["archive_batch"], name="dojo_endpstatus_archive_batch"), + ), + AddIndexConcurrently( + model_name="engagement", + index=models.Index(condition=models.Q(("archive_batch__isnull", False)), fields=["archive_batch"], name="dojo_engagement_archive_batch"), + ), + AddIndexConcurrently( + model_name="finding", + index=models.Index(condition=models.Q(("archive_batch__isnull", False)), fields=["archive_batch"], name="dojo_finding_archive_batch"), + ), + AddIndexConcurrently( + model_name="jira_issue", + index=models.Index(condition=models.Q(("archive_batch__isnull", False)), fields=["archive_batch"], name="dojo_jiraissue_archive_batch"), + ), + AddIndexConcurrently( + model_name="locationfindingreference", + index=models.Index(condition=models.Q(("archive_batch__isnull", False)), fields=["archive_batch"], name="dojo_locfindref_archive_batch"), + ), + AddIndexConcurrently( + model_name="product", + index=models.Index(condition=models.Q(("archive_batch__isnull", False)), fields=["archive_batch"], name="dojo_product_archive_batch"), + ), + AddIndexConcurrently( + model_name="product_type", + index=models.Index(condition=models.Q(("archive_batch__isnull", False)), fields=["archive_batch"], name="dojo_prod_type_archive_batch"), + ), + AddIndexConcurrently( + model_name="test", + index=models.Index(condition=models.Q(("archive_batch__isnull", False)), fields=["archive_batch"], name="dojo_test_archive_batch"), + ), + AddIndexConcurrently( + model_name="test_import_finding_action", + index=models.Index(condition=models.Q(("archive_batch__isnull", False)), fields=["archive_batch"], name="dojo_tifa_archive_batch"), + ), + AddIndexConcurrently( + model_name="vulnerability_id", + index=models.Index(condition=models.Q(("archive_batch__isnull", False)), fields=["archive_batch"], name="dojo_vulnid_archive_batch"), + ), + ] diff --git a/dojo/endpoint/models.py b/dojo/endpoint/models.py index 628b28b9f2f..0963340ddfb 100644 --- a/dojo/endpoint/models.py +++ b/dojo/endpoint/models.py @@ -20,6 +20,7 @@ # before the re-export that loads this module — resolves despite partial circular load. # Must keep their dojo.models.* path for Django migration serialization. from dojo.models import copy_model_util, get_current_date, get_current_datetime +from dojo.query_hooks import HookedManager, UnfilteredManager logger = logging.getLogger(__name__) @@ -44,8 +45,17 @@ class Endpoint_Status(models.Model): endpoint = models.ForeignKey("dojo.Endpoint", null=False, blank=False, on_delete=models.CASCADE, related_name="status_endpoint") finding = models.ForeignKey("dojo.Finding", null=False, blank=False, on_delete=models.CASCADE, related_name="status_finding") + # Read and written only by plugins; open source never sets them. + archived_at = models.DateTimeField(null=True, blank=True, editable=False) + archive_batch = models.UUIDField(null=True, blank=True, editable=False) + + # objects is declared first, so it is the default manager; see dojo.query_hooks. + objects = HookedManager() + unfiltered = UnfilteredManager() + class Meta: indexes = [ + models.Index(fields=["archive_batch"], condition=models.Q(archive_batch__isnull=False), name="dojo_endpstatus_archive_batch"), models.Index(fields=["finding", "mitigated"]), models.Index(fields=["endpoint", "mitigated"]), # Optimize frequent lookups of "active" statuses (mitigated/flags all False) @@ -141,6 +151,14 @@ class Endpoint(models.Model): tags = TagField(blank=True, force_lowercase=True, help_text=_("Add tags that help describe this endpoint. Choose from the list or add new tags. Press Enter key to add.")) inherited_tags = TagField(blank=True, force_lowercase=True, help_text=_("Internal use tags sepcifically for maintaining parity with product. This field will be present as a subset in the tags field")) + # Read and written only by plugins; open source never sets them. + archived_at = models.DateTimeField(null=True, blank=True, editable=False) + archive_batch = models.UUIDField(null=True, blank=True, editable=False) + + # objects is declared first, so it is the default manager; see dojo.query_hooks. + objects = HookedManager() + unfiltered = UnfilteredManager() + class Meta: ordering = ["product", "host", "protocol", "port", "userinfo", "path", "query", "fragment"] indexes = [ diff --git a/dojo/engagement/models.py b/dojo/engagement/models.py index 07492938afd..cd84840af3c 100644 --- a/dojo/engagement/models.py +++ b/dojo/engagement/models.py @@ -10,7 +10,8 @@ from django.utils.translation import gettext as _ from django_tagulous.models import TagField -from dojo.base_models.base import BaseModel +from dojo.base_models.base import BaseManager, BaseModel +from dojo.query_hooks import HookedBaseManager, HookedManager, UnfilteredManager logger = logging.getLogger(__name__) @@ -24,6 +25,14 @@ class Engagement_Presets(models.Model): product = models.ForeignKey("dojo.Product", on_delete=models.CASCADE) created = models.DateTimeField(auto_now_add=True, null=False) + # Read and written only by plugins; open source never sets them. + archived_at = models.DateTimeField(null=True, blank=True, editable=False) + archive_batch = models.UUIDField(null=True, blank=True, editable=False) + + # objects is declared first, so it is the default manager; see dojo.query_hooks. + objects = HookedManager() + unfiltered = UnfilteredManager() + class Meta: ordering = ["title"] @@ -94,9 +103,18 @@ class Engagement(BaseModel): tags = TagField(blank=True, force_lowercase=True, help_text=_("Add tags that help describe this engagement. Choose from the list or add new tags. Press Enter key to add.")) inherited_tags = TagField(blank=True, force_lowercase=True, help_text=_("Internal use tags sepcifically for maintaining parity with product. This field will be present as a subset in the tags field")) + # Read and written only by plugins; open source never sets them. + archived_at = models.DateTimeField(null=True, blank=True, editable=False) + archive_batch = models.UUIDField(null=True, blank=True, editable=False) + + # objects is declared first, so it is the default manager; see dojo.query_hooks. + objects = HookedBaseManager() + unfiltered = BaseManager() + class Meta: ordering = ["-target_start"] indexes = [ + models.Index(fields=["archive_batch"], condition=models.Q(archive_batch__isnull=False), name="dojo_engagement_archive_batch"), models.Index(fields=["product", "active"]), # Global search (pro/search/): weighted tsvector FTS + trigram fuzzy match. GinIndex( diff --git a/dojo/finding/models.py b/dojo/finding/models.py index 3a8601d66dd..3c0001b058d 100644 --- a/dojo/finding/models.py +++ b/dojo/finding/models.py @@ -24,7 +24,7 @@ from django_tagulous.models import TagField from titlecase import titlecase -from dojo.base_models.base import BaseModel +from dojo.base_models.base import BaseManager, BaseModel from dojo.finding.cwe import cwe_label, finding_cwe_labels from dojo.finding.vulnerability_id import resolve_vulnerability_id_type @@ -32,6 +32,7 @@ # re-export that loads this module — so this resolves despite the partial circular load, and # keeps their dojo.models.* path for Django migration serialization (used as field defaults). from dojo.models import copy_model_util, get_current_date, tomorrow +from dojo.query_hooks import HookedBaseManager, HookedManager, UnfilteredManager from dojo.validators import cvss3_validator, cvss4_validator if TYPE_CHECKING: @@ -454,9 +455,18 @@ class Finding(BaseModel): SEVERITIES = {"Info": 4, "Low": 3, "Medium": 2, "High": 1, "Critical": 0} + # Read and written only by plugins; open source never sets them. + archived_at = models.DateTimeField(null=True, blank=True, editable=False) + archive_batch = models.UUIDField(null=True, blank=True, editable=False) + + # objects is declared first, so it is the default manager; see dojo.query_hooks. + objects = HookedBaseManager() + unfiltered = BaseManager() + class Meta: ordering = ("numerical_severity", "-date", "title", "epss_score", "epss_percentile") indexes = [ + models.Index(fields=["archive_batch"], condition=models.Q(archive_batch__isnull=False), name="dojo_finding_archive_batch"), # Global search (pro/search/): weighted tsvector FTS + trigram fuzzy match. GinIndex( SearchVector("title", weight="A", config="english") @@ -1562,11 +1572,20 @@ class Vulnerability_Id(models.Model): # prefix. Denormalized/indexed so type-scoped queries (e.g. GROUP BY type) stay cheap. vulnerability_id_type = models.CharField(max_length=20, null=True, blank=True, editable=False, db_index=True) + # Read and written only by plugins; open source never sets them. + archived_at = models.DateTimeField(null=True, blank=True, editable=False) + archive_batch = models.UUIDField(null=True, blank=True, editable=False) + + # objects is declared first, so it is the default manager; see dojo.query_hooks. + objects = HookedManager() + unfiltered = UnfilteredManager() + class Meta: constraints = [ models.UniqueConstraint(fields=["finding", "vulnerability_id"], name="unique_finding_vulnerability_id"), ] indexes = [ + models.Index(fields=["archive_batch"], condition=models.Q(archive_batch__isnull=False), name="dojo_vulnid_archive_batch"), # Leading on vulnerability_id (the unique constraint's index leads on finding), for the # vulnerability-id Explorer's GROUP BY vulnerability_id / lookups by exact id. models.Index(fields=["vulnerability_id"], name="dojo_vuln_id_lookup_idx"), @@ -1635,6 +1654,14 @@ class Finding_Group(TimeStampedModel): findings = models.ManyToManyField("dojo.Finding") creator = models.ForeignKey("dojo.Dojo_User", on_delete=models.RESTRICT) + # Read and written only by plugins; open source never sets them. + archived_at = models.DateTimeField(null=True, blank=True, editable=False) + archive_batch = models.UUIDField(null=True, blank=True, editable=False) + + # objects is declared first, so it is the default manager; see dojo.query_hooks. + objects = HookedManager() + unfiltered = UnfilteredManager() + def __str__(self): return self.name diff --git a/dojo/jira/models.py b/dojo/jira/models.py index 17b742f98b5..a2d7f998edb 100644 --- a/dojo/jira/models.py +++ b/dojo/jira/models.py @@ -5,6 +5,8 @@ from django.db import models from django.utils.translation import gettext as _ +from dojo.query_hooks import HookedManager, UnfilteredManager + class JIRA_Instance(models.Model): configuration_name = models.CharField(max_length=2000, help_text=_("Enter a name to give to this configuration"), default="") @@ -139,6 +141,14 @@ class JIRA_Project(models.Model): default=True, blank=True) + # Read and written only by plugins; open source never sets them. + archived_at = models.DateTimeField(null=True, blank=True, editable=False) + archive_batch = models.UUIDField(null=True, blank=True, editable=False) + + # objects is declared first, so it is the default manager; see dojo.query_hooks. + objects = HookedManager() + unfiltered = UnfilteredManager() + class Meta: app_label = "dojo" @@ -197,7 +207,18 @@ class JIRA_Issue(models.Model): verbose_name=_("Jira last update"), help_text=_("The date the linked Jira issue was last modified.")) + # Read and written only by plugins; open source never sets them. + archived_at = models.DateTimeField(null=True, blank=True, editable=False) + archive_batch = models.UUIDField(null=True, blank=True, editable=False) + + # objects is declared first, so it is the default manager; see dojo.query_hooks. + objects = HookedManager() + unfiltered = UnfilteredManager() + class Meta: + indexes = [ + models.Index(fields=["archive_batch"], condition=models.Q(archive_batch__isnull=False), name="dojo_jiraissue_archive_batch"), + ] app_label = "dojo" def __str__(self): diff --git a/dojo/location/manager.py b/dojo/location/manager.py index 56b8bd6b445..1cf940257f0 100644 --- a/dojo/location/manager.py +++ b/dojo/location/manager.py @@ -4,6 +4,7 @@ from dojo.base_models.base import BaseManager, BaseQuerySet from dojo.location.status import rollup_finding_location_status +from dojo.query_hooks import HookedManagerMixin class LocationQueryset(BaseQuerySet): @@ -72,3 +73,13 @@ class LocationFindingReferenceManager(BaseManager): """LocationFindingReference manager to manipulate all objects with.""" QUERY_SET_CLASS = LocationFindingReferenceQueryset + + +class HookedLocationProductReferenceManager(HookedManagerMixin, LocationProductReferenceManager): + + """LocationProductReference manager that applies the registered default-queryset filters.""" + + +class HookedLocationFindingReferenceManager(HookedManagerMixin, LocationFindingReferenceManager): + + """LocationFindingReference manager that applies the registered default-queryset filters.""" diff --git a/dojo/location/models.py b/dojo/location/models.py index f59d7264753..1d0b24c564b 100644 --- a/dojo/location/models.py +++ b/dojo/location/models.py @@ -23,6 +23,7 @@ QuerySet, TextChoices, UniqueConstraint, + UUIDField, ) from django.utils.translation import gettext_lazy as _ from django_tagulous.models import TagField @@ -30,6 +31,8 @@ from dojo.base_models.base import BaseModel, BaseModelWithoutTimeMeta from dojo.base_models.validators import validate_not_empty from dojo.location.manager import ( + HookedLocationFindingReferenceManager, + HookedLocationProductReferenceManager, LocationFindingReferenceManager, LocationFindingReferenceQueryset, LocationManager, @@ -654,7 +657,13 @@ class LocationFindingReference(BaseModel, ReferenceDataMixin): help_text=_("The status of the the given Location"), ) - objects = LocationFindingReferenceManager().from_queryset(LocationFindingReferenceQueryset)() + # Read and written only by plugins; open source never sets them. + archived_at = DateTimeField(null=True, blank=True, editable=False) + archive_batch = UUIDField(null=True, blank=True, editable=False) + + # objects is declared first, so it is the default manager; see dojo.query_hooks. + objects = HookedLocationFindingReferenceManager().from_queryset(LocationFindingReferenceQueryset)() + unfiltered = LocationFindingReferenceManager().from_queryset(LocationFindingReferenceQueryset)() class Meta: verbose_name = "Locations - FindingReference" @@ -666,6 +675,7 @@ class Meta: ), ] indexes = [ + Index(fields=["archive_batch"], condition=Q(archive_batch__isnull=False), name="dojo_locfindref_archive_batch"), Index(fields=["location"]), Index(fields=["finding"]), ] @@ -717,7 +727,13 @@ class LocationProductReference(BaseModel, ReferenceDataMixin): help_text=_("The status of the the given Location"), ) - objects = LocationProductReferenceManager().from_queryset(LocationProductReferenceQueryset)() + # Read and written only by plugins; open source never sets them. + archived_at = DateTimeField(null=True, blank=True, editable=False) + archive_batch = UUIDField(null=True, blank=True, editable=False) + + # objects is declared first, so it is the default manager; see dojo.query_hooks. + objects = HookedLocationProductReferenceManager().from_queryset(LocationProductReferenceQueryset)() + unfiltered = LocationProductReferenceManager().from_queryset(LocationProductReferenceQueryset)() class Meta: verbose_name = "Locations - ProductReference" diff --git a/dojo/models.py b/dojo/models.py index c813004454a..8f936e6f63d 100644 --- a/dojo/models.py +++ b/dojo/models.py @@ -173,6 +173,7 @@ def get_current_datetime(): Product_Line, # noqa: F401 -- re-export ) from dojo.product_type.models import Product_Type # noqa: E402, F401 -- re-export +from dojo.query_hooks import HookedManager, UnfilteredManager # noqa: E402 from dojo.reports.models import Report_Type # noqa: E402, F401 -- re-export from dojo.test.models import ( # noqa: E402 -- re-export; class-body FKs below reference these IMPORT_ACTIONS, # noqa: F401 -- re-export @@ -218,6 +219,14 @@ class DojoMeta(models.Model): editable=False, related_name="location_meta_scope") + # Read and written only by plugins; open source never sets them. + archived_at = models.DateTimeField(null=True, blank=True, editable=False) + archive_batch = models.UUIDField(null=True, blank=True, editable=False) + + # objects is declared first, so it is the default manager; see dojo.query_hooks. + objects = HookedManager() + unfiltered = UnfilteredManager() + class Meta: unique_together = (("product", "name"), ("endpoint", "name"), @@ -545,6 +554,14 @@ class Languages(models.Model): code = models.IntegerField(blank=True, null=True, verbose_name=_("Number of code lines")) created = models.DateTimeField(auto_now_add=True, null=False) + # Read and written only by plugins; open source never sets them. + archived_at = models.DateTimeField(null=True, blank=True, editable=False) + archive_batch = models.UUIDField(null=True, blank=True, editable=False) + + # objects is declared first, so it is the default manager; see dojo.query_hooks. + objects = HookedManager() + unfiltered = UnfilteredManager() + class Meta: unique_together = [("language", "product")] @@ -565,6 +582,14 @@ class App_Analysis(models.Model): tags = TagField(blank=True, force_lowercase=True) + # Read and written only by plugins; open source never sets them. + archived_at = models.DateTimeField(null=True, blank=True, editable=False) + archive_batch = models.UUIDField(null=True, blank=True, editable=False) + + # objects is declared first, so it is the default manager; see dojo.query_hooks. + objects = HookedManager() + unfiltered = UnfilteredManager() + class Meta: indexes = [ # Global search (pro/search/): weighted tsvector FTS + trigram fuzzy match. diff --git a/dojo/object/models.py b/dojo/object/models.py index 30b086ba544..5f1fb2b3d60 100644 --- a/dojo/object/models.py +++ b/dojo/object/models.py @@ -2,6 +2,8 @@ from django.utils.translation import gettext as _ from django_tagulous.models import TagField +from dojo.query_hooks import HookedManager, UnfilteredManager + class Objects_Review(models.Model): name = models.CharField(max_length=100, null=True, blank=True) @@ -25,6 +27,14 @@ class Objects_Product(models.Model): tags = TagField(blank=True, force_lowercase=True, help_text=_("Add tags that help describe this object. Choose from the list or add new tags. Press Enter key to add.")) + # Read and written only by plugins; open source never sets them. + archived_at = models.DateTimeField(null=True, blank=True, editable=False) + archive_batch = models.UUIDField(null=True, blank=True, editable=False) + + # objects is declared first, so it is the default manager; see dojo.query_hooks. + objects = HookedManager() + unfiltered = UnfilteredManager() + def __str__(self): name = None if self.path is not None: diff --git a/dojo/product/models.py b/dojo/product/models.py index 8fd475308eb..52d00ce79c1 100644 --- a/dojo/product/models.py +++ b/dojo/product/models.py @@ -11,7 +11,8 @@ from django.utils.translation import gettext as _ from django_tagulous.models import TagField -from dojo.base_models.base import BaseModel +from dojo.base_models.base import BaseManager, BaseModel +from dojo.query_hooks import HookedBaseManager, HookedManager, UnfilteredManager class Product_Line(models.Model): @@ -131,9 +132,18 @@ class Product(BaseModel): async_updating = models.BooleanField(default=False, help_text=_("Findings under this Product or SLA configuration are asynchronously being updated")) + # Read and written only by plugins; open source never sets them. + archived_at = models.DateTimeField(null=True, blank=True, editable=False) + archive_batch = models.UUIDField(null=True, blank=True, editable=False) + + # objects is declared first, so it is the default manager; see dojo.query_hooks. + objects = HookedBaseManager() + unfiltered = BaseManager() + class Meta: ordering = ("name",) indexes = [ + models.Index(fields=["archive_batch"], condition=models.Q(archive_batch__isnull=False), name="dojo_product_archive_batch"), # Serves the case-insensitive product-name lookup # (WHERE UPPER(name) = UPPER(%s)) used when filtering findings by # product name; the plain unique btree on name can't (Sentry DJANGO-D2M). @@ -307,6 +317,14 @@ class Product_API_Scan_Configuration(models.Model): service_key_2 = models.CharField(max_length=200, null=True, blank=True) service_key_3 = models.CharField(max_length=200, null=True, blank=True) + # Read and written only by plugins; open source never sets them. + archived_at = models.DateTimeField(null=True, blank=True, editable=False) + archive_batch = models.UUIDField(null=True, blank=True, editable=False) + + # objects is declared first, so it is the default manager; see dojo.query_hooks. + objects = HookedManager() + unfiltered = UnfilteredManager() + def __str__(self): name = self.tool_configuration.name if self.service_key_1 or self.service_key_2 or self.service_key_3: diff --git a/dojo/product_type/models.py b/dojo/product_type/models.py index e9394d7e45a..7cfa3450e61 100644 --- a/dojo/product_type/models.py +++ b/dojo/product_type/models.py @@ -4,7 +4,8 @@ from django.urls import reverse from django.utils.functional import cached_property -from dojo.base_models.base import BaseModel +from dojo.base_models.base import BaseManager, BaseModel +from dojo.query_hooks import HookedBaseManager class Product_Type(BaseModel): @@ -25,9 +26,18 @@ class Product_Type(BaseModel): key_product = models.BooleanField(default=False) authorized_users = models.ManyToManyField("dojo.Dojo_User", related_name="authorized_product_types", blank=True) + # Read and written only by plugins; open source never sets them. + archived_at = models.DateTimeField(null=True, blank=True, editable=False) + archive_batch = models.UUIDField(null=True, blank=True, editable=False) + + # objects is declared first, so it is the default manager; see dojo.query_hooks. + objects = HookedBaseManager() + unfiltered = BaseManager() + class Meta: ordering = ("name",) indexes = [ + models.Index(fields=["archive_batch"], condition=models.Q(archive_batch__isnull=False), name="dojo_prod_type_archive_batch"), # Global search (pro/search/): weighted tsvector FTS + trigram fuzzy match. GinIndex( SearchVector("name", weight="A", config="english") diff --git a/dojo/query_hooks.py b/dojo/query_hooks.py new file mode 100644 index 00000000000..ca0d0e955f9 --- /dev/null +++ b/dojo/query_hooks.py @@ -0,0 +1,53 @@ +""" +Default-queryset hooks for plugins. + +A model whose ``objects`` manager is a ``HookedManager`` (or ``HookedBaseManager``) +applies every filter registered for its label, in registration order, to the +queryset it returns. With nothing registered the queryset is unchanged, so the +open source behaviour is exactly that of a plain manager. + +``objects`` is declared first on those models, so it is also ``_default_manager``: +the filters reach reverse relations, ``get()`` and uniqueness checks as well. Each +model also carries an ``unfiltered`` manager, the explicit way to bypass them. +``_base_manager`` stays a plain manager, so forward foreign key access and the +deletion collector are never filtered. +""" + +from django.db.models import Manager + +from dojo.base_models.base import BaseManager + +_DEFAULT_QUERYSET_FILTERS = {} + + +def register_default_queryset_filter(model_label, key, func): + # Keyed so a repeated ready() (tests, autoreload) replaces rather than stacks. + _DEFAULT_QUERYSET_FILTERS.setdefault(model_label.lower(), {})[key] = func + + +def get_default_queryset_filters(model_label): + return tuple(_DEFAULT_QUERYSET_FILTERS.get(model_label.lower(), {}).values()) + + +def apply_default_queryset_filters(model, queryset): + for func in get_default_queryset_filters(model._meta.label): + queryset = func(queryset) + return queryset + + +class HookedManagerMixin: + def get_queryset(self): + return apply_default_queryset_filters(self.model, super().get_queryset()) + + +class HookedManager(HookedManagerMixin, Manager): + pass + + +class HookedBaseManager(HookedManagerMixin, BaseManager): + pass + + +class UnfilteredManager(Manager): + + """A plain manager, declared as ``unfiltered`` beside a hooked ``objects``: the explicit bypass.""" diff --git a/dojo/tasks.py b/dojo/tasks.py index deb9b6028dd..0bd8d9cab3e 100644 --- a/dojo/tasks.py +++ b/dojo/tasks.py @@ -29,6 +29,23 @@ # Findings locked and re-checked per transaction by _delete_excess_duplicates. DUPE_DELETE_CHUNK_SIZE = 1000 +# A plugin may set excess duplicates aside instead of deleting them. The handler gets each +# chunk's queryset inside the chunk's transaction, with the rows already locked, and returns +# True when it has dealt with them. It must leave them out of Finding.objects, or the next run +# selects them again. With no handler, or one that returns False, the chunk is deleted. +_excess_duplicate_handler = None + + +def register_excess_duplicate_handler(func): + global _excess_duplicate_handler # noqa: PLW0603 + _excess_duplicate_handler = func + + +def _remove_excess_duplicates(findings): + if _excess_duplicate_handler is not None and _excess_duplicate_handler(findings): + return + bulk_delete_findings(findings, order_desc=True) + from dojo.notifications.tasks import ( # noqa: E402, F401 -- backward compat add_alerts, @@ -216,7 +233,7 @@ def _delete_excess_duplicates(ids_to_delete): if skipped := len(chunk) - len(still_settled): logger.info("skipping %s excess duplicates that an import is writing, or that were saved or deleted since they were selected", skipped) if still_settled: - bulk_delete_findings(Finding.objects.filter(id__in=still_settled), order_desc=True) + _remove_excess_duplicates(Finding.objects.filter(id__in=still_settled)) deleted_ids.extend(still_settled) return deleted_ids diff --git a/dojo/test/models.py b/dojo/test/models.py index 92c1e44ceab..15ef11ae108 100644 --- a/dojo/test/models.py +++ b/dojo/test/models.py @@ -11,6 +11,8 @@ from django_extensions.db.models import TimeStampedModel from django_tagulous.models import TagField +from dojo.query_hooks import HookedManager, UnfilteredManager + logger = logging.getLogger(__name__) deduplicationLogger = logging.getLogger("dojo.specific-loggers.deduplication") @@ -80,8 +82,17 @@ class Test(models.Model): null=True, blank=True, help_text=_("Tag or branch that was tested, a reimport may update this field."), verbose_name=_("Branch/Tag")) api_scan_configuration = models.ForeignKey("dojo.Product_API_Scan_Configuration", null=True, editable=True, blank=True, on_delete=models.CASCADE, verbose_name=_("API Scan Configuration")) + # Read and written only by plugins; open source never sets them. + archived_at = models.DateTimeField(null=True, blank=True, editable=False) + archive_batch = models.UUIDField(null=True, blank=True, editable=False) + + # objects is declared first, so it is the default manager; see dojo.query_hooks. + objects = HookedManager() + unfiltered = UnfilteredManager() + class Meta: indexes = [ + models.Index(fields=["archive_batch"], condition=models.Q(archive_batch__isnull=False), name="dojo_test_archive_batch"), models.Index(fields=["engagement", "test_type"]), # Global search (pro/search/): weighted tsvector FTS + trigram fuzzy match. GinIndex( @@ -249,6 +260,14 @@ class Test_Import(TimeStampedModel): branch_tag = models.CharField(editable=True, max_length=150, null=True, blank=True, help_text=_("Tag or branch that was tested, a reimport may update this field."), verbose_name=_("Branch/Tag")) + # Read and written only by plugins; open source never sets them. + archived_at = models.DateTimeField(null=True, blank=True, editable=False) + archive_batch = models.UUIDField(null=True, blank=True, editable=False) + + # objects is declared first, so it is the default manager; see dojo.query_hooks. + objects = HookedManager() + unfiltered = UnfilteredManager() + def get_queryset(self): logger.debug("prefetch test_import counts") super_query = super().get_queryset() @@ -288,8 +307,17 @@ class Test_Import_Finding_Action(TimeStampedModel): finding = models.ForeignKey("dojo.Finding", editable=False, null=False, blank=False, on_delete=models.CASCADE) action = models.CharField(max_length=100, null=True, blank=True, choices=IMPORT_ACTIONS) + # Read and written only by plugins; open source never sets them. + archived_at = models.DateTimeField(null=True, blank=True, editable=False) + archive_batch = models.UUIDField(null=True, blank=True, editable=False) + + # objects is declared first, so it is the default manager; see dojo.query_hooks. + objects = HookedManager() + unfiltered = UnfilteredManager() + class Meta: indexes = [ + models.Index(fields=["archive_batch"], condition=models.Q(archive_batch__isnull=False), name="dojo_tifa_archive_batch"), models.Index(fields=["finding", "action", "test_import"]), ] unique_together = (("test_import", "finding")) diff --git a/dojo/tool_product/models.py b/dojo/tool_product/models.py index 2f77ea89a6e..a68130581bc 100644 --- a/dojo/tool_product/models.py +++ b/dojo/tool_product/models.py @@ -2,6 +2,8 @@ from django.utils.timezone import now from django.utils.translation import gettext_lazy as _ +from dojo.query_hooks import HookedManager, UnfilteredManager + class Tool_Product_Settings(models.Model): name = models.CharField(max_length=200, null=False) @@ -13,6 +15,14 @@ class Tool_Product_Settings(models.Model): tool_project_id = models.CharField(max_length=200, null=True, blank=True) notes = models.ManyToManyField("dojo.Notes", blank=True, editable=False) + # Read and written only by plugins; open source never sets them. + archived_at = models.DateTimeField(null=True, blank=True, editable=False) + archive_batch = models.UUIDField(null=True, blank=True, editable=False) + + # objects is declared first, so it is the default manager; see dojo.query_hooks. + objects = HookedManager() + unfiltered = UnfilteredManager() + class Meta: ordering = ["name"] diff --git a/dojo/vulnerability/models.py b/dojo/vulnerability/models.py index 6ae4cb9b935..d919b63af3a 100644 --- a/dojo/vulnerability/models.py +++ b/dojo/vulnerability/models.py @@ -4,6 +4,8 @@ from django.db import models from django.db.models.functions import Upper +from dojo.query_hooks import HookedManager, UnfilteredManager + class Vulnerability(models.Model): @@ -80,6 +82,14 @@ class FindingVulnerabilityReference(models.Model): ) created = models.DateTimeField(auto_now_add=True) + # Read and written only by plugins; open source never sets them. + archived_at = models.DateTimeField(null=True, blank=True, editable=False) + archive_batch = models.UUIDField(null=True, blank=True, editable=False) + + # objects is declared first, so it is the default manager; see dojo.query_hooks. + objects = HookedManager() + unfiltered = UnfilteredManager() + class Meta: ordering = ["order"] constraints = [ @@ -89,7 +99,11 @@ class Meta: # insert write path, which assigns 0..n-1 in one transaction (see manager.py). models.UniqueConstraint(fields=["finding", "order"], name="unique_finding_order"), ] - indexes = [models.Index(fields=["finding", "order"]), models.Index(fields=["vulnerability"])] + indexes = [ + models.Index(fields=["finding", "order"]), + models.Index(fields=["vulnerability"]), + models.Index(fields=["archive_batch"], condition=models.Q(archive_batch__isnull=False), name="dojo_findvulnref_archive_batch"), + ] def __str__(self): return self.vulnerability.vulnerability_id diff --git a/unittests/test_excess_duplicate_handler.py b/unittests/test_excess_duplicate_handler.py new file mode 100644 index 00000000000..5a6f344e1b9 --- /dev/null +++ b/unittests/test_excess_duplicate_handler.py @@ -0,0 +1,47 @@ +""" +A plugin can set excess duplicates aside instead of deleting them. + +``register_excess_duplicate_handler`` installs one handler for the chunks the excess-duplicate +task removes. When the handler returns True it has dealt with the chunk and nothing is deleted; +with no handler, or one that returns False, the chunk is deleted as before. Only the hand-off is +tested here, so ``bulk_delete_findings`` is mocked and no database is touched. +""" +from unittest.mock import Mock, patch + +from django.test import SimpleTestCase + +from dojo import tasks + + +class ExcessDuplicateHandlerTest(SimpleTestCase): + def setUp(self): + self.addCleanup(tasks.register_excess_duplicate_handler, None) + self.chunk = Mock(name="chunk") + + @patch("dojo.tasks.bulk_delete_findings") + def test_without_a_handler_the_chunk_is_deleted(self, delete): + tasks.register_excess_duplicate_handler(None) + + tasks._remove_excess_duplicates(self.chunk) + + delete.assert_called_once_with(self.chunk, order_desc=True) + + @patch("dojo.tasks.bulk_delete_findings") + def test_a_handler_that_takes_the_chunk_stops_the_delete(self, delete): + handler = Mock(return_value=True) + tasks.register_excess_duplicate_handler(handler) + + tasks._remove_excess_duplicates(self.chunk) + + handler.assert_called_once_with(self.chunk) + delete.assert_not_called() + + @patch("dojo.tasks.bulk_delete_findings") + def test_a_handler_that_declines_leaves_the_delete_in_place(self, delete): + handler = Mock(return_value=False) + tasks.register_excess_duplicate_handler(handler) + + tasks._remove_excess_duplicates(self.chunk) + + handler.assert_called_once_with(self.chunk) + delete.assert_called_once_with(self.chunk, order_desc=True) diff --git a/unittests/test_metrics_queries.py b/unittests/test_metrics_queries.py index 94ec80f2035..81f4a15242f 100644 --- a/unittests/test_metrics_queries.py +++ b/unittests/test_metrics_queries.py @@ -337,12 +337,12 @@ def test_endpoint_queries(self, mock_now): self.assertCountEqual( endpoint_queries["all"].values(), [ - {"id": 1, "date": date(2020, 7, 1), "last_modified": datetime(2020, 7, 1, 17, 45, 39, 791907, tzinfo=zoneinfo.ZoneInfo("UTC")), "mitigated": False, "mitigated_time": None, "mitigated_by_id": None, "false_positive": False, "out_of_scope": False, "risk_accepted": False, "endpoint_id": 2, "finding_id": 2}, - {"id": 3, "date": date(2020, 7, 1), "last_modified": datetime(2020, 7, 1, 17, 45, 39, 791907, tzinfo=zoneinfo.ZoneInfo("UTC")), "mitigated": False, "mitigated_time": None, "mitigated_by_id": None, "false_positive": True, "out_of_scope": False, "risk_accepted": False, "endpoint_id": 5, "finding_id": 228}, - {"id": 4, "date": date(2020, 7, 1), "last_modified": datetime(2020, 7, 1, 17, 45, 39, 791907, tzinfo=zoneinfo.ZoneInfo("UTC")), "mitigated": False, "mitigated_time": None, "mitigated_by_id": None, "false_positive": False, "out_of_scope": True, "risk_accepted": False, "endpoint_id": 5, "finding_id": 229}, - {"id": 5, "date": date(2020, 7, 1), "last_modified": datetime(2020, 7, 1, 17, 45, 39, 791907, tzinfo=zoneinfo.ZoneInfo("UTC")), "mitigated": False, "mitigated_time": None, "mitigated_by_id": None, "false_positive": False, "out_of_scope": False, "risk_accepted": True, "endpoint_id": 5, "finding_id": 230}, - {"id": 7, "date": date(2020, 7, 1), "last_modified": datetime(2020, 7, 1, 17, 45, 39, 791907, tzinfo=zoneinfo.ZoneInfo("UTC")), "mitigated": False, "mitigated_time": None, "mitigated_by_id": None, "false_positive": False, "out_of_scope": False, "risk_accepted": False, "endpoint_id": 7, "finding_id": 227}, - {"id": 8, "date": date(2020, 7, 1), "last_modified": datetime(2020, 7, 1, 17, 45, 39, 791907, tzinfo=zoneinfo.ZoneInfo("UTC")), "mitigated": False, "mitigated_time": None, "mitigated_by_id": None, "false_positive": False, "out_of_scope": False, "risk_accepted": False, "endpoint_id": 8, "finding_id": 231}, + {"id": 1, "date": date(2020, 7, 1), "last_modified": datetime(2020, 7, 1, 17, 45, 39, 791907, tzinfo=zoneinfo.ZoneInfo("UTC")), "mitigated": False, "mitigated_time": None, "mitigated_by_id": None, "false_positive": False, "out_of_scope": False, "risk_accepted": False, "endpoint_id": 2, "finding_id": 2, "archived_at": None, "archive_batch": None}, + {"id": 3, "date": date(2020, 7, 1), "last_modified": datetime(2020, 7, 1, 17, 45, 39, 791907, tzinfo=zoneinfo.ZoneInfo("UTC")), "mitigated": False, "mitigated_time": None, "mitigated_by_id": None, "false_positive": True, "out_of_scope": False, "risk_accepted": False, "endpoint_id": 5, "finding_id": 228, "archived_at": None, "archive_batch": None}, + {"id": 4, "date": date(2020, 7, 1), "last_modified": datetime(2020, 7, 1, 17, 45, 39, 791907, tzinfo=zoneinfo.ZoneInfo("UTC")), "mitigated": False, "mitigated_time": None, "mitigated_by_id": None, "false_positive": False, "out_of_scope": True, "risk_accepted": False, "endpoint_id": 5, "finding_id": 229, "archived_at": None, "archive_batch": None}, + {"id": 5, "date": date(2020, 7, 1), "last_modified": datetime(2020, 7, 1, 17, 45, 39, 791907, tzinfo=zoneinfo.ZoneInfo("UTC")), "mitigated": False, "mitigated_time": None, "mitigated_by_id": None, "false_positive": False, "out_of_scope": False, "risk_accepted": True, "endpoint_id": 5, "finding_id": 230, "archived_at": None, "archive_batch": None}, + {"id": 7, "date": date(2020, 7, 1), "last_modified": datetime(2020, 7, 1, 17, 45, 39, 791907, tzinfo=zoneinfo.ZoneInfo("UTC")), "mitigated": False, "mitigated_time": None, "mitigated_by_id": None, "false_positive": False, "out_of_scope": False, "risk_accepted": False, "endpoint_id": 7, "finding_id": 227, "archived_at": None, "archive_batch": None}, + {"id": 8, "date": date(2020, 7, 1), "last_modified": datetime(2020, 7, 1, 17, 45, 39, 791907, tzinfo=zoneinfo.ZoneInfo("UTC")), "mitigated": False, "mitigated_time": None, "mitigated_by_id": None, "false_positive": False, "out_of_scope": False, "risk_accepted": False, "endpoint_id": 8, "finding_id": 231, "archived_at": None, "archive_batch": None}, ], ) self.assertSequenceEqual( @@ -351,7 +351,7 @@ def test_endpoint_queries(self, mock_now): ) self.assertSequenceEqual( endpoint_queries["accepted"].values(), - [{"id": 5, "date": date(2020, 7, 1), "last_modified": datetime(2020, 7, 1, 17, 45, 39, 791907, tzinfo=zoneinfo.ZoneInfo("UTC")), "mitigated": False, "mitigated_time": None, "mitigated_by_id": None, "false_positive": False, "out_of_scope": False, "risk_accepted": True, "endpoint_id": 5, "finding_id": 230}], + [{"id": 5, "date": date(2020, 7, 1), "last_modified": datetime(2020, 7, 1, 17, 45, 39, 791907, tzinfo=zoneinfo.ZoneInfo("UTC")), "mitigated": False, "mitigated_time": None, "mitigated_by_id": None, "false_positive": False, "out_of_scope": False, "risk_accepted": True, "endpoint_id": 5, "finding_id": 230, "archived_at": None, "archive_batch": None}], ) self.assertSequenceEqual( list(endpoint_queries["accepted_count"].values()), diff --git a/unittests/test_query_hooks.py b/unittests/test_query_hooks.py new file mode 100644 index 00000000000..a394f43b20b --- /dev/null +++ b/unittests/test_query_hooks.py @@ -0,0 +1,47 @@ +from dojo.models import Engagement, Finding, Product, Product_Type, Test +from dojo.query_hooks import _DEFAULT_QUERYSET_FILTERS, register_default_queryset_filter # noqa: PLC2701 +from unittests.dojo_test_case import DojoTestCase, versioned_fixtures + + +@versioned_fixtures +class TestDefaultQuerysetHooks(DojoTestCase): + fixtures = ["dojo_testdata.json"] + + def setUp(self): + self._saved = {label: dict(funcs) for label, funcs in _DEFAULT_QUERYSET_FILTERS.items()} + _DEFAULT_QUERYSET_FILTERS.clear() + + def tearDown(self): + _DEFAULT_QUERYSET_FILTERS.clear() + _DEFAULT_QUERYSET_FILTERS.update(self._saved) + + def test_nothing_registered_leaves_querysets_unchanged(self): + for model in (Product_Type, Product, Engagement, Test, Finding): + with self.subTest(model=model.__name__): + self.assertEqual(model.objects.count(), model.unfiltered.count()) + + def test_hooked_manager_is_the_default_manager(self): + for model in (Product_Type, Product, Engagement, Test, Finding): + with self.subTest(model=model.__name__): + self.assertIs(model._default_manager, model.objects) + self.assertIsNot(model._base_manager, model.objects) + + def test_registered_filter_applies_to_objects_get_and_reverse_relations(self): + finding = Finding.objects.filter(test__isnull=False).first() + register_default_queryset_filter("dojo.Finding", "hide-one", lambda qs: qs.exclude(pk=finding.pk)) + + with self.subTest("objects"): + self.assertFalse(Finding.objects.filter(pk=finding.pk).exists()) + with self.subTest("get"), self.assertRaises(Finding.DoesNotExist): + Finding.objects.get(pk=finding.pk) + with self.subTest("reverse relation"): + self.assertNotIn(finding.pk, finding.test.finding_set.values_list("pk", flat=True)) + with self.subTest("unfiltered bypasses"): + self.assertTrue(Finding.unfiltered.filter(pk=finding.pk).exists()) + with self.subTest("base manager bypasses"): + self.assertTrue(Finding._base_manager.filter(pk=finding.pk).exists()) + + def test_registering_the_same_key_replaces_the_filter(self): + register_default_queryset_filter("dojo.Product", "k", lambda qs: qs.none()) + register_default_queryset_filter("dojo.Product", "k", lambda qs: qs) + self.assertEqual(Product.objects.count(), Product.unfiltered.count())