diff --git a/core/module.properties b/core/module.properties index 90a5223381f..756c5aea7e0 100644 --- a/core/module.properties +++ b/core/module.properties @@ -1,6 +1,6 @@ Name: Core ModuleClass: org.labkey.core.CoreModule -SchemaVersion: 26.003 +SchemaVersion: 26.004 Label: Administration and Essential Services Description: The Core module provides central services such as login, \ security, administration, folder management, user management, \ diff --git a/core/resources/schemas/dbscripts/postgresql/core-25.008-25.009.sql b/core/resources/schemas/dbscripts/postgresql/core-25.008-25.009.sql index 0e03311ca13..c7dc1519f74 100644 --- a/core/resources/schemas/dbscripts/postgresql/core-25.008-25.009.sql +++ b/core/resources/schemas/dbscripts/postgresql/core-25.008-25.009.sql @@ -1,3 +1 @@ ALTER TABLE core.Documents ADD ParentType VARCHAR(300); - -SELECT core.executeJavaUpgradeCode('populateAttachmentParentTypeColumn'); diff --git a/core/resources/schemas/dbscripts/postgresql/core-25.009-25.010.sql b/core/resources/schemas/dbscripts/postgresql/core-25.009-25.010.sql index 07546062a3a..774da99d529 100644 --- a/core/resources/schemas/dbscripts/postgresql/core-25.009-25.010.sql +++ b/core/resources/schemas/dbscripts/postgresql/core-25.009-25.010.sql @@ -4,5 +4,5 @@ DELETE FROM core.Documents WHERE Container = (SELECT EntityId FROM core.Containers WHERE Parent IS NULL) AND Parent = (SELECT EntityId FROM core.Containers WHERE Parent IS NULL) AND - ParentType IS NULL AND + ParentType IS NULL AND -- ParentType is always NULL at this point, since populating the column is deferred. But the DocumentName condition below is sufficiently specific. (DocumentName LIKE 'auth_header_logo_%' OR DocumentName LIKE 'auth_login_page_logo_%'); diff --git a/core/resources/schemas/dbscripts/postgresql/core-26.000-26.001.sql b/core/resources/schemas/dbscripts/postgresql/core-26.000-26.001.sql deleted file mode 100644 index 92b17b23648..00000000000 --- a/core/resources/schemas/dbscripts/postgresql/core-26.000-26.001.sql +++ /dev/null @@ -1,3 +0,0 @@ --- Extraction of parent EntityIds from data class LSIDs has been fixed, so re-run population of the ParentType column. --- Keep the invocation in core-25.008-25.009.sql since core-25.009-25.010.sql relies on ParentType being populated. -SELECT core.executeJavaUpgradeCode('populateAttachmentParentTypeColumn'); diff --git a/core/resources/schemas/dbscripts/postgresql/core-26.003-26.004.sql b/core/resources/schemas/dbscripts/postgresql/core-26.003-26.004.sql new file mode 100644 index 00000000000..baa19d4e91e --- /dev/null +++ b/core/resources/schemas/dbscripts/postgresql/core-26.003-26.004.sql @@ -0,0 +1,3 @@ +-- Detection of the data class Compound.Structure2D attachment column was corrected in a recent PR: https://github.com/LabKey/platform/pull/7513 +-- This re-populates the ParentType column to pick up those changes. +SELECT core.executeJavaUpgradeCode('populateAttachmentParentTypeColumn'); diff --git a/core/resources/schemas/dbscripts/sqlserver/core-25.008-25.009.sql b/core/resources/schemas/dbscripts/sqlserver/core-25.008-25.009.sql index 468a4ff1b0e..90d4b8792d7 100644 --- a/core/resources/schemas/dbscripts/sqlserver/core-25.008-25.009.sql +++ b/core/resources/schemas/dbscripts/sqlserver/core-25.008-25.009.sql @@ -1,3 +1 @@ ALTER TABLE core.Documents ADD ParentType NVARCHAR(300); - -EXEC core.executeJavaUpgradeCode 'populateAttachmentParentTypeColumn'; diff --git a/core/resources/schemas/dbscripts/sqlserver/core-25.009-25.010.sql b/core/resources/schemas/dbscripts/sqlserver/core-25.009-25.010.sql index 07546062a3a..774da99d529 100644 --- a/core/resources/schemas/dbscripts/sqlserver/core-25.009-25.010.sql +++ b/core/resources/schemas/dbscripts/sqlserver/core-25.009-25.010.sql @@ -4,5 +4,5 @@ DELETE FROM core.Documents WHERE Container = (SELECT EntityId FROM core.Containers WHERE Parent IS NULL) AND Parent = (SELECT EntityId FROM core.Containers WHERE Parent IS NULL) AND - ParentType IS NULL AND + ParentType IS NULL AND -- ParentType is always NULL at this point, since populating the column is deferred. But the DocumentName condition below is sufficiently specific. (DocumentName LIKE 'auth_header_logo_%' OR DocumentName LIKE 'auth_login_page_logo_%'); diff --git a/core/resources/schemas/dbscripts/sqlserver/core-26.000-26.001.sql b/core/resources/schemas/dbscripts/sqlserver/core-26.000-26.001.sql deleted file mode 100644 index be2043e0c12..00000000000 --- a/core/resources/schemas/dbscripts/sqlserver/core-26.000-26.001.sql +++ /dev/null @@ -1,3 +0,0 @@ --- Extraction of parent EntityIds from data class LSIDs has been fixed, so re-run population of the ParentType column. --- Keep the invocation in core-25.008-25.009.sql since core-25.009-25.010.sql relies on ParentType being populated. -EXEC core.executeJavaUpgradeCode 'populateAttachmentParentTypeColumn'; diff --git a/core/resources/schemas/dbscripts/sqlserver/core-26.003-26.004.sql b/core/resources/schemas/dbscripts/sqlserver/core-26.003-26.004.sql new file mode 100644 index 00000000000..f7a61fa3c86 --- /dev/null +++ b/core/resources/schemas/dbscripts/sqlserver/core-26.003-26.004.sql @@ -0,0 +1,3 @@ +-- Detection of the data class Compound.Structure2D attachment column was corrected in a recent PR: https://github.com/LabKey/platform/pull/7513 +-- This re-populates the ParentType column to pick up those changes. +EXEC core.executeJavaUpgradeCode 'populateAttachmentParentTypeColumn'; diff --git a/core/src/org/labkey/core/CoreUpgradeCode.java b/core/src/org/labkey/core/CoreUpgradeCode.java index fdc15f89175..4001279f522 100644 --- a/core/src/org/labkey/core/CoreUpgradeCode.java +++ b/core/src/org/labkey/core/CoreUpgradeCode.java @@ -15,6 +15,7 @@ */ package org.labkey.core; +import jakarta.servlet.ServletContext; import org.apache.logging.log4j.Logger; import org.labkey.api.attachments.AttachmentParentType; import org.labkey.api.attachments.AttachmentService; @@ -29,6 +30,8 @@ import org.labkey.api.module.ModuleLoader; import org.labkey.api.security.Directive; import org.labkey.api.settings.AppProps; +import org.labkey.api.util.ContextListener; +import org.labkey.api.util.StartupListener; import org.labkey.api.util.logging.LogHelper; import org.labkey.core.security.AllowedExternalResourceHosts; import org.labkey.core.security.AllowedExternalResourceHosts.AllowedHost; @@ -82,38 +85,55 @@ public static void migrateAllowedExternalConnectionHosts(ModuleContext context) } /** - * Called from core-25.008-25.009.sql - * Called from core-26.000-26.001.sql + * Called from core-26.003-26.004.sql */ @SuppressWarnings("unused") + // @DeferredUpgrade ensures that the upgrade code method gets queued in the database so the listener eventually + // gets registered and run, even in the case of an upgrade failure or server shutdown. @DeferredUpgrade public static void populateAttachmentParentTypeColumn(ModuleContext context) { if (context.isNewInstall()) return; - for (AttachmentParentType type : AttachmentService.get().getAttachmentParentTypes()) + // This code needs to run after all @DeferredUpgrades are complete. In particular, it needs to wait for + // ExperimentUpgradeCode.addRowIdToProvisionedDataClassTables() to restructure data class provisioned tables. + ContextListener.addStartupListener(new StartupListener() { - LOG.info("Populating attachment parent type for {}", type.getUniqueName()); - - SQLFragment updateSql = new SQLFragment("UPDATE ") - .append(CoreSchema.getInstance().getTableInfoDocuments()) - .append(" SET ParentType = ?") - .add(type.getUniqueName()) - .append(" WHERE "); - // TODO: This is the only caller of addWhereSql(), which can be removed when this upgrade code is deleted. - type.addWhereSql(updateSql, "Parent", "DocumentName"); - - new SqlExecutor(CoreSchema.getInstance().getSchema()).execute(updateSql); - } + @Override + public String getName() + { + return "Populate Attachment Parent Types"; + } + + @Override + public void moduleStartupComplete(ServletContext servletContext) + { + for (AttachmentParentType type : AttachmentService.get().getAttachmentParentTypes()) + { + LOG.info("Populating attachment parent type for {}", type.getUniqueName()); + + SQLFragment updateSql = new SQLFragment("UPDATE ") + .append(CoreSchema.getInstance().getTableInfoDocuments()) + .append(" SET ParentType = ?") + .add(type.getUniqueName()) + .append(" WHERE "); + // TODO: This is the only caller of addWhereSql(), which can be removed when this upgrade code is deleted. + type.addWhereSql(updateSql, "Parent", "DocumentName"); + + new SqlExecutor(CoreSchema.getInstance().getSchema()).execute(updateSql); + } + } + }); } /** - * This is not invoked from any script yet. We want to make sure our orphaned attachment detection is perfect - * before blanket deleting them. + * This is not invoked from any script yet. We want to make sure our orphaned attachment detection is well tested + * and reviewed before blanket deleting them. TODO: Do not just call this from a script! We likely need to work + * this code into a StartupListener like we do above. Or integrate them into one. Or something. */ - @DeferredUpgrade // Need to execute this after AttachmentTypes are registered @SuppressWarnings("unused") + @DeferredUpgrade // Need to execute this after AttachmentTypes are registered public static void deleteOrphanedAttachments(ModuleContext context) { if (context.isNewInstall()) diff --git a/experiment/src/org/labkey/experiment/ExperimentUpgradeCode.java b/experiment/src/org/labkey/experiment/ExperimentUpgradeCode.java index e693224a7ec..c821141996b 100644 --- a/experiment/src/org/labkey/experiment/ExperimentUpgradeCode.java +++ b/experiment/src/org/labkey/experiment/ExperimentUpgradeCode.java @@ -122,6 +122,7 @@ public class ExperimentUpgradeCode implements UpgradeCode @SuppressWarnings("unused") public static void ensureBigObjectIds(ModuleContext context) { + // We force dev mode deployments to use BIGINT ObjectIds everywhere to ensure comprehensive testing if (AppProps.getInstance().isDevMode() && ModuleLoader.getInstance().shouldInsertData()) { DbScope primary = DbScope.getLabKeyScope(); @@ -695,7 +696,7 @@ private String bracketIt(String name) } /** - * Called from exp-26.004-26.005.sql, on SQL Server only + * Called from exp-26.004-26.005.sql on SQL Server only * GitHub Issue 869: Long table/column names cause SQL Server migration to fail * Query all table & column storage names and rename the ones that are too long for PostgreSQL * TODO: When this upgrade code is removed, get rid of the StorageProvisionerImpl.makeTableName() method it uses.