diff --git a/patches/patch20200426-3.0.0/fix_unversioned.sql b/patches/patch20200426-3.0.0/fix_unversioned.sql index 069409d62e1bb495f5c487620d707b90266cbe72..94cafbfb2bab7fff1fe60fb25a145ccd372a2f01 100644 --- a/patches/patch20200426-3.0.0/fix_unversioned.sql +++ b/patches/patch20200426-3.0.0/fix_unversioned.sql @@ -65,35 +65,39 @@ BEGIN 0 as nanos ) AS tmp ORDER BY tmp.seconds DESC, tmp.nanos DESC LIMIT 1; - -- insert single version into entity_version (for id>99) + -- insert single version into entity_version INSERT INTO entity_version (entity_id, hash, version, _iversion, _ipparent, srid) - SELECT - l.entity_id AS entity_id, - NULL as hash, - SHA1(UUID()) as version, - 1 AS _iversion, - NULL AS _ipparent, - t.srid AS srid - FROM transactions AS t JOIN transaction_log as l - ON ( t.seconds = l.seconds - AND t.nanos = l.nanos - AND t.username = l.username - AND t.realm = l.realm ) - WHERE l.entity_id = unversioned_id AND unversioned_id > 99; - - -- insert single version into entity_version (for id<100) - INSERT IGNORE INTO entity_version (entity_id, hash, version, _iversion, - _ipparent, srid) - SELECT - unversioned_id AS entity_id, - NULL AS hash, - SHA1(UUID()) AS version, - 1 AS _iversion, - NULL AS _ipparent, - t.srid AS srid - FROM transactions AS t - WHERE t.seconds = 0 AND t.nanos = 0 AND unversioned_id<100; + SELECT tmp.entity_id, tmp.hash, tmp.version, tmp._iversion, + tmp._ipparent, tmp.srid + FROM ( + SELECT + l.entity_id AS entity_id, + NULL as hash, + SHA1(UUID()) as version, + 1 AS _iversion, + NULL AS _ipparent, + t.srid AS srid, + t.seconds AS seconds, + t.nanos AS nanos + FROM transactions AS t JOIN transaction_log as l + ON ( t.seconds = l.seconds + AND t.nanos = l.nanos + AND t.username = l.username + AND t.realm = l.realm ) + WHERE l.entity_id = unversioned_id AND unversioned_id > 99 + UNION SELECT + unversioned_id AS entity_id, + NULL AS hash, + SHA1(UUID()) AS version, + 1 AS _iversion, + NULL AS _ipparent, + t.srid AS srid, + t.seconds AS seconds, + t.nanos AS nanos + FROM transactions AS t + WHERE t.seconds = 0 AND t.nanos = 0 AND unversioned_id<100 + ) AS tmp ORDER BY tmp.seconds DESC, tmp.nanos DESC LIMIT 1; END LOOP; @@ -104,3 +108,5 @@ END; delimiter ; CALL _fix_unversioned(); + +DROP PROCEDURE _fix_unversioned; diff --git a/tests/test_entity_versioning.sql b/tests/test_entity_versioning.sql index b84bc4063aa86c1292e511b550cccc6f9cadd58d..9285dec9d7e9afd4094cf30aaff56ab9920bca3d 100644 --- a/tests/test_entity_versioning.sql +++ b/tests/test_entity_versioning.sql @@ -186,7 +186,6 @@ DELETE FROM entity_version; DELETE FROM transactions; -- insert entity without versioning DELETE FROM feature_config WHERE _key = "ENTITY_VERSIONING"; -DELETE FROM entities WHERE name="EntityName"; CALL entityACL(@ACLID1, "{acl1}"); CALL insertEntity("EntityName", "EntityDesc", "RECORDTYPE", "{acl1}"); SELECT count(*) INTO @NumOfEntities FROM entities; @@ -225,3 +224,60 @@ SELECT tap.ok(srid IS NOT NULL, "srid was generated and user/time matches entrie CALL tap.finish(); ROLLBACK; + + +-- TEST _fix_unversioned 2 +-- Nastier case: two entities. together inserted, one got updated afterwards. +-- Both should be in the entity_version table after execution _fix_unversioned. +BEGIN; +CALL tap.no_plan(); + + +-- setup +DELETE FROM entity_version; +DELETE FROM transactions; +-- insert entity without versioning +DELETE FROM feature_config WHERE _key = "ENTITY_VERSIONING"; + +CALL entityACL(@ACLID1, "{acl1}"); +CALL insertEntity("EntityName1", "EntityDesc1", "RECORDTYPE", "{acl1}"); +CALL insertEntity("EntityName2", "EntityDesc2", "RECORDTYPE", "{acl1}"); +SELECT count(*) INTO @NumOfEntities FROM entities; +SELECT id INTO @EntityID1 FROM entities WHERE name="EntityName1"; +SELECT id INTO @EntityID2 FROM entities WHERE name="EntityName2"; + +INSERT INTO transaction_log (transaction, entity_id, username, realm, seconds, + nanos) + -- the first entry is the one which is be found by _fix_unversioned + VALUES ("INSERT", @EntityID1, "User", "CaosDB", 10000, 250), + ("INSERT", @EntityID2, "User", "CaosDB", 10000, 250), + ("UPDATE", @EntityID2, "User", "CaosDB", 20000, 250); + + +SELECT tap.eq(COUNT(*), 3, "three entries in transaction_log") FROM transaction_log; +SELECT tap.eq(COUNT(*), 0, "no versioned entity there") FROM entity_version; +SELECT tap.eq(COUNT(*), 0, "no transaction there") FROM transactions; + +INSERT INTO feature_config (_key, _value) VALUES ("ENTITY_VERSIONING", "ENABLED"); +SELECT tap.eq(COUNT(*), 0, "still, no versioned entity there") FROM entity_version; +SELECT tap.eq(COUNT(*), 0, "still, no transaction there") FROM transactions; + +-- call _fix_unversioned +CALL _fix_unversioned(); +SELECT tap.eq(COUNT(*), @NumOfEntities, + "after _fix_unversioned, one entry for our test entity in entity_version") + FROM entity_version; +SELECT tap.eq(COUNT(*), 3, + "after _fix_unversioned, one entry for each of our test entities in + transactions, one for the standard entities.") + FROM transactions; + +SELECT tap.eq(seconds, 10000, "version seconds of entity 1 is correct") + FROM entity_version AS v JOIN transactions AS t + ON (v.srid = t.srid) WHERE v.entity_id = @EntityID1; +SELECT tap.eq(seconds, 20000, "version seconds of entity 2 is correct") + FROM entity_version AS v JOIN transactions AS t + ON (v.srid = t.srid) WHERE v.entity_id = @EntityID2; + +CALL tap.finish(); +ROLLBACK;