Skip to content

Instantly share code, notes, and snippets.

@lucaswiman
Created July 14, 2017 21:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lucaswiman/a10efc60f0496d703a4ebd729a8acd59 to your computer and use it in GitHub Desktop.
Save lucaswiman/a10efc60f0496d703a4ebd729a8acd59 to your computer and use it in GitHub Desktop.
jsonpatch plpythonu
DROP TABLE IF EXISTS mytable;
DROP TABLE IF EXISTS mytable_patches;
CREATE TABLE mytable(
id SERIAL PRIMARY KEY,
data JSON
);
CREATE TABLE mytable_patches(
id SERIAL PRIMARY KEY,
mytable_id integer,
timestamp timestamp default current_timestamp,
patch JSON
);
CREATE OR REPLACE FUNCTION diff_jsonpatch (old JSON, new JSON)
RETURNS JSON
AS $$
import jsonpatch, json
return jsonpatch.make_patch(json.loads(old), json.loads(new)).to_string()
$$ LANGUAGE plpythonu;
-- https://stackoverflow.com/questions/1295795/how-can-i-use-a-postgres-triggers-to-store-changes
CREATE OR REPLACE FUNCTION process_mytable_audit() RETURNS TRIGGER AS $mytable_audit$
BEGIN
IF (TG_OP = 'DELETE') THEN
INSERT INTO mytable_patches (mytable_id, patch) VALUES (OLD.id, diff_jsonpatch(OLD.data, 'null'::JSON));
RETURN OLD;
ELSIF (TG_OP = 'UPDATE') THEN
INSERT INTO mytable_patches (mytable_id, patch) VALUES (OLD.id, diff_jsonpatch(OLD.data, NEW.data));
RETURN NEW;
ELSIF (TG_OP = 'INSERT') THEN
INSERT INTO mytable_patches (mytable_id, patch) VALUES (NEW.id, diff_jsonpatch('null'::JSON, NEW.data));
RETURN NEW;
END IF;
RETURN NULL;
END;
$mytable_audit$ LANGUAGE plpgsql;
DROP TRIGGER IF EXISTS mytable_audit ON mytable;
CREATE TRIGGER mytable_audit
AFTER INSERT OR UPDATE OR DELETE ON mytable
FOR EACH ROW EXECUTE PROCEDURE process_mytable_audit();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment