From: Ray Lee Date: Fri, 3 Apr 2020 05:05:41 +0000 (-0400) Subject: DRYD-835: Add uoc upgrade script, make others re-runnable. X-Git-Url: https://git.aero2k.de/?a=commitdiff_plain;h=5b94eb1c2f445d949f6f96df43694c9b4f5859ea;p=tmp%2Fjakarta-migration.git DRYD-835: Add uoc upgrade script, make others re-runnable. --- diff --git a/services/common/src/main/java/org/collectionspace/services/common/ServiceMain.java b/services/common/src/main/java/org/collectionspace/services/common/ServiceMain.java index 77776f2a8..084660171 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/ServiceMain.java +++ b/services/common/src/main/java/org/collectionspace/services/common/ServiceMain.java @@ -477,10 +477,15 @@ public class ServiceMain { } private void upgradeRepository(String dataSourceName, String repositoryName, String cspaceInstanceId) throws Exception { - // Install the pgcrypto extension so that the gen_random_uuid function will be available - // to upgrade scripts. + // Install the uuid-ossp extension so that the uuid_generate_v4 function will be available to + // upgrade scripts. - JDBCTools.executeUpdate(JDBCTools.CSADMIN_NUXEO_DATASOURCE_NAME, repositoryName, cspaceInstanceId, "CREATE EXTENSION IF NOT EXISTS \"pgcrypto\""); + try { + JDBCTools.executeUpdate(JDBCTools.CSADMIN_NUXEO_DATASOURCE_NAME, repositoryName, cspaceInstanceId, "CREATE EXTENSION IF NOT EXISTS \"uuid-ossp\""); + } + catch(Exception e) { + logger.warn("Could not install uuid-ossp postgresql extension. Database upgrades may fail without this extension. On some platforms you may need to manually install this extension as a superuser."); + } String stage = "post-init"; Connection conn = null; diff --git a/services/common/src/main/java/org/collectionspace/services/common/storage/JDBCTools.java b/services/common/src/main/java/org/collectionspace/services/common/storage/JDBCTools.java index a6bbb646b..338405271 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/storage/JDBCTools.java +++ b/services/common/src/main/java/org/collectionspace/services/common/storage/JDBCTools.java @@ -32,7 +32,6 @@ import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; -import java.io.Reader; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; @@ -826,6 +825,7 @@ public class JDBCTools { scriptRunner.setAutoCommit(false); scriptRunner.setStopOnError(true); + scriptRunner.setSendFullScript(true); scriptRunner.runScript(new BufferedReader(new FileReader(scriptFile))); } diff --git a/src/main/resources/db/postgresql/upgrade/6.0.0/post-init/01_organization.sql b/src/main/resources/db/postgresql/upgrade/6.0.0/post-init/01_organization.sql index c07fc48cd..d6ceb8047 100644 --- a/src/main/resources/db/postgresql/upgrade/6.0.0/post-init/01_organization.sql +++ b/src/main/resources/db/postgresql/upgrade/6.0.0/post-init/01_organization.sql @@ -1,10 +1,87 @@ -- Upgrade organization. Move contact names into the new repeating contact group (DRYD-566). -INSERT INTO hierarchy (id, parentid, pos, name, isproperty, primarytype) - SELECT gen_random_uuid(), id, pos, 'organizations_common:contactGroupList', TRUE, 'contactGroup' - FROM organizations_common_contactnames; - -INSERT INTO contactgroup (id, contactname) - SELECT h.id, occ.item - FROM organizations_common_contactnames occ - INNER JOIN hierarchy h ON h.parentid = occ.id AND h.pos = occ.pos AND h.name = 'organizations_common:contactGroupList'; +DO $$ +DECLARE + trow record; + maxpos int; + uuid varchar(36); +BEGIN + + -- For new install, if organizations_common_contactnames does not exist, there is nothing to migrate. + + IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='organizations_common_contactnames') THEN + FOR trow IN + -- Get record in organizations_common_contactnames that does not have an existing/matching record in contactgroup: + -- Verify that there is data to migrate. + + SELECT id AS parentid, item, pos + FROM public.organizations_common_contactnames + WHERE ROW(id, pos) NOT IN ( + SELECT occ.id, occ.pos + FROM public.organizations_common_contactnames occ + JOIN public.hierarchy h ON (occ.id = h.parentid) + JOIN public.contactgroup cg ON ( + h.id = cg.id + AND occ.item IS NOT DISTINCT FROM cg.contactname + ) + ) + AND (item IS NOT NULL) + ORDER BY pos + + LOOP + -- Get max pos value for the organization record's contact group, and generate a new uuid: + + SELECT + coalesce(max(pos), -1), + uuid_generate_v4()::varchar + INTO + maxpos, + uuid + FROM public.hierarchy + WHERE parentid = trow.parentid + AND name = 'organizations_common:contactGroupList' + AND primarytype = 'contactGroup'; + + -- Insert new record into hierarchy table first, due to foreign key on contactgroup table: + + INSERT INTO public.hierarchy ( + id, + parentid, + pos, + name, + isproperty, + primarytype) + VALUES ( + uuid, + trow.parentid, + maxpos + 1, + 'organizations_common:contactGroupList', + TRUE, + 'contactGroup'); + + -- Migrate organization contact data into contactgroup table: + + INSERT INTO public.contactgroup ( + id, + contactname) + VALUES ( + uuid, + trow.item); + + END LOOP; + + ELSE + RAISE NOTICE 'No v5.2 organization data to migrate: organizations_common_contactnames does not exist'; + + END IF; +END +$$; + +-- INSERT INTO hierarchy (id, parentid, pos, name, isproperty, primarytype) +-- SELECT uuid_generate_v4(), id, pos, 'organizations_common:contactGroupList', TRUE, 'contactGroup' +-- FROM organizations_common_contactnames; + +-- INSERT INTO contactgroup (id, contactname) +-- SELECT h.id, occ.item +-- FROM organizations_common_contactnames occ +-- INNER JOIN hierarchy h ON h.parentid = occ.id AND h.pos = occ.pos AND h.name = 'organizations_common:contactGroupList'; diff --git a/src/main/resources/db/postgresql/upgrade/6.0.0/post-init/02_intake.sql b/src/main/resources/db/postgresql/upgrade/6.0.0/post-init/02_intake.sql index 7babdf402..d14936a4a 100644 --- a/src/main/resources/db/postgresql/upgrade/6.0.0/post-init/02_intake.sql +++ b/src/main/resources/db/postgresql/upgrade/6.0.0/post-init/02_intake.sql @@ -1,17 +1,133 @@ -- Upgrade intake. Move depositor and currentowner into repeating fields (DRYD-801). -INSERT INTO intakes_common_currentowners (id, pos, item) - SELECT id, 0, currentowner - FROM intakes_common - WHERE currentowner IS NOT NULL; - -INSERT INTO hierarchy (id, parentid, pos, name, isproperty, primarytype) - SELECT gen_random_uuid(), id, 0, 'intakes_common:depositorGroupList', TRUE, 'depositorGroup' - FROM intakes_common - WHERE depositor IS NOT NULL OR depositorsrequirements IS NOT NULL; - -INSERT INTO depositorgroup (id, depositor, depositorsrequirements) - SELECT h.id, ic.depositor, ic.depositorsrequirements - FROM intakes_common ic - INNER JOIN hierarchy h ON h.parentid = ic.id AND h.name = 'intakes_common:depositorGroupList' - WHERE ic.depositor IS NOT NULL OR ic.depositorsrequirements IS NOT NULL; +DO $$ +DECLARE + trow record; + maxpos int; +BEGIN + -- For new install, if intakes_common.currentowner does not exist, there is nothing to migrate. + + IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='intakes_common' AND column_name='currentowner') THEN + FOR trow IN + -- Get record in intakes_common that does not have an existing/matching record in intakes_common_currentowners: + + SELECT ic.id, ic.currentowner + FROM public.intakes_common ic + LEFT OUTER JOIN public.intakes_common_currentowners icc ON (ic.id = icc.id AND ic.currentowner = icc.item) + WHERE ic.currentowner IS NOT NULL AND ic.currentowner != '' AND icc.item IS NULL + + LOOP + -- Get max pos value for the intake record's current owner field: + + SELECT coalesce(max(pos), -1) INTO maxpos + FROM public.intakes_common_currentowners + WHERE id = trow.id; + + -- Migrate intakes_common current owner data to intakes_common_currentowners table: + + INSERT INTO public.intakes_common_currentowners (id, pos, item) + VALUES (trow.id, maxpos + 1, trow.currentowner); + + END LOOP; + + ELSE + RAISE NOTICE 'No v5.2 intake current owner data to migrate: intakes_common.currentowner does not exist'; + + END IF; +END +$$; + +-- INSERT INTO intakes_common_currentowners (id, pos, item) +-- SELECT id, 0, currentowner +-- FROM intakes_common +-- WHERE currentowner IS NOT NULL; + +DO $$ +DECLARE + trow record; + maxpos int; + uuid varchar(36); +BEGIN + + -- For new install, if intakes_common.depositor does not exist, there is nothing to migrate. + + IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='intakes_common' AND column_name='depositor') THEN + FOR trow IN + -- Get record in intakes_common that does not have an existing/matching record in depositorgroup: + -- Verify that there is data to migrate. + + SELECT id AS parentid, depositor, depositorsrequirements + FROM public.intakes_common + WHERE id NOT IN ( + SELECT ic.id + FROM public.intakes_common ic + JOIN public.hierarchy h ON (ic.id = h.parentid) + JOIN public.depositorgroup dg ON ( + h.id = dg.id + AND ic.depositor IS NOT DISTINCT FROM dg.depositor + AND ic.depositorsrequirements IS NOT DISTINCT FROM dg.depositorsrequirements + ) + ) + AND (depositor IS NOT NULL OR depositorsrequirements IS NOT NULL) + + LOOP + -- Get max pos value for the intake record's depositor group, and generate a new uuid: + + SELECT + coalesce(max(pos), -1), + uuid_generate_v4()::varchar + INTO + maxpos, + uuid + FROM public.hierarchy + WHERE parentid = trow.parentid + AND name = 'intakes_common:depositorGroupList' + AND primarytype = 'depositorGroup'; + + -- Insert new record into hierarchy table first, due to foreign key on depositorgroup table: + + INSERT INTO public.hierarchy ( + id, + parentid, + pos, + name, + isproperty, + primarytype) + VALUES ( + uuid, + trow.parentid, + maxpos + 1, + 'intakes_common:depositorGroupList', + TRUE, + 'depositorGroup'); + + -- Migrate intake depositor data into depositorgroup table: + + INSERT INTO public.depositorgroup ( + id, + depositor, + depositorsrequirements) + VALUES ( + uuid, + trow.depositor, + trow.depositorsrequirements); + + END LOOP; + + ELSE + RAISE NOTICE 'No v5.2 intake depositor data to migrate: intakes_common.depositor does not exist'; + + END IF; +END +$$; + +-- INSERT INTO hierarchy (id, parentid, pos, name, isproperty, primarytype) +-- SELECT uuid_generate_v4(), id, 0, 'intakes_common:depositorGroupList', TRUE, 'depositorGroup' +-- FROM intakes_common +-- WHERE depositor IS NOT NULL OR depositorsrequirements IS NOT NULL; + +-- INSERT INTO depositorgroup (id, depositor, depositorsrequirements) +-- SELECT h.id, ic.depositor, ic.depositorsrequirements +-- FROM intakes_common ic +-- INNER JOIN hierarchy h ON h.parentid = ic.id AND h.name = 'intakes_common:depositorGroupList' +-- WHERE ic.depositor IS NOT NULL OR ic.depositorsrequirements IS NOT NULL; diff --git a/src/main/resources/db/postgresql/upgrade/6.0.0/post-init/04_anthro-collectionobject.sql b/src/main/resources/db/postgresql/upgrade/6.0.0/post-init/04_anthro-collectionobject.sql index 33f985f0e..890474cd0 100644 --- a/src/main/resources/db/postgresql/upgrade/6.0.0/post-init/04_anthro-collectionobject.sql +++ b/src/main/resources/db/postgresql/upgrade/6.0.0/post-init/04_anthro-collectionobject.sql @@ -1,11 +1,88 @@ -- Upgrade the anthropology collectionobject extension. Move nagpra cultural determinations into -- the the note field in the new nagpra determination group (DRYD-820). -INSERT INTO hierarchy (id, parentid, pos, name, isproperty, primarytype) - SELECT gen_random_uuid(), id, pos, 'collectionobjects_nagpra:nagpraDetermGroupList', TRUE, 'nagpraDetermGroup' - FROM collectionobjects_nagpra_nagpraculturaldeterminations; - -INSERT INTO nagpradetermgroup (id, nagpradetermnote) - SELECT h.id, cnn.item - FROM collectionobjects_nagpra_nagpraculturaldeterminations cnn - INNER JOIN hierarchy h ON h.parentid = cnn.id AND h.pos = cnn.pos AND h.name = 'collectionobjects_nagpra:nagpraDetermGroupList'; +DO $$ +DECLARE + trow record; + maxpos int; + uuid varchar(36); +BEGIN + + -- For new install, if collectionobjects_nagpra_nagpraculturaldeterminations does not exist, there is nothing to migrate. + + IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='collectionobjects_nagpra_nagpraculturaldeterminations') THEN + FOR trow IN + -- Get record in collectionobjects_nagpra_nagpraculturaldeterminations that does not have an existing/matching record in nagpradetermgroup: + -- Verify that there is data to migrate. + + SELECT id AS parentid, item, pos + FROM public.collectionobjects_nagpra_nagpraculturaldeterminations + WHERE ROW(id, pos) NOT IN ( + SELECT cnn.id, cnn.pos + FROM public.collectionobjects_nagpra_nagpraculturaldeterminations cnn + JOIN public.hierarchy h ON (cnn.id = h.parentid) + JOIN public.nagpradetermgroup ndg ON ( + h.id = ndg.id + AND cnn.item IS NOT DISTINCT FROM ndg.nagpradetermnote + ) + ) + AND (item IS NOT NULL) + ORDER BY pos + + LOOP + -- Get max pos value for the collectionobject record's nagpra determination group, and generate a new uuid: + + SELECT + coalesce(max(pos), -1), + uuid_generate_v4()::varchar + INTO + maxpos, + uuid + FROM public.hierarchy + WHERE parentid = trow.parentid + AND name = 'collectionobjects_nagpra:nagpraDetermGroupList' + AND primarytype = 'nagpraDetermGroup'; + + -- Insert new record into hierarchy table first, due to foreign key on nagpradetermgroup table: + + INSERT INTO public.hierarchy ( + id, + parentid, + pos, + name, + isproperty, + primarytype) + VALUES ( + uuid, + trow.parentid, + maxpos + 1, + 'collectionobjects_nagpra:nagpraDetermGroupList', + TRUE, + 'nagpraDetermGroup'); + + -- Migrate collectionobject nagpra cultural determination data into nagpradetermgroup table: + + INSERT INTO public.nagpradetermgroup ( + id, + nagpradetermnote) + VALUES ( + uuid, + trow.item); + + END LOOP; + + ELSE + RAISE NOTICE 'No v5.2 collectionobject nagpra cultural determination data to migrate: collectionobjects_nagpra_nagpraculturaldeterminations does not exist'; + + END IF; +END +$$; + +-- INSERT INTO hierarchy (id, parentid, pos, name, isproperty, primarytype) +-- SELECT uuid_generate_v4(), id, pos, 'collectionobjects_nagpra:nagpraDetermGroupList', TRUE, 'nagpraDetermGroup' +-- FROM collectionobjects_nagpra_nagpraculturaldeterminations; + +-- INSERT INTO nagpradetermgroup (id, nagpradetermnote) +-- SELECT h.id, cnn.item +-- FROM collectionobjects_nagpra_nagpraculturaldeterminations cnn +-- INNER JOIN hierarchy h ON h.parentid = cnn.id AND h.pos = cnn.pos AND h.name = 'collectionobjects_nagpra:nagpraDetermGroupList'; diff --git a/src/main/resources/db/postgresql/upgrade/6.0.0/post-init/05_uoc.sql b/src/main/resources/db/postgresql/upgrade/6.0.0/post-init/05_uoc.sql new file mode 100644 index 000000000..18b0b124c --- /dev/null +++ b/src/main/resources/db/postgresql/upgrade/6.0.0/post-init/05_uoc.sql @@ -0,0 +1,395 @@ +/* Use of Collections Data Migration from Version 5.2 + +-- This SQL script migrates existing Use of Collections data from Version 5.2 to incorporate new features developed by the UCB CSpace team, based on the following assumptions: + + -- The appropriate database is specified in executing this script. + This script does not contain commands to connect to the appropriate database. + + -- New database changes have been made: e.g. new tables created, foreign keys added. + + -- New records should not exist in newly created tables. + But, since this script may possibly be run repeatedly, it checks for data in the new tables + and it only creates a new record if the record has not yet been migrated. + + -- The uuid_generate_v4() function is required to generate UUID for new records. + Installing the uuid-ossp extension will make all UUID generation functions available. + + -- To install the uuid-ossp extension and make all the UUID functions available: + CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; + + -- To only install the uuid_generate_v4() function to generate Type 4 UUIDs: + CREATE OR REPLACE FUNCTION public.uuid_generate_v4() + RETURNS uuid + LANGUAGE c + PARALLEL SAFE STRICT + AS '$libdir/uuid-ossp', $function$uuid_generate_v4$function$; + + -- Once existing data has been migrated, this script does not delete data from, + nor drop the newly obsolete columns. + +-- Version 5.2 Use of Collections tables: + + public.uoc_common ============> MIGRATION NEEDED: various fields updated to repeatable fields/groups. + public.uoc_common_methodlist => NO MIGRATION NEEDED. + public.usergroup =============> NO MIGRATION NEEDED, although 3 new fields were added to the table. + +-- Version 5.2 uoc_common table description and migration note: + + Table "public.uoc_common" + Column | Type | Nullable | Migrate To + -------------------+-----------------------------+----------+------------------------- + id | character varying(36) | not null | + enddate | timestamp without time zone | | + location | character varying | | uoc_common_locationlist + authorizationdate | timestamp without time zone | | authorizationgroup + title | character varying | | + note | character varying | | + provisos | character varying | | + result | character varying | | + referencenumber | character varying | | + authorizationnote | character varying | | authorizationgroup + authorizedby | character varying | | authorizationgroup + startsingledate | timestamp without time zone | | usedategroup + Indexes: + "uoc_common_pk" PRIMARY KEY, btree (id) + Foreign-key constraints: + "uoc_common_id_hierarchy_fk" FOREIGN KEY (id) REFERENCES hierarchy(id) ON DELETE CASCADE + +-- NO CHANGES are required for the following uoc_common columns: + + uoc_common.id + uoc_common.enddate + uoc_common.title + uoc_common.note + uoc_common.provisos + uoc_common.result + uoc_common.referencenumber + +-- REPEATABLE FIELDS: The following uoc_common columns are now repeatable fields; migration path: + + uoc_common.location ==========> uoc_common_locationlist.item + uoc_common.authorizationdate => authorizationgroup.authorizationdate + uoc_common.authorizationnote => authorizationgroup.authorizationnote + uoc_common.authorizedby ======> authorizationgroup.authorizedby + uoc_common.startsingledate ===> usedategroup.usedate + +*/ + + +-- 1) Create function uuid_generate_v4() for generating UUID before migration: + +-- CREATE OR REPLACE FUNCTION public.uuid_generate_v4() +-- RETURNS uuid +-- LANGUAGE c +-- PARALLEL SAFE STRICT +-- AS '$libdir/uuid-ossp', $function$uuid_generate_v4$function$ + + +/* 2) Migrate v5.2 UOC Location data to uoc_common_locationlist table: + +-- NEW uoc_common_locationlist table description: + + Table "public.uoc_common_locationlist" + Column | Type | Modifiers + --------+-----------------------+----------- + id | character varying(36) | not null + pos | integer | + item | character varying | + Indexes: + "uoc_common_locationlist_id_idx" btree (id) + Foreign-key constraints: + "uoc_common_locationlist_id_hierarchy_fk" FOREIGN KEY (id) REFERENCES hierarchy(id) ON DELETE CASCADE + +-- Migration path for uoc_common.location: + + uoc_common.id ========> uoc_common_locationlist.id + 0 or next pos value ==> uoc_common_locationlist.pos + uoc_common.location ==> uoc_common_locationlist.item + +-- Only add a new record to uoc_common_locationlist when there is a value for location; do not create empty records. +-- Only add the record if it does NOT already exist. +-- In the case of a new install, check for the uoc_common.location column and do nothing if it does not exist. + +*/ + +-- Insert a new record into uoc_common_locationlist table. + +DO $$ +DECLARE + trow record; + maxpos int; +BEGIN + -- For new install, if uoc_common.location does not exist, there is nothing to migrate. + + IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='uoc_common' AND column_name='location') THEN + FOR trow IN + -- Get record in uoc_common that does not have an existing/matching record in uoc_common_locationlist: + + SELECT uc.id, uc.location + FROM public.uoc_common uc + LEFT OUTER JOIN public.uoc_common_locationlist ucll ON (uc.id = ucll.id AND uc.location = ucll.item) + WHERE uc.location IS NOT NULL AND uc.location != '' AND ucll.item IS NULL + + LOOP + -- Get max pos value for the UOC record's location field: + + SELECT coalesce(max(pos), -1) INTO maxpos + FROM public.uoc_common_locationlist + WHERE id = trow.id; + + -- Migrate uoc_common Location data to uoc_common_locationlist table: + + INSERT INTO public.uoc_common_locationlist (id, pos, item) + VALUES (trow.id, maxpos + 1, trow.location); + + END LOOP; + + ELSE + RAISE NOTICE 'No v5.2 uoc location data to migrate: uoc_common.location does not exist'; + + END IF; +END +$$; + + +/* 3) Migrate v5.2 UOC Authorization data to authorizationgroup table: + +-- NEW authorizationgroup table description: + + Table "public.authorizationgroup" + Column | Type | Modifiers + ---------------------+-----------------------------+----------- + id | character varying(36) | not null + authorizationnote | character varying | + authorizedby | character varying | + authorizationdate | timestamp without time zone | + authorizationstatus | character varying | + Indexes: + "authorizationgroup_pk" PRIMARY KEY, btree (id) + Foreign-key constraints: + "authorizationgroup_id_hierarchy_fk" FOREIGN KEY (id) REFERENCES hierarchy(id) ON DELETE CASCADE + +-- Migrate/add data from uoc_common to hierarchy. +-- The foreign key on the authorizationgroup table requires first adding new records to hierarchy. +-- Use the uuid_generate_v4() function to generate a new type 4 UUID for the new record. + + uuid_generate_v4()::varchar AS id ====> hierarchy.id + uoc_common.id ========================> hierarchy.parentid + 0 ====================================> hierarchy.pos + 'uoc_common:authorizationGroupList' ==> hierarchy.name + True =================================> hierarchy.isproperty + 'authorizationGroup' =================> hierarchy.primarytype + +-- Migrate data from uoc_common to authorizationgroup: +-- Only add a new record when there is a value for authorizationdate, authorizationnote, or authorizedby. +-- Do not create empty records in authorizationgroup. + + hierarchy.id ==> authorizationgroup.id + uoc_common.authorizationdate =======> authorizationgroup.authorizationdate + uoc_common.authorizationnote =======> authorizationgroup.authorizationnote + uoc_common.authorizedby ============> authorizationgroup.authorizedby + +*/ + +-- Migrate/add Authorization data to hierarchy, authorizationgroup tables. + +DO $$ +DECLARE + trow record; + maxpos int; + uuid varchar(36); +BEGIN + + -- For new install, if uoc_common.authorizedby does not exist, there is nothing to migrate. + + IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='uoc_common' AND column_name='authorizedby') THEN + FOR trow IN + -- Get record in uoc_common that does not have an existing/matching record in authorizationgroup: + -- Verify that there is data to migrate. + + SELECT id AS parentid, authorizedby, authorizationdate, authorizationnote + FROM public.uoc_common + WHERE id NOT IN ( + SELECT uc.id + FROM public.uoc_common uc + JOIN public.hierarchy h ON (uc.id = h.parentid) + JOIN public.authorizationgroup ag ON ( + h.id = ag.id + AND uc.authorizedby IS NOT DISTINCT FROM ag.authorizedby + AND uc.authorizationdate IS NOT DISTINCT FROM ag.authorizationdate + AND uc.authorizationnote IS NOT DISTINCT FROM ag.authorizationnote + ) + ) + AND (authorizedby IS NOT NULL OR authorizationdate IS NOT NULL OR authorizationnote IS NOT NULL) + + LOOP + -- Get max pos value for the uoc record's authorization group, and generate a new uuid: + + SELECT + coalesce(max(pos), -1), + uuid_generate_v4()::varchar + INTO + maxpos, + uuid + FROM public.hierarchy + WHERE parentid = trow.parentid + AND name = 'uoc_common:authorizationGroupList' + AND primarytype = 'authorizationGroup'; + + -- Insert new record into hierarchy table first, due to foreign key on authorizationgroup table: + + INSERT INTO public.hierarchy ( + id, + parentid, + pos, + name, + isproperty, + primarytype) + VALUES ( + uuid, + trow.parentid, + maxpos + 1, + 'uoc_common:authorizationGroupList', + TRUE, + 'authorizationGroup'); + + -- Migrate uoc_common authorization data into authorizationgroup table: + + INSERT INTO public.authorizationgroup ( + id, + authorizedby, + authorizationdate, + authorizationnote) + VALUES ( + uuid, + trow.authorizedby, + trow.authorizationdate, + trow.authorizationnote); + + END LOOP; + + ELSE + RAISE NOTICE 'No v5.2 uoc authorization data to migrate: uoc_common.authorizedby does not exist'; + + END IF; +END +$$; + + +/* 4) Migrate v5.2 UOC Start/single date data to usedategroup table: + +-- NEW usedategroup table description: + + Table "public.usedategroup" + Column | Type | Modifiers + -------------------------+-----------------------------+----------- + id | character varying(36) | not null + usedate | timestamp without time zone | + usedatenumberofvisitors | bigint | + usedatevisitornote | character varying | + usedatehoursspent | double precision | + usedatetimenote | character varying | + Indexes: + "usedategroup_pk" PRIMARY KEY, btree (id) + Foreign-key constraints: + "usedategroup_id_hierarchy_fk" FOREIGN KEY (id) REFERENCES hierarchy(id) ON DELETE CASCADE + +-- Migrate/add data from uoc_common to hierarchy. +-- The foreign key on the usedategroup table requires first adding new records to hierarchy. +-- Use the uuid_generate_v4() function to generate a new type 4 UUID for the new record. + + uuid_generate_v4()::varchar AS id ====> hierarchy.id + uoc_common.id ========================> hierarchy.parentid + 0 ====================================> hierarchy.pos + 'uoc_common:useDateGroupList' ========> hierarchy.name + True =================================> hierarchy.isproperty + 'useDateGroup' =======================> hierarchy.primarytype + +-- Migrate data from uoc_common to usedategroup. +-- Only add a new record when there is a value for startsingledate. +-- Do not create empty records in usedategroup. + + hierarchy.id ==> usedategroup.id + uoc_common.startsingledate =========> usedategroup.usedate + +*/ + +-- Migrate/add Start/single date data to hierarchy, usedategroup tables. + +DO $$ +DECLARE + trow record; + maxpos int; + uuid varchar(36); +BEGIN + + -- For new install, if uoc_common.startsingledate does not exist, there is nothing to migrate. + + IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='uoc_common' AND column_name='startsingledate') THEN + FOR trow IN + -- Get record in uoc_common that does not have an existing/matching record in usedategroup. + -- Verify that there is data to migrate. + + SELECT id AS parentid, startsingledate AS usedate + FROM public.uoc_common + WHERE id NOT IN ( + SELECT uc.id + FROM public.uoc_common uc + JOIN public.hierarchy h ON (uc.id = h.parentid) + JOIN public.usedategroup udg ON ( + h.id = udg.id + AND uc.startsingledate IS NOT DISTINCT FROM udg.usedate + ) + ) + AND startsingledate IS NOT NULL + + LOOP + -- Get max pos value for the uoc record's use date group, and generate a new uuid: + + SELECT + coalesce(max(pos), -1), + uuid_generate_v4()::varchar + INTO + maxpos, + uuid + FROM public.hierarchy + WHERE parentid = trow.parentid + AND name = 'uoc_common:useDateGroupList' + AND primarytype = 'useDateGroup'; + + -- Insert new record into hierarchy table first, due to foreign key on usedategroup table: + + INSERT INTO public.hierarchy ( + id, + parentid, + pos, + name, + isproperty, + primarytype) + VALUES ( + uuid, + trow.parentid, + maxpos + 1, + 'uoc_common:useDateGroupList', + true, + 'useDateGroup'); + + -- Insert new record into authorizationgroup table: + + INSERT INTO public.usedategroup ( + id, + usedate) + VALUES ( + uuid, + trow.usedate); + + END LOOP; + + ELSE + RAISE NOTICE 'No v5.2 uoc start/single date data to migrate: uoc_common.startsingledate does not exist'; + + END IF; +END +$$; + +-- END OF MIGRATION