diff --git a/README.md b/README.md index c3d6d91..11507c6 100644 --- a/README.md +++ b/README.md @@ -83,14 +83,26 @@ public class CouchbaseConfiguration extends AbstractCouchbaseConfiguration imple ##### application.yml ```yaml couchbase: - cluster: - ip: 127.0.0.1 - bucket: dev - password: superSecretPassword + cluster: + ip: 127.0.0.1 + bucket: dev + password: superSecretPassword ``` ## Usage and features Basically, CouchbaseQueryExecutor provides you with functions to build and run queries dynamically. After running, the executor parses them to the POJO class that you gave as a parameter. +### Configuration + +```yaml +couchbase-query-executor: + with-sync-gateway: false # Default is false + use-default-id-fields: true #Default is true +``` + +If you are using Couchbase server with SyncGateway you should set the `couchbase-query-executor.with-sync-gateway` to `true`, so the executor can map `_rev` and `_id` to your entities. + +If you are using the default naming convention for `id` fields (without SyncGateway it is `id` with SyncGateway it is `_id`) you should leave the `couchbase-query-executor.use-default-id-fields` flag on `true`. If you set that config to false Executor will find the field annotated with `com.couchbase.client.java.repository.annotation.Id` And use it as the id. I recommend you to use the default fields :) + ### CouchbaseQueryExecutor functions |**Name**|**Return type**|**Description**| |---|---|---| @@ -100,21 +112,29 @@ Basically, CouchbaseQueryExecutor provides you with functions to build and run q |`public Integer count(JsonObject params)`|`Integer`|Executes a query which counts all of the matching documents| |`sum(JsonObject params, String field)`|`Integer`|Executes a query which sums the results by the given field| -There are constant postfixes defined in CouchbaseQueryExecutor, helping you make the query you want. All you need is to append the postfix to your key, and CouchbaseQueryExecutor will do the work for you. - -### CouchbaseQueryExecutor constant postfixes -|**Name**|**Description**|**Example**| -|---|---|---| -|CONTAINS_FILTER|Compares the field and the given value ignoring the case|`filters.put("title" + CouchbaseQueryExecutor.CONAINS_FILTER, "a string")`| -|FROM_FILTER|Gives back documents that has higher value in the field|`filters.put("estimatedTime" + CouchbaseQueryExecutor.FROM_FILTER, 20)`| -|TO_FILTER|Gives back documents that has lower value in the field|`filters.put("estimatedTime" + CouchbaseQueryExecutor.TO_FILTER, 20)`| -|NOT_FILTER|Compares the field and the given value. Gives back the document if the field doesn't equal to the value|`filters.put("title" + CouchbaseQueryExecutor.NOT_FILTER, "i don't need this")`| -|IN_FILTER|Compares the field and the given value. Gives back the document any of the values match the field|`filters.put("age" + CouchbaseQueryExecutor.IN_FILTER, JsonArray.from(17, 18))`| -|NULL|Gives back document if it has the field, but the value is null|`filters.put("fieldName" + CouchbaseQueryExecutor.NULL_FILTER, null);`| -|NOT_NULL|Gives back document if it has the field, but the value is not null|`filters.put("fieldName" + CouchbaseQueryExecutor.NOT_NULL_FILTER, null);`| -|MISSING|Gives back document if it doesn't have the field|`filters.put("fieldName" + CouchbaseQueryExecutor.MISSING_FILTER, null);`| -|NULL_OR_MISSING|Gives back document if it doesn't have the field, or if it has but value is null|`filters.put("fieldName" + CouchbaseQueryExecutor.NULL_OR_MISSING_FILTER, null);`| - +### How to add parameters to queries + +First of all create a `new Parameters()` object, and you can use the builder pattenr is gives to build yout queries an easy way + +|**BuilderPath**|**FunctionName**|**Returning / instantly add**|**Description**| +|---|---|---|---| +|Parameters|on(String key)|OnPath|You can provide the key of the parameter with this function. Executor is supporting nested querying, so `address.zipCode` means it will look up your document's `address`, then it's `zipCode` to execute the given condition on it| +|OnPath|isNull()|Adding parameter|Checks if the given key's value is null| +|OnPath|isNotNull()|Adding parameter|Checks if the given key's value is not null| +|OnPath|isMissing()|Adding parameter|Checks if the given key's value is missing| +|OnPath|isMissingOrNull()|Adding parameter|Checks if the given key's value is missing or null| +|OnPath|is(String value)|ExpressionPath|Checks whether the document's value on the path is equal to the value| +|OnPath|isNot(String value)|ExpressionPath|Checks whether the document's value on the path is NOT equal to the value| +|OnPath|contains(String value)|ExpressionPath|Checks whether the document's value on the path contains (ignoring the case) the value| +|OnPath|in(String value)|ExpressionPath|Checks whether the document's value is in the given array| +|OnPath|from(String value)|ExpressionPath|Checks whether the document's value on the path is greater than or equal to the value| +|OnPath|to(String value)|ExpressionPath|Checks whether the document's value on the path is less than or equal to the value| +|ExpressionPath|onlyIfNonEmpty()|ApplyPath|The expression will only appear in the query if the value is not empty| +|ExpressionPath|onlyIf(Predicate condition)|ApplyPath|The expression will only appear in the query if the value matches the custom condition| +|ExpressionPath|andApply(Function parser)|Adding parameter|Applies the given parser on the value| +|ExpressionPath|add()|Adding parameter|Adds the parameter| +|ApplyPath|andApply(Function parser)|Adding parameter|Applies the given parser on the value| +|ApplyPath|add()|Adding parameter|Adds the parameter| Also if you add the `CouchbaseQueryExecutor.IGNORE_CASE_ORDER` postfix to a sort param in the Pageable object, it will sort the documents ignoring case. Actually in SpringData, you have to provide this postfix in the query string, and the executor will check the ending of the parameter. Therefore: diff --git a/pom.xml b/pom.xml index ee6bff7..b098420 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.wanari.utils CouchbaseQueryExecutor - 1.0-SNAPSHOT + 1.0.5 jar diff --git a/src/main/java/com/wanari/utils/couchbase/CouchbaseFilter.java b/src/main/java/com/wanari/utils/couchbase/CouchbaseFilter.java deleted file mode 100644 index e36f674..0000000 --- a/src/main/java/com/wanari/utils/couchbase/CouchbaseFilter.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.wanari.utils.couchbase; - -import com.couchbase.client.java.document.json.JsonObject; -import org.apache.commons.lang3.StringUtils; - -import java.util.HashMap; -import java.util.function.BiFunction; -import java.util.function.Function; - -public class CouchbaseFilter extends HashMap { - - public void putIfNotEmpty(String key, String value) { - if(!StringUtils.isEmpty(value)) { - put(key, value); - } - } - - public void putIfNotEmptyAndApply(String key, String value, Function parser) { - if(!StringUtils.isEmpty(value)) { - put(key, parser.apply(value)); - } - } - - public void putIfConditionAndApply(String key, String value, Function condition, Function parser) { - if(!StringUtils.isEmpty(value)) { - T parsedValue = parser.apply(value); - if(condition.apply(parsedValue)) { - put(key, parsedValue); - } - } - } - - public void putCustom(String param1, String param2, BiFunction function) { - CouchbaseFilterEntry entry = function.apply(param1, param2); - if(entry.isEmpty()) { - put(entry.key, entry.value); - } - } - - public JsonObject toJsonObject() { - return JsonObject.from(this); - } -} diff --git a/src/main/java/com/wanari/utils/couchbase/CouchbaseFilterConditions.java b/src/main/java/com/wanari/utils/couchbase/CouchbaseFilterConditions.java deleted file mode 100644 index 2004c3b..0000000 --- a/src/main/java/com/wanari/utils/couchbase/CouchbaseFilterConditions.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.wanari.utils.couchbase; - -public class CouchbaseFilterConditions { - public static Boolean isPositive(Long number) { - return number > 0; - } -} diff --git a/src/main/java/com/wanari/utils/couchbase/CouchbaseFilterEntry.java b/src/main/java/com/wanari/utils/couchbase/CouchbaseFilterEntry.java deleted file mode 100644 index fcb9594..0000000 --- a/src/main/java/com/wanari/utils/couchbase/CouchbaseFilterEntry.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.wanari.utils.couchbase; - -public class CouchbaseFilterEntry { - public String key; - public Object value; - private boolean isEmpty = false; - - public CouchbaseFilterEntry(String key, Object value) { - this.key = key; - this.value = value; - this.isEmpty = true; - } - - private CouchbaseFilterEntry() { - this.isEmpty = false; - } - - public static CouchbaseFilterEntry empty() { - return new CouchbaseFilterEntry(); - } - - public boolean isEmpty() { - return isEmpty; - } -} diff --git a/src/main/java/com/wanari/utils/couchbase/CouchbaseQueryExecutor.java b/src/main/java/com/wanari/utils/couchbase/CouchbaseQueryExecutor.java index 8b0e063..1c2c260 100644 --- a/src/main/java/com/wanari/utils/couchbase/CouchbaseQueryExecutor.java +++ b/src/main/java/com/wanari/utils/couchbase/CouchbaseQueryExecutor.java @@ -1,6 +1,5 @@ package com.wanari.utils.couchbase; -import com.couchbase.client.java.document.json.JsonObject; import com.couchbase.client.java.query.N1qlQuery; import com.couchbase.client.java.query.Statement; import com.couchbase.client.java.query.dsl.Expression; @@ -9,6 +8,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.wanari.utils.couchbase.converters.*; import com.wanari.utils.couchbase.exceptions.NonUniqueResultException; +import com.wanari.utils.couchbase.parameter.Parameters; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.couchbase.core.CouchbaseTemplate; import org.springframework.data.domain.Page; @@ -36,15 +36,6 @@ public class CouchbaseQueryExecutor { @Value("${couchbase-query-executor.use-default-id-fields:true}") private Boolean useDefaultIdFields; - public static final String CONTAINS_FILTER = "_contains"; - public static final String FROM_FILTER = "_from"; - public static final String TO_FILTER = "_to"; - public static final String NOT_FILTER = "_not"; - public static final String IN_FILTER = "_in"; - public static final String NULL_FILTER = "_null"; - public static final String NOT_NULL_FILTER = "_notnull"; - public static final String MISSING_FILTER = "_missing"; - public static final String NULL_OR_MISSING_FILTER = "_nullormissing"; private static final String IGNORE_CASE_ORDER = "_ignorecase"; private DataConverter converter; private final ObjectMapper objectMapper; @@ -81,19 +72,6 @@ public void setConverter(DataConverter converter) { this.converter = converter; } - private String getPropertyKey(String key) { - return key.replaceAll("[\\\\.]", "_"); - } - - private JsonObject paramaterizeParams(JsonObject params) { - return JsonObject.from( - params.toMap().entrySet().stream().collect(Collectors.toMap( - entry -> getPropertyKey(entry.getKey()), - entry -> params.get(entry.getKey()) - )) - ); - } - private CouchbaseTemplate createTemplate() { try { return new CouchbaseTemplate(couchbaseConfiguration.couchbaseClusterInfo(), couchbaseConfiguration.couchbaseClient()); @@ -102,16 +80,16 @@ private CouchbaseTemplate createTemplate() { } } - public Optional findOne(JsonObject params, Class clazz) { + public Optional findOne(Parameters params, Class clazz) { List documents = find(params, clazz); return asOptional(documents, params); } - public Page find(JsonObject params, Pageable pageable, Class clazz) { + public Page find(Parameters params, Pageable pageable, Class clazz) { CouchbaseTemplate template = createTemplate(); Statement query = createQueryStatement(params, pageable); - N1qlQuery queryWithParameter = N1qlQuery.parameterized(query, paramaterizeParams(params)); + N1qlQuery queryWithParameter = N1qlQuery.parameterized(query, params.toJsonObject()); List data = convertToDataList(template.findByN1QLProjection(queryWithParameter, LinkedHashMap.class), clazz); Integer count = count(params); @@ -119,11 +97,11 @@ public Page find(JsonObject params, Pageable pageable, Class clazz) { return new PageImpl<>(data, pageable, count); } - public List find(JsonObject params, Class clazz) { + public List find(Parameters params, Class clazz) { CouchbaseTemplate template = createTemplate(); Statement query = createQueryStatement(params); - N1qlQuery queryWithParameter = N1qlQuery.parameterized(query, paramaterizeParams(params)); + N1qlQuery queryWithParameter = N1qlQuery.parameterized(query, params.toJsonObject()); return convertToDataList(template.findByN1QLProjection(queryWithParameter, LinkedHashMap.class), clazz); } @@ -134,28 +112,28 @@ private List convertToDataList(List queriedList, Class claz .collect(Collectors.toList()); } - public Integer count(JsonObject params) { + public Integer count(Parameters params) { CouchbaseTemplate template = createTemplate(); Statement query = createCountStatement(params); - N1qlQuery queryWithParams = N1qlQuery.parameterized(query, paramaterizeParams(params)); + N1qlQuery queryWithParams = N1qlQuery.parameterized(query, params.toJsonObject()); LinkedHashMap countMap = ((LinkedHashMap) template.findByN1QLProjection(queryWithParams, Object.class).get(0)); return ((Integer) countMap.get("count")); } - public Integer sum(JsonObject params, String field) { + public Integer sum(Parameters params, String field) { CouchbaseTemplate template = createTemplate(); Statement query = createSumStatement(params, field); - N1qlQuery queryWithParams = N1qlQuery.parameterized(query, paramaterizeParams(params)); + N1qlQuery queryWithParams = N1qlQuery.parameterized(query, params.toJsonObject()); LinkedHashMap sumMap = ((LinkedHashMap) template.findByN1QLProjection(queryWithParams, Object.class).get(0)); return ((Integer) sumMap.get("sum")); } - private Statement createCountStatement(JsonObject params) { + private Statement createCountStatement(Parameters params) { Expression bucketName = i(couchbaseConfiguration.getBucketName()); return count(bucketName) .from(bucketName) @@ -163,7 +141,7 @@ private Statement createCountStatement(JsonObject params) { .groupBy(meta(bucketName)); } - private Statement createSumStatement(JsonObject params, String field) { + private Statement createSumStatement(Parameters params, String field) { Expression bucketName = i(couchbaseConfiguration.getBucketName()); return sum(bucketName, field) .from(bucketName) @@ -171,7 +149,7 @@ private Statement createSumStatement(JsonObject params, String field) { .groupBy(meta(bucketName)); } - private Statement createQueryStatement(JsonObject params, Pageable pageable) { + private Statement createQueryStatement(Parameters params, Pageable pageable) { Expression bucketName = i(couchbaseConfiguration.getBucketName()); return selectWithMeta(bucketName) .from(bucketName) @@ -181,7 +159,7 @@ private Statement createQueryStatement(JsonObject params, Pageable pageable) { .offset(pageable.getOffset()); } - private Statement createQueryStatement(JsonObject params) { + private Statement createQueryStatement(Parameters params) { Expression bucketName = i(couchbaseConfiguration.getBucketName()); return selectWithMeta(bucketName) .from(bucketName) @@ -204,11 +182,8 @@ private String meta(Expression bucketName) { return "meta(" + bucketName + ").id"; } - private Expression composeWhere(Expression bucketName, JsonObject params) { - List expressions = params.getNames() - .stream() - .map(this::createExpression) - .collect(Collectors.toList()); + private Expression composeWhere(Expression bucketName, Parameters params) { + List expressions = params.toExpressions(); expressions.add(x("meta(" + bucketName + ").id NOT LIKE \"_sync:%\"")); @@ -218,82 +193,6 @@ private Expression composeWhere(Expression bucketName, JsonObject params) { .get(); } - private Expression createExpression(String key) { - String propertyKey = key; - key = getPropertyKey(key); - - if(key.endsWith(CONTAINS_FILTER)) { - propertyKey = propertyKey.substring(0, propertyKey.length() - CONTAINS_FILTER.length()); - return createContainsExpression(propertyKey, key); - } else if(key.endsWith(FROM_FILTER)) { - propertyKey = propertyKey.substring(0, propertyKey.length() - FROM_FILTER.length()); - return createGreaterThanOrEqualsExpression(propertyKey, key); - } else if(key.endsWith(TO_FILTER)) { - propertyKey = propertyKey.substring(0, propertyKey.length() - TO_FILTER.length()); - return createLessThanOrEqualsExpression(propertyKey, key); - } else if(key.endsWith(NOT_FILTER)) { - propertyKey = propertyKey.substring(0, propertyKey.length() - NOT_FILTER.length()); - return createNotEqualsExpression(propertyKey, key); - } else if(key.endsWith(IN_FILTER)) { - propertyKey = propertyKey.substring(0, propertyKey.length() - IN_FILTER.length()); - return createInExpression(propertyKey, key); - } else if(key.endsWith(NULL_FILTER)) { - propertyKey = propertyKey.substring(0, propertyKey.length() - NULL_FILTER.length()); - return createNullExpression(propertyKey, key); - } else if(key.endsWith(NOT_NULL_FILTER)) { - propertyKey = propertyKey.substring(0, propertyKey.length() - NOT_NULL_FILTER.length()); - return createNotNullExpression(propertyKey, key); - } else if(key.endsWith(MISSING_FILTER)) { - propertyKey = propertyKey.substring(0, propertyKey.length() - MISSING_FILTER.length()); - return createMissingExpression(propertyKey, key); - } else if(key.endsWith(NULL_OR_MISSING_FILTER)) { - propertyKey = propertyKey.substring(0, propertyKey.length() - NULL_OR_MISSING_FILTER.length()); - return createNullOrMissingExpression(propertyKey, key); - } else { - return createEqualsExpression(propertyKey, key); - } - } - - private Expression createInExpression(String propertyKey, String key) { - return x(propertyKey).in("$" + key); - } - - private Expression createGreaterThanOrEqualsExpression(String propertyKey, String key) { - return x(propertyKey).gte("$" + key); - } - - private Expression createLessThanOrEqualsExpression(String propertyKey, String key) { - return x(propertyKey).lte("$" + key); - } - - private Expression createEqualsExpression(String propertyKey, String key) { - return x(propertyKey).eq("$" + key); - } - - private Expression createNotEqualsExpression(String propertyKey, String key) { - return x(propertyKey).ne("$" + key); - } - - private Expression createContainsExpression(String propertyKey, String key) { - return x("CONTAINS(LOWER(" + propertyKey + "), LOWER($" + key + "))"); - } - - private Expression createNullExpression(String propertyKey, String key) { - return x(propertyKey + " IS NULL"); - } - - private Expression createNotNullExpression(String propertyKey, String key) { - return x(propertyKey + " IS NOT NULL"); - } - - private Expression createMissingExpression(String propertyKey, String key) { - return x(propertyKey + " IS MISSING"); - } - - private Expression createNullOrMissingExpression(String propertyKey, String key) { - return x(propertyKey + " IS NULL OR " + propertyKey + " IS MISSING"); - } - private String lowerCase(String input) { return "LOWER(" + input + ")"; } @@ -323,7 +222,7 @@ private Sort[] fromPageable(Pageable pageable) { return orderBy.toArray(new Sort[orderBy.size()]); } - private Optional asOptional(List documents, JsonObject params) { + private Optional asOptional(List documents, Parameters params) { if(documents.isEmpty()) { return Optional.empty(); } diff --git a/src/main/java/com/wanari/utils/couchbase/exceptions/NonUniqueResultException.java b/src/main/java/com/wanari/utils/couchbase/exceptions/NonUniqueResultException.java index 10f84f5..a03a58c 100644 --- a/src/main/java/com/wanari/utils/couchbase/exceptions/NonUniqueResultException.java +++ b/src/main/java/com/wanari/utils/couchbase/exceptions/NonUniqueResultException.java @@ -1,9 +1,9 @@ package com.wanari.utils.couchbase.exceptions; -import com.couchbase.client.java.document.json.JsonObject; +import com.wanari.utils.couchbase.parameter.Parameters; public class NonUniqueResultException extends RuntimeException { - public NonUniqueResultException(JsonObject params) { - super("More than one document found with params: " + params.toString()); + public NonUniqueResultException(Parameters params) { + super("More than one document found with params: " + params.toJsonObject().toString()); } } diff --git a/src/main/java/com/wanari/utils/couchbase/parameter/ExpressionMethods.java b/src/main/java/com/wanari/utils/couchbase/parameter/ExpressionMethods.java new file mode 100644 index 0000000..334998a --- /dev/null +++ b/src/main/java/com/wanari/utils/couchbase/parameter/ExpressionMethods.java @@ -0,0 +1,48 @@ +package com.wanari.utils.couchbase.parameter; + +import com.couchbase.client.java.query.dsl.Expression; + +import static com.couchbase.client.java.query.dsl.Expression.x; + +public class ExpressionMethods { + + public static Expression equals(String propertyKey, String key) { + return x(propertyKey).eq("$" + key); + } + + public static Expression notEquals(String propertyKey, String key) { + return x(propertyKey).ne("$" + key); + } + + public static Expression contains(String propertyKey, String key) { + return x("CONTAINS(LOWER(" + propertyKey + "), LOWER($" + key + "))"); + } + + public static Expression in(String propertyKey, String key) { + return x(propertyKey).in("$" + key); + } + + public static Expression greaterThanOrEquals(String propertyKey, String key) { + return x(propertyKey).gte("$" + key); + } + + public static Expression lessThanOrEquals(String propertyKey, String key) { + return x(propertyKey).lte("$" + key); + } + + public static Expression isNull(String propertyKey, String key) { + return x(propertyKey + " IS NULL"); + } + + public static Expression isNotNull(String propertyKey, String key) { + return x(propertyKey + " IS NOT NULL"); + } + + public static Expression isMissing(String propertyKey, String key) { + return x(propertyKey + " IS MISSING"); + } + + public static Expression isNullOrMissing(String propertyKey, String key) { + return x(propertyKey + " IS NULL OR " + propertyKey + " IS MISSING"); + } +} diff --git a/src/main/java/com/wanari/utils/couchbase/parameter/Parameter.java b/src/main/java/com/wanari/utils/couchbase/parameter/Parameter.java new file mode 100644 index 0000000..1d00d47 --- /dev/null +++ b/src/main/java/com/wanari/utils/couchbase/parameter/Parameter.java @@ -0,0 +1,79 @@ +package com.wanari.utils.couchbase.parameter; + +import com.couchbase.client.java.query.dsl.Expression; + +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.function.Predicate; + +public class Parameter { + private final String key; + private final String value; + private final Predicate condition; + private final BiFunction expressionMethod; + private final Function parser; + private final ParameterType type; + + public Parameter(String key, String value, Predicate condition, BiFunction expressionMethod, Function parser, ParameterType type) { + this.key = key; + this.value = value; + this.condition = condition; + this.expressionMethod = expressionMethod; + this.parser = parser; + this.type = type; + } + + public Parameter(String key, String value, Predicate condition, BiFunction expressionMethod, ParameterType type) { + this.key = key; + this.value = value; + this.condition = condition; + this.expressionMethod = expressionMethod; + this.parser = null; + this.type = type; + } + + public Parameter(String key, String value, BiFunction expressionMethod, ParameterType type) { + this.key = key; + this.value = value; + this.type = type; + this.condition = null; + this.expressionMethod = expressionMethod; + this.parser = null; + } + + public String getKey() { + return key; + } + + public T getValue() { + return parse(value); + } + + public boolean ifCondition() { + if(condition == null) { + return true; + } else { + return condition.test(value); + } + } + + public Expression toExpression() { + return expressionMethod.apply(key, getQueryKey()); + } + + private T parse(String value) { + if(parser != null) { + return parser.apply(value); + } else { + return (T) value; + } + } + + public String getQueryKey() { + if(key != null) { + return key.replaceAll("[\\\\.]", "_") + "_" + type.name(); + } else { + return null; + } + } +} diff --git a/src/main/java/com/wanari/utils/couchbase/parameter/ParameterType.java b/src/main/java/com/wanari/utils/couchbase/parameter/ParameterType.java new file mode 100644 index 0000000..acb2e3b --- /dev/null +++ b/src/main/java/com/wanari/utils/couchbase/parameter/ParameterType.java @@ -0,0 +1,14 @@ +package com.wanari.utils.couchbase.parameter; + +public enum ParameterType { + EQUALS, + NOT_EQUALS, + CONTAINS, + IN, + GREATER_THAN_OR_EQUALS, + LESS_THAN_OR_EQUALS, + IS_NULL, + IS_NOT_NULL, + IS_MISSING, + IS_MISSING_OR_NULL +} diff --git a/src/main/java/com/wanari/utils/couchbase/parameter/Parameters.java b/src/main/java/com/wanari/utils/couchbase/parameter/Parameters.java new file mode 100644 index 0000000..4c7fb1b --- /dev/null +++ b/src/main/java/com/wanari/utils/couchbase/parameter/Parameters.java @@ -0,0 +1,41 @@ +package com.wanari.utils.couchbase.parameter; + +import com.couchbase.client.java.document.json.JsonObject; +import com.couchbase.client.java.query.dsl.Expression; +import com.wanari.utils.couchbase.parameter.builder.OnPath; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class Parameters { + + private List parameters = new ArrayList<>(); + + public OnPath on(String key) { + return new OnPath(key, this); + } + + public List toExpressions() { + return parameters.stream() + .filter(Parameter::ifCondition) + .map(Parameter::toExpression) + .collect(Collectors.toList()); + } + + public JsonObject toJsonObject() { + Map map = new HashMap<>(); + + parameters.stream() + .filter(Parameter::ifCondition) + .forEach(parameter -> map.put(parameter.getQueryKey(), parameter.getValue())); + + return JsonObject.from(map); + } + + public void add(Parameter parameter) { + parameters.add(parameter); + } +} diff --git a/src/main/java/com/wanari/utils/couchbase/parameter/builder/ApplyPath.java b/src/main/java/com/wanari/utils/couchbase/parameter/builder/ApplyPath.java new file mode 100644 index 0000000..53a7b1b --- /dev/null +++ b/src/main/java/com/wanari/utils/couchbase/parameter/builder/ApplyPath.java @@ -0,0 +1,20 @@ +package com.wanari.utils.couchbase.parameter.builder; + +import com.wanari.utils.couchbase.parameter.Parameter; + +import java.util.function.Function; + +public class ApplyPath extends BasePath { + + public ApplyPath(BasePath basePath) { + super(basePath); + } + + public void andApply(Function parser) { + parameters.add(new Parameter<>(key, value, condition, expressionMethod, parser, type)); + } + + public void add() { + parameters.add(new Parameter(key, value, condition, expressionMethod, type)); + } +} diff --git a/src/main/java/com/wanari/utils/couchbase/parameter/builder/BasePath.java b/src/main/java/com/wanari/utils/couchbase/parameter/builder/BasePath.java new file mode 100644 index 0000000..0ff2eda --- /dev/null +++ b/src/main/java/com/wanari/utils/couchbase/parameter/builder/BasePath.java @@ -0,0 +1,31 @@ +package com.wanari.utils.couchbase.parameter.builder; + +import com.couchbase.client.java.query.dsl.Expression; +import com.wanari.utils.couchbase.parameter.ParameterType; +import com.wanari.utils.couchbase.parameter.Parameters; + +import java.util.function.BiFunction; +import java.util.function.Predicate; + +class BasePath { + String key; + String value; + ParameterType type; + BiFunction expressionMethod; + Predicate condition; + Parameters parameters; + + BasePath(String key, Parameters parameters) { + this.key = key; + this.parameters = parameters; + } + + BasePath(BasePath other) { + this.key = other.key; + this.value = other.value; + this.expressionMethod = other.expressionMethod; + this.condition = other.condition; + this.parameters = other.parameters; + this.type = other.type; + } +} diff --git a/src/main/java/com/wanari/utils/couchbase/parameter/builder/ExpressionPath.java b/src/main/java/com/wanari/utils/couchbase/parameter/builder/ExpressionPath.java new file mode 100644 index 0000000..4014ce3 --- /dev/null +++ b/src/main/java/com/wanari/utils/couchbase/parameter/builder/ExpressionPath.java @@ -0,0 +1,32 @@ +package com.wanari.utils.couchbase.parameter.builder; + +import com.wanari.utils.couchbase.parameter.Parameter; +import org.apache.commons.lang3.StringUtils; + +import java.util.function.Function; +import java.util.function.Predicate; + +public class ExpressionPath extends BasePath { + + ExpressionPath(BasePath other) { + super(other); + } + + public ApplyPath onlyIfNonEmpty() { + this.condition = StringUtils::isNotEmpty; + return new ApplyPath(this); + } + + public ApplyPath onlyIf(Predicate condition) { + this.condition = condition; + return new ApplyPath(this); + } + + public void andApply(Function parser) { + parameters.add(new Parameter<>(key, value, condition, expressionMethod, parser, type)); + } + + public void add() { + parameters.add(new Parameter(key, value, condition, expressionMethod, type)); + } +} diff --git a/src/main/java/com/wanari/utils/couchbase/parameter/builder/OnPath.java b/src/main/java/com/wanari/utils/couchbase/parameter/builder/OnPath.java new file mode 100644 index 0000000..1288d56 --- /dev/null +++ b/src/main/java/com/wanari/utils/couchbase/parameter/builder/OnPath.java @@ -0,0 +1,75 @@ +package com.wanari.utils.couchbase.parameter.builder; + +import com.couchbase.client.java.query.dsl.Expression; +import com.wanari.utils.couchbase.parameter.ExpressionMethods; +import com.wanari.utils.couchbase.parameter.Parameter; +import com.wanari.utils.couchbase.parameter.Parameters; + +import java.util.function.BiFunction; + +import static com.wanari.utils.couchbase.parameter.ParameterType.*; + +public class OnPath extends BasePath { + + public OnPath(String key, Parameters parameters) { + super(key, parameters); + } + + public void isNull() { + parameters.add(new Parameter(key, value, ExpressionMethods::isNull, IS_NULL)); + } + + public void isNotNull() { + parameters.add(new Parameter(key, value, ExpressionMethods::isNotNull, IS_NOT_NULL)); + } + + public void isMissing() { + parameters.add(new Parameter(key, value, ExpressionMethods::isMissing, IS_MISSING)); + } + + public void isNullOrMissing() { + parameters.add(new Parameter(key, value, ExpressionMethods::isNullOrMissing, IS_MISSING_OR_NULL)); + } + + public ExpressionPath isNot(String value) { + this.expressionMethod = ExpressionMethods::notEquals; + this.value = value; + this.type = NOT_EQUALS; + return new ExpressionPath(this); + } + + public ExpressionPath is(String value) { + this.expressionMethod = ExpressionMethods::equals; + this.value = value; + this.type = EQUALS; + return new ExpressionPath(this); + } + + public ExpressionPath contains(String value) { + this.expressionMethod = ExpressionMethods::contains; + this.value = value; + this.type = CONTAINS; + return new ExpressionPath(this); + } + + public ExpressionPath in(String value) { + this.expressionMethod = ExpressionMethods::in; + this.value = value; + this.type = IN; + return new ExpressionPath(this); + } + + public ExpressionPath from(String value) { + this.expressionMethod = ExpressionMethods::greaterThanOrEquals; + this.value = value; + this.type = GREATER_THAN_OR_EQUALS; + return new ExpressionPath(this); + } + + public ExpressionPath to(String value) { + this.expressionMethod = ExpressionMethods::lessThanOrEquals; + this.value = value; + this.type = LESS_THAN_OR_EQUALS; + return new ExpressionPath(this); + } +}