mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-18 13:10:44 +00:00
Fix query bugs w/ in-list, empty; format booleans as Yes/No
This commit is contained in:
6
pom.xml
6
pom.xml
@ -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>
|
||||||
|
@ -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>
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 //
|
||||||
//////////////////////////////////////////////////
|
//////////////////////////////////////////////////
|
||||||
|
@ -183,12 +183,32 @@ public abstract class AbstractRDBMSAction implements QActionInterface
|
|||||||
}
|
}
|
||||||
case IN:
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case NOT_IN:
|
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;
|
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;
|
||||||
|
@ -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<>();
|
||||||
|
@ -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.");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
Reference in New Issue
Block a user