basis.tx_context, basis.tx_journal, basis.tx_journal_v, asis.create_journal

This commit is contained in:
Michael Hoennig 2024-09-13 08:51:12 +02:00
parent 18b53ad220
commit 5f00a093e4
30 changed files with 52 additions and 52 deletions

View File

@ -21,7 +21,7 @@ do $$
/* /*
A table storing transactions with context data. A table storing transactions with context data.
*/ */
create table tx_context create table basis.tx_context
( (
txId xid8 primary key not null, txId xid8 primary key not null,
txTimestamp timestamp not null, txTimestamp timestamp not null,
@ -31,7 +31,7 @@ create table tx_context
currentRequest text not null currentRequest text not null
); );
create index on tx_context using brin (txTimestamp); create index on basis.tx_context using brin (txTimestamp);
--// --//
-- ============================================================================ -- ============================================================================
@ -40,28 +40,28 @@ create index on tx_context using brin (txTimestamp);
/* /*
A table storing the transaction audit journal for all target tables it's configured for. A table storing the transaction audit journal for all target tables it's configured for.
*/ */
create table tx_journal create table basis.tx_journal
( (
txId xid8 not null references tx_context (txId), txId xid8 not null references basis.tx_context (txId),
targetTable text not null, targetTable text not null,
targetUuid uuid not null, -- Assumes that all audited tables have a uuid column. targetUuid uuid not null, -- Assumes that all audited tables have a uuid column.
targetOp operation not null, targetOp operation not null,
targetDelta jsonb targetDelta jsonb
); );
create index on tx_journal (targetTable, targetUuid); create index on basis.tx_journal (targetTable, targetUuid);
--// --//
-- ============================================================================ -- ============================================================================
--changeset audit-TX-JOURNAL-VIEW:1 endDelimiter:--// --changeset audit-TX-JOURNAL-VIEW:1 endDelimiter:--//
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
/* /*
A view combining tx_journal with tx_context. A view combining basis.tx_journal with basis.tx_context.
*/ */
create view tx_journal_v as create view basis.tx_journal_v as
select txc.*, txj.targettable, txj.targetop, txj.targetuuid, txj.targetdelta select txc.*, txj.targettable, txj.targetop, txj.targetuuid, txj.targetdelta
from tx_journal txj from basis.tx_journal txj
left join tx_context txc using (txId) left join basis.tx_context txc using (txId)
order by txc.txtimestamp; order by txc.txtimestamp;
--// --//
@ -82,24 +82,24 @@ begin
curTxId := pg_current_xact_id(); curTxId := pg_current_xact_id();
insert insert
into tx_context (txId, txTimestamp, currentUser, assumedRoles, currentTask, currentRequest) into basis.tx_context (txId, txTimestamp, currentUser, assumedRoles, currentTask, currentRequest)
values ( curTxId, now(), values ( curTxId, now(),
currentUser(), assumedRoles(), curTask, basis.currentRequest()) currentUser(), assumedRoles(), curTask, basis.currentRequest())
on conflict do nothing; on conflict do nothing;
case tg_op case tg_op
when 'INSERT' then insert when 'INSERT' then insert
into tx_journal into basis.tx_journal
values (curTxId, values (curTxId,
tg_table_name, new.uuid, tg_op::operation, tg_table_name, new.uuid, tg_op::operation,
to_jsonb(new)); to_jsonb(new));
when 'UPDATE' then insert when 'UPDATE' then insert
into tx_journal into basis.tx_journal
values (curTxId, values (curTxId,
tg_table_name, old.uuid, tg_op::operation, tg_table_name, old.uuid, tg_op::operation,
basis.jsonb_changes_delta(to_jsonb(old), to_jsonb(new))); basis.jsonb_changes_delta(to_jsonb(old), to_jsonb(new)));
when 'DELETE' then insert when 'DELETE' then insert
into tx_journal into basis.tx_journal
values (curTxId, values (curTxId,
tg_table_name, old.uuid, 'DELETE'::operation, tg_table_name, old.uuid, 'DELETE'::operation,
null::jsonb); null::jsonb);
@ -116,7 +116,7 @@ end; $$;
Trigger function for transaction audit journal. Trigger function for transaction audit journal.
*/ */
create or replace procedure create_journal(targetTable varchar) create or replace procedure basis.create_journal(targetTable varchar)
language plpgsql as $$ language plpgsql as $$
declare declare
createTriggerSQL varchar; createTriggerSQL varchar;

View File

@ -27,7 +27,7 @@ begin
if historicalTxIdSetting is null or historicalTxIdSetting = '' then if historicalTxIdSetting is null or historicalTxIdSetting = '' then
select historicalTimestampSetting::timestamp into historicalTimestamp; select historicalTimestampSetting::timestamp into historicalTimestamp;
select max(txc.txid) from tx_context txc where txc.txtimestamp <= historicalTimestamp into historicalTxId; select max(txc.txid) from basis.tx_context txc where txc.txtimestamp <= historicalTimestamp into historicalTxId;
else else
historicalTxId = historicalTxIdSetting::xid8; historicalTxId = historicalTxIdSetting::xid8;
end if; end if;
@ -110,7 +110,7 @@ begin
createHistTableSql = '' || createHistTableSql = '' ||
'CREATE TABLE ' || baseTable || '_ex (' || 'CREATE TABLE ' || baseTable || '_ex (' ||
' version_id serial PRIMARY KEY,' || ' version_id serial PRIMARY KEY,' ||
' txid xid8 NOT NULL REFERENCES tx_context(txid),' || ' txid xid8 NOT NULL REFERENCES basis.tx_context(txid),' ||
' trigger_op tx_operation NOT NULL,' || ' trigger_op tx_operation NOT NULL,' ||
' alive boolean not null,' || ' alive boolean not null,' ||
' LIKE ' || baseTable || ' LIKE ' || baseTable ||
@ -131,7 +131,7 @@ begin
createViewSQL = format( createViewSQL = format(
'CREATE OR REPLACE VIEW %1$s AS' || 'CREATE OR REPLACE VIEW %1$s AS' ||
'(' || '(' ||
-- make sure the function is only called once, not for every matching row in tx_context -- make sure the function is only called once, not for every matching row in basis.tx_context
' WITH txh AS (SELECT tx_history_txid() AS txid) ' || ' WITH txh AS (SELECT tx_history_txid() AS txid) ' ||
' SELECT %2$s' || ' SELECT %2$s' ||
' FROM %3$s' || ' FROM %3$s' ||
@ -140,7 +140,7 @@ begin
' (' || ' (' ||
' SELECT max(ex.version_id) AS history_id' || ' SELECT max(ex.version_id) AS history_id' ||
' FROM %3$s AS ex' || ' FROM %3$s AS ex' ||
' JOIN tx_context as txc ON ex.txid = txc.txid' || ' JOIN basis.tx_context as txc ON ex.txid = txc.txid' ||
' WHERE txc.txid <= (SELECT txid FROM txh)' || ' WHERE txc.txid <= (SELECT txid FROM txh)' ||
' GROUP BY uuid' || ' GROUP BY uuid' ||
' )' || ' )' ||

View File

@ -44,7 +44,7 @@ create table RbacUser
name varchar(63) not null unique name varchar(63) not null unique
); );
call create_journal('RbacUser'); call basis.create_journal('RbacUser');
create or replace function createRbacUser(userName varchar) create or replace function createRbacUser(userName varchar)
returns uuid returns uuid
@ -102,7 +102,7 @@ create table RbacObject
unique (objectTable, uuid) unique (objectTable, uuid)
); );
call create_journal('RbacObject'); call basis.create_journal('RbacObject');
--// --//
@ -174,7 +174,7 @@ create table RbacRole
unique (objectUuid, roleType) unique (objectUuid, roleType)
); );
call create_journal('RbacRole'); call basis.create_journal('RbacRole');
create type RbacRoleDescriptor as create type RbacRoleDescriptor as
( (
@ -379,7 +379,7 @@ create index on RbacPermission (opTableName, op);
ALTER TABLE RbacPermission ALTER TABLE RbacPermission
ADD CONSTRAINT RbacPermission_uc UNIQUE NULLS NOT DISTINCT (objectUuid, op, opTableName); ADD CONSTRAINT RbacPermission_uc UNIQUE NULLS NOT DISTINCT (objectUuid, op, opTableName);
call create_journal('RbacPermission'); call basis.create_journal('RbacPermission');
create or replace function createPermission(forObjectUuid uuid, forOp RbacOp, forOpTableName text = null) create or replace function createPermission(forObjectUuid uuid, forOp RbacOp, forOpTableName text = null)
returns uuid returns uuid
@ -497,7 +497,7 @@ create table RbacGrants
create index on RbacGrants (ascendantUuid); create index on RbacGrants (ascendantUuid);
create index on RbacGrants (descendantUuid); create index on RbacGrants (descendantUuid);
call create_journal('RbacGrants'); call basis.create_journal('RbacGrants');
create or replace function findGrantees(grantedId uuid) create or replace function findGrantees(grantedId uuid)
returns setof RbacReference returns setof RbacReference
returns null on null input returns null on null input

View File

@ -20,5 +20,5 @@ create table if not exists hs_office_contact
--changeset hs-office-contact-MAIN-TABLE-JOURNAL:1 endDelimiter:--// --changeset hs-office-contact-MAIN-TABLE-JOURNAL:1 endDelimiter:--//
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
call create_journal('hs_office_contact'); call basis.create_journal('hs_office_contact');
--// --//

View File

@ -31,5 +31,5 @@ create table if not exists hs_office_person
--changeset hs-office-person-MAIN-TABLE-JOURNAL:1 endDelimiter:--// --changeset hs-office-person-MAIN-TABLE-JOURNAL:1 endDelimiter:--//
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
call create_journal('hs_office_person'); call basis.create_journal('hs_office_person');
--// --//

View File

@ -33,5 +33,5 @@ create table if not exists hs_office_relation
--changeset hs-office-relation-MAIN-TABLE-JOURNAL:1 endDelimiter:--// --changeset hs-office-relation-MAIN-TABLE-JOURNAL:1 endDelimiter:--//
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
call create_journal('hs_office_relation'); call basis.create_journal('hs_office_relation');
--// --//

View File

@ -23,7 +23,7 @@ create table hs_office_partner_details
--changeset hs-office-partner-DETAILS-TABLE-JOURNAL:1 endDelimiter:--// --changeset hs-office-partner-DETAILS-TABLE-JOURNAL:1 endDelimiter:--//
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
call create_journal('hs_office_partner_details'); call basis.create_journal('hs_office_partner_details');
--// --//
-- ============================================================================ -- ============================================================================
@ -83,5 +83,5 @@ create trigger hs_office_partner_delete_dependents_trigger
--changeset hs-office-partner-MAIN-TABLE-JOURNAL:1 endDelimiter:--// --changeset hs-office-partner-MAIN-TABLE-JOURNAL:1 endDelimiter:--//
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
call create_journal('hs_office_partner'); call basis.create_journal('hs_office_partner');
--// --//

View File

@ -18,5 +18,5 @@ create table hs_office_bankaccount
--changeset hs-office-bankaccount-MAIN-TABLE-JOURNAL:1 endDelimiter:--// --changeset hs-office-bankaccount-MAIN-TABLE-JOURNAL:1 endDelimiter:--//
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
call create_journal('hs_office_bankaccount'); call basis.create_journal('hs_office_bankaccount');
--// --//

View File

@ -61,5 +61,5 @@ execute procedure deleteHsOfficeDependentsOnDebitorDelete();
--changeset hs-office-debitor-MAIN-TABLE-JOURNAL:1 endDelimiter:--// --changeset hs-office-debitor-MAIN-TABLE-JOURNAL:1 endDelimiter:--//
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
call create_journal('hs_office_debitor'); call basis.create_journal('hs_office_debitor');
--// --//

View File

@ -21,5 +21,5 @@ create table if not exists hs_office_sepamandate
--changeset hs-office-sepamandate-MAIN-TABLE-JOURNAL:1 endDelimiter:--// --changeset hs-office-sepamandate-MAIN-TABLE-JOURNAL:1 endDelimiter:--//
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
call create_journal('hs_office_sepamandate'); call basis.create_journal('hs_office_sepamandate');
--// --//

View File

@ -36,5 +36,5 @@ create table if not exists hs_office_membership
--changeset hs-office-membership-MAIN-TABLE-JOURNAL:1 endDelimiter:--// --changeset hs-office-membership-MAIN-TABLE-JOURNAL:1 endDelimiter:--//
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
call create_journal('hs_office_membership'); call basis.create_journal('hs_office_membership');
--// --//

View File

@ -64,5 +64,5 @@ alter table hs_office_coopsharestransaction
--changeset hs-office-coopshares-MAIN-TABLE-JOURNAL:1 endDelimiter:--// --changeset hs-office-coopshares-MAIN-TABLE-JOURNAL:1 endDelimiter:--//
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
call create_journal('hs_office_coopsharestransaction'); call basis.create_journal('hs_office_coopsharestransaction');
--// --//

View File

@ -72,5 +72,5 @@ alter table hs_office_coopassetstransaction
--changeset hs-office-coopassets-MAIN-TABLE-JOURNAL:1 endDelimiter:--// --changeset hs-office-coopassets-MAIN-TABLE-JOURNAL:1 endDelimiter:--//
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
call create_journal('hs_office_coopassetstransaction'); call basis.create_journal('hs_office_coopassetstransaction');
--// --//

View File

@ -18,7 +18,7 @@ create table if not exists hs_booking_project
--changeset hs-booking-project-MAIN-TABLE-JOURNAL:1 endDelimiter:--// --changeset hs-booking-project-MAIN-TABLE-JOURNAL:1 endDelimiter:--//
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
call create_journal('hs_booking_project'); call basis.create_journal('hs_booking_project');
--// --//

View File

@ -35,7 +35,7 @@ create table if not exists hs_booking_item
--changeset hs-booking-item-MAIN-TABLE-JOURNAL:1 endDelimiter:--// --changeset hs-booking-item-MAIN-TABLE-JOURNAL:1 endDelimiter:--//
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
call create_journal('hs_booking_item'); call basis.create_journal('hs_booking_item');
--// --//

View File

@ -166,7 +166,7 @@ execute procedure hs_hosting_asset_booking_item_hierarchy_check_tf();
-- ============================================================================ -- ============================================================================
--changeset hs-hosting-asset-MAIN-TABLE-JOURNAL:1 endDelimiter:--// --changeset hs-hosting-asset-MAIN-TABLE-JOURNAL:1 endDelimiter:--//
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
call create_journal('hs_hosting_asset'); call basis.create_journal('hs_hosting_asset');
--// --//

View File

@ -69,7 +69,7 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
// given // given
final var query = em.createNativeQuery(""" final var query = em.createNativeQuery("""
select currentTask, targetTable, targetOp, targetdelta->>'caption' select currentTask, targetTable, targetOp, targetdelta->>'caption'
from tx_journal_v from basis.tx_journal_v
where targettable = 'hs_booking_item'; where targettable = 'hs_booking_item';
"""); """);

View File

@ -64,7 +64,7 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea
// given // given
final var query = em.createNativeQuery(""" final var query = em.createNativeQuery("""
select currentTask, targetTable, targetOp, targetdelta->>'caption' select currentTask, targetTable, targetOp, targetdelta->>'caption'
from tx_journal_v from basis.tx_journal_v
where targettable = 'hs_booking_project'; where targettable = 'hs_booking_project';
"""); """);

View File

@ -77,7 +77,7 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
// given // given
final var query = em.createNativeQuery(""" final var query = em.createNativeQuery("""
select currentTask, targetTable, targetOp, targetdelta->>'caption' select currentTask, targetTable, targetOp, targetdelta->>'caption'
from tx_journal_v from basis.tx_journal_v
where targettable = 'hs_hosting_asset'; where targettable = 'hs_hosting_asset';
"""); """);

View File

@ -299,8 +299,8 @@ public class CsvDataImport extends ContextBasedTest {
jpaAttempt.transacted(() -> { jpaAttempt.transacted(() -> {
context(rbacSuperuser); context(rbacSuperuser);
em.createNativeQuery("delete from rbacuser_rv where name not like 'superuser-%'").executeUpdate(); em.createNativeQuery("delete from rbacuser_rv where name not like 'superuser-%'").executeUpdate();
em.createNativeQuery("delete from tx_journal where true").executeUpdate(); em.createNativeQuery("delete from basis.tx_journal where true").executeUpdate();
em.createNativeQuery("delete from tx_context where true").executeUpdate(); em.createNativeQuery("delete from basis.tx_context where true").executeUpdate();
}).assertSuccessful(); }).assertSuccessful();
} }

View File

@ -272,7 +272,7 @@ class HsOfficeBankAccountRepositoryIntegrationTest extends ContextBasedTestWithC
// given // given
final var query = em.createNativeQuery(""" final var query = em.createNativeQuery("""
select currentTask, targetTable, targetOp, targetdelta->>'iban' select currentTask, targetTable, targetOp, targetdelta->>'iban'
from tx_journal_v from basis.tx_journal_v
where targettable = 'hs_office_bankaccount'; where targettable = 'hs_office_bankaccount';
"""); """);

View File

@ -257,7 +257,7 @@ class HsOfficeContactRbacRepositoryIntegrationTest extends ContextBasedTestWithC
// given // given
final var query = em.createNativeQuery(""" final var query = em.createNativeQuery("""
select currentTask, targetTable, targetOp, targetdelta->>'caption' select currentTask, targetTable, targetOp, targetdelta->>'caption'
from tx_journal_v from basis.tx_journal_v
where targettable = 'hs_office_contact'; where targettable = 'hs_office_contact';
"""); """);

View File

@ -221,7 +221,7 @@ class HsOfficeCoopAssetsTransactionRepositoryIntegrationTest extends ContextBase
// given // given
final var query = em.createNativeQuery(""" final var query = em.createNativeQuery("""
select currentTask, targetTable, targetOp, targetdelta->>'reference' select currentTask, targetTable, targetOp, targetdelta->>'reference'
from tx_journal_v from basis.tx_journal_v
where targettable = 'hs_office_coopassetstransaction'; where targettable = 'hs_office_coopassetstransaction';
"""); """);

View File

@ -220,7 +220,7 @@ class HsOfficeCoopSharesTransactionRepositoryIntegrationTest extends ContextBase
// given // given
final var query = em.createNativeQuery(""" final var query = em.createNativeQuery("""
select currentTask, targetTable, targetOp, targetdelta->>'reference' select currentTask, targetTable, targetOp, targetdelta->>'reference'
from tx_journal_v from basis.tx_journal_v
where targettable = 'hs_office_coopsharestransaction'; where targettable = 'hs_office_coopsharestransaction';
"""); """);

View File

@ -590,7 +590,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean
// given // given
final var query = em.createNativeQuery(""" final var query = em.createNativeQuery("""
select currentTask, targetTable, targetOp, targetdelta->>'defaultprefix' select currentTask, targetTable, targetOp, targetdelta->>'defaultprefix'
from tx_journal_v from basis.tx_journal_v
where targettable = 'hs_office_debitor'; where targettable = 'hs_office_debitor';
"""); """);

View File

@ -337,7 +337,7 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTestWithCl
// given // given
final var query = em.createNativeQuery(""" final var query = em.createNativeQuery("""
select currentTask, targetTable, targetOp, targetdelta->>'membernumbersuffix' select currentTask, targetTable, targetOp, targetdelta->>'membernumbersuffix'
from tx_journal_v from basis.tx_journal_v
where targettable = 'hs_office_membership'; where targettable = 'hs_office_membership';
"""); """);

View File

@ -434,7 +434,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
// given // given
final var query = em.createNativeQuery(""" final var query = em.createNativeQuery("""
select currentTask, targetTable, targetOp, targetdelta->>'partnernumber' select currentTask, targetTable, targetOp, targetdelta->>'partnernumber'
from tx_journal_v from basis.tx_journal_v
where targettable = 'hs_office_partner'; where targettable = 'hs_office_partner';
"""); """);

View File

@ -261,7 +261,7 @@ class HsOfficePersonRepositoryIntegrationTest extends ContextBasedTestWithCleanu
// given // given
final var query = em.createNativeQuery(""" final var query = em.createNativeQuery("""
select currentTask, targetTable, targetOp, targetdelta->>'tradename', targetdelta->>'lastname' select currentTask, targetTable, targetOp, targetdelta->>'tradename', targetdelta->>'lastname'
from tx_journal_v from basis.tx_journal_v
where targettable = 'hs_office_person'; where targettable = 'hs_office_person';
"""); """);

View File

@ -395,7 +395,7 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
// given // given
final var query = em.createNativeQuery(""" final var query = em.createNativeQuery("""
select currentTask, targetTable, targetOp, targetdelta->>'mark' select currentTask, targetTable, targetOp, targetdelta->>'mark'
from tx_journal_v from basis.tx_journal_v
where targettable = 'hs_office_relation'; where targettable = 'hs_office_relation';
"""); """);

View File

@ -380,7 +380,7 @@ class HsOfficeSepaMandateRepositoryIntegrationTest extends ContextBasedTestWithC
// given // given
final var query = em.createNativeQuery(""" final var query = em.createNativeQuery("""
select currentTask, targetTable, targetOp, targetdelta->>'reference' select currentTask, targetTable, targetOp, targetdelta->>'reference'
from tx_journal_v from basis.tx_journal_v
where targettable = 'hs_office_sepamandate'; where targettable = 'hs_office_sepamandate';
"""); """);