diff --git a/sql/01-enable_versioning.sql b/sql/01-enable_versioning.sql index 1d7ac12e..97f13046 100644 --- a/sql/01-enable_versioning.sql +++ b/sql/01-enable_versioning.sql @@ -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 ), ' || 'LIKE ' || v_table_oid::text || ');'; BEGIN @@ -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(@extschema@.ver_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 @extschema@.versioned_tables ) ) + THEN + RETURN; + END IF; + + RAISE NOTICE 'Updating definition of revision tables'; + FOR rec IN + SELECT + @extschema@.ver_get_version_table_full(schema_name, table_name) + AS rt + FROM @extschema@.ver_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'; +--} diff --git a/test/sql/base.pg b/test/sql/base.pg index cf44a9b8..407d0bd5 100644 --- a/test/sql/base.pg +++ b/test/sql/base.pg @@ -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' ); @@ -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() $$);