-- Independent governance journal; never install in a WeKnora business schema. CREATE TABLE IF NOT EXISTS kg_object_gateway_plans ( scope text NOT NULL, plan text NOT NULL, body bytea NOT NULL, PRIMARY KEY(scope,plan) ); CREATE TABLE IF NOT EXISTS kg_object_gateway_scopes ( scope text PRIMARY KEY, epoch bigint NOT NULL DEFAULT 0 ); CREATE TABLE IF NOT EXISTS kg_object_gateway_grants ( scope text NOT NULL REFERENCES kg_object_gateway_scopes(scope), epoch bigint NOT NULL CHECK (epoch > 0), owner text NOT NULL, plan text NOT NULL, PRIMARY KEY(scope,epoch) ); CREATE TABLE IF NOT EXISTS kg_object_gateway_intents ( scope text NOT NULL REFERENCES kg_object_gateway_scopes(scope), operation text NOT NULL, key text NOT NULL, request bytea NOT NULL, recorded_at timestamptz NOT NULL DEFAULT clock_timestamp(), PRIMARY KEY(scope,operation) ); CREATE INDEX IF NOT EXISTS kg_object_gateway_key ON kg_object_gateway_intents(scope,key); CREATE TABLE IF NOT EXISTS kg_object_gateway_receipts ( scope text NOT NULL, operation text NOT NULL, receipt bytea NOT NULL, recorded_at timestamptz NOT NULL DEFAULT clock_timestamp(), PRIMARY KEY(scope,operation), FOREIGN KEY(scope,operation) REFERENCES kg_object_gateway_intents(scope,operation) ); CREATE TABLE IF NOT EXISTS kg_object_gateway_deliveries ( scope text NOT NULL, job text NOT NULL, attempt_epoch bigint NOT NULL CHECK(attempt_epoch>0), claim bytea NOT NULL, grant_epoch bigint NOT NULL, grant_body bytea NOT NULL, PRIMARY KEY(scope,job,attempt_epoch), FOREIGN KEY(scope,grant_epoch) REFERENCES kg_object_gateway_grants(scope,epoch) ); CREATE OR REPLACE FUNCTION kg_object_gateway_immutable() RETURNS trigger LANGUAGE plpgsql AS $$ BEGIN RAISE EXCEPTION 'object gateway evidence is immutable'; END; $$; DO $$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_trigger WHERE tgname='kg_object_gateway_deliveries_immutable') THEN CREATE TRIGGER kg_object_gateway_deliveries_immutable BEFORE UPDATE OR DELETE ON kg_object_gateway_deliveries FOR EACH ROW EXECUTE FUNCTION kg_object_gateway_immutable(); END IF; IF NOT EXISTS (SELECT 1 FROM pg_trigger WHERE tgname='kg_object_gateway_plans_immutable') THEN CREATE TRIGGER kg_object_gateway_plans_immutable BEFORE UPDATE OR DELETE ON kg_object_gateway_plans FOR EACH ROW EXECUTE FUNCTION kg_object_gateway_immutable(); END IF; IF NOT EXISTS (SELECT 1 FROM pg_trigger WHERE tgname='kg_object_gateway_intents_immutable') THEN CREATE TRIGGER kg_object_gateway_intents_immutable BEFORE UPDATE OR DELETE ON kg_object_gateway_intents FOR EACH ROW EXECUTE FUNCTION kg_object_gateway_immutable(); END IF; IF NOT EXISTS (SELECT 1 FROM pg_trigger WHERE tgname='kg_object_gateway_receipts_immutable') THEN CREATE TRIGGER kg_object_gateway_receipts_immutable BEFORE UPDATE OR DELETE ON kg_object_gateway_receipts FOR EACH ROW EXECUTE FUNCTION kg_object_gateway_immutable(); END IF; IF NOT EXISTS (SELECT 1 FROM pg_trigger WHERE tgname='kg_object_gateway_grants_immutable') THEN CREATE TRIGGER kg_object_gateway_grants_immutable BEFORE UPDATE OR DELETE ON kg_object_gateway_grants FOR EACH ROW EXECUTE FUNCTION kg_object_gateway_immutable(); END IF; END $$; DO $$ DECLARE t text; BEGIN FOREACH t IN ARRAY ARRAY['plans','grants','intents','receipts','deliveries'] LOOP IF NOT EXISTS (SELECT 1 FROM pg_trigger WHERE tgname='kg_object_gateway_'||t||'_no_truncate') THEN EXECUTE format('CREATE TRIGGER %I BEFORE TRUNCATE ON %I FOR EACH STATEMENT EXECUTE FUNCTION kg_object_gateway_immutable()', 'kg_object_gateway_'||t||'_no_truncate', 'kg_object_gateway_'||t); END IF; END LOOP; END $$;