Fix query bugs w/ in-list, empty; format booleans as Yes/No

This commit is contained in:
2022-10-04 09:56:33 -05:00
parent e3903c0ab9
commit c5a3534d43
7 changed files with 94 additions and 4 deletions

View File

@ -74,6 +74,12 @@
<version>5.8.1</version> <version>5.8.1</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>5.8.1</version>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<groupId>org.assertj</groupId> <groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId> <artifactId>assertj-core</artifactId>

View File

@ -133,6 +133,11 @@
<artifactId>junit-jupiter-engine</artifactId> <artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<groupId>org.assertj</groupId> <groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId> <artifactId>assertj-core</artifactId>

View File

@ -30,6 +30,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import com.kingsrook.qqq.backend.core.model.data.QRecord; 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.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.model.metadata.tables.QTableMetaData;
import com.kingsrook.qqq.backend.core.utils.StringUtils; import com.kingsrook.qqq.backend.core.utils.StringUtils;
import com.kingsrook.qqq.backend.core.utils.ValueUtils; import com.kingsrook.qqq.backend.core.utils.ValueUtils;
@ -55,6 +56,23 @@ public class QValueFormatter
*******************************************************************************/ *******************************************************************************/
public String formatValue(QFieldMetaData field, Serializable value) 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)); return (formatValue(field.getDisplayFormat(), field.getName(), value));
} }

View File

@ -73,6 +73,10 @@ class QValueFormatterTest
assertEquals("1.10%", qValueFormatter.formatValue(new QFieldMetaData().withDisplayFormat(DisplayFormat.PERCENT_POINT2), new BigDecimal("1.1"))); 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"))); 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 // // this one flows through the exceptional cases //
////////////////////////////////////////////////// //////////////////////////////////////////////////

View File

@ -182,13 +182,33 @@ public abstract class AbstractRDBMSAction implements QActionInterface
break; break;
} }
case IN: case IN:
{
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(",")) + ") "; clause += " IN (" + values.stream().map(x -> "?").collect(Collectors.joining(",")) + ") ";
}
break; break;
} }
case NOT_IN: case NOT_IN:
{
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(",")) + ") "; clause += " NOT IN (" + values.stream().map(x -> "?").collect(Collectors.joining(",")) + ") ";
}
break; break;
} }
case STARTS_WITH: case STARTS_WITH:
@ -272,7 +292,7 @@ public abstract class AbstractRDBMSAction implements QActionInterface
clause += " IS NOT NULL "; clause += " IS NOT NULL ";
if(isString(field.getType())) if(isString(field.getType()))
{ {
clause += " AND " + column + " !+ '' "; clause += " AND " + column + " != '' ";
} }
expectedNoOfParams = 0; expectedNoOfParams = 0;
break; break;

View File

@ -121,7 +121,6 @@ public class RDBMSQueryAction extends AbstractRDBMSAction implements QueryInterf
ResultSetMetaData metaData = resultSet.getMetaData(); ResultSetMetaData metaData = resultSet.getMetaData();
while(resultSet.next()) while(resultSet.next())
{ {
// todo - Add display values (String labels for possibleValues, formatted #'s, etc)
QRecord record = new QRecord(); QRecord record = new QRecord();
record.setTableName(table.getName()); record.setTableName(table.getName());
LinkedHashMap<String, Serializable> values = new LinkedHashMap<>(); LinkedHashMap<String, Serializable> values = new LinkedHashMap<>();

View File

@ -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(); 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.");
}
} }