From eb99f8a7331242655a2bb063abb3815b3cf46d6d Mon Sep 17 00:00:00 2001 From: Timm Fitschen <t.fitschen@indiscale.com> Date: Wed, 20 May 2020 14:59:23 +0200 Subject: [PATCH] WIP: phase 7: vorbereitung des partionings --- patches/patch20200426-3.0.0/versioning.sql | 1 + procedures/entityVersioning.sql | 26 +++++++++++++++++++--- tests/test_autotap.sql | 11 ++++++++- tests/test_entity_versioning.sql | 20 +++++++++++------ 4 files changed, 47 insertions(+), 11 deletions(-) diff --git a/patches/patch20200426-3.0.0/versioning.sql b/patches/patch20200426-3.0.0/versioning.sql index 17e359f..af42e4d 100644 --- a/patches/patch20200426-3.0.0/versioning.sql +++ b/patches/patch20200426-3.0.0/versioning.sql @@ -34,6 +34,7 @@ CREATE TABLE entity_version ( _iversion INT UNSIGNED NOT NULL, _ipparent INT UNSIGNED NULL, srid VARBINARY(255) NOT NULL, + _is_head BOOLEAN DEFAULT FALSE, PRIMARY KEY (`entity_id`, `_iversion`), FOREIGN KEY (`entity_id`) REFERENCES `entities` (`id`) ON DELETE CASCADE, FOREIGN KEY (`srid`) REFERENCES `transactions` (`srid`), diff --git a/procedures/entityVersioning.sql b/procedures/entityVersioning.sql index f6d4665..ff83084 100644 --- a/procedures/entityVersioning.sql +++ b/procedures/entityVersioning.sql @@ -57,10 +57,18 @@ BEGIN SET newiversion = 1; END IF; + -- remove old HEAD marker + UPDATE entity_version + SET _is_head = FALSE + WHERE entity_id = EntityID + AND _is_head IS TRUE; + + + -- insert new version with HEAD marker INSERT INTO entity_version - (entity_id, hash, version, _iversion, _ipparent, srid) + (entity_id, hash, version, _iversion, _ipparent, srid, _is_head) VALUES - (EntityID, Hash, Version, newiversion, newipparent, Transaction); + (EntityID, Hash, Version, newiversion, newipparent, Transaction, TRUE); @@ -121,10 +129,19 @@ CREATE FUNCTION db_2_0.get_head_version( RETURNS VARBINARY(255) READS SQL DATA BEGIN - RETURN get_head_relative(EntityID, 0); + RETURN ( + SELECT e.version + FROM entity_version AS e + WHERE e.entity_id = EntityID + AND e._is_head IS TRUE + ); END; // +-- This implementation assumes that the distance from the head equals the +-- difference between the _iversion numbers. This will not be correct anymore, +-- as soon as branches may split and merge. Then, an tree-walk will be +-- necessary, traversing the primary parents (_pparent), will be necessary. DROP FUNCTION IF EXISTS db_2_0.get_head_relative // CREATE FUNCTION db_2_0.get_head_relative( EntityID INT UNSIGNED, @@ -156,6 +173,9 @@ BEGIN ON ( c.srid = t.srid ) WHERE c.entity_id = EntityID AND c._ipparent is Null + -- TODO This first SELECT statement is necessary because the second one + -- does not return the root. However, this should be doable in one go with + -- a left join. -- retrieve branches UNION SELECT c.version AS child, diff --git a/tests/test_autotap.sql b/tests/test_autotap.sql index 2be5ec6..8493609 100644 --- a/tests/test_autotap.sql +++ b/tests/test_autotap.sql @@ -2216,7 +2216,7 @@ SELECT tap.table_collation_is('_caosdb_schema_unit_tests','entity_version','utf8 SELECT tap.table_engine_is('_caosdb_schema_unit_tests','entity_version','InnoDB',''); -- COLUMNS -SELECT tap.columns_are('_caosdb_schema_unit_tests','entity_version','`entity_id`,`hash`,`version`,`_iversion`,`_ipparent`,`srid`',''); +SELECT tap.columns_are('_caosdb_schema_unit_tests','entity_version','`entity_id`,`hash`,`version`,`_iversion`,`_ipparent`,`srid`,`_is_head`',''); -- COLUMN entity_version.entity_id @@ -2272,6 +2272,15 @@ SELECT tap.col_default_is('_caosdb_schema_unit_tests','entity_version','srid',NU SELECT tap.col_charset_is('_caosdb_schema_unit_tests','entity_version','srid',NULL,''); SELECT tap.col_collation_is('_caosdb_schema_unit_tests','entity_version','srid',NULL,''); +-- COLUMN entity_version._is_head + +SELECT tap.has_column('_caosdb_schema_unit_tests','entity_version','_is_head',''); +SELECT tap.col_column_type_is('_caosdb_schema_unit_tests','entity_version','_is_head','tinyint(1)',''); +SELECT tap.col_extra_is('_caosdb_schema_unit_tests','entity_version','_is_head','',''); +SELECT tap.col_default_is('_caosdb_schema_unit_tests','entity_version','_is_head','0',''); +SELECT tap.col_charset_is('_caosdb_schema_unit_tests','entity_version','_is_head',NULL,''); +SELECT tap.col_collation_is('_caosdb_schema_unit_tests','entity_version','_is_head',NULL,''); + -- CONSTRAINTS SELECT tap.constraints_are('_caosdb_schema_unit_tests','entity_version','`entity_id`,`PRIMARY`,`entity_version_ibfk_1`,`entity_version_ibfk_2`',''); diff --git a/tests/test_entity_versioning.sql b/tests/test_entity_versioning.sql index 3c7c96e..a8084c9 100644 --- a/tests/test_entity_versioning.sql +++ b/tests/test_entity_versioning.sql @@ -30,7 +30,7 @@ SELECT count(*) INTO @x FROM entity_version; SELECT tap.eq(@x, 0, "no versions there yet"); CALL insert_single_child_version(@EntityID, "hashbla", "versionbla", NULL, "SRIDbla"); -SELECT _ipparent INTO @x from entity_version WHERE version="versionbla"; +SELECT _ipparent INTO @x from entity_version WHERE version="versionbla" AND _is_head IS TRUE; SELECT tap.eq(@x, NULL, "no parent for the first version"); -- add a second version @@ -38,10 +38,10 @@ SELECT count(*) INTO @x FROM entity_version; SELECT tap.eq(@x, 1, "one version there yet"); CALL insert_single_child_version(@EntityID, "hashblub", "versionblub", "versionbla", "SRIDblub"); -SELECT _ipparent INTO @x from entity_version WHERE version="versionblub"; +SELECT _ipparent INTO @x from entity_version WHERE version="versionblub" AND _is_head IS TRUE; SELECT tap.eq(@x, 1, "the original entity is the parent"); --- error: parent does not exist +-- test error: parent does not exist SELECT count(*) INTO @x FROM entity_version; SELECT tap.eq(@x, 2, "two version there yet"); @@ -89,10 +89,10 @@ CALL insertEntityProperty(0, @EntityID, 17, "null_data", NULL, NULL, SELECT count(*) INTO @x FROM entity_version WHERE entity_id = @EntityID; SELECT tap.eq(@x, 1, "after insertEntity, a version is there."); -SELECT _iversion INTO @x FROM entity_version WHERE entity_id = @EntityID and _ipparent is NULL; +SELECT _iversion INTO @x FROM entity_version WHERE entity_id = @EntityID and _ipparent is NULL AND _is_head IS TRUE; SELECT tap.eq(@x, 1, "after insertEntity, the _iversion number is 1."); -SELECT _ipparent INTO @x from entity_version WHERE entity_id = @EntityID; +SELECT _ipparent INTO @x from entity_version WHERE entity_id = @EntityID AND _is_head IS TRUE; SELECT tap.eq(@x, NULL, "no parent for the freshly inserted entity"); SELECT tap.eq(count(*), 0, "no entity in archive_entities before first update") FROM archive_entities; @@ -105,9 +105,9 @@ CALL updateEntity(@EntityID, "NewEntityName", "NewEntityDesc", "RECORD", NULL, N SELECT count(*) INTO @x FROM entity_version WHERE entity_id = @EntityID; SELECT tap.eq(@x, 2, "after updateEntity, a second version is there."); -SELECT _iversion INTO @x FROM entity_version WHERE entity_id = @EntityID and _ipparent = 1; +SELECT _iversion INTO @x FROM entity_version WHERE entity_id = @EntityID and _ipparent = 1 AND _is_head IS TRUE; SELECT tap.eq(@x, 2, "after updateEntity, the _iversion number incremented."); -SELECT _ipparent INTO @x FROM entity_version WHERE entity_id = @EntityID and _ipparent = 1; +SELECT _ipparent INTO @x FROM entity_version WHERE entity_id = @EntityID and _ipparent = 1 AND _is_head IS TRUE; SELECT tap.eq(@x, 1, "after updateEntity, the _pparent points to the first version"); SELECT tap.eq(count(*), 1, "after updateEntity, one entity in archive_entities") @@ -152,6 +152,12 @@ CALL updateEntity(@EntityID, "EntityName", "EntityDesc", "RECORDTYPE", NULL, NUL SELECT count(*) INTO @x FROM entity_version WHERE entity_id = @EntityID; SELECT tap.eq(@x, 3, "after 2nd updateEntity, a 3rd version is there."); +SELECT tap.eq(count(*), 1, "after 2nd updateEntity, a single HEAD version is there.") + FROM entity_version WHERE entity_id = @EntityID AND _is_head IS TRUE; + +SELECT tap.eq(count(*), 2, "after 2nd updateEntity, two non-HEAD versions are there.") + FROM entity_version WHERE entity_id = @EntityID AND _is_head IS FALSE; + SELECT _iversion INTO @x FROM entity_version WHERE entity_id = @EntityID and _ipparent = 2; SELECT tap.eq(@x, 3, "after 2nd updateEntity, the _iversion number incremented again."); SELECT _ipparent INTO @x FROM entity_version WHERE entity_id = @EntityID and _iversion = 3; -- GitLab