Add try_register_patch function

Fixes #2 - reported by Zach
Levow.
parent 829ee00e
......@@ -63,24 +63,18 @@ This will make sure that patch 001-users can only be applied after
# AVAILABLE FUNCTIONS
## \_v.register_patch( TEXT )
Registers named patch, or dies if it is already registered.
Returns integer which is id of patch in \_v.patches table - only if it
succeeded.
## \_v.register_patch( TEXT, TEXT[] )
## \_v.register_patch( TEXT, TEXT[], TEXT[] )
Same as \_v.register_patch( TEXT ), but checks is all given patches (given as
array in second argument) are already registered.
Registers named patch (first argument), checking if all required patches (2nd
argument) are installed, and that no conflicting patches (3rd argument) are
installed.
## \_v.register_patch( TEXT, TEXT[], TEXT[] )
2nd and 3rd arguments default to NULL/empty array.
Same as \_v.register_patch( TEXT, TEXT[] ), but also checks if there are no conflicts with preexisting patches.
## \_v.try_register_patch( TEXT, TEXT[], TEXT[] )
Third argument is array of names of patches that conflict with current one. So
if any of them is installed - register_patch will error out.
Works just like \_v.register_patch(), but instead of raising exception it
returns true if it worked, and false if it didn't.
## \_v.unregister_patch( TEXT )
......
......@@ -9,6 +9,7 @@ BEGIN;
CREATE SCHEMA IF NOT EXISTS _v;
COMMENT ON SCHEMA _v IS 'Schema for versioning data and functionality.';
CREATE TABLE IF NOT EXISTS _v.patches (
patch_name TEXT PRIMARY KEY,
applied_tsz TIMESTAMPTZ NOT NULL DEFAULT now(),
......@@ -23,6 +24,7 @@ COMMENT ON COLUMN _v.patches.applied_by IS 'Who applied this patch (PostgreSQL
COMMENT ON COLUMN _v.patches.requires IS 'List of patches that are required for given patch.';
COMMENT ON COLUMN _v.patches.conflicts IS 'List of patches that conflict with given patch.';
CREATE OR REPLACE FUNCTION _v.register_patch( IN in_patch_name TEXT, IN in_requirements TEXT[] DEFAULT NULL, in_conflicts TEXT[] DEFAULT NULL, OUT versioning INT4 ) RETURNS setof INT4 AS $$
DECLARE
t_text TEXT;
......@@ -61,6 +63,23 @@ END;
$$ language plpgsql;
COMMENT ON FUNCTION _v.register_patch( TEXT, TEXT[], TEXT[] ) IS 'Function to register patches in database. Raises exception if there are conflicts, prerequisites are not installed or the migration has already been installed.';
CREATE OR REPLACE FUNCTION _v.try_register_patch( IN in_patch_name TEXT, IN in_requirements TEXT[] DEFAULT NULL, in_conflicts TEXT[] DEFAULT NULL ) RETURNS BOOL AS $$
declare
temptext TEXT;
BEGIN
PERFORM _v.register_patch( in_patch_name, in_requirements, in_conflicts );
RETURN true;
EXCEPTION
WHEN raise_exception THEN
GET STACKED DIAGNOSTICS temptext := MESSAGE_TEXT;
RAISE WARNING '%', temptext;
RETURN false;
END;
$$ language plpgsql;
COMMENT ON FUNCTION _v.try_register_patch( TEXT, TEXT[], TEXT[] ) IS 'Function to register patches in database, returns true if it worked, false otherwise.';
CREATE OR REPLACE FUNCTION _v.unregister_patch( IN in_patch_name TEXT, OUT versioning INT4 ) RETURNS setof INT4 AS $$
DECLARE
i INT4;
......@@ -85,6 +104,7 @@ END;
$$ language plpgsql;
COMMENT ON FUNCTION _v.unregister_patch( TEXT ) IS 'Function to unregister patches in database. Dies if the patch is not registered, or if unregistering it would break dependencies.';
CREATE OR REPLACE FUNCTION _v.assert_patch_is_applied( IN in_patch_name TEXT ) RETURNS TEXT as $$
DECLARE
t_text TEXT;
......@@ -98,6 +118,7 @@ END;
$$ language plpgsql;
COMMENT ON FUNCTION _v.assert_patch_is_applied( TEXT ) IS 'Function that can be used to make sure that patch has been applied.';
CREATE OR REPLACE FUNCTION _v.assert_user_is_superuser() RETURNS TEXT as $$
DECLARE
v_super bool;
......@@ -111,6 +132,7 @@ END;
$$ language plpgsql;
COMMENT ON FUNCTION _v.assert_user_is_superuser() IS 'Function that can be used to make sure that patch is being applied using superuser account.';
CREATE OR REPLACE FUNCTION _v.assert_user_is_not_superuser() RETURNS TEXT as $$
DECLARE
v_super bool;
......@@ -124,6 +146,7 @@ END;
$$ language plpgsql;
COMMENT ON FUNCTION _v.assert_user_is_not_superuser() IS 'Function that can be used to make sure that patch is being applied using normal (not superuser) account.';
CREATE OR REPLACE FUNCTION _v.assert_user_is_one_of(VARIADIC p_acceptable_users TEXT[] ) RETURNS TEXT as $$
DECLARE
BEGIN
......@@ -135,4 +158,5 @@ END;
$$ language plpgsql;
COMMENT ON FUNCTION _v.assert_user_is_one_of(TEXT[]) IS 'Function that can be used to make sure that patch is being applied by one of defined users.';
COMMIT;
BEGIN;
-- Disable printing warning messages
SET client_min_messages = ERROR;
-- load pgtap - change next line to point to correct path for your system!
\i t/00-load.sql.inc
SELECT plan(7);
SELECT is( ( SELECT count(*) FROM _v.patches ), 0::bigint, 'When running tests _v.patches table should be empty to prevent bad interactions between patches and tests.' );
SELECT is(
_v.try_register_patch( 'first_patch' ),
true,
'Installation of patch without dependencies and conflicts.'
);
SELECT is(
_v.try_register_patch( 'first_patch' ),
false,
'Reinstallation of patch without dependencies and conflicts.'
);
SELECT is(
_v.try_register_patch( 'second_patch', ARRAY['first_patch'] ),
true,
'Installation of patch with correct dependency.'
);
SELECT is(
_v.try_register_patch( 'third_patch', ARRAY['bad_patch'] ),
false,
'Installation of patch with bad dependency.'
);
SELECT is(
_v.try_register_patch( 'fourth_patch', NULL, ARRAY['bad_patch'] ),
true,
'Installation of patch with and correct conflict.'
);
SELECT is(
_v.try_register_patch( 'fifth_patch', NULL, ARRAY['first_patch'] ),
false,
'Installation of patch with bad conflict.'
);
SELECT * FROM finish();
ROLLBACK;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment