fix: 9414 Firestore where clause not fetching numbers (#10775)
* Fixed issue with Firestore in fetching data while using numbers in the where condition. * Other Fixes made in the where condition : When using Boolean When using Date When Using Timestamp When given space in the key When Space given in the Value
This commit is contained in:
parent
da655b5748
commit
6e7687450e
|
|
@ -1,14 +1,18 @@
|
||||||
package com.external.utils;
|
package com.external.utils;
|
||||||
|
|
||||||
|
import com.appsmith.external.constants.DataType;
|
||||||
import com.appsmith.external.exceptions.pluginExceptions.AppsmithPluginError;
|
import com.appsmith.external.exceptions.pluginExceptions.AppsmithPluginError;
|
||||||
import com.appsmith.external.exceptions.pluginExceptions.AppsmithPluginException;
|
import com.appsmith.external.exceptions.pluginExceptions.AppsmithPluginException;
|
||||||
import com.appsmith.external.constants.ConditionalOperator;
|
import com.appsmith.external.constants.ConditionalOperator;
|
||||||
|
import com.appsmith.external.helpers.DataTypeStringUtils;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.google.cloud.firestore.FieldPath;
|
import com.google.cloud.firestore.FieldPath;
|
||||||
import com.google.cloud.firestore.Query;
|
import com.google.cloud.firestore.Query;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|
@ -16,7 +20,9 @@ public class WhereConditionUtils {
|
||||||
|
|
||||||
protected static final ObjectMapper objectMapper = new ObjectMapper();
|
protected static final ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
|
||||||
public static Query applyWhereConditional(Query query, String path, String operatorString, String value) throws AppsmithPluginException {
|
public static Query applyWhereConditional(Query query, String strPath, String operatorString, String strValue) throws AppsmithPluginException {
|
||||||
|
|
||||||
|
String path = strPath.trim();
|
||||||
|
|
||||||
if (query == null) {
|
if (query == null) {
|
||||||
throw new AppsmithPluginException(
|
throw new AppsmithPluginException(
|
||||||
|
|
@ -37,6 +43,44 @@ public class WhereConditionUtils {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DataType dataType = DataTypeStringUtils.stringToKnownDataTypeConverter(strValue);
|
||||||
|
Object value = strValue.trim();
|
||||||
|
|
||||||
|
switch (dataType) {
|
||||||
|
case INTEGER:
|
||||||
|
case LONG:
|
||||||
|
case FLOAT:
|
||||||
|
case DOUBLE:
|
||||||
|
value = Double.parseDouble(strValue);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BOOLEAN:
|
||||||
|
value = Boolean.parseBoolean(strValue);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DATE:
|
||||||
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
||||||
|
java.util.Date date = null;
|
||||||
|
try {
|
||||||
|
date = sdf.parse(strValue);
|
||||||
|
} catch (ParseException e) {
|
||||||
|
//Input may not be of above pattern
|
||||||
|
}
|
||||||
|
value = date;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TIMESTAMP:
|
||||||
|
SimpleDateFormat sdfTs = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
|
java.util.Date timeStamp = null;
|
||||||
|
try {
|
||||||
|
timeStamp = sdfTs.parse(strValue);
|
||||||
|
} catch (ParseException e) {
|
||||||
|
//Input may not be of above pattern
|
||||||
|
}
|
||||||
|
value = timeStamp;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
FieldPath fieldPath = FieldPath.of(path.split("\\."));
|
FieldPath fieldPath = FieldPath.of(path.split("\\."));
|
||||||
switch (operator) {
|
switch (operator) {
|
||||||
case LT:
|
case LT:
|
||||||
|
|
@ -56,7 +100,7 @@ public class WhereConditionUtils {
|
||||||
return query.whereArrayContains(fieldPath, value);
|
return query.whereArrayContains(fieldPath, value);
|
||||||
case ARRAY_CONTAINS_ANY:
|
case ARRAY_CONTAINS_ANY:
|
||||||
try {
|
try {
|
||||||
return query.whereArrayContainsAny(fieldPath, parseList(value));
|
return query.whereArrayContainsAny(fieldPath, parseList((String) value));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new AppsmithPluginException(
|
throw new AppsmithPluginException(
|
||||||
AppsmithPluginError.PLUGIN_EXECUTE_ARGUMENT_ERROR,
|
AppsmithPluginError.PLUGIN_EXECUTE_ARGUMENT_ERROR,
|
||||||
|
|
@ -65,7 +109,7 @@ public class WhereConditionUtils {
|
||||||
}
|
}
|
||||||
case IN:
|
case IN:
|
||||||
try {
|
try {
|
||||||
return query.whereIn(fieldPath, parseList(value));
|
return query.whereIn(fieldPath, parseList((String) value));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new AppsmithPluginException(
|
throw new AppsmithPluginException(
|
||||||
AppsmithPluginError.PLUGIN_EXECUTE_ARGUMENT_ERROR,
|
AppsmithPluginError.PLUGIN_EXECUTE_ARGUMENT_ERROR,
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ import com.appsmith.external.models.Property;
|
||||||
import com.appsmith.external.models.RequestParamDTO;
|
import com.appsmith.external.models.RequestParamDTO;
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.google.api.client.util.DateTime;
|
||||||
import com.google.cloud.NoCredentials;
|
import com.google.cloud.NoCredentials;
|
||||||
import com.google.cloud.ServiceOptions;
|
import com.google.cloud.ServiceOptions;
|
||||||
import com.google.cloud.firestore.Blob;
|
import com.google.cloud.firestore.Blob;
|
||||||
|
|
@ -33,6 +34,9 @@ import reactor.core.publisher.Mono;
|
||||||
import reactor.test.StepVerifier;
|
import reactor.test.StepVerifier;
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
@ -79,7 +83,7 @@ public class FirestorePluginTest {
|
||||||
static DatasourceConfiguration dsConfig = new DatasourceConfiguration();
|
static DatasourceConfiguration dsConfig = new DatasourceConfiguration();
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void setUp() throws ExecutionException, InterruptedException {
|
public static void setUp() throws ExecutionException, InterruptedException, ParseException {
|
||||||
firestoreConnection = FirestoreOptions.newBuilder()
|
firestoreConnection = FirestoreOptions.newBuilder()
|
||||||
.setHost(emulator.getEmulatorEndpoint())
|
.setHost(emulator.getEmulatorEndpoint())
|
||||||
.setCredentials(NoCredentials.getInstance())
|
.setCredentials(NoCredentials.getInstance())
|
||||||
|
|
@ -115,6 +119,14 @@ public class FirestorePluginTest {
|
||||||
)
|
)
|
||||||
)).get();
|
)).get();
|
||||||
|
|
||||||
|
final Map<String, Object> numData = new HashMap<>(Map.of(
|
||||||
|
"score", Integer.valueOf("99"),
|
||||||
|
"isPlural", Boolean.TRUE,
|
||||||
|
"dob", new SimpleDateFormat("yyyy-MM-dd").parse("2000-03-24"),
|
||||||
|
"start", Timestamp.valueOf("2018-09-01 09:01:15")
|
||||||
|
));
|
||||||
|
firestoreConnection.document("numeric/two").set(numData).get();
|
||||||
|
|
||||||
firestoreConnection.document("changing/to-update").set(Map.of("value", 1)).get();
|
firestoreConnection.document("changing/to-update").set(Map.of("value", 1)).get();
|
||||||
firestoreConnection.document("changing/to-delete").set(Map.of("value", 1)).get();
|
firestoreConnection.document("changing/to-delete").set(Map.of("value", 1)).get();
|
||||||
|
|
||||||
|
|
@ -785,6 +797,182 @@ public class FirestorePluginTest {
|
||||||
.verifyComplete();
|
.verifyComplete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNumberWhereConditional() {
|
||||||
|
Map<String, Object> configMap = new HashMap<>();
|
||||||
|
setValueSafelyInFormData(configMap, COMMAND, "GET_COLLECTION");
|
||||||
|
|
||||||
|
List<Object> children = new ArrayList<>();
|
||||||
|
children.add(new HashMap<String, Object>() {{
|
||||||
|
put("key", "{{Input1.text}}");
|
||||||
|
put("condition", "EQ");
|
||||||
|
put("value", "{{Input2.text}}");
|
||||||
|
}});
|
||||||
|
|
||||||
|
Map<String, Object> whereMap = new HashMap<>();
|
||||||
|
whereMap.put(CHILDREN, children);
|
||||||
|
setValueSafelyInFormData(configMap, WHERE, whereMap);
|
||||||
|
|
||||||
|
ActionConfiguration actionConfiguration = new ActionConfiguration();
|
||||||
|
actionConfiguration.setPath("numeric");
|
||||||
|
actionConfiguration.setFormData(configMap);
|
||||||
|
|
||||||
|
List params = new ArrayList();
|
||||||
|
Param param = new Param();
|
||||||
|
param.setKey("Input1.text");
|
||||||
|
param.setValue("score");
|
||||||
|
params.add(param);
|
||||||
|
param = new Param();
|
||||||
|
param.setKey("Input2.text");
|
||||||
|
param.setValue("99");
|
||||||
|
params.add(param);
|
||||||
|
|
||||||
|
ExecuteActionDTO executeActionDTO = new ExecuteActionDTO();
|
||||||
|
executeActionDTO.setParams(params);
|
||||||
|
Mono<ActionExecutionResult> resultMono = pluginExecutor
|
||||||
|
.executeParameterized(firestoreConnection, executeActionDTO, dsConfig, actionConfiguration);
|
||||||
|
|
||||||
|
StepVerifier.create(resultMono)
|
||||||
|
.assertNext(result -> {
|
||||||
|
assertTrue(result.getIsExecutionSuccess());
|
||||||
|
List<Map<String, Object>> results = (List) result.getBody();
|
||||||
|
assertEquals(1, results.size());
|
||||||
|
})
|
||||||
|
.verifyComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBooleanWhereConditional() {
|
||||||
|
Map<String, Object> configMap = new HashMap<>();
|
||||||
|
setValueSafelyInFormData(configMap, COMMAND, "GET_COLLECTION");
|
||||||
|
|
||||||
|
List<Object> children = new ArrayList<>();
|
||||||
|
children.add(new HashMap<String, Object>() {{
|
||||||
|
put("key", "{{Input1.text}}");
|
||||||
|
put("condition", "EQ");
|
||||||
|
put("value", "{{Input2.text}}");
|
||||||
|
}});
|
||||||
|
|
||||||
|
Map<String, Object> whereMap = new HashMap<>();
|
||||||
|
whereMap.put(CHILDREN, children);
|
||||||
|
setValueSafelyInFormData(configMap, WHERE, whereMap);
|
||||||
|
|
||||||
|
ActionConfiguration actionConfiguration = new ActionConfiguration();
|
||||||
|
actionConfiguration.setPath("numeric");
|
||||||
|
actionConfiguration.setFormData(configMap);
|
||||||
|
|
||||||
|
List params = new ArrayList();
|
||||||
|
Param param = new Param();
|
||||||
|
param.setKey("Input1.text");
|
||||||
|
param.setValue("isPlural");
|
||||||
|
params.add(param);
|
||||||
|
param = new Param();
|
||||||
|
param.setKey("Input2.text");
|
||||||
|
param.setValue("true");
|
||||||
|
params.add(param);
|
||||||
|
|
||||||
|
ExecuteActionDTO executeActionDTO = new ExecuteActionDTO();
|
||||||
|
executeActionDTO.setParams(params);
|
||||||
|
Mono<ActionExecutionResult> resultMono = pluginExecutor
|
||||||
|
.executeParameterized(firestoreConnection, executeActionDTO, dsConfig, actionConfiguration);
|
||||||
|
|
||||||
|
StepVerifier.create(resultMono)
|
||||||
|
.assertNext(result -> {
|
||||||
|
assertTrue(result.getIsExecutionSuccess());
|
||||||
|
List<Map<String, Object>> results = (List) result.getBody();
|
||||||
|
assertEquals(1, results.size());
|
||||||
|
})
|
||||||
|
.verifyComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDateWhereConditional() {
|
||||||
|
Map<String, Object> configMap = new HashMap<>();
|
||||||
|
setValueSafelyInFormData(configMap, COMMAND, "GET_COLLECTION");
|
||||||
|
|
||||||
|
List<Object> children = new ArrayList<>();
|
||||||
|
children.add(new HashMap<String, Object>() {{
|
||||||
|
put("key", "{{Input1.text}}");
|
||||||
|
put("condition", "EQ");
|
||||||
|
put("value", "{{Input2.text}}");
|
||||||
|
}});
|
||||||
|
|
||||||
|
Map<String, Object> whereMap = new HashMap<>();
|
||||||
|
whereMap.put(CHILDREN, children);
|
||||||
|
setValueSafelyInFormData(configMap, WHERE, whereMap);
|
||||||
|
|
||||||
|
ActionConfiguration actionConfiguration = new ActionConfiguration();
|
||||||
|
actionConfiguration.setPath("numeric");
|
||||||
|
actionConfiguration.setFormData(configMap);
|
||||||
|
|
||||||
|
List params = new ArrayList();
|
||||||
|
Param param = new Param();
|
||||||
|
param.setKey("Input1.text");
|
||||||
|
param.setValue("dob");
|
||||||
|
params.add(param);
|
||||||
|
param = new Param();
|
||||||
|
param.setKey("Input2.text");
|
||||||
|
param.setValue("2000-03-24");
|
||||||
|
params.add(param);
|
||||||
|
|
||||||
|
ExecuteActionDTO executeActionDTO = new ExecuteActionDTO();
|
||||||
|
executeActionDTO.setParams(params);
|
||||||
|
Mono<ActionExecutionResult> resultMono = pluginExecutor
|
||||||
|
.executeParameterized(firestoreConnection, executeActionDTO, dsConfig, actionConfiguration);
|
||||||
|
|
||||||
|
StepVerifier.create(resultMono)
|
||||||
|
.assertNext(result -> {
|
||||||
|
assertTrue(result.getIsExecutionSuccess());
|
||||||
|
List<Map<String, Object>> results = (List) result.getBody();
|
||||||
|
assertEquals(1, results.size());
|
||||||
|
})
|
||||||
|
.verifyComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTimeStampWhereConditional() {
|
||||||
|
Map<String, Object> configMap = new HashMap<>();
|
||||||
|
setValueSafelyInFormData(configMap, COMMAND, "GET_COLLECTION");
|
||||||
|
|
||||||
|
List<Object> children = new ArrayList<>();
|
||||||
|
children.add(new HashMap<String, Object>() {{
|
||||||
|
put("key", "{{Input1.text}}");
|
||||||
|
put("condition", "EQ");
|
||||||
|
put("value", "{{Input2.text}}");
|
||||||
|
}});
|
||||||
|
|
||||||
|
Map<String, Object> whereMap = new HashMap<>();
|
||||||
|
whereMap.put(CHILDREN, children);
|
||||||
|
setValueSafelyInFormData(configMap, WHERE, whereMap);
|
||||||
|
|
||||||
|
ActionConfiguration actionConfiguration = new ActionConfiguration();
|
||||||
|
actionConfiguration.setPath("numeric");
|
||||||
|
actionConfiguration.setFormData(configMap);
|
||||||
|
|
||||||
|
List params = new ArrayList();
|
||||||
|
Param param = new Param();
|
||||||
|
param.setKey("Input1.text");
|
||||||
|
param.setValue("start");
|
||||||
|
params.add(param);
|
||||||
|
param = new Param();
|
||||||
|
param.setKey("Input2.text");
|
||||||
|
param.setValue("2018-09-01 09:01:15");
|
||||||
|
params.add(param);
|
||||||
|
|
||||||
|
ExecuteActionDTO executeActionDTO = new ExecuteActionDTO();
|
||||||
|
executeActionDTO.setParams(params);
|
||||||
|
Mono<ActionExecutionResult> resultMono = pluginExecutor
|
||||||
|
.executeParameterized(firestoreConnection, executeActionDTO, dsConfig, actionConfiguration);
|
||||||
|
|
||||||
|
StepVerifier.create(resultMono)
|
||||||
|
.assertNext(result -> {
|
||||||
|
assertTrue(result.getIsExecutionSuccess());
|
||||||
|
List<Map<String, Object>> results = (List) result.getBody();
|
||||||
|
assertEquals(1, results.size());
|
||||||
|
})
|
||||||
|
.verifyComplete();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUpdateDocumentWithFieldValueTimestamp() {
|
public void testUpdateDocumentWithFieldValueTimestamp() {
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user