Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure _revision_expired is always > _revision_created #121

Closed
wants to merge 8 commits into from
62 changes: 62 additions & 0 deletions sql/01-enable_versioning.sql
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ BEGIN
'CREATE TABLE ' || v_revision_table || '(' ||
'_revision_created INTEGER NOT NULL,' ||
'_revision_expired INTEGER,' ||
'CONSTRAINT expired_after_created CHECK ( _revision_created < _revision_expired ), ' ||
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this need an OR _revision_expired IS NULL check?

'LIKE ' || v_table_oid::text ||
');';
BEGIN
Expand Down Expand Up @@ -245,3 +246,64 @@ $$ LANGUAGE plpgsql;
DROP EVENT TRIGGER IF EXISTS _ver_abort_drop_of_versioned_table;
CREATE EVENT TRIGGER _ver_abort_drop_of_versioned_table
ON sql_drop EXECUTE PROCEDURE _ver_abort_drop_of_versioned_table();

--
-- Fix existing revision table definitions if coming from a version prior to 1.8.0
--
-- WARNING: this needs to be sourced _before_ the script defining
-- ver_version() function
-- {
DO $$
DECLARE
old_version TEXT;
rec RECORD;
sql TEXT;
BEGIN
BEGIN
-- version can be in the form '1.3.3 more-info-here'
old_version := regexp_replace(
regexp_replace(@[email protected]_version(), ' .*', ''),
'[^0-9.].*', ''
);
EXCEPTION WHEN undefined_function THEN
RAISE DEBUG 'ver_version not available, '
'we are either doing a new install '
'or coming from version before 1.3';
END;

RAISE WARNING 'OLD VERSION IS %', old_version;

-- We only need to update table definitions when coming
-- from versions 1.7 or earlier.
-- NOTE: coming from 1.8.0dev won't update triggers
IF ( string_to_array(old_version, '.')::int[] >= ARRAY[1,8,0] )
THEN
RETURN;
END IF;

-- We only need to update table definitions when any table
-- is known as versioned. NOTE: we do this before using
-- functions that may not even be present in the database
-- (as it happens on first install)
--
IF ( NOT EXISTS ( SELECT * FROM @[email protected]_tables ) )
THEN
RETURN;
END IF;

RAISE NOTICE 'Updating definition of revision tables';
FOR rec IN
SELECT
@[email protected]_get_version_table_full(schema_name, table_name)
AS rt
FROM @[email protected]_get_versioned_tables()
LOOP
sql := format('ALTER TABLE %s ADD CONSTRAINT expired_after_created '
'CHECK ( _revision_created < _revision_expired)',
rec.rt);
RAISE DEBUG 'Executing %', sql;
EXECUTE sql;
END LOOP;
END
$$ LANGUAGE 'plpgsql';
--}
12 changes: 11 additions & 1 deletion test/sql/base.pg
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

BEGIN;

SELECT plan(181);
SELECT plan(183);

SELECT has_schema( 'table_version' );
SELECT has_table( 'table_version', 'revision', 'Should have revision table' );
Expand Down Expand Up @@ -782,6 +782,16 @@ SELECT lives_ok($$ SELECT table_version.ver_complete_revision() $$);
SELECT lives_ok($$ SELECT setval('table_version.revision_id_seq', 1, true) $$);

SELECT lives_ok($$ SELECT table_version.ver_create_revision('r2') $$); -- 1

SELECT throws_like( $$ UPDATE t set v = 'a2' WHERE k = 1 $$,
'%violates check constraint%',
'ver_create_revision bails out on revision sequence disorder'
);

SELECT lives_ok($$
ALTER TABLE table_version.public_t_revision DROP CONSTRAINT expired_after_created
$$);

SELECT lives_ok($$ UPDATE t set v = 'a2' WHERE k = 1 $$);
SELECT lives_ok($$ SELECT table_version.ver_complete_revision() $$);

Expand Down