diff --git a/dotCMS/src/integration-test/java/com/dotcms/MainSuite.java b/dotCMS/src/integration-test/java/com/dotcms/MainSuite.java index b08ff0c9d5f2..0706993b588e 100644 --- a/dotCMS/src/integration-test/java/com/dotcms/MainSuite.java +++ b/dotCMS/src/integration-test/java/com/dotcms/MainSuite.java @@ -164,52 +164,7 @@ import com.dotmarketing.quartz.job.PopulateContentletAsJSONJobTest; import com.dotmarketing.startup.StartupTasksExecutorTest; import com.dotmarketing.startup.runalways.Task00050LoadAppsSecretsTest; -import com.dotmarketing.startup.runonce.Task05195CreatesDestroyActionAndAssignDestroyDefaultActionsToTheSystemWorkflowTest; -import com.dotmarketing.startup.runonce.Task05210CreateDefaultDotAssetTest; -import com.dotmarketing.startup.runonce.Task05225RemoveLoadRecordsToIndexTest; -import com.dotmarketing.startup.runonce.Task05305AddPushPublishFilterColumnTest; -import com.dotmarketing.startup.runonce.Task05350AddDotSaltClusterColumnTest; -import com.dotmarketing.startup.runonce.Task05370AddAppsPortletToLayoutTest; -import com.dotmarketing.startup.runonce.Task05380ChangeContainerPathToAbsoluteTest; -import com.dotmarketing.startup.runonce.Task05390MakeRoomForLongerJobDetailTest; -import com.dotmarketing.startup.runonce.Task05395RemoveEndpointIdForeignKeyInIntegrityResolverTablesIntegrationTest; -import com.dotmarketing.startup.runonce.Task201013AddNewColumnsToIdentifierTableTest; -import com.dotmarketing.startup.runonce.Task201014UpdateColumnsValuesInIdentifierTableTest; -import com.dotmarketing.startup.runonce.Task201102UpdateColumnSitelicTableTest; -import com.dotmarketing.startup.runonce.Task210218MigrateUserProxyTableTest; -import com.dotmarketing.startup.runonce.Task210319CreateStorageTableTest; -import com.dotmarketing.startup.runonce.Task210321RemoveOldMetadataFilesTest; -import com.dotmarketing.startup.runonce.Task210506UpdateStorageTableTest; -import com.dotmarketing.startup.runonce.Task210510UpdateStorageTableDropMetadataColumnTest; -import com.dotmarketing.startup.runonce.Task210520UpdateAnonymousEmailTest; -import com.dotmarketing.startup.runonce.Task210527DropReviewFieldsFromContentletTableTest; -import com.dotmarketing.startup.runonce.Task210719CleanUpTitleFieldTest; -import com.dotmarketing.startup.runonce.Task210802UpdateStructureTableTest; -import com.dotmarketing.startup.runonce.Task210805DropUserProxyTableTest; -import com.dotmarketing.startup.runonce.Task210816DeInodeRelationshipTest; -import com.dotmarketing.startup.runonce.Task210901UpdateDateTimezonesTest; -import com.dotmarketing.startup.runonce.Task211007RemoveNotNullConstraintFromCompanyMXColumnTest; -import com.dotmarketing.startup.runonce.Task211012AddCompanyDefaultLanguageTest; -import com.dotmarketing.startup.runonce.Task211101AddContentletAsJsonColumnTest; -import com.dotmarketing.startup.runonce.Task211103RenameHostNameLabelTest; -import com.dotmarketing.startup.runonce.Task220202RemoveFKStructureFolderConstraintTest; -import com.dotmarketing.startup.runonce.Task220203RemoveFolderInodeConstraintTest; -import com.dotmarketing.startup.runonce.Task220214AddOwnerAndIDateToFolderTableTest; -import com.dotmarketing.startup.runonce.Task220215MigrateDataFromInodeToFolderTest; -import com.dotmarketing.startup.runonce.Task220330ChangeVanityURLSiteFieldTypeTest; -import com.dotmarketing.startup.runonce.Task220401CreateClusterLockTableTest; -import com.dotmarketing.startup.runonce.Task220402UpdateDateTimezonesTest; -import com.dotmarketing.startup.runonce.Task220413IncreasePublishedPushedAssetIdColTest; -import com.dotmarketing.startup.runonce.Task220512UpdateNoHTMLRegexValueTest; -import com.dotmarketing.startup.runonce.Task220606UpdatePushNowActionletNameTest; -import com.dotmarketing.startup.runonce.Task220822CreateVariantTableTest; -import com.dotmarketing.startup.runonce.Task220824CreateDefaultVariantTest; -import com.dotmarketing.startup.runonce.Task220825CreateVariantFieldTest; -import com.dotmarketing.startup.runonce.Task220825MakeSomeSystemFieldsRemovableTest; -import com.dotmarketing.startup.runonce.Task220829CreateExperimentsTableTest; -import com.dotmarketing.startup.runonce.Task220912UpdateCorrectShowOnMenuPropertyTest; -import com.dotmarketing.startup.runonce.Task220928AddLookbackWindowColumnToExperimentTest; -import com.dotmarketing.startup.runonce.Task221007AddVariantIntoPrimaryKeyTest; +import com.dotmarketing.startup.runonce.*; import com.dotmarketing.util.ConfigTest; import com.dotmarketing.util.HashBuilderTest; import com.dotmarketing.util.MaintenanceUtilTest; @@ -653,7 +608,8 @@ VisitorsGeolocationConditionletTest.class, ManifestUtilTest.class, ZipUtilTest.class, - PopulateContentletAsJSONJobTest.class + PopulateContentletAsJSONJobTest.class, + Task230426AlterVarcharLengthOfLockedByColTest.class }) public class MainSuite { diff --git a/dotCMS/src/integration-test/java/com/dotmarketing/common/db/DotDatabaseMetaDataTest.java b/dotCMS/src/integration-test/java/com/dotmarketing/common/db/DotDatabaseMetaDataTest.java index 4fb3b3c67cf5..de03d21d1c45 100644 --- a/dotCMS/src/integration-test/java/com/dotmarketing/common/db/DotDatabaseMetaDataTest.java +++ b/dotCMS/src/integration-test/java/com/dotmarketing/common/db/DotDatabaseMetaDataTest.java @@ -1,8 +1,5 @@ package com.dotmarketing.common.db; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - import com.dotcms.util.IntegrationTestInitService; import com.dotmarketing.db.DbConnectionFactory; import com.dotmarketing.db.HibernateUtil; @@ -11,16 +8,15 @@ import com.dotmarketing.portlets.workflows.business.BaseWorkflowIntegrationTest; import java.sql.Connection; import java.sql.SQLException; -import java.util.Arrays; -import java.util.List; -import java.util.Optional; -import java.util.Set; +import java.util.*; import java.util.stream.Collectors; import org.jetbrains.annotations.NotNull; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; +import static org.junit.Assert.*; + public class DotDatabaseMetaDataTest extends BaseWorkflowIntegrationTest { @BeforeClass @@ -39,7 +35,7 @@ public void findForeignKeysTest() throws DotDataException, DotSecurityException ("contentlet", "structure", Arrays.asList("structure_inode"), Arrays.asList("inode")); - Assert.assertNotNull(foreignKey); + assertNotNull(foreignKey); assertEquals("FK_structure_inode".toLowerCase(), foreignKey.getForeignKeyName().toLowerCase()); } @@ -49,7 +45,7 @@ public void getForeignKeysTest() throws DotDataException, DotSecurityException { //alter table contentlet add constraint FK_structure_inode foreign key (structure_inode) references structure(inode); final List foreignKeys = new DotDatabaseMetaData().getForeignKeys("contentlet"); - Assert.assertNotNull(foreignKeys); + assertNotNull(foreignKeys); Assert.assertTrue(foreignKeys.size()>0); } @@ -119,4 +115,20 @@ public void getContentletVersionInfoPrimaryKeyFields() { assertTrue(primaryKeysFields.contains("identifier")); assertTrue(primaryKeysFields.contains("variant_id")); } + + // the result should not be null + @Test + public void getModifiedColumnLength() throws SQLException, DotDataException { + final String colName = "locked_by"; + final String tblName = "contentlet_version_info"; + + if (DbConnectionFactory.isPostgres()){ + final String query = "alter table "+tblName+" alter column locked_by type varchar (100);"; + final DotConnect dotConnect = new DotConnect(); + dotConnect.executeStatement(query); + } + + final Map result = new DotDatabaseMetaData().getModifiedColumnLength(tblName, colName); + assertNotNull(result); + } } diff --git a/dotCMS/src/integration-test/java/com/dotmarketing/startup/runonce/Task230426AlterVarcharLengthOfLockedByColTest.java b/dotCMS/src/integration-test/java/com/dotmarketing/startup/runonce/Task230426AlterVarcharLengthOfLockedByColTest.java new file mode 100644 index 000000000000..667777438087 --- /dev/null +++ b/dotCMS/src/integration-test/java/com/dotmarketing/startup/runonce/Task230426AlterVarcharLengthOfLockedByColTest.java @@ -0,0 +1,63 @@ +package com.dotmarketing.startup.runonce; + +import com.dotmarketing.common.db.DotConnect; +import com.dotmarketing.common.db.DotDatabaseMetaData; +import com.dotmarketing.db.DbConnectionFactory; +import com.dotmarketing.exception.DotDataException; +import org.junit.Test; + +import java.sql.SQLException; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +public class Task230426AlterVarcharLengthOfLockedByColTest { + // Change the length to recreate the scenario + private void setMinLengthBeforeTask (String tblName) throws SQLException { + String query = ""; + if (DbConnectionFactory.isPostgres()){ + query = "alter table "+tblName+" alter column locked_by type varchar (36);"; + } + + final DotConnect dotConnect = new DotConnect(); + dotConnect.executeStatement(query); + } + + /** + * Method to test: {@link Task230426AlterVarcharLengthOfLockedByCol#executeUpgrade()} + * Given Scenario: The varchar length of the column locked_by in the specified table should be increased + * Specified Tables: contentlet_version_info, container_version_info, template_version_info, link_version_info + * ExpectedResult: The length of the column locked_by should be more than 36. We set it in 100 + * + */ + @Test + public void test_executeUpgrade_GivenIncreaseLockedByLength_LengthShouldBeMoreThan36() throws SQLException, DotDataException { + final String[] tableNames = { "contentlet_version_info", "container_version_info", "template_version_info", "link_version_info" }; + final String colName = "locked_by"; + Map result; + final DotDatabaseMetaData dotDatabaseMetaData = new DotDatabaseMetaData(); + + //The method is created and tested only for postgres + if (DbConnectionFactory.isPostgres()){ + + //iterate and test all the tables + for (String tableName : tableNames) { + setMinLengthBeforeTask(tableName); + //set the length 36 to recreate the given scenario + result = dotDatabaseMetaData.getModifiedColumnLength(tableName, colName); + assertEquals("36", result.get("field_length")); + } + + //Execute the task + final Task230426AlterVarcharLengthOfLockedByCol taskToBeTested = new Task230426AlterVarcharLengthOfLockedByCol(); + taskToBeTested.executeUpgrade(); + + //Check if the length was increased to 100 + for (String tableName : tableNames) { + result = dotDatabaseMetaData.getModifiedColumnLength(tableName, colName);; + assertEquals("100", result.get("field_length")); + } + } + + } + +} \ No newline at end of file diff --git a/dotCMS/src/main/java/com/dotmarketing/common/db/DotDatabaseMetaData.java b/dotCMS/src/main/java/com/dotmarketing/common/db/DotDatabaseMetaData.java index f9fbcfd4e8d8..a6339fbed69b 100644 --- a/dotCMS/src/main/java/com/dotmarketing/common/db/DotDatabaseMetaData.java +++ b/dotCMS/src/main/java/com/dotmarketing/common/db/DotDatabaseMetaData.java @@ -756,5 +756,37 @@ public static Optional getPrimaryKeyName(final String tableName) { } } + /** + * Get the length of a modified column in a specified table. + * + * @param tableName + * - The name of the table to be queried. + * @param columnName + * - The name of the column that wants to be queried. + * @return Map + * - the length of the field and if is nullable + * + * @throws SQLException + * An error occurred when executing the SQL query. + */ + public Map getModifiedColumnLength ( final String tableName, final String columnName) throws SQLException, DotDataException { + final DotConnect dotConnect = new DotConnect(); + + //the same query works for both supported sql versions + if(DbConnectionFactory.isPostgres() || DbConnectionFactory.isMsSql() ) { + return getColPropertiesQuery(dotConnect, tableName, columnName); + } + + throw new DotDataException("Unknown database type."); + } // getModifiedColumnLength. + + private Map getColPropertiesQuery(DotConnect dotConnect, String tableName, String columnName) throws DotDataException { + final String query = "select character_maximum_length as field_length, is_nullable as nullable_value " + + "from information_schema.columns " + + "where table_name = '"+tableName+"' and column_name='"+columnName+"'"; + dotConnect.setSQL(query); + return (Map)dotConnect.loadResults().get(0); + } + } // E:O:F:DotDatabaseMetaData. diff --git a/dotCMS/src/main/java/com/dotmarketing/startup/runonce/Task230426AlterVarcharLengthOfLockedByCol.java b/dotCMS/src/main/java/com/dotmarketing/startup/runonce/Task230426AlterVarcharLengthOfLockedByCol.java new file mode 100644 index 000000000000..0429abeb927c --- /dev/null +++ b/dotCMS/src/main/java/com/dotmarketing/startup/runonce/Task230426AlterVarcharLengthOfLockedByCol.java @@ -0,0 +1,38 @@ +package com.dotmarketing.startup.runonce; +import com.dotmarketing.common.db.DotConnect; +import com.dotmarketing.exception.DotDataException; +import com.dotmarketing.exception.DotRuntimeException; +import com.dotmarketing.startup.StartupTask; + +import java.sql.SQLException; + +/** + * This class alter the locked_by column in four different tables. + * The locked_by column in some coses has a length of 36. With this class + * we are increasing that length to 100. + */ +public class Task230426AlterVarcharLengthOfLockedByCol implements StartupTask { + private void alterTables() throws SQLException { + final DotConnect dc = new DotConnect(); + dc.executeStatement("alter table contentlet_version_info alter column locked_by type varchar (100)"); + dc.executeStatement("alter table container_version_info alter column locked_by type varchar (100)"); + dc.executeStatement("alter table template_version_info alter column locked_by type varchar (100)"); + dc.executeStatement("alter table link_version_info alter column locked_by type varchar (100)"); + } + @Override + public boolean forceRun() { + return true; + } + + @Override + public void executeUpgrade() throws DotDataException, DotRuntimeException { + try { + alterTables(); + } catch (SQLException e) { + throw new DotDataException(e.getMessage(),e); + } + } + + + +} \ No newline at end of file diff --git a/dotCMS/src/main/java/com/dotmarketing/util/TaskLocatorUtil.java b/dotCMS/src/main/java/com/dotmarketing/util/TaskLocatorUtil.java index 16152f0c87e1..ec5df1d28d73 100644 --- a/dotCMS/src/main/java/com/dotmarketing/util/TaskLocatorUtil.java +++ b/dotCMS/src/main/java/com/dotmarketing/util/TaskLocatorUtil.java @@ -367,6 +367,7 @@ public static List> getStartupRunAlwaysTaskClasses() { public static List> getBackportedUpgradeTaskClasses() { final List> ret = new ArrayList>(); ret.add(Task230320FixMissingContentletAsJSON.class); + ret.add(Task230426AlterVarcharLengthOfLockedByCol.class); return ret.stream().sorted(classNameComparator).collect(Collectors.toList()); } diff --git a/hotfix_tracking.md b/hotfix_tracking.md index 054d28cc4b7d..65255431c320 100644 --- a/hotfix_tracking.md +++ b/hotfix_tracking.md @@ -59,3 +59,4 @@ This maintenance release includes the following code fixes: 44. https://github.com/dotCMS/core/issues/25008 : Date format has changed for fields in newer versions of dotCMS #25008 45. https://github.com/dotCMS/core/issues/25097 : Update Normalization Filter #25097 46. https://github.com/dotCMS/core/issues/24286 : Creating a content in a third language in a row throws an error #24286 +47. https://github.com/dotCMS/core/issues/24133 : User is unable to lock content because of validation limit on locked_by column of contentlet_version_info #24133