-------------------------------------------------------------------------------- -- postgresql-dbpatch - PostgreSQL database patch change management extension -- -- Copyright 2016 Crown copyright (c) -- Land Information New Zealand and the New Zealand Government. -- All rights reserved -- -- This software is released under the terms of the new BSD license. See the -- LICENSE file for more information. -- -------------------------------------------------------------------------------- -- complain if script is sourced in psql, rather than via CREATE EXTENSION \echo Use "CREATE EXTENSION dbpatch" to load this file. \quit CREATE TABLE IF NOT EXISTS @extschema@.applied_patches ( patch_name TEXT NOT NULL PRIMARY KEY, datetime_applied TIMESTAMP NOT NULL DEFAULT now(), patch_sql TEXT[] NOT NULL ); COMMENT ON TABLE @extschema@.applied_patches IS 'dbpatch versioning data'; SELECT pg_catalog.pg_extension_config_dump('@extschema@.applied_patches', ''); CREATE OR REPLACE FUNCTION @extschema@.apply_patch( p_patch_name TEXT, p_patch_sql TEXT[] ) RETURNS BOOLEAN AS $$ -- $Id$ DECLARE v_sql TEXT; BEGIN -- Make sure that only one patch can be applied at a time LOCK TABLE @extschema@.applied_patches IN EXCLUSIVE MODE; IF EXISTS ( SELECT patch_name FROM @extschema@.applied_patches WHERE patch_name = p_patch_name ) THEN RAISE INFO 'Patch % is already applied', p_patch_name; RETURN FALSE; END IF; RAISE INFO 'Applying patch %', p_patch_name; BEGIN FOR v_sql IN SELECT * FROM unnest(p_patch_sql) LOOP RAISE DEBUG 'Running SQL: %', v_sql; EXECUTE v_sql; END LOOP; EXCEPTION WHEN others THEN RAISE EXCEPTION 'Could not applied % patch using %. ERROR: %', p_patch_name, v_sql, SQLERRM; END; INSERT INTO @extschema@.applied_patches( patch_name, datetime_applied, patch_sql ) VALUES( p_patch_name, now(), p_patch_sql ); RETURN TRUE; END; $$ LANGUAGE plpgsql; CREATE OR REPLACE FUNCTION @extschema@.reapply_patch( p_patch_name TEXT ) RETURNS BOOLEAN AS $$ -- $Id$ WITH matches AS ( DELETE FROM @extschema@.applied_patches WHERE patch_name = p_patch_name RETURNING patch_sql ) SELECT @extschema@.apply_patch(p_patch_name, patch_sql) FROM matches; $$ LANGUAGE sql VOLATILE; CREATE OR REPLACE FUNCTION @extschema@.apply_patch( p_patch_name TEXT, p_patch_sql TEXT ) RETURNS BOOLEAN AS $$ -- $Id$ SELECT @extschema@.apply_patch($1, ARRAY[$2]) $$ LANGUAGE sql; CREATE OR REPLACE FUNCTION @extschema@.dbpatch_version() RETURNS TEXT AS $$ SELECT '@@VERSION@@ $Id$'::text; $$ LANGUAGE sql;