2022-08-24 12:01:54 +02:00
|
|
|
--liquibase formatted sql
|
|
|
|
|
|
|
|
-- ============================================================================
|
|
|
|
--changeset audit-OPERATION-TYPE:1 endDelimiter:--//
|
|
|
|
-- ----------------------------------------------------------------------------
|
|
|
|
/*
|
|
|
|
A type representing a DML operation.
|
|
|
|
*/
|
|
|
|
do $$
|
|
|
|
begin
|
|
|
|
if not exists(select 1 from pg_type where typname = 'operation') then
|
|
|
|
create type "operation" as enum ('INSERT', 'UPDATE', 'DELETE', 'TRUNCATE');
|
|
|
|
end if;
|
|
|
|
--more types here...
|
|
|
|
end $$;
|
|
|
|
--//
|
|
|
|
|
|
|
|
-- ============================================================================
|
2022-08-24 12:52:28 +02:00
|
|
|
--changeset audit-TX-CONTEXT-TABLE:1 endDelimiter:--//
|
2022-08-24 12:01:54 +02:00
|
|
|
-- ----------------------------------------------------------------------------
|
|
|
|
/*
|
2022-08-24 12:52:28 +02:00
|
|
|
A table storing transactions with context data.
|
2022-08-24 12:01:54 +02:00
|
|
|
*/
|
2022-08-24 12:52:28 +02:00
|
|
|
create table tx_context
|
2022-08-24 12:01:54 +02:00
|
|
|
(
|
2022-08-24 12:52:28 +02:00
|
|
|
txId bigint primary key not null,
|
|
|
|
txTimestamp timestamp not null,
|
|
|
|
currentUser varchar(63) not null, -- not the uuid, because users can be deleted
|
|
|
|
assumedRoles varchar not null, -- not the uuids, because roles can be deleted
|
|
|
|
currentTask varchar not null
|
2022-08-24 12:01:54 +02:00
|
|
|
);
|
|
|
|
|
2022-08-24 12:52:28 +02:00
|
|
|
create index on tx_context using brin (txTimestamp);
|
2022-08-24 12:01:54 +02:00
|
|
|
--//
|
|
|
|
|
|
|
|
-- ============================================================================
|
2022-08-24 12:52:28 +02:00
|
|
|
--changeset audit-TX-JOURNAL-TABLE:1 endDelimiter:--//
|
2022-08-24 12:01:54 +02:00
|
|
|
-- ----------------------------------------------------------------------------
|
|
|
|
/*
|
2022-08-24 12:52:28 +02:00
|
|
|
A table storing the transaction audit journal for all target tables it's configured for.
|
2022-08-24 12:01:54 +02:00
|
|
|
*/
|
2022-08-24 12:52:28 +02:00
|
|
|
create table tx_journal
|
|
|
|
(
|
|
|
|
txId bigint not null references tx_context (txId),
|
|
|
|
targetTable text not null,
|
|
|
|
targetUuid uuid not null, -- Assumes that all audited tables have a uuid column.
|
|
|
|
targetOp operation not null,
|
|
|
|
targetDelta jsonb
|
|
|
|
);
|
|
|
|
|
|
|
|
create index on tx_journal (targetTable, targetUuid);
|
|
|
|
--//
|
|
|
|
|
|
|
|
-- ============================================================================
|
|
|
|
--changeset audit-TX-JOURNAL-TRIGGER:1 endDelimiter:--//
|
|
|
|
-- ----------------------------------------------------------------------------
|
|
|
|
/*
|
|
|
|
Trigger function for transaction audit journal.
|
|
|
|
*/
|
|
|
|
create or replace function tx_journal_trigger()
|
2022-08-24 12:01:54 +02:00
|
|
|
returns trigger
|
|
|
|
language plpgsql as $$
|
|
|
|
begin
|
2022-08-24 12:52:28 +02:00
|
|
|
|
|
|
|
insert
|
|
|
|
into tx_context
|
|
|
|
values (txid_current(), now(),
|
|
|
|
currentUser(), assumedRoles(), currentTask())
|
|
|
|
on conflict do nothing;
|
|
|
|
|
2022-08-24 12:01:54 +02:00
|
|
|
case tg_op
|
2022-08-24 12:52:28 +02:00
|
|
|
when 'INSERT' then insert
|
|
|
|
into tx_journal
|
|
|
|
values (txid_current(),
|
|
|
|
tg_table_name, new.uuid, tg_op::operation,
|
|
|
|
to_jsonb(new));
|
|
|
|
when 'UPDATE' then insert
|
|
|
|
into tx_journal
|
|
|
|
values (txid_current(),
|
|
|
|
tg_table_name, old.uuid, tg_op::operation,
|
|
|
|
jsonb_changes_delta(to_jsonb(old), to_jsonb(new)));
|
|
|
|
when 'DELETE' then insert
|
|
|
|
into tx_journal
|
|
|
|
values (txid_current(),
|
|
|
|
tg_table_name, old.uuid, 'DELETE'::operation,
|
|
|
|
null::jsonb);
|
|
|
|
else raise exception 'Trigger op % not supported for %.', tg_op, tg_table_name;
|
|
|
|
end case;
|
2022-08-24 12:01:54 +02:00
|
|
|
return null;
|
|
|
|
end; $$;
|
|
|
|
--//
|
|
|
|
|
|
|
|
-- ============================================================================
|
2022-08-24 12:52:28 +02:00
|
|
|
--changeset audit-CREATE-JOURNAL-LOG:1 endDelimiter:--//
|
2022-08-24 12:01:54 +02:00
|
|
|
-- ----------------------------------------------------------------------------
|
|
|
|
/*
|
2022-08-24 12:52:28 +02:00
|
|
|
Trigger function for transaction audit journal.
|
2022-08-24 12:01:54 +02:00
|
|
|
*/
|
|
|
|
|
2022-08-24 12:52:28 +02:00
|
|
|
create or replace procedure create_journal(targetTable varchar)
|
2022-08-24 12:01:54 +02:00
|
|
|
language plpgsql as $$
|
|
|
|
declare
|
2022-08-24 12:52:28 +02:00
|
|
|
createTriggerSQL varchar;
|
2022-08-24 12:01:54 +02:00
|
|
|
begin
|
2022-08-24 12:52:28 +02:00
|
|
|
createTriggerSQL = 'CREATE TRIGGER ' || targetTable || '_journal' ||
|
2022-08-24 12:01:54 +02:00
|
|
|
' AFTER INSERT OR UPDATE OR DELETE ON ' || targetTable ||
|
2022-08-24 12:52:28 +02:00
|
|
|
' FOR EACH ROW EXECUTE PROCEDURE tx_journal_trigger()';
|
2022-08-24 12:01:54 +02:00
|
|
|
raise notice 'sql: %', createTriggerSQL;
|
|
|
|
execute createTriggerSQL;
|
|
|
|
end; $$;
|
|
|
|
--//
|