diff --git a/pom.xml b/pom.xml index abdb50e5..958e5d75 100644 --- a/pom.xml +++ b/pom.xml @@ -74,6 +74,12 @@ 5.8.1 test + + org.junit.jupiter + junit-jupiter-params + 5.8.1 + test + org.assertj assertj-core diff --git a/qqq-backend-core/pom.xml b/qqq-backend-core/pom.xml index d29ad206..174a284a 100644 --- a/qqq-backend-core/pom.xml +++ b/qqq-backend-core/pom.xml @@ -133,6 +133,11 @@ junit-jupiter-engine test + + org.junit.jupiter + junit-jupiter-params + test + org.assertj assertj-core diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/values/QValueFormatter.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/values/QValueFormatter.java index 50ca7d04..791986a2 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/values/QValueFormatter.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/values/QValueFormatter.java @@ -30,6 +30,7 @@ import java.util.List; import java.util.Map; import com.kingsrook.qqq.backend.core.model.data.QRecord; import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData; +import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldType; import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData; import com.kingsrook.qqq.backend.core.utils.StringUtils; import com.kingsrook.qqq.backend.core.utils.ValueUtils; @@ -55,6 +56,23 @@ public class QValueFormatter *******************************************************************************/ public String formatValue(QFieldMetaData field, Serializable value) { + if(QFieldType.BOOLEAN.equals(field.getType())) + { + Boolean b = ValueUtils.getValueAsBoolean(value); + if(b == null) + { + return (null); + } + else if(b) + { + return ("Yes"); + } + else + { + return ("No"); + } + } + return (formatValue(field.getDisplayFormat(), field.getName(), value)); } diff --git a/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/actions/values/QValueFormatterTest.java b/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/actions/values/QValueFormatterTest.java index 341f58f3..3620ba0b 100644 --- a/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/actions/values/QValueFormatterTest.java +++ b/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/actions/values/QValueFormatterTest.java @@ -73,6 +73,10 @@ class QValueFormatterTest assertEquals("1.10%", qValueFormatter.formatValue(new QFieldMetaData().withDisplayFormat(DisplayFormat.PERCENT_POINT2), new BigDecimal("1.1"))); assertEquals("1.12%", qValueFormatter.formatValue(new QFieldMetaData().withDisplayFormat(DisplayFormat.PERCENT_POINT2), new BigDecimal("1.12"))); + assertNull(qValueFormatter.formatValue(new QFieldMetaData().withType(QFieldType.BOOLEAN), null)); + assertEquals("Yes", qValueFormatter.formatValue(new QFieldMetaData().withType(QFieldType.BOOLEAN), true)); + assertEquals("No", qValueFormatter.formatValue(new QFieldMetaData().withType(QFieldType.BOOLEAN), false)); + ////////////////////////////////////////////////// // this one flows through the exceptional cases // ////////////////////////////////////////////////// diff --git a/qqq-backend-module-rdbms/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/AbstractRDBMSAction.java b/qqq-backend-module-rdbms/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/AbstractRDBMSAction.java index 6e11d546..984ac552 100644 --- a/qqq-backend-module-rdbms/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/AbstractRDBMSAction.java +++ b/qqq-backend-module-rdbms/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/AbstractRDBMSAction.java @@ -183,12 +183,32 @@ public abstract class AbstractRDBMSAction implements QActionInterface } case IN: { - clause += " IN (" + values.stream().map(x -> "?").collect(Collectors.joining(",")) + ") "; + if(values.isEmpty()) + { + ////////////////////////////////////////////////////////////////////////////////// + // if there are no values, then we want a false here - so say column != column. // + ////////////////////////////////////////////////////////////////////////////////// + clause += " != " + column; + } + else + { + clause += " IN (" + values.stream().map(x -> "?").collect(Collectors.joining(",")) + ") "; + } break; } case NOT_IN: { - clause += " NOT IN (" + values.stream().map(x -> "?").collect(Collectors.joining(",")) + ") "; + if(values.isEmpty()) + { + ///////////////////////////////////////////////////////////////////////////////// + // if there are no values, then we want a true here - so say column == column. // + ///////////////////////////////////////////////////////////////////////////////// + clause += " = " + column; + } + else + { + clause += " NOT IN (" + values.stream().map(x -> "?").collect(Collectors.joining(",")) + ") "; + } break; } case STARTS_WITH: @@ -272,7 +292,7 @@ public abstract class AbstractRDBMSAction implements QActionInterface clause += " IS NOT NULL "; if(isString(field.getType())) { - clause += " AND " + column + " !+ '' "; + clause += " AND " + column + " != '' "; } expectedNoOfParams = 0; break; diff --git a/qqq-backend-module-rdbms/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSQueryAction.java b/qqq-backend-module-rdbms/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSQueryAction.java index 2261a63c..a901eab5 100644 --- a/qqq-backend-module-rdbms/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSQueryAction.java +++ b/qqq-backend-module-rdbms/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSQueryAction.java @@ -121,7 +121,6 @@ public class RDBMSQueryAction extends AbstractRDBMSAction implements QueryInterf ResultSetMetaData metaData = resultSet.getMetaData(); while(resultSet.next()) { - // todo - Add display values (String labels for possibleValues, formatted #'s, etc) QRecord record = new QRecord(); record.setTableName(table.getName()); LinkedHashMap values = new LinkedHashMap<>(); diff --git a/qqq-backend-module-rdbms/src/test/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSQueryActionTest.java b/qqq-backend-module-rdbms/src/test/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSQueryActionTest.java index e9b60dc6..97568eaa 100644 --- a/qqq-backend-module-rdbms/src/test/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSQueryActionTest.java +++ b/qqq-backend-module-rdbms/src/test/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSQueryActionTest.java @@ -375,6 +375,25 @@ public class RDBMSQueryActionTest extends RDBMSActionTest + /******************************************************************************* + ** + *******************************************************************************/ + @Test + public void testIsNotBlankQuery() throws QException + { + QueryInput queryInput = initQueryRequest(); + queryInput.setFilter(new QQueryFilter() + .withCriteria(new QFilterCriteria() + .withFieldName("firstName") + .withOperator(QCriteriaOperator.IS_NOT_BLANK) + )); + QueryOutput queryOutput = new RDBMSQueryAction().execute(queryInput); + Assertions.assertEquals(5, queryOutput.getRecords().size(), "Expected # of rows"); + Assertions.assertTrue(queryOutput.getRecords().stream().allMatch(r -> r.getValue("firstName") != null), "Should find expected rows"); + } + + + /******************************************************************************* ** *******************************************************************************/ @@ -484,4 +503,23 @@ public class RDBMSQueryActionTest extends RDBMSActionTest transaction.rollback(); } + + + /******************************************************************************* + ** + *******************************************************************************/ + @Test + void testEmptyInList() throws QException + { + QueryInput queryInput = initQueryRequest(); + queryInput.setFilter(new QQueryFilter().withCriteria(new QFilterCriteria("firstName", QCriteriaOperator.IN, List.of()))); + QueryOutput queryOutput = new QueryAction().execute(queryInput); + Assertions.assertEquals(0, queryOutput.getRecords().size(), "IN empty list should find nothing."); + + queryInput.setFilter(new QQueryFilter().withCriteria(new QFilterCriteria("firstName", QCriteriaOperator.NOT_IN, List.of()))); + queryOutput = new QueryAction().execute(queryInput); + Assertions.assertEquals(5, queryOutput.getRecords().size(), "NOT_IN empty list should find everything."); + + } + } \ No newline at end of file