Add LIKE criteria operator; more api endpoints to understand versions, get swagger json; more field name mapping

This commit is contained in:
2023-03-24 10:20:26 -05:00
parent 74cf24a00e
commit 17d4c81cc3
11 changed files with 374 additions and 43 deletions

View File

@ -33,6 +33,8 @@ public enum QCriteriaOperator
IN,
NOT_IN,
IS_NULL_OR_IN,
LIKE,
NOT_LIKE,
STARTS_WITH,
ENDS_WITH,
CONTAINS,

View File

@ -123,6 +123,8 @@ public class BackendQueryFilterUtils
case CONTAINS -> testContains(criterion, fieldName, value);
case NOT_CONTAINS -> !testContains(criterion, fieldName, value);
case IS_NULL_OR_IN -> testBlank(criterion, value) || testIn(criterion, value);
case LIKE -> testLike(criterion, fieldName, value);
case NOT_LIKE -> !testLike(criterion, fieldName, value);
case STARTS_WITH -> testStartsWith(criterion, fieldName, value);
case NOT_STARTS_WITH -> !testStartsWith(criterion, fieldName, value);
case ENDS_WITH -> testEndsWith(criterion, fieldName, value);
@ -152,6 +154,21 @@ public class BackendQueryFilterUtils
/*******************************************************************************
**
*******************************************************************************/
private static boolean testLike(QFilterCriteria criterion, String fieldName, Serializable value)
{
String stringValue = getStringFieldValue(value, fieldName, criterion);
String criterionValue = getFirstStringCriterionValue(criterion);
String regex = sqlLikeToRegex(criterionValue);
return (stringValue.matches(regex));
}
/*******************************************************************************
** Based on an incoming boolean value (accumulator), a new value, and a boolean
** operator, update the accumulator, and if we can then short-circuit remaining
@ -514,4 +531,38 @@ public class BackendQueryFilterUtils
return recordList;
}
/*******************************************************************************
** ... written by ChatGPT
*******************************************************************************/
static String sqlLikeToRegex(String sqlLikeExpression)
{
StringBuilder regex = new StringBuilder("^");
for(int i = 0; i < sqlLikeExpression.length(); i++)
{
char c = sqlLikeExpression.charAt(i);
if(c == '%')
{
regex.append(".*");
}
else if(c == '_')
{
regex.append(".");
}
else if("[]^$|\\(){}.*+?".indexOf(c) >= 0)
{
regex.append("\\").append(c);
}
else
{
regex.append(c);
}
}
regex.append("$");
return regex.toString();
}
}

View File

@ -87,6 +87,78 @@ class BackendQueryFilterUtilsTest
assertFalse(BackendQueryFilterUtils.doesCriteriaMatch(new QFilterCriteria("f", QCriteriaOperator.NOT_BETWEEN, List.of(1, 3)), "f", 2));
assertFalse(BackendQueryFilterUtils.doesCriteriaMatch(new QFilterCriteria("f", QCriteriaOperator.NOT_BETWEEN, List.of(1, 3)), "f", 3));
assertTrue(BackendQueryFilterUtils.doesCriteriaMatch(new QFilterCriteria("f", QCriteriaOperator.NOT_BETWEEN, List.of(1, 3)), "f", 4));
////////////////
// like & not //
////////////////
assertTrue(BackendQueryFilterUtils.doesCriteriaMatch(new QFilterCriteria("f", QCriteriaOperator.LIKE, "Test"), "f", "Test"));
assertTrue(BackendQueryFilterUtils.doesCriteriaMatch(new QFilterCriteria("f", QCriteriaOperator.LIKE, "T%"), "f", "Test"));
assertTrue(BackendQueryFilterUtils.doesCriteriaMatch(new QFilterCriteria("f", QCriteriaOperator.LIKE, "T_st"), "f", "Test"));
assertTrue(BackendQueryFilterUtils.doesCriteriaMatch(new QFilterCriteria("f", QCriteriaOperator.NOT_LIKE, "Test"), "f", "Tst"));
assertTrue(BackendQueryFilterUtils.doesCriteriaMatch(new QFilterCriteria("f", QCriteriaOperator.NOT_LIKE, "T%"), "f", "Rest"));
assertTrue(BackendQueryFilterUtils.doesCriteriaMatch(new QFilterCriteria("f", QCriteriaOperator.NOT_LIKE, "T_st"), "f", "Toast"));
}
/*******************************************************************************
**
*******************************************************************************/
@Test
void testLikeDarPercent()
{
String pattern = BackendQueryFilterUtils.sqlLikeToRegex("Dar%");
assertTrue("Darin".matches(pattern));
assertTrue("Dar".matches(pattern));
assertFalse("Not Darin".matches(pattern));
assertFalse("David".matches(pattern));
}
/*******************************************************************************
**
*******************************************************************************/
@Test
void testLikeDPercentIn()
{
String pattern = BackendQueryFilterUtils.sqlLikeToRegex("D%in");
assertTrue("Darin".matches(pattern));
assertFalse("Dar".matches(pattern));
assertFalse("Not Darin".matches(pattern));
assertTrue("Davin".matches(pattern));
}
/*******************************************************************************
**
*******************************************************************************/
@Test
void testLikeDPercentUnderscoreN()
{
String pattern = BackendQueryFilterUtils.sqlLikeToRegex("D%_n");
assertTrue("Darin".matches(pattern));
assertTrue("Daron".matches(pattern));
assertTrue("Dan".matches(pattern));
assertFalse("Dar".matches(pattern));
assertFalse("Not Darin".matches(pattern));
assertTrue("Davin".matches(pattern));
}
/*******************************************************************************
**
*******************************************************************************/
@Test
void testLikeDarUnderscore()
{
String pattern = BackendQueryFilterUtils.sqlLikeToRegex("Dar_");
assertFalse("Darin".matches(pattern));
assertFalse("Dar".matches(pattern));
assertTrue("Dart".matches(pattern));
assertFalse("Not Darin".matches(pattern));
assertFalse("David".matches(pattern));
}
}