From 3eca3b9bed14c91b8385d22046daefea544ac239 Mon Sep 17 00:00:00 2001 From: Filip Hrisafov Date: Mon, 20 Nov 2023 09:42:02 +0100 Subject: [PATCH] Always use search string escape when looking up Flowable specific tables --- .../entity/TableDataManagerImpl.java | 9 ++-- .../examples/mgmt/ManagementServiceTest.java | 54 +++++++++++++++++++ 2 files changed, 59 insertions(+), 4 deletions(-) diff --git a/modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/persistence/entity/TableDataManagerImpl.java b/modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/persistence/entity/TableDataManagerImpl.java index 38a332b7852..3a7e5a4e6be 100644 --- a/modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/persistence/entity/TableDataManagerImpl.java +++ b/modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/persistence/entity/TableDataManagerImpl.java @@ -85,12 +85,13 @@ public List getTablesPresentInDatabase() { } protected String getTableNameFilter(DatabaseMetaData databaseMetaData, String databaseTablePrefix, String flowableTablePrefix) throws SQLException { - String tableNameFilter = databaseTablePrefix + flowableTablePrefix + "_%"; + // We are using the search string escape for the filter since the underscore character (_) means match any character when used in LIKE. + // However, we want to get the tables that do have that charactery literally + String tableNameFilter; if ("postgres".equals(getDbSqlSession().getDbSqlSessionFactory().getDatabaseType()) || "cockroachdb".equals(getDbSqlSession().getDbSqlSessionFactory().getDatabaseType())) { - tableNameFilter = databaseTablePrefix + flowableTablePrefix.toLowerCase(Locale.ROOT) + "_%"; - } - if ("oracle".equals(getDbSqlSession().getDbSqlSessionFactory().getDatabaseType())) { + tableNameFilter = databaseTablePrefix + flowableTablePrefix.toLowerCase(Locale.ROOT) + databaseMetaData.getSearchStringEscape() + "_%"; + } else { tableNameFilter = databaseTablePrefix + flowableTablePrefix + databaseMetaData.getSearchStringEscape() + "_%"; } diff --git a/modules/flowable-engine/src/test/java/org/flowable/examples/mgmt/ManagementServiceTest.java b/modules/flowable-engine/src/test/java/org/flowable/examples/mgmt/ManagementServiceTest.java index bb03bc9ae45..a49a9510e31 100644 --- a/modules/flowable-engine/src/test/java/org/flowable/examples/mgmt/ManagementServiceTest.java +++ b/modules/flowable-engine/src/test/java/org/flowable/examples/mgmt/ManagementServiceTest.java @@ -15,10 +15,15 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.fail; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; import java.util.Arrays; import java.util.List; import java.util.Map; +import javax.sql.DataSource; + import org.flowable.common.engine.api.management.TableMetaData; import org.flowable.common.engine.impl.interceptor.Command; import org.flowable.common.engine.impl.interceptor.CommandContext; @@ -26,6 +31,7 @@ import org.flowable.engine.ManagementService; import org.flowable.engine.impl.context.Context; import org.flowable.engine.impl.test.PluggableFlowableTestCase; +import org.flowable.engine.impl.util.CommandContextUtil; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.DisabledIfSystemProperty; import org.slf4j.Logger; @@ -94,6 +100,54 @@ public void testGetTableMetaData() { assertOneOf(new String[] { "TIMESTAMP", "TIMESTAMP(6)", "datetime", "DATETIME" }, tableMetaData.getColumnTypes().get(createTimeIndex)); } + @Test + public void testTableCountWithCustomTablesWithoutActOrFlwPrefix() { + String tablePrefix = processEngineConfiguration.getDatabaseTablePrefix(); + try { + + managementService.executeCommand(commandContext -> { + DataSource dataSource = CommandContextUtil.getProcessEngineConfiguration(commandContext) + .getDataSource(); + + try (Connection connection = dataSource.getConnection()) { + PreparedStatement statement = connection.prepareStatement("create table " + tablePrefix + "FLWTEST(id varchar(10))"); + statement.execute(); + + statement = connection.prepareStatement("create table " + tablePrefix + "ACTIVITY_TEST(id varchar(10))"); + statement.execute(); + } catch (SQLException e) { + throw new RuntimeException(e); + } + return null; + }); + + // ManagementService#getTableCount returns the counts of the flowable tables (tables with the FLW_ and ACT_ prefix) + // Therefore, the FLWTEST and ACTIVITY_TEST tables should not be included in the table count + Map tableCount = managementService.getTableCount(); + assertThat(tableCount) + .doesNotContainKeys( + tablePrefix + "FLWTEST", + tablePrefix + "ACTIVITY_TEST" + ); + } finally { + managementService.executeCommand(commandContext -> { + DataSource dataSource = CommandContextUtil.getProcessEngineConfiguration(commandContext) + .getDataSource(); + + try (Connection connection = dataSource.getConnection()) { + PreparedStatement statement = connection.prepareStatement("drop table " + tablePrefix + "FLWTEST"); + statement.execute(); + + statement = connection.prepareStatement("drop table " + tablePrefix + "ACTIVITY_TEST"); + statement.execute(); + } catch (SQLException e) { + throw new RuntimeException(e); + } + return null; + }); + } + } + private void assertOneOf(String[] possibleValues, String currentValue) { for (String value : possibleValues) { if (currentValue.equals(value)) {