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