diff --git a/app/server/appsmith-plugins/firestorePlugin/src/main/java/com/external/utils/WhereConditionUtils.java b/app/server/appsmith-plugins/firestorePlugin/src/main/java/com/external/utils/WhereConditionUtils.java index e2dc18c4c3..8476f987e9 100644 --- a/app/server/appsmith-plugins/firestorePlugin/src/main/java/com/external/utils/WhereConditionUtils.java +++ b/app/server/appsmith-plugins/firestorePlugin/src/main/java/com/external/utils/WhereConditionUtils.java @@ -1,14 +1,18 @@ package com.external.utils; +import com.appsmith.external.constants.DataType; import com.appsmith.external.exceptions.pluginExceptions.AppsmithPluginError; import com.appsmith.external.exceptions.pluginExceptions.AppsmithPluginException; import com.appsmith.external.constants.ConditionalOperator; +import com.appsmith.external.helpers.DataTypeStringUtils; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.cloud.firestore.FieldPath; import com.google.cloud.firestore.Query; import org.apache.commons.lang3.StringUtils; import java.io.IOException; +import java.text.ParseException; +import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.List; @@ -16,7 +20,9 @@ public class WhereConditionUtils { 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) { 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("\\.")); switch (operator) { case LT: @@ -56,7 +100,7 @@ public class WhereConditionUtils { return query.whereArrayContains(fieldPath, value); case ARRAY_CONTAINS_ANY: try { - return query.whereArrayContainsAny(fieldPath, parseList(value)); + return query.whereArrayContainsAny(fieldPath, parseList((String) value)); } catch (IOException e) { throw new AppsmithPluginException( AppsmithPluginError.PLUGIN_EXECUTE_ARGUMENT_ERROR, @@ -65,7 +109,7 @@ public class WhereConditionUtils { } case IN: try { - return query.whereIn(fieldPath, parseList(value)); + return query.whereIn(fieldPath, parseList((String) value)); } catch (IOException e) { throw new AppsmithPluginException( AppsmithPluginError.PLUGIN_EXECUTE_ARGUMENT_ERROR, diff --git a/app/server/appsmith-plugins/firestorePlugin/src/test/java/com/external/plugins/FirestorePluginTest.java b/app/server/appsmith-plugins/firestorePlugin/src/test/java/com/external/plugins/FirestorePluginTest.java index 92193318ba..ed77068468 100644 --- a/app/server/appsmith-plugins/firestorePlugin/src/test/java/com/external/plugins/FirestorePluginTest.java +++ b/app/server/appsmith-plugins/firestorePlugin/src/test/java/com/external/plugins/FirestorePluginTest.java @@ -14,6 +14,7 @@ import com.appsmith.external.models.Property; import com.appsmith.external.models.RequestParamDTO; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.api.client.util.DateTime; import com.google.cloud.NoCredentials; import com.google.cloud.ServiceOptions; import com.google.cloud.firestore.Blob; @@ -33,6 +34,9 @@ import reactor.core.publisher.Mono; import reactor.test.StepVerifier; import java.nio.charset.StandardCharsets; +import java.sql.Timestamp; +import java.text.ParseException; +import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -79,7 +83,7 @@ public class FirestorePluginTest { static DatasourceConfiguration dsConfig = new DatasourceConfiguration(); @BeforeClass - public static void setUp() throws ExecutionException, InterruptedException { + public static void setUp() throws ExecutionException, InterruptedException, ParseException { firestoreConnection = FirestoreOptions.newBuilder() .setHost(emulator.getEmulatorEndpoint()) .setCredentials(NoCredentials.getInstance()) @@ -115,6 +119,14 @@ public class FirestorePluginTest { ) )).get(); + final Map 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-delete").set(Map.of("value", 1)).get(); @@ -785,6 +797,182 @@ public class FirestorePluginTest { .verifyComplete(); } + @Test + public void testNumberWhereConditional() { + Map configMap = new HashMap<>(); + setValueSafelyInFormData(configMap, COMMAND, "GET_COLLECTION"); + + List children = new ArrayList<>(); + children.add(new HashMap() {{ + put("key", "{{Input1.text}}"); + put("condition", "EQ"); + put("value", "{{Input2.text}}"); + }}); + + Map 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 resultMono = pluginExecutor + .executeParameterized(firestoreConnection, executeActionDTO, dsConfig, actionConfiguration); + + StepVerifier.create(resultMono) + .assertNext(result -> { + assertTrue(result.getIsExecutionSuccess()); + List> results = (List) result.getBody(); + assertEquals(1, results.size()); + }) + .verifyComplete(); + } + + @Test + public void testBooleanWhereConditional() { + Map configMap = new HashMap<>(); + setValueSafelyInFormData(configMap, COMMAND, "GET_COLLECTION"); + + List children = new ArrayList<>(); + children.add(new HashMap() {{ + put("key", "{{Input1.text}}"); + put("condition", "EQ"); + put("value", "{{Input2.text}}"); + }}); + + Map 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 resultMono = pluginExecutor + .executeParameterized(firestoreConnection, executeActionDTO, dsConfig, actionConfiguration); + + StepVerifier.create(resultMono) + .assertNext(result -> { + assertTrue(result.getIsExecutionSuccess()); + List> results = (List) result.getBody(); + assertEquals(1, results.size()); + }) + .verifyComplete(); + } + + @Test + public void testDateWhereConditional() { + Map configMap = new HashMap<>(); + setValueSafelyInFormData(configMap, COMMAND, "GET_COLLECTION"); + + List children = new ArrayList<>(); + children.add(new HashMap() {{ + put("key", "{{Input1.text}}"); + put("condition", "EQ"); + put("value", "{{Input2.text}}"); + }}); + + Map 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 resultMono = pluginExecutor + .executeParameterized(firestoreConnection, executeActionDTO, dsConfig, actionConfiguration); + + StepVerifier.create(resultMono) + .assertNext(result -> { + assertTrue(result.getIsExecutionSuccess()); + List> results = (List) result.getBody(); + assertEquals(1, results.size()); + }) + .verifyComplete(); + } + + @Test + public void testTimeStampWhereConditional() { + Map configMap = new HashMap<>(); + setValueSafelyInFormData(configMap, COMMAND, "GET_COLLECTION"); + + List children = new ArrayList<>(); + children.add(new HashMap() {{ + put("key", "{{Input1.text}}"); + put("condition", "EQ"); + put("value", "{{Input2.text}}"); + }}); + + Map 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 resultMono = pluginExecutor + .executeParameterized(firestoreConnection, executeActionDTO, dsConfig, actionConfiguration); + + StepVerifier.create(resultMono) + .assertNext(result -> { + assertTrue(result.getIsExecutionSuccess()); + List> results = (List) result.getBody(); + assertEquals(1, results.size()); + }) + .verifyComplete(); + } + @Test public void testUpdateDocumentWithFieldValueTimestamp() {