From 3288ec257f8e898a7c2de2ba25fb03991b964386 Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Tue, 17 Jun 2025 12:37:24 +0300 Subject: [PATCH 1/3] EDQS SQL like query updates to be in sync with legacy --- ...stractEntityProfileNameQueryProcessor.java | 2 +- .../AbstractEntityProfileQueryProcessor.java | 2 +- .../processor/EntityNameQueryProcessor.java | 2 +- .../server/edqs/util/RepositoryUtils.java | 29 ++++++------------- .../server/edqs/repo/RepositoryUtilsTest.java | 2 +- 5 files changed, 13 insertions(+), 24 deletions(-) diff --git a/common/edqs/src/main/java/org/thingsboard/server/edqs/query/processor/AbstractEntityProfileNameQueryProcessor.java b/common/edqs/src/main/java/org/thingsboard/server/edqs/query/processor/AbstractEntityProfileNameQueryProcessor.java index f881d616ef..95a1a79392 100644 --- a/common/edqs/src/main/java/org/thingsboard/server/edqs/query/processor/AbstractEntityProfileNameQueryProcessor.java +++ b/common/edqs/src/main/java/org/thingsboard/server/edqs/query/processor/AbstractEntityProfileNameQueryProcessor.java @@ -36,7 +36,7 @@ public abstract class AbstractEntityProfileNameQueryProcessor(getProfileNames(this.filter)); - pattern = RepositoryUtils.toContainsSqlLikePattern(getEntityNameFilter(filter)); + pattern = RepositoryUtils.toEntityNameSqlLikePattern(getEntityNameFilter(filter)); } protected abstract String getEntityNameFilter(T filter); diff --git a/common/edqs/src/main/java/org/thingsboard/server/edqs/query/processor/AbstractEntityProfileQueryProcessor.java b/common/edqs/src/main/java/org/thingsboard/server/edqs/query/processor/AbstractEntityProfileQueryProcessor.java index 9d043ff6fc..94a7a95404 100644 --- a/common/edqs/src/main/java/org/thingsboard/server/edqs/query/processor/AbstractEntityProfileQueryProcessor.java +++ b/common/edqs/src/main/java/org/thingsboard/server/edqs/query/processor/AbstractEntityProfileQueryProcessor.java @@ -43,7 +43,7 @@ public abstract class AbstractEntityProfileQueryProcessor value.equals(predicateValue); - case STARTS_WITH -> toStartsWithSqlLikePattern(predicateValue).matcher(value).matches(); - case ENDS_WITH -> toEndsWithSqlLikePattern(predicateValue).matcher(value).matches(); + case STARTS_WITH -> toSqlLikePattern(predicateValue, "^", ".*").matcher(value).matches(); + case ENDS_WITH -> toSqlLikePattern(predicateValue, ".*", "$").matcher(value).matches(); case NOT_EQUAL -> !value.equals(predicateValue); - case CONTAINS -> toContainsSqlLikePattern(predicateValue).matcher(value).matches(); - case NOT_CONTAINS -> !toContainsSqlLikePattern(predicateValue).matcher(value).matches(); + case CONTAINS -> toSqlLikePattern(predicateValue, ".*", ".*").matcher(value).matches(); + case NOT_CONTAINS -> !toSqlLikePattern(predicateValue, ".*", ".*").matcher(value).matches(); case IN -> equalsAny(value, splitByCommaWithoutQuotes(predicateValue)); case NOT_IN -> !equalsAny(value, splitByCommaWithoutQuotes(predicateValue)); }; @@ -322,35 +322,24 @@ public class RepositoryUtils { } } - public static Pattern toContainsSqlLikePattern(String filter) { + public static Pattern toEntityNameSqlLikePattern(String filter) { if (StringUtils.isNotBlank(filter)) { - return toSqlLikePattern(filter, ".*", ".*"); + return toSqlLikePattern(filter, "", ".*"); } return null; } - private static Pattern toStartsWithSqlLikePattern(String filter) { - return toSqlLikePattern(filter, "^", ".*"); - } - - private static Pattern toEndsWithSqlLikePattern(String filter) { - return toSqlLikePattern(filter, ".*", "$"); - } - private static Pattern toSqlLikePattern(String value, String prefix, String suffix) { if (value.contains("%") || value.contains("_")) { String regexValue = value .replace("_", ".") .replace("%", ".*"); - String regex; if ("^".equals(prefix)) { - regex = "^" + regexValue + (regexValue.endsWith(".*") ? "" : ".*"); + regexValue = "^" + regexValue + (regexValue.endsWith(".*") ? "" : ".*"); } else if ("$".equals(suffix)) { - regex = (regexValue.startsWith(".*") ? "" : ".*") + regexValue + "$"; - } else { - regex = (regexValue.startsWith(".*") ? "" : ".*") + regexValue + (regexValue.endsWith(".*") ? "" : ".*"); + regexValue = (regexValue.startsWith(".*") ? "" : ".*") + regexValue + "$"; } - return Pattern.compile(regex); + return Pattern.compile(regexValue); } else { return Pattern.compile(prefix + Pattern.quote(value) + suffix); } diff --git a/edqs/src/test/java/org/thingsboard/server/edqs/repo/RepositoryUtilsTest.java b/edqs/src/test/java/org/thingsboard/server/edqs/repo/RepositoryUtilsTest.java index fa3784ca19..f4c256a8cf 100644 --- a/edqs/src/test/java/org/thingsboard/server/edqs/repo/RepositoryUtilsTest.java +++ b/edqs/src/test/java/org/thingsboard/server/edqs/repo/RepositoryUtilsTest.java @@ -73,7 +73,7 @@ public class RepositoryUtilsTest { Arguments.of("loranet 123", getNameFilter(StringOperation.NOT_IN, "loranet 123, loranet 126"), false), // Basic CONTAINS - Arguments.of("loranet 123", getNameFilter(StringOperation.CONTAINS, "%loranet"), true), + Arguments.of("loranet 123", getNameFilter(StringOperation.CONTAINS, "%loranet"), false), Arguments.of("loranet 123", getNameFilter(StringOperation.CONTAINS, "loranet%"), true), Arguments.of("loranet 123", getNameFilter(StringOperation.CONTAINS, "%ranet%"), true), Arguments.of("loranet 123", getNameFilter(StringOperation.CONTAINS, "%123"), true), From 969b0fec00cbce93f59ac5ccd6786ffebbc3bc9e Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Tue, 17 Jun 2025 15:49:01 +0300 Subject: [PATCH 2/3] Edqs - sql like queries case insensitive --- .../org/thingsboard/server/edqs/util/RepositoryUtils.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/edqs/src/main/java/org/thingsboard/server/edqs/util/RepositoryUtils.java b/common/edqs/src/main/java/org/thingsboard/server/edqs/util/RepositoryUtils.java index 3ecbe0d5fa..6a3fb0fe40 100644 --- a/common/edqs/src/main/java/org/thingsboard/server/edqs/util/RepositoryUtils.java +++ b/common/edqs/src/main/java/org/thingsboard/server/edqs/util/RepositoryUtils.java @@ -339,9 +339,9 @@ public class RepositoryUtils { } else if ("$".equals(suffix)) { regexValue = (regexValue.startsWith(".*") ? "" : ".*") + regexValue + "$"; } - return Pattern.compile(regexValue); + return Pattern.compile(regexValue, Pattern.CASE_INSENSITIVE); } else { - return Pattern.compile(prefix + Pattern.quote(value) + suffix); + return Pattern.compile(prefix + Pattern.quote(value) + suffix, Pattern.CASE_INSENSITIVE); } } From b0a8b9fc25b8a1045f0968a0dac6a5edf6f098c1 Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Tue, 17 Jun 2025 17:32:04 +0300 Subject: [PATCH 3/3] EDQS - ignore case for name and not ignore for filters --- .../server/edqs/util/RepositoryUtils.java | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/common/edqs/src/main/java/org/thingsboard/server/edqs/util/RepositoryUtils.java b/common/edqs/src/main/java/org/thingsboard/server/edqs/util/RepositoryUtils.java index 6a3fb0fe40..fab98027ed 100644 --- a/common/edqs/src/main/java/org/thingsboard/server/edqs/util/RepositoryUtils.java +++ b/common/edqs/src/main/java/org/thingsboard/server/edqs/util/RepositoryUtils.java @@ -324,14 +324,19 @@ public class RepositoryUtils { public static Pattern toEntityNameSqlLikePattern(String filter) { if (StringUtils.isNotBlank(filter)) { - return toSqlLikePattern(filter, "", ".*"); + return toSqlLikePattern(filter, "", ".*", true); } return null; } private static Pattern toSqlLikePattern(String value, String prefix, String suffix) { + return toSqlLikePattern(value, prefix, suffix, false); + } + + private static Pattern toSqlLikePattern(String value, String prefix, String suffix, boolean ignoreCase) { + String regexValue; if (value.contains("%") || value.contains("_")) { - String regexValue = value + regexValue = value .replace("_", ".") .replace("%", ".*"); if ("^".equals(prefix)) { @@ -339,10 +344,10 @@ public class RepositoryUtils { } else if ("$".equals(suffix)) { regexValue = (regexValue.startsWith(".*") ? "" : ".*") + regexValue + "$"; } - return Pattern.compile(regexValue, Pattern.CASE_INSENSITIVE); } else { - return Pattern.compile(prefix + Pattern.quote(value) + suffix, Pattern.CASE_INSENSITIVE); + regexValue = prefix + Pattern.quote(value) + suffix; } + return ignoreCase ? Pattern.compile(regexValue, Pattern.CASE_INSENSITIVE) : Pattern.compile(regexValue); } @FunctionalInterface