diff --git a/modules/dataverse-migrate-db/extra-migrations/V4.20.0.6__remove-ejb-timer.sql b/modules/dataverse-migrate-db/extra-migrations/V4.20.0.6__remove-ejb-timer.sql
new file mode 100644
index 00000000000..de29aa0da4a
--- /dev/null
+++ b/modules/dataverse-migrate-db/extra-migrations/V4.20.0.6__remove-ejb-timer.sql
@@ -0,0 +1,2 @@
+--
+DROP TABLE IF EXISTS EJB__TIMER__TBL;
diff --git a/modules/dataverse-migrate-db/extra-migrations/V5.1.1.0__prepare-table-exttooltype.sql b/modules/dataverse-migrate-db/extra-migrations/V5.1.1.0__prepare-table-exttooltype.sql
new file mode 100644
index 00000000000..a74c8aa1602
--- /dev/null
+++ b/modules/dataverse-migrate-db/extra-migrations/V5.1.1.0__prepare-table-exttooltype.sql
@@ -0,0 +1,10 @@
+-- This is a workaround for the missing DDL statements in migration V5.1.1.2
+
+CREATE TABLE IF NOT EXISTS externaltooltype
+(
+ id SERIAL PRIMARY KEY,
+ type VARCHAR(255) NOT NULL,
+ externalTool_id BIGINT NOT NULL CONSTRAINT fk_externaltooltype_externaltool_id REFERENCES externaltool (id)
+);
+
+CREATE INDEX IF NOT EXISTS index_externaltooltype_externaltool_id ON externaltooltype (externaltool_id);
diff --git a/modules/dataverse-migrate-db/extra-migrations/V5.10.0.0__8600-orphaned-templates.sql b/modules/dataverse-migrate-db/extra-migrations/V5.10.0.0__8600-orphaned-templates.sql
new file mode 100644
index 00000000000..d10e0e37ac7
--- /dev/null
+++ b/modules/dataverse-migrate-db/extra-migrations/V5.10.0.0__8600-orphaned-templates.sql
@@ -0,0 +1,115 @@
+-- Migration script to delete orphan templates (templates with no associated dataverse), see also issue #8600
+
+DO
+$$
+ DECLARE
+ orphan_templates_count INTEGER;
+ affected_collections_count INTEGER;
+ row_count INTEGER;
+ BEGIN
+ -- Get the count of orphan templates
+ SELECT COUNT(t.id) INTO orphan_templates_count
+ FROM template t
+ WHERE dataverse_id IS NULL;
+
+ -- Count dataverse collections that use orphan templates as default
+ SELECT COUNT(*) INTO affected_collections_count
+ FROM dataverse d
+ WHERE d.defaulttemplate_id IN (
+ SELECT t.id FROM template t WHERE dataverse_id IS NULL
+ );
+
+ -- Only execute queries if the affected count is greater than 0
+ IF orphan_templates_count > 0 THEN
+ RAISE NOTICE '--- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---';
+ RAISE NOTICE 'Found % orphan templates (templates with no associated dataverse)', orphan_templates_count;
+ RAISE NOTICE 'Found % dataverses using orphan templates as their default template', affected_collections_count;
+
+ -- Please note: The below is quite a bunch of things we need to execute. When using the Admin API call
+ -- to delete the template, all the cascading is handled by JPA for us. We don't have that...
+
+ -- First, update all dataverses that use orphan templates as default template
+ UPDATE dataverse
+ SET defaulttemplate_id = NULL
+ WHERE defaulttemplate_id IN (
+ SELECT t.id FROM template t WHERE dataverse_id IS NULL
+ );
+
+ GET DIAGNOSTICS row_count = ROW_COUNT;
+ RAISE NOTICE 'Updated % collections to remove orphan templates set as default', row_count;
+
+ -- Create a temporary table to keep track of datasetfields to delete
+ CREATE TEMPORARY TABLE temp_datasetfields_to_delete AS
+ SELECT id FROM datasetfield
+ WHERE template_id IN (
+ SELECT t.id FROM template t WHERE dataverse_id IS NULL
+ );
+
+ -- Create a temporary table to keep track of compound values to delete
+ CREATE TEMPORARY TABLE temp_compoundvalues_to_delete AS
+ SELECT cv.id
+ FROM datasetfieldcompoundvalue cv
+ WHERE cv.parentdatasetfield_id IN (
+ SELECT id FROM temp_datasetfields_to_delete
+ );
+
+ -- Delete mappings between datasetfield and controlledvocabularyvalues
+ DELETE FROM datasetfield_controlledvocabularyvalue
+ WHERE datasetfield_id IN (
+ SELECT id FROM temp_datasetfields_to_delete
+ );
+
+ GET DIAGNOSTICS row_count = ROW_COUNT;
+ RAISE NOTICE 'Deleted % vocabulary mappings associated with orphan templates', row_count;
+
+ -- Delete datasetfieldvalue records that reference the datasetfields we're going to delete
+ DELETE FROM datasetfieldvalue
+ WHERE datasetfield_id IN (
+ SELECT id FROM temp_datasetfields_to_delete
+ );
+
+ GET DIAGNOSTICS row_count = ROW_COUNT;
+ RAISE NOTICE 'Deleted % datasetfieldvalues associated with orphan templates', row_count;
+
+ -- Break the circular reference by setting parentdatasetfieldcompoundvalue_id to NULL
+ UPDATE datasetfield
+ SET parentdatasetfieldcompoundvalue_id = NULL
+ WHERE parentdatasetfieldcompoundvalue_id IN (
+ SELECT id FROM temp_compoundvalues_to_delete
+ );
+
+ GET DIAGNOSTICS row_count = ROW_COUNT;
+ RAISE NOTICE 'Updated % datasetfields to remove references to compound values', row_count;
+
+ -- Now we can safely delete the compound values
+ DELETE FROM datasetfieldcompoundvalue
+ WHERE id IN (
+ SELECT id FROM temp_compoundvalues_to_delete
+ );
+
+ GET DIAGNOSTICS row_count = ROW_COUNT;
+ RAISE NOTICE 'Deleted % datasetfieldcompoundvalues associated with orphan templates', row_count;
+
+ -- Delete datasetfields that reference orphan templates
+ DELETE FROM datasetfield
+ WHERE id IN (
+ SELECT id FROM temp_datasetfields_to_delete
+ );
+
+ GET DIAGNOSTICS row_count = ROW_COUNT;
+ RAISE NOTICE 'Deleted % datasetfields referencing orphan templates', row_count;
+
+ -- Clean up temporary tables
+ DROP TABLE temp_datasetfields_to_delete;
+ DROP TABLE temp_compoundvalues_to_delete;
+
+ -- Then finally delete all orphan templates
+ DELETE FROM template
+ WHERE dataverse_id IS NULL;
+
+ GET DIAGNOSTICS row_count = ROW_COUNT;
+ RAISE NOTICE 'Deleted % orphan templates', row_count;
+ RAISE NOTICE '--- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---';
+ END IF;
+ END
+$$;
\ No newline at end of file
diff --git a/modules/dataverse-migrate-db/extra-migrations/V5.3.0.7__7398-cleanup-saved-searches-and-links.sql b/modules/dataverse-migrate-db/extra-migrations/V5.3.0.7__7398-cleanup-saved-searches-and-links.sql
new file mode 100644
index 00000000000..ac3eab95679
--- /dev/null
+++ b/modules/dataverse-migrate-db/extra-migrations/V5.3.0.7__7398-cleanup-saved-searches-and-links.sql
@@ -0,0 +1,93 @@
+--
+DO
+$$
+ DECLARE
+ should_delete BOOLEAN := CASE WHEN UPPER('${V5_4_cleanup_searches_and_links}') = 'TRUE' THEN TRUE ELSE FALSE END;
+ affected_searches_count INTEGER;
+ affected_linked_datasets_count INTEGER;
+ affected_linked_collections_count INTEGER;
+ row_count INTEGER;
+ BEGIN
+ -- Get the count of rows that match the criteria
+ SELECT COUNT(*) INTO affected_searches_count
+ from savedsearch ss, savedsearchfilterquery ssfq, dataverselinkingdataverse dld
+ where ss.id = ssfq.savedsearch_id
+ and ss.definitionpoint_id = dld.linkingdataverse_id
+ and dld.dataverse_id = rtrim(reverse(split_part(reverse(ssfq.filterquery),'/',1)),'"')::integer
+ and ss.query='*'
+ and ssfq.filterquery like 'subtreePaths%';
+
+ select COUNT(*) INTO affected_linked_datasets_count
+ from datasetlinkingdataverse dld, dvobject dvo, dataverselinkingdataverse dvld
+ where dld.dataset_id = dvo.id
+ and dld.linkingdataverse_id = dvld.linkingdataverse_id
+ and dvo.owner_id = dvld.dataverse_id;
+
+ select COUNT(*) INTO affected_linked_collections_count
+ from dataverselinkingdataverse dld, dvobject dvo, dataverselinkingdataverse dvld
+ where dld.dataverse_id = dvo.id
+ and dld.linkingdataverse_id = dvld.linkingdataverse_id
+ and dvo.owner_id = dvld.dataverse_id;
+
+ -- Only show hint if count is greater than 0
+ IF affected_searches_count > 0 OR affected_linked_datasets_count > 0 OR affected_linked_collections_count > 0 THEN
+ RAISE NOTICE '--- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---';
+ RAISE NOTICE 'Found % saved searches affected by issue #7398', affected_searches_count;
+ RAISE NOTICE 'Found % dataset links affected by issue #7398', affected_linked_datasets_count;
+ RAISE NOTICE 'Found % collections links affected by issue #7398', affected_linked_collections_count;
+
+ IF should_delete THEN
+ RAISE NOTICE 'Cleaning up Saved Searches and Linked Datasets as requested by -Dmigrate.cleanupSavedSearches';
+
+ -- delete the saved searches identified using the ss_for_deletion query
+ create temporary table delete_ss on commit drop as (
+ Select ss.id
+ from savedsearch ss, savedsearchfilterquery ssfq, dataverselinkingdataverse dld
+ where ss.id = ssfq.savedsearch_id
+ and ss.definitionpoint_id = dld.linkingdataverse_id
+ and dld.dataverse_id = rtrim(reverse(split_part(reverse(ssfq.filterquery),'/',1)),'"')::integer
+ and ss.query='*'
+ and ssfq.filterquery like 'subtreePaths%'
+ );
+
+ GET DIAGNOSTICS row_count = ROW_COUNT;
+
+ delete from savedsearchfilterquery where savedsearch_id in (select id from delete_ss);
+ delete from savedsearch where id in (select id from delete_ss);
+
+ RAISE NOTICE 'Deleted % saved searches', row_count;
+
+ COMMIT;
+
+ -- delete linked objects identified using the query in dld_for_deletion
+ delete from datasetlinkingdataverse where id in (
+ select dld.id
+ from datasetlinkingdataverse dld, dvobject dvo, dataverselinkingdataverse dvld
+ where dld.dataset_id = dvo.id
+ and dld.linkingdataverse_id = dvld.linkingdataverse_id
+ and dvo.owner_id = dvld.dataverse_id
+ );
+
+ GET DIAGNOSTICS row_count = ROW_COUNT;
+ RAISE NOTICE 'Deleted % linked datasets', row_count;
+
+ delete from dataverselinkingdataverse where id in (
+ select dld.id
+ from dataverselinkingdataverse dld, dvobject dvo, dataverselinkingdataverse dvld
+ where dld.dataverse_id = dvo.id
+ and dld.linkingdataverse_id = dvld.linkingdataverse_id
+ and dvo.owner_id = dvld.dataverse_id
+ );
+
+ GET DIAGNOSTICS row_count = ROW_COUNT;
+ RAISE NOTICE 'Deleted % linked collections', row_count;
+
+ COMMIT;
+
+ ELSE
+ RAISE NOTICE 'Auto-migrate these using `mvn -Dmigrate.cleanupSavedSearches ...` (re-execute migrations)';
+ END IF;
+ RAISE NOTICE '--- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---';
+ END IF;
+ END
+$$;
diff --git a/modules/dataverse-migrate-db/extra-migrations/V5.3.0.8__7687-file-access-flag-update-bug.sql b/modules/dataverse-migrate-db/extra-migrations/V5.3.0.8__7687-file-access-flag-update-bug.sql
new file mode 100644
index 00000000000..60f87ac80fc
--- /dev/null
+++ b/modules/dataverse-migrate-db/extra-migrations/V5.3.0.8__7687-file-access-flag-update-bug.sql
@@ -0,0 +1,30 @@
+-- this query will identify datasets where a superuser has run the Curate command and the update included a change to
+-- the fileaccessrequest flag, resulting in the file access request updates not being reflected in the published version
+DO
+$$
+ DECLARE
+ -- should_migrate BOOLEAN := CASE WHEN UPPER('...') = 'TRUE' THEN TRUE ELSE FALSE END;
+ affected_count INTEGER;
+ BEGIN
+ -- Get the count of rows that match the criteria
+ SELECT COUNT(*) INTO affected_count
+ from datasetversion dv, termsofuseandaccess ta, dataset da
+ where dv.dataset_id=da.id
+ and dv.termsofuseandaccess_id=ta.id
+ and ta.fileaccessrequest != da.fileaccessrequest
+ and dv.versionstate='RELEASED'
+ and dv.releasetime in (select max(releasetime)
+ from datasetversion
+ where dataset_id=da.id);
+
+ -- Only show hint if count is greater than 0
+ IF affected_count > 0 THEN
+ RAISE NOTICE '--- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---';
+ RAISE NOTICE 'Found % datasets affected by issue #7687', affected_count;
+ RAISE NOTICE 'For now, please fix these manually. See Dataverse v5.4 release notes about #7687.';
+ RAISE NOTICE '--- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---';
+ END IF;
+
+ -- TODO: an opt-in migration to fix them all would be nice!
+ END;
+$$;
\ No newline at end of file
diff --git a/modules/dataverse-migrate-db/extra-migrations/V5.4.1.0__prepare-table-auxfile.sql b/modules/dataverse-migrate-db/extra-migrations/V5.4.1.0__prepare-table-auxfile.sql
new file mode 100644
index 00000000000..071c80cfc2c
--- /dev/null
+++ b/modules/dataverse-migrate-db/extra-migrations/V5.4.1.0__prepare-table-auxfile.sql
@@ -0,0 +1,15 @@
+-- This is a workaround for the missing auxiliaryfile table in migration V5.4.1.1
+
+create table if not exists auxiliaryfile
+(
+ id serial primary key,
+ checksum varchar(255),
+ contenttype varchar(255),
+ filesize bigint,
+ formattag varchar(255),
+ formatversion varchar(255),
+ ispublic boolean,
+ origin varchar(255),
+ type varchar(255),
+ datafile_id bigint not null constraint fk_auxiliaryfile_datafile_id references dvobject
+);
diff --git a/modules/dataverse-migrate-db/extra-migrations/V5.9.0.0__prepare-table-license.sql b/modules/dataverse-migrate-db/extra-migrations/V5.9.0.0__prepare-table-license.sql
new file mode 100644
index 00000000000..df66ccff90f
--- /dev/null
+++ b/modules/dataverse-migrate-db/extra-migrations/V5.9.0.0__prepare-table-license.sql
@@ -0,0 +1,15 @@
+-- This is a workaround for the missing license table in migration V5.9.0.1
+
+create table if not exists license
+(
+ id serial primary key,
+ active boolean not null,
+ iconurl text,
+ isdefault boolean not null,
+ name text constraint unq_license_0 unique,
+ shortdescription text,
+ sortorder bigint default 0 not null,
+ uri text constraint unq_license_1 unique
+);
+
+create index if not exists license_sortorder_id on license (sortorder, id);
diff --git a/modules/dataverse-migrate-db/extra-migrations/V6.0.0.0__prepare-tables-embargo-storageuse.sql b/modules/dataverse-migrate-db/extra-migrations/V6.0.0.0__prepare-tables-embargo-storageuse.sql
new file mode 100644
index 00000000000..9d57a82a0d9
--- /dev/null
+++ b/modules/dataverse-migrate-db/extra-migrations/V6.0.0.0__prepare-tables-embargo-storageuse.sql
@@ -0,0 +1,17 @@
+-- This is a workaround for the missing embargo table in migration V6.0.0.2
+create table if not exists embargo
+(
+ id serial primary key,
+ dateavailable date not null,
+ reason text
+);
+
+-- This is a workaround for the missing storageuse table in migration V6.0.0.5
+create table if not exists storageuse
+(
+ id serial primary key,
+ sizeinbytes bigint,
+ dvobjectcontainer_id bigint not null constraint fk_storageuse_dvobjectcontainer_id references dvobject
+);
+create index if not exists index_storageuse_dvobjectcontainer_id on storageuse (dvobjectcontainer_id);
+
diff --git a/modules/dataverse-migrate-db/extra-migrations/V6.1.0.0__prepare-table-extvocab.sql b/modules/dataverse-migrate-db/extra-migrations/V6.1.0.0__prepare-table-extvocab.sql
new file mode 100644
index 00000000000..76146039b98
--- /dev/null
+++ b/modules/dataverse-migrate-db/extra-migrations/V6.1.0.0__prepare-table-extvocab.sql
@@ -0,0 +1,12 @@
+-- This is a workaround for the missing externalvocabularyvalue table in migration V6.1.0.3
+create table if not exists externalvocabularyvalue
+(
+ id serial primary key,
+ lastupdatedate timestamp,
+ uri text constraint externalvocabularvalue_uri_key unique,
+ value text
+);
+
+create index if not exists index_externalvocabularyvalue_uri on externalvocabularyvalue (uri);
+
+
diff --git a/modules/dataverse-migrate-db/extra-migrations/V6.2.0.2__migrate_keywordTermUri.sql b/modules/dataverse-migrate-db/extra-migrations/V6.2.0.2__migrate_keywordTermUri.sql
new file mode 100644
index 00000000000..eaefa85c7e3
--- /dev/null
+++ b/modules/dataverse-migrate-db/extra-migrations/V6.2.0.2__migrate_keywordTermUri.sql
@@ -0,0 +1,44 @@
+-- See also
+DO
+$$
+ DECLARE
+ should_migrate BOOLEAN := CASE WHEN UPPER('${V6_3_migrate_keywordTermUri}') = 'TRUE' THEN TRUE ELSE FALSE END;
+ keyword_count INTEGER;
+ BEGIN
+ -- Get the count of rows that match the criteria
+ SELECT COUNT(*) INTO keyword_count
+ FROM datasetfieldvalue dfv INNER JOIN datasetfield df ON df.id = dfv.datasetfield_id
+ WHERE df.datasetfieldtype_id = (SELECT id FROM datasetfieldtype WHERE name = 'keywordValue')
+ AND value ILIKE 'http%';
+
+ -- Only show hint if count is greater than 0
+ IF keyword_count > 0 THEN
+ RAISE NOTICE '--- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---';
+ RAISE NOTICE 'Found % keywordValue metadata fields starting with "http"', keyword_count;
+ RAISE NOTICE 'See release notes of Dataverse 6.3 to learn more about migrating these to the keywordTermURI field.';
+
+ /*
+ To execute this migration, the keywordTermURI metadata field needs to be loaded.
+ So far, we never added metadata fields using a migration. Maybe it's fine to keep it a manual task for now.
+
+ IF should_migrate THEN
+ RAISE NOTICE 'Migrating keywordValue fields with http... to keywordTermUri as requested by -Dmigrate.keywordTermUri';
+ UPDATE datasetfield df
+ SET datasetfieldtype_id = (SELECT id FROM datasetfieldtype WHERE name = 'keywordTermURI')
+ FROM datasetfieldvalue dfv
+ WHERE dfv.datasetfield_id = df.id
+ AND df.datasetfieldtype_id = (SELECT id FROM datasetfieldtype WHERE name = 'keywordValue')
+ AND dfv.value ILIKE 'http%';
+
+ GET DIAGNOSTICS keyword_count = ROW_COUNT;
+ RAISE NOTICE 'Updated % rows', keyword_count;
+
+ ELSE
+ RAISE NOTICE 'Auto-migrate these into keywordTermUri using `mvn -Dmigrate.keywordTermUri ...` (re-execute migrations)';
+ END IF;
+ */
+
+ RAISE NOTICE '--- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---';
+ END IF;
+ END
+$$;
\ No newline at end of file
diff --git a/modules/dataverse-migrate-db/extra-migrations/V6.3.0.0__prepare-table-datasettype.sql b/modules/dataverse-migrate-db/extra-migrations/V6.3.0.0__prepare-table-datasettype.sql
new file mode 100644
index 00000000000..e326c1ec69c
--- /dev/null
+++ b/modules/dataverse-migrate-db/extra-migrations/V6.3.0.0__prepare-table-datasettype.sql
@@ -0,0 +1,29 @@
+-- This is a workaround for the missing dataset type tables in migration V6.3.0.3
+
+create table if not exists datasettype
+(
+ id serial primary key,
+ name varchar(255) not null constraint unq_datasettype_0 unique
+);
+
+create table if not exists datasettype_licenses
+(
+ datasettype_id bigint not null
+ constraint fk_datasettype_license_datasettype_id
+ references datasettype,
+ licenses_id bigint not null
+ constraint fk_datasettype_license_licenses_id
+ references license,
+ primary key (datasettype_id, licenses_id)
+);
+
+create table if not exists datasettype_metadatablocks
+(
+ datasettype_id bigint not null
+ constraint fk_datasettype_metadatablock_datasettype_id
+ references datasettype,
+ metadatablocks_id bigint not null
+ constraint fk_datasettype_metadatablock_metadatablocks_id
+ references public.metadatablock,
+ primary key (datasettype_id, metadatablocks_id)
+);
\ No newline at end of file
diff --git a/modules/dataverse-migrate-db/extra-migrations/V6.5.0.0__prepare-table-mdc-proc-state.sql b/modules/dataverse-migrate-db/extra-migrations/V6.5.0.0__prepare-table-mdc-proc-state.sql
new file mode 100644
index 00000000000..0c2f1373721
--- /dev/null
+++ b/modules/dataverse-migrate-db/extra-migrations/V6.5.0.0__prepare-table-mdc-proc-state.sql
@@ -0,0 +1,12 @@
+-- This is a workaround for the missing MakeDataCount tables in migration V6.5.0.10
+
+CREATE TABLE IF NOT EXISTS MakeDataCountProcessState
+(
+ id SERIAL PRIMARY KEY,
+ yearMonth VARCHAR(255) NOT NULL,
+ state INTEGER NOT NULL,
+ stateChangeTimestamp TIMESTAMP WITHOUT TIME ZONE,
+ server VARCHAR(255)
+);
+
+CREATE INDEX IF NOT EXISTS index_makedatacountprocessstate_yearmonth ON MakeDataCountProcessState (yearMonth);
diff --git a/modules/dataverse-migrate-db/extra-migrations/V6.6.0.0__prepare-table-dataversefeatureditem.sql b/modules/dataverse-migrate-db/extra-migrations/V6.6.0.0__prepare-table-dataversefeatureditem.sql
new file mode 100644
index 00000000000..15ca0d6e31b
--- /dev/null
+++ b/modules/dataverse-migrate-db/extra-migrations/V6.6.0.0__prepare-table-dataversefeatureditem.sql
@@ -0,0 +1,16 @@
+-- This is a workaround for the missing tables in migration V6.6.0.2
+
+create table if not exists dataversefeatureditem
+(
+ id serial primary key,
+ content text,
+ displayorder integer not null,
+ imagefilename varchar(255),
+ type text,
+ dataverse_id bigint not null constraint fk_dataversefeatureditem_dataverse_id references dvobject,
+ dvobject_id bigint constraint fk_dataversefeatureditem_dvobject_id references dvobject
+);
+
+create index if not exists index_dataversefeatureditem_displayorder on dataversefeatureditem (displayorder);
+-- It's unclear why EclipseLink generated this particular index and with this name... Just going along with it.
+create index if not exists index_harvestingclient_harvesttype on dataversefeatureditem (id);
diff --git a/modules/dataverse-migrate-db/extra-migrations/afterMigrate__2-8191-check-restricted-file-terms.sql b/modules/dataverse-migrate-db/extra-migrations/afterMigrate__2-8191-check-restricted-file-terms.sql
new file mode 100644
index 00000000000..62e39ace8b2
--- /dev/null
+++ b/modules/dataverse-migrate-db/extra-migrations/afterMigrate__2-8191-check-restricted-file-terms.sql
@@ -0,0 +1,69 @@
+-- this query will identify datasets where at least one file does not have either terms of access or
+-- request access enabled, and will include owner information for those datasets
+
+DO
+$$
+ DECLARE
+ affected_dataset RECORD;
+ row_count INTEGER := 0;
+ BEGIN
+ -- Create a temporary table to store the results
+ CREATE TEMPORARY TABLE IF NOT EXISTS affected_dataset_results (
+ email TEXT,
+ name TEXT,
+ dataset_url TEXT
+ );
+
+ -- Insert the query results into the temporary table
+ INSERT INTO affected_dataset_results
+ select au.email,
+ concat(au.firstname, ' ', au.lastname) as name,
+ concat('dx.doi.org/' , dvo.authority , '/' , dvo.identifier) as dataset_url
+ from roleassignment ra, dataverserole dvr,
+ authenticateduser au, dvobject dvo
+ where
+ au.useridentifier = rtrim(substring(ra.assigneeidentifier, 2, 100))
+ and dvo.id = ra.definitionpoint_id
+ and
+ ra.role_id = dvr.id and
+ dvr.alias in (
+ 'fullContributor',
+ 'dsContributor',
+ 'contributor',
+ 'admin',
+ 'curator'
+ ) and
+ ra.definitionpoint_id in (
+ select dvo.id from datasetversion v
+ join termsofuseandaccess ua on ua.id = v.termsofuseandaccess_id
+ join filemetadata fm on v.id = fm.datasetversion_id
+ join datafile f on f.id = fm.datafile_id
+ join dvobject dvo on v.dataset_id = dvo.id
+ where ua.fileaccessrequest = false and ua.termsofaccess isnull
+ and f.restricted = true
+ );
+
+ -- Get the number of affected rows
+ GET DIAGNOSTICS row_count = ROW_COUNT;
+
+ -- Print notice if there are affected datasets
+ IF row_count > 0 THEN
+ RAISE NOTICE '--- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---';
+ RAISE NOTICE 'Found % dataset(s) with files lacking proper access settings.', row_count;
+ RAISE NOTICE 'For details see Dataverse 5.11 release notes and issue 8191.';
+
+ -- Loop through affected datasets and print details
+ FOR affected_dataset IN SELECT * FROM affected_dataset_results LOOP
+ RAISE NOTICE 'Dataset %, Owner % (%)',
+ affected_dataset.dataset_url,
+ affected_dataset.name,
+ affected_dataset.email;
+ END LOOP;
+
+ RAISE NOTICE '--- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---';
+ END IF;
+
+ -- Clean up temporary table
+ DROP TABLE IF EXISTS affected_dataset_results;
+ END;
+$$;
diff --git a/modules/dataverse-migrate-db/pom.xml b/modules/dataverse-migrate-db/pom.xml
new file mode 100644
index 00000000000..567b8535dda
--- /dev/null
+++ b/modules/dataverse-migrate-db/pom.xml
@@ -0,0 +1,275 @@
+
+
+ 4.0.0
+
+
+ edu.harvard.iq
+ dataverse-parent
+ ${revision}
+ ../dataverse-parent
+
+
+ migrate-db
+ pom
+ migrate-db
+
+
+
+ true
+ true
+ true
+ true
+ true
+ true
+
+ true
+ postgres,pg_dump
+ false
+ ${docker.skip}
+ ${docker.skip}
+ ${docker.skip}
+ true
+ true
+
+ localhost
+ 15432
+ dataverse
+ ${postgresql.db}
+ supersecret
+ ${project.basedir}/db_dump.sql
+ sql
+ ${project.build.directory}
+
+ 30
+
+
+
+ false
+ false
+
+
+
+
+
+ io.fabric8
+ docker-maven-plugin
+
+ true
+
+
+
+ postgres
+ postgres:${postgresql.server.version}
+
+ true
+
+
+
+ custom
+ migration
+ migrationdb
+
+
+ localhost:${postgresql.port}:5432
+
+
+ ${postgresql.username}
+ ${postgresql.password}
+ ${postgresql.db}
+
+
+
+ ${postgresql.dump.file}:/docker-entrypoint-initdb.d/dump.${postgresql.dump.file.ext}
+
+
+
+
+
+
+
+
+ 5432
+
+
+
+
+
+
+
+ pg_dump
+ postgres:${postgresql.server.version}
+
+ true
+
+
+
+ custom
+ migration
+
+
+ ${postgresql.username}
+ ${postgresql.password}
+
+
+
+ ${postgresql.dump.target}:/dumptarget
+
+
+
+
+
+ ${postgresql.password}
+
+
+
+
+ sh
+ -c
+ pg_dump -h migrationdb -p 5432 -U ${postgresql.username} -v -f /dumptarget/migrated_db_dump.sql ${postgresql.db}
+
+
+
+
+
+
+
+
+
+
+
+ cleanup
+ clean
+
+ stop
+
+
+
+ start
+ prepare-package
+
+ start
+
+
+ ${docker.skipStart}
+
+
+ postgres
+
+ false
+
+
+
+ pg_dump
+
+ true
+
+
+
+
+
+
+ dump
+ verify
+
+ start
+
+
+ ${docker.skipDump}
+
+
+ postgres
+
+ true
+
+
+
+ pg_dump
+
+ false
+
+
+
+
+
+
+ stop
+ install
+
+ stop
+
+
+ ${docker.skipStop}
+
+
+
+
+
+ org.flywaydb
+ flyway-maven-plugin
+ ${flyway.version}
+
+
+ org.flywaydb
+ flyway-core
+ ${flyway.version}
+
+
+ org.flywaydb
+ flyway-database-postgresql
+ ${flyway.version}
+
+
+ org.postgresql
+ postgresql
+ ${postgresql.version}
+
+
+
+ jdbc:postgresql://${postgresql.host}:${postgresql.port}/${postgresql.db}
+ ${postgresql.username}
+ ${postgresql.password}
+ __
+
+
+
+ migrate
+ package
+
+ migrate
+
+
+ true
+
+ filesystem:../../src/main/resources/db/migration
+ filesystem:extra-migrations
+
+
+ ${migrate.keywordTermUri}
+ ${migrate.cleanupSavedSearches}
+
+
+
+
+ cleanup
+ package
+
+ repair
+
+
+
+ filesystem:../../src/main/resources/db/migration
+
+
+
+
+
+
+
+
diff --git a/modules/dataverse-parent/pom.xml b/modules/dataverse-parent/pom.xml
index df1b31181bd..45bc90c4c9b 100644
--- a/modules/dataverse-parent/pom.xml
+++ b/modules/dataverse-parent/pom.xml
@@ -151,6 +151,8 @@
6.2025.342.7.7
+ 16
+ 10.19.09.8.02.31.326.30.0
diff --git a/pom.xml b/pom.xml
index c8971fb6587..92179cbcbe1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -27,7 +27,6 @@
war1.2.18.4
- 10.19.01.1.11.20.15.4.0
@@ -1110,7 +1109,6 @@
truedocker-build
- 17gdcc/dataverse:${app.image.tag}