From c4491dc8b4119bc6917188b0ee95f62ae2a5cedc Mon Sep 17 00:00:00 2001 From: Subhashni Balakrishnan Date: Tue, 13 Nov 2018 19:11:29 -0800 Subject: [PATCH] DATACOUCH-413 Use parameterized queries for Query derivation Changes ------- - N1ql query creators implement an interface which provides the place holder values. - The query creator uses a position index counter to inject place holders in the statement created and caches the place holder values in an array. - Repository query constructor passes the generated query statement and place holder values to query through the SDK. - Cleanup N1ql integration tests for count validation and also add couple of more tests Results ------- The testing for changes are already covered under the modified existing tests in N1qlQueryCreator and Repository. --- .../N1qlCouchbaseRepositoryTests.java | 16 +- .../couchbase/repository/PartyRepository.java | 2 + .../ReactiveN1qlCouchbaseRepositoryTests.java | 12 +- .../repository/ReactivePartyRepository.java | 2 + .../query/AbstractN1qlBasedQuery.java | 1 + .../query/N1qlMutateQueryCreator.java | 17 +- .../repository/query/N1qlQueryCreator.java | 15 +- .../query/PartTreeN1qlBasedQuery.java | 18 +- .../query/PartTreeN1qlQueryCreator.java | 30 ++ .../query/ReactivePartTreeN1qlBasedQuery.java | 5 +- .../query/support/N1qlQueryCreatorUtils.java | 135 ++++-- .../query/N1qlQueryCreatorTest.java | 452 ++++++++++++------ .../query/PartTreeN1qBasedQueryTest.java | 5 +- 13 files changed, 492 insertions(+), 218 deletions(-) create mode 100644 src/main/java/org/springframework/data/couchbase/repository/query/PartTreeN1qlQueryCreator.java diff --git a/src/integration/java/org/springframework/data/couchbase/repository/N1qlCouchbaseRepositoryTests.java b/src/integration/java/org/springframework/data/couchbase/repository/N1qlCouchbaseRepositoryTests.java index 7c73b587..646ed179 100644 --- a/src/integration/java/org/springframework/data/couchbase/repository/N1qlCouchbaseRepositoryTests.java +++ b/src/integration/java/org/springframework/data/couchbase/repository/N1qlCouchbaseRepositoryTests.java @@ -129,7 +129,7 @@ public class N1qlCouchbaseRepositoryTests { Pageable pageable = new PageRequest(0, 8); Page page1 = repository.findAll(pageable); - assertEquals(17, page1.getTotalElements()); //12 generated parties + 5 specifically crafted party + assertTrue("Query for parties should be atleast 12", page1.getTotalElements() >= 12); assertEquals(8, page1.getNumberOfElements()); } @@ -138,7 +138,7 @@ public class N1qlCouchbaseRepositoryTests { Pageable pageable = new PageRequest(0, 8, Sort.Direction.DESC, "attendees"); Page page1 = repository.findAll(pageable); - assertEquals(17, page1.getTotalElements()); //12 generated parties + 5 specifically crafted party + assertTrue("Query for parties should be atleast 12", page1.getTotalElements() >= 12); assertEquals(8, page1.getNumberOfElements()); List parties = page1.getContent(); @@ -161,7 +161,7 @@ public class N1qlCouchbaseRepositoryTests { public void shouldPageWithStringBasedQuery() { Pageable pageable = new PageRequest(0, 8, Sort.Direction.DESC, "attendees"); Page page1 = partyRepository.findPartiesWithAttendee(1, pageable); - assertEquals(16, page1.getTotalElements()); //12 generated parties + 4 specifically crafted party + assertTrue("Query for parties with attendees should be atleast 12", page1.getTotalElements() >= 12); assertEquals(8, page1.getNumberOfElements()); List parties = page1.getContent(); @@ -187,7 +187,7 @@ public class N1qlCouchbaseRepositoryTests { @Test(expected = MappingInstantiationException.class) public void shouldFailWithMissingFilterStringBasedQuery() { Sort sort = new Sort(Sort.Direction.DESC, "attendees"); - List parties = partyRepository.findParties(sort); + partyRepository.findParties(sort); } @Test @@ -209,4 +209,12 @@ public class N1qlCouchbaseRepositoryTests { assertTrue(partyList.size() == 1); assertEquals("Key mismatch", partyList.get(0).getKey(), key); } + + @Test + public void testN1qlQueryWithInvalidValue() { + partyRepository.save(new Party("testN1qlQueryWithInvalidValue", "", "testN1qlQueryWithInvalidValue", null, 0, null)); + final String description = "testN1qlQueryWithInvalidValue* OR `description` LIKE \"\""; + List partyList = partyRepository.findByDescriptionStartingWith(description); + assertTrue(partyList.size() == 0); + } } diff --git a/src/integration/java/org/springframework/data/couchbase/repository/PartyRepository.java b/src/integration/java/org/springframework/data/couchbase/repository/PartyRepository.java index 355346d1..64e45e82 100644 --- a/src/integration/java/org/springframework/data/couchbase/repository/PartyRepository.java +++ b/src/integration/java/org/springframework/data/couchbase/repository/PartyRepository.java @@ -92,4 +92,6 @@ public interface PartyRepository extends CouchbaseRepository { @Query("#{#n1ql.selectEntity} where #{#n1ql.filter} and eventDate = $1") List getByEventDate(Date eventDate); + + List findByDescriptionStartingWith(String description); } diff --git a/src/integration/java/org/springframework/data/couchbase/repository/ReactiveN1qlCouchbaseRepositoryTests.java b/src/integration/java/org/springframework/data/couchbase/repository/ReactiveN1qlCouchbaseRepositoryTests.java index 8f7c10f0..4e58fc96 100644 --- a/src/integration/java/org/springframework/data/couchbase/repository/ReactiveN1qlCouchbaseRepositoryTests.java +++ b/src/integration/java/org/springframework/data/couchbase/repository/ReactiveN1qlCouchbaseRepositoryTests.java @@ -119,13 +119,13 @@ public class ReactiveN1qlCouchbaseRepositoryTests { @Test public void testCustomSpelCountQuery() { long count = partyRepository.countCustom().block(); - assertEquals("Test N1QL Spel based query", 17, count); + assertTrue("Count query for parties should be atleast 12", count >= 12); } @Test public void testPartTreeQuery() { long count = partyRepository.countAllByDescriptionNotNull().block(); - assertEquals("Test N1QL part tree based query", 17, count); + assertTrue("Count query for parties with description not null should be atleast 12", count >= 12); } @Test @@ -140,4 +140,12 @@ public class ReactiveN1qlCouchbaseRepositoryTests { assertTrue(partyList.size() == 1); assertEquals("Key mismatch", partyList.get(0).getKey(), key); } + + @Test + public void testN1qlQueryWithInvalidValue() { + partyRepository.save(new Party("testReactiveN1qlQueryWithInvalidValue", "", "testReactiveN1qlQueryWithInvalidValue", null, 0, null)); + final String description = "testReactiveN1qlQueryWithInvalidValue* OR `description` LIKE \"\""; + List partyList = partyRepository.findByDescriptionStartingWith(description).collectList().block(); + assertTrue(partyList.size() == 0); + } } diff --git a/src/integration/java/org/springframework/data/couchbase/repository/ReactivePartyRepository.java b/src/integration/java/org/springframework/data/couchbase/repository/ReactivePartyRepository.java index 7138e075..389e9d90 100644 --- a/src/integration/java/org/springframework/data/couchbase/repository/ReactivePartyRepository.java +++ b/src/integration/java/org/springframework/data/couchbase/repository/ReactivePartyRepository.java @@ -59,4 +59,6 @@ public interface ReactivePartyRepository extends ReactiveCouchbaseRepository getByEventDate(Date eventDate); + + Flux findByDescriptionStartingWith(String description); } diff --git a/src/main/java/org/springframework/data/couchbase/repository/query/AbstractN1qlBasedQuery.java b/src/main/java/org/springframework/data/couchbase/repository/query/AbstractN1qlBasedQuery.java index b5d15ecd..28c2670f 100644 --- a/src/main/java/org/springframework/data/couchbase/repository/query/AbstractN1qlBasedQuery.java +++ b/src/main/java/org/springframework/data/couchbase/repository/query/AbstractN1qlBasedQuery.java @@ -101,6 +101,7 @@ public abstract class AbstractN1qlBasedQuery implements RepositoryQuery { //prepare a count query Statement countStatement = getCount(accessor, parameters); + //the place holder values are the same for the count query as well N1qlQuery countQuery = buildQuery(countStatement, queryPlaceholderValues, getCouchbaseOperations().getDefaultConsistency().n1qlConsistency()); return processor.processResult(executeDependingOnType(query, countQuery, queryMethod, accessor.getPageable(), typeToRead)); diff --git a/src/main/java/org/springframework/data/couchbase/repository/query/N1qlMutateQueryCreator.java b/src/main/java/org/springframework/data/couchbase/repository/query/N1qlMutateQueryCreator.java index 2794d32c..2262b1e5 100644 --- a/src/main/java/org/springframework/data/couchbase/repository/query/N1qlMutateQueryCreator.java +++ b/src/main/java/org/springframework/data/couchbase/repository/query/N1qlMutateQueryCreator.java @@ -17,6 +17,10 @@ package org.springframework.data.couchbase.repository.query; import java.util.Iterator; +import java.util.concurrent.atomic.AtomicInteger; + +import com.couchbase.client.java.document.json.JsonArray; +import com.couchbase.client.java.document.json.JsonValue; import com.couchbase.client.java.query.dsl.Expression; import com.couchbase.client.java.query.dsl.path.*; import org.springframework.data.couchbase.core.convert.CouchbaseConverter; @@ -35,11 +39,13 @@ import org.springframework.data.repository.query.parser.PartTree; * * @author Subhashni Balakrishnan */ -public class N1qlMutateQueryCreator extends AbstractQueryCreator { +public class N1qlMutateQueryCreator extends AbstractQueryCreator implements PartTreeN1qlQueryCreator { private final MutateWherePath mutateFrom; private final CouchbaseConverter converter; private final CouchbaseQueryMethod queryMethod; private final ParameterAccessor accessor; + private final JsonArray placeHolderValues; + private final AtomicInteger position; public N1qlMutateQueryCreator(PartTree tree, ParameterAccessor parameters, MutateWherePath mutateFrom, CouchbaseConverter converter, CouchbaseQueryMethod queryMethod) { @@ -48,11 +54,13 @@ public class N1qlMutateQueryCreator extends AbstractQueryCreator iterator) { - return N1qlQueryCreatorUtils.prepareExpression(this.converter, part, iterator); + return N1qlQueryCreatorUtils.prepareExpression(this.converter, part, iterator, this.position, this.placeHolderValues); } @Override @@ -74,4 +82,9 @@ public class N1qlMutateQueryCreator extends AbstractQueryCreator { - +public class N1qlQueryCreator extends AbstractQueryCreator implements PartTreeN1qlQueryCreator { private final WherePath selectFrom; private final CouchbaseConverter converter; private final CouchbaseQueryMethod queryMethod; private final ParameterAccessor accessor; + private final JsonArray placeHolderValues; + private final AtomicInteger position; public N1qlQueryCreator(PartTree tree, ParameterAccessor parameters, WherePath selectFrom, CouchbaseConverter converter, CouchbaseQueryMethod queryMethod) { @@ -97,11 +100,13 @@ public class N1qlQueryCreator extends AbstractQueryCreator iterator) { - return N1qlQueryCreatorUtils.prepareExpression(converter, part, iterator); + return N1qlQueryCreatorUtils.prepareExpression(converter, part, iterator, this.position, this.placeHolderValues); } @Override @@ -137,4 +142,8 @@ public class N1qlQueryCreator extends AbstractQueryCreator iterator) { + public static Expression prepareExpression(CouchbaseConverter converter, Part part, Iterator iterator, AtomicInteger position, JsonArray placeHolderValues) { PersistentPropertyPath path = N1qlUtils.getPathWithAlternativeFieldNames( converter, part.getProperty()); ConvertingIterator parameterValues = new ConvertingIterator(iterator, converter); @@ -59,68 +63,116 @@ public class N1qlQueryCreatorUtils { ignoreCase = true; } - return createExpression(part.getType(), fieldNamePath, ignoreCase, parameterValues); + return createExpression(part.getType(), fieldNamePath, ignoreCase, parameterValues, position, placeHolderValues); } - public static Expression createExpression(Part.Type partType, String fieldNamePath, boolean ignoreCase, Iterator parameterValues) { + public static Expression createExpression(Part.Type partType, String fieldNamePath, boolean ignoreCase, + Iterator parameterValues, AtomicInteger position, JsonArray placeHolderValues) { //create the left hand side of the expression, taking ignoreCase into account - Expression left = ignoreCase ? StringFunctions.lower(x(fieldNamePath)) : x(fieldNamePath); + Expression left = ignoreCase ? StringFunctions.lower(x(fieldNamePath)) : x(fieldNamePath); + Expression exp; switch (partType) { case BETWEEN: - return left.between(leftAndRight(parameterValues, ignoreCase)); + exp = left.between(x(getPlaceHolder(position, ignoreCase)).and(x(getPlaceHolder(position, ignoreCase)))); + placeHolderValues.add(getValue(parameterValues)); + placeHolderValues.add(getValue(parameterValues)); + break; case IS_NOT_NULL: - return left.isNotNull(); + exp = left.isNotNull(); + break; case IS_NULL: - return left.isNull(); + exp = left.isNull(); + break; case NEGATING_SIMPLE_PROPERTY: - return left.ne(right(parameterValues, ignoreCase)); + exp = left.ne(getPlaceHolder(position, ignoreCase)); + placeHolderValues.add(getValue(parameterValues)); + break; case SIMPLE_PROPERTY: - return left.eq(right(parameterValues, ignoreCase)); + exp = left.eq(getPlaceHolder(position, ignoreCase)); + placeHolderValues.add(getValue(parameterValues)); + break; case BEFORE: case LESS_THAN: - return left.lt(right(parameterValues, ignoreCase)); + exp = left.lt(getPlaceHolder(position, ignoreCase)); + placeHolderValues.add(getValue(parameterValues)); + break; case LESS_THAN_EQUAL: - return left.lte(right(parameterValues, ignoreCase)); + exp = left.lte(getPlaceHolder(position, ignoreCase)); + placeHolderValues.add(getValue(parameterValues)); + break; case GREATER_THAN_EQUAL: - return left.gte(right(parameterValues, ignoreCase)); + exp = left.gte(getPlaceHolder(position, ignoreCase)); + placeHolderValues.add(getValue(parameterValues)); + break; case AFTER: case GREATER_THAN: - return left.gt(right(parameterValues, ignoreCase)); + exp = left.gt(getPlaceHolder(position, ignoreCase)); + placeHolderValues.add(getValue(parameterValues)); + break; case NOT_LIKE: - return left.notLike(right(parameterValues, ignoreCase)); + exp = left.notLike(getPlaceHolder(position, ignoreCase)); + placeHolderValues.add(getValue(parameterValues)); + break; case LIKE: - return left.like(right(parameterValues, ignoreCase)); + exp = left.like(getPlaceHolder(position, ignoreCase)); + placeHolderValues.add(getValue(parameterValues)); + break; case STARTING_WITH: - return left.like(like(parameterValues, ignoreCase, false, true)); + exp = left.like(getPlaceHolder(position, ignoreCase) + " || '%'"); + placeHolderValues.add(getValue(parameterValues)); + break; case ENDING_WITH: - return left.like(like(parameterValues, ignoreCase, true, false)); + exp = left.like("'%' || " + getPlaceHolder(position, ignoreCase)); + placeHolderValues.add(getValue(parameterValues)); + break; case NOT_CONTAINING: - return left.notLike(like(parameterValues, ignoreCase, true, true)); + exp = left.notLike("'%' || " + getPlaceHolder(position, ignoreCase) + " || '%'"); + placeHolderValues.add(getValue(parameterValues)); + break; case CONTAINING: - return left.like(like(parameterValues, ignoreCase, true, true)); + exp = left.like("'%' || " + getPlaceHolder(position, ignoreCase) + " || '%'"); + placeHolderValues.add(getValue(parameterValues)); + break; case NOT_IN: - return left.notIn(rightArray(parameterValues)); + exp = left.notIn(getPlaceHolder(position, false)); + placeHolderValues.add(getArray(parameterValues)); + break; case IN: - return left.in(rightArray(parameterValues)); + exp = left.in(getPlaceHolder(position, false)); + placeHolderValues.add(getArray(parameterValues)); + break; case TRUE: - return left.eq(true); + exp = left.eq(true); + break; case FALSE: - return left.eq(false); + exp = left.eq(false); + break; case REGEX: - return regexp(fieldNamePath, parameterValues); + exp = x("REGEXP_LIKE(" + left.toString() + ", " + getPlaceHolder(position, false) + ")"); + placeHolderValues.add(getValueAsString(parameterValues)); + break; case EXISTS: - return left.isNotMissing(); + exp = left.isNotMissing(); + break; case WITHIN: case NEAR: default: throw new IllegalArgumentException("Unsupported keyword in N1QL query derivation"); } + return exp; } + protected static String getPlaceHolder(AtomicInteger position, boolean ignoreCase) { + String placeHolder = "$" + position.getAndIncrement(); + if (ignoreCase) { + placeHolder = StringFunctions.lower(x(placeHolder)).toString(); + } + return placeHolder; + } - protected static Expression regexp(String left, Iterator parameterValues) { + protected static String getValueAsString(Iterator parameterValues) { Object next = parameterValues.next(); String pattern; @@ -129,11 +181,7 @@ public class N1qlQueryCreatorUtils { } else { pattern = String.valueOf(next); } - return PatternMatchingFunctions.regexpLike(left, pattern); - } - - protected static Expression leftAndRight(Iterator parameterValues, boolean ignoreCase) { - return right(parameterValues, ignoreCase).and(right(parameterValues, ignoreCase)); + return pattern; } protected static Expression like(Iterator parameterValues, boolean ignoreCase, @@ -164,28 +212,15 @@ public class N1qlQueryCreatorUtils { return converted; } - protected static Expression right(Iterator parameterValues, boolean ignoreCase) { + protected static Object getValue(Iterator parameterValues) { Object next = parameterValues.next(); - if (next == null) { - return Expression.NULL(); + if (next instanceof Enum) { + next = String.valueOf(next); } - - Expression converted; - if (next instanceof String) { - converted = s((String) next); - } else if (next instanceof Enum) { - converted = s(String.valueOf(next)); - } else { - converted = x(String.valueOf(next)); - } - - if (ignoreCase) { - return StringFunctions.lower(converted); - } - return converted; + return next; } - protected static JsonArray rightArray(Iterator parameterValues) { + protected static JsonArray getArray(Iterator parameterValues) { Object next = parameterValues.next(); Object[] values; @@ -198,4 +233,4 @@ public class N1qlQueryCreatorUtils { } return JsonArray.from(values); } -} +} \ No newline at end of file diff --git a/src/test/java/org/springframework/data/couchbase/repository/query/N1qlQueryCreatorTest.java b/src/test/java/org/springframework/data/couchbase/repository/query/N1qlQueryCreatorTest.java index 82aad5bf..cd67bcba 100644 --- a/src/test/java/org/springframework/data/couchbase/repository/query/N1qlQueryCreatorTest.java +++ b/src/test/java/org/springframework/data/couchbase/repository/query/N1qlQueryCreatorTest.java @@ -1,20 +1,18 @@ package org.springframework.data.couchbase.repository.query; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.*; -import static org.springframework.data.couchbase.repository.query.N1qlQueryCreator.*; - import java.util.Arrays; import java.util.Iterator; import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + +import com.couchbase.client.java.document.json.JsonArray; import com.couchbase.client.java.query.dsl.Expression; import org.junit.Test; import org.springframework.data.couchbase.repository.query.support.N1qlQueryCreatorUtils; import org.springframework.data.repository.query.parser.Part; -import com.couchbase.client.java.query.dsl.Expression; - public class N1qlQueryCreatorTest { //==== The tests below check mapping between a Part.Type and the corresponding N1QL expression ==== @@ -22,18 +20,24 @@ public class N1qlQueryCreatorTest { @Test public void testBETWEEN() throws Exception { Part.Type keyword = Part.Type.BETWEEN; - Iterator values = Arrays.asList("a", "b", 1, 2, "c", "d").iterator(); - String expected = "doc.field BETWEEN \"a\" AND \"b\""; - String expectedNum = "doc.field BETWEEN 1 AND 2"; - String expectedIgnoreCase = "LOWER(doc.field) BETWEEN LOWER(\"c\") AND LOWER(\"d\")"; + Iterator values = Arrays.asList("a", "b", 1, 2, "C", "D").iterator(); + String expected = "doc.field BETWEEN $0 AND $1"; + String expectedNum = "doc.field BETWEEN $0 AND $1"; + String expectedIgnoreCase = "LOWER(doc.field) BETWEEN LOWER($0) AND LOWER($1)"; - Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); - Expression expNum = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); - Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values); + JsonArray phexp = JsonArray.create(); + Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexp); + JsonArray phexpNum = JsonArray.create(); + Expression expNum = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexpNum); + JsonArray phexpIgnoreCase = JsonArray.create(); + Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values, new AtomicInteger(), phexpIgnoreCase); assertEquals(expected, exp.toString()); assertEquals(expectedNum, expNum.toString()); assertEquals(expectedIgnoreCase, expIgnoreCase.toString()); + assertEquals(JsonArray.create().add("a").add("b"), phexp); + assertEquals(JsonArray.create().add(1).add(2), phexpNum); + assertEquals(JsonArray.create().add("C").add("D"), phexpIgnoreCase); } @Test @@ -44,13 +48,19 @@ public class N1qlQueryCreatorTest { String expectedNum = "doc.field IS NOT NULL"; String expectedIgnoreCase = "LOWER(doc.field) IS NOT NULL"; - Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); - Expression expNum = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); - Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values); + JsonArray phexp = JsonArray.create(); + Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexp); + JsonArray phexpNum = JsonArray.create(); + Expression expNum = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexpNum); + JsonArray phexpIgnoreCase = JsonArray.create(); + Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values, new AtomicInteger(), phexpIgnoreCase); assertEquals(expected, exp.toString()); assertEquals(expectedNum, expNum.toString()); assertEquals(expectedIgnoreCase, expIgnoreCase.toString()); + assertEquals(JsonArray.create(), phexp); + assertEquals(JsonArray.create(), phexpNum); + assertEquals(JsonArray.create(), phexpIgnoreCase); } @Test @@ -61,234 +71,318 @@ public class N1qlQueryCreatorTest { String expectedNum = "doc.field IS NULL"; String expectedIgnoreCase = "LOWER(doc.field) IS NULL"; - Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); - Expression expNum = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); - Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values); + JsonArray phexp = JsonArray.create(); + Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexp); + JsonArray phexpNum = JsonArray.create(); + Expression expNum = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexpNum); + JsonArray phexpIgnoreCase = JsonArray.create(); + Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values, new AtomicInteger(), phexpIgnoreCase); assertEquals(expected, exp.toString()); assertEquals(expectedNum, expNum.toString()); assertEquals(expectedIgnoreCase, expIgnoreCase.toString()); + assertEquals(JsonArray.create(), phexp); + assertEquals(JsonArray.create(), phexpNum); + assertEquals(JsonArray.create(), phexpIgnoreCase); } @Test public void testLESS_THAN() throws Exception { Part.Type keyword = Part.Type.LESS_THAN; Iterator values = Arrays.asList("a", 1, "b").iterator(); - String expected = "doc.field < \"a\""; - String expectedNum = "doc.field < 1"; - String expectedIgnoreCase = "LOWER(doc.field) < LOWER(\"b\")"; + String expected = "doc.field < $0"; + String expectedNum = "doc.field < $0"; + String expectedIgnoreCase = "LOWER(doc.field) < LOWER($0)"; - Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); - Expression expNum = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); - Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values); + JsonArray phexp = JsonArray.create(); + Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexp); + JsonArray phexpNum = JsonArray.create(); + Expression expNum = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexpNum); + JsonArray phexpIgnoreCase = JsonArray.create(); + Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values, new AtomicInteger(), phexpIgnoreCase); assertEquals(expected, exp.toString()); assertEquals(expectedNum, expNum.toString()); assertEquals(expectedIgnoreCase, expIgnoreCase.toString()); + assertEquals(JsonArray.create().add("a"), phexp); + assertEquals(JsonArray.create().add(1), phexpNum); + assertEquals(JsonArray.create().add("b"), phexpIgnoreCase); } @Test public void testLESS_THAN_EQUAL() throws Exception { Part.Type keyword = Part.Type.LESS_THAN_EQUAL; Iterator values = Arrays.asList("a", 1, "b").iterator(); - String expected = "doc.field <= \"a\""; - String expectedNum = "doc.field <= 1"; - String expectedIgnoreCase = "LOWER(doc.field) <= LOWER(\"b\")"; + String expected = "doc.field <= $0"; + String expectedNum = "doc.field <= $0"; + String expectedIgnoreCase = "LOWER(doc.field) <= LOWER($0)"; - Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); - Expression expNum = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); - Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values); + JsonArray phexp = JsonArray.create(); + Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexp); + JsonArray phexpNum = JsonArray.create(); + Expression expNum = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexpNum); + JsonArray phexpIgnoreCase = JsonArray.create(); + Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values, new AtomicInteger(), phexpIgnoreCase); assertEquals(expected, exp.toString()); assertEquals(expectedNum, expNum.toString()); assertEquals(expectedIgnoreCase, expIgnoreCase.toString()); + assertEquals(JsonArray.create().add("a"), phexp); + assertEquals(JsonArray.create().add(1), phexpNum); + assertEquals(JsonArray.create().add("b"), phexpIgnoreCase); } @Test public void testGREATER_THAN() throws Exception { Part.Type keyword = Part.Type.GREATER_THAN; Iterator values = Arrays.asList("a", 1, "b").iterator(); - String expected = "doc.field > \"a\""; - String expectedNum = "doc.field > 1"; - String expectedIgnoreCase = "LOWER(doc.field) > LOWER(\"b\")"; + String expected = "doc.field > $0"; + String expectedNum = "doc.field > $0"; + String expectedIgnoreCase = "LOWER(doc.field) > LOWER($0)"; - Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); - Expression expNum = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); - Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values); + JsonArray phexp = JsonArray.create(); + Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexp); + JsonArray phexpNum = JsonArray.create(); + Expression expNum = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexpNum); + JsonArray phexpIgnoreCase = JsonArray.create(); + Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values, new AtomicInteger(), phexpIgnoreCase); assertEquals(expected, exp.toString()); assertEquals(expectedNum, expNum.toString()); assertEquals(expectedIgnoreCase, expIgnoreCase.toString()); + assertEquals(JsonArray.create().add("a"), phexp); + assertEquals(JsonArray.create().add(1), phexpNum); + assertEquals(JsonArray.create().add("b"), phexpIgnoreCase); } @Test public void testGREATER_THAN_EQUAL() throws Exception { Part.Type keyword = Part.Type.GREATER_THAN_EQUAL; Iterator values = Arrays.asList("a", 1, "b").iterator(); - String expected = "doc.field >= \"a\""; - String expectedNum = "doc.field >= 1"; - String expectedIgnoreCase = "LOWER(doc.field) >= LOWER(\"b\")"; + String expected = "doc.field >= $0"; + String expectedNum = "doc.field >= $0"; + String expectedIgnoreCase = "LOWER(doc.field) >= LOWER($0)"; - Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); - Expression expNum = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); - Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values); + JsonArray phexp = JsonArray.create(); + Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexp); + JsonArray phexpNum = JsonArray.create(); + Expression expNum = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexpNum); + JsonArray phexpIgnoreCase = JsonArray.create(); + Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values, new AtomicInteger(), phexpIgnoreCase); assertEquals(expected, exp.toString()); assertEquals(expectedNum, expNum.toString()); assertEquals(expectedIgnoreCase, expIgnoreCase.toString()); + assertEquals(JsonArray.create().add("a"), phexp); + assertEquals(JsonArray.create().add(1), phexpNum); + assertEquals(JsonArray.create().add("b"), phexpIgnoreCase); } @Test public void testBEFORE() throws Exception { Part.Type keyword = Part.Type.BEFORE; Iterator values = Arrays.asList("a", 1, "b").iterator(); - String expected = "doc.field < \"a\""; - String expectedNum = "doc.field < 1"; - String expectedIgnoreCase = "LOWER(doc.field) < LOWER(\"b\")"; + String expected = "doc.field < $0"; + String expectedNum = "doc.field < $0"; + String expectedIgnoreCase = "LOWER(doc.field) < LOWER($0)"; - Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); - Expression expNum = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); - Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values); + JsonArray phexp = JsonArray.create(); + Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexp); + JsonArray phexpNum = JsonArray.create(); + Expression expNum = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexpNum); + JsonArray phexpIgnoreCase = JsonArray.create(); + Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values, new AtomicInteger(), phexpIgnoreCase); assertEquals(expected, exp.toString()); assertEquals(expectedNum, expNum.toString()); assertEquals(expectedIgnoreCase, expIgnoreCase.toString()); + assertEquals(JsonArray.create().add("a"), phexp); + assertEquals(JsonArray.create().add(1), phexpNum); + assertEquals(JsonArray.create().add("b"), phexpIgnoreCase); } @Test public void testAFTER() throws Exception { Part.Type keyword = Part.Type.AFTER; Iterator values = Arrays.asList("a", 1, "b").iterator(); - String expected = "doc.field > \"a\""; - String expectedNum = "doc.field > 1"; - String expectedIgnoreCase = "LOWER(doc.field) > LOWER(\"b\")"; + String expected = "doc.field > $0"; + String expectedNum = "doc.field > $0"; + String expectedIgnoreCase = "LOWER(doc.field) > LOWER($0)"; - Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); - Expression expNum = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); - Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values); + JsonArray phexp = JsonArray.create(); + Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexp); + JsonArray phexpNum = JsonArray.create(); + Expression expNum = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexpNum); + JsonArray phexpIgnoreCase = JsonArray.create(); + Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values, new AtomicInteger(), phexpIgnoreCase); assertEquals(expected, exp.toString()); assertEquals(expectedNum, expNum.toString()); assertEquals(expectedIgnoreCase, expIgnoreCase.toString()); + assertEquals(JsonArray.create().add("a"), phexp); + assertEquals(JsonArray.create().add(1), phexpNum); + assertEquals(JsonArray.create().add("b"), phexpIgnoreCase); } @Test public void testNOT_LIKE() throws Exception { Part.Type keyword = Part.Type.NOT_LIKE; Iterator values = Arrays.asList("a", 1, "b").iterator(); - String expected = "doc.field NOT LIKE \"a\""; - String expectedNum = "doc.field NOT LIKE 1"; - String expectedIgnoreCase = "LOWER(doc.field) NOT LIKE LOWER(\"b\")"; + String expected = "doc.field NOT LIKE $0"; + String expectedNum = "doc.field NOT LIKE $0"; + String expectedIgnoreCase = "LOWER(doc.field) NOT LIKE LOWER($0)"; - Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); - Expression expNum = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); - Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values); + JsonArray phexp = JsonArray.create(); + Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexp); + JsonArray phexpNum = JsonArray.create(); + Expression expNum = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexpNum); + JsonArray phexpIgnoreCase = JsonArray.create(); + Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values, new AtomicInteger(), phexpIgnoreCase); assertEquals(expected, exp.toString()); assertEquals(expectedNum, expNum.toString()); assertEquals(expectedIgnoreCase, expIgnoreCase.toString()); + assertEquals(JsonArray.create().add("a"), phexp); + assertEquals(JsonArray.create().add(1), phexpNum); + assertEquals(JsonArray.create().add("b"), phexpIgnoreCase); } @Test public void testLIKE() throws Exception { Part.Type keyword = Part.Type.LIKE; Iterator values = Arrays.asList("a", 1, "b").iterator(); - String expected = "doc.field LIKE \"a\""; - String expectedNum = "doc.field LIKE 1"; - String expectedIgnoreCase = "LOWER(doc.field) LIKE LOWER(\"b\")"; + String expected = "doc.field LIKE $0"; + String expectedNum = "doc.field LIKE $0"; + String expectedIgnoreCase = "LOWER(doc.field) LIKE LOWER($0)"; - Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); - Expression expNum = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); - Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values); + JsonArray phexp = JsonArray.create(); + Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexp); + JsonArray phexpNum = JsonArray.create(); + Expression expNum = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexpNum); + JsonArray phexpIgnoreCase = JsonArray.create(); + Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values, new AtomicInteger(), phexpIgnoreCase); assertEquals(expected, exp.toString()); assertEquals(expectedNum, expNum.toString()); assertEquals(expectedIgnoreCase, expIgnoreCase.toString()); + assertEquals(JsonArray.create().add("a"), phexp); + assertEquals(JsonArray.create().add(1), phexpNum); + assertEquals(JsonArray.create().add("b"), phexpIgnoreCase); } @Test public void testSTARTING_WITH() throws Exception { Part.Type keyword = Part.Type.STARTING_WITH; Iterator values = Arrays.asList("a", 1, "b").iterator(); - String expected = "doc.field LIKE \"a%\""; - String expectedNum = "doc.field LIKE 1"; - String expectedIgnoreCase = "LOWER(doc.field) LIKE LOWER(\"b%\")"; + String expected = "doc.field LIKE $0 || '%'"; + String expectedNum = "doc.field LIKE $0 || '%'"; + String expectedIgnoreCase = "LOWER(doc.field) LIKE LOWER($0) || '%'"; - Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); - Expression expNum = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); - Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values); + JsonArray phexp = JsonArray.create(); + Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexp); + JsonArray phexpNum = JsonArray.create(); + Expression expNum = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexpNum); + JsonArray phexpIgnoreCase = JsonArray.create(); + Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values, new AtomicInteger(), phexpIgnoreCase); assertEquals(expected, exp.toString()); assertEquals(expectedNum, expNum.toString()); assertEquals(expectedIgnoreCase, expIgnoreCase.toString()); + assertEquals(JsonArray.create().add("a"), phexp); + assertEquals(JsonArray.create().add(1), phexpNum); + assertEquals(JsonArray.create().add("b"), phexpIgnoreCase); } @Test public void testENDING_WITH() throws Exception { Part.Type keyword = Part.Type.ENDING_WITH; Iterator values = Arrays.asList("a", 1, "b").iterator(); - String expected = "doc.field LIKE \"%a\""; - String expectedNum = "doc.field LIKE 1"; - String expectedIgnoreCase = "LOWER(doc.field) LIKE LOWER(\"%b\")"; + String expected = "doc.field LIKE '%' || $0"; + String expectedNum = "doc.field LIKE '%' || $0"; + String expectedIgnoreCase = "LOWER(doc.field) LIKE '%' || LOWER($0)"; - Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); - Expression expNum = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); - Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values); + JsonArray phexp = JsonArray.create(); + Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexp); + JsonArray phexpNum = JsonArray.create(); + Expression expNum = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexpNum); + JsonArray phexpIgnoreCase = JsonArray.create(); + Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values, new AtomicInteger(), phexpIgnoreCase); assertEquals(expected, exp.toString()); assertEquals(expectedNum, expNum.toString()); assertEquals(expectedIgnoreCase, expIgnoreCase.toString()); + assertEquals(JsonArray.create().add("a"), phexp); + assertEquals(JsonArray.create().add(1), phexpNum); + assertEquals(JsonArray.create().add("b"), phexpIgnoreCase); } @Test public void testNOT_CONTAINING() throws Exception { Part.Type keyword = Part.Type.NOT_CONTAINING; Iterator values = Arrays.asList("a", 1, "b").iterator(); - String expected = "doc.field NOT LIKE \"%a%\""; - String expectedNum = "doc.field NOT LIKE 1"; - String expectedIgnoreCase = "LOWER(doc.field) NOT LIKE LOWER(\"%b%\")"; + String expected = "doc.field NOT LIKE '%' || $0 || '%'"; + String expectedNum = "doc.field NOT LIKE '%' || $0 || '%'"; + String expectedIgnoreCase = "LOWER(doc.field) NOT LIKE '%' || LOWER($0) || '%'"; - Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); - Expression expNum = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); - Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values); + JsonArray phexp = JsonArray.create(); + Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexp); + JsonArray phexpNum = JsonArray.create(); + Expression expNum = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexpNum); + JsonArray phexpIgnoreCase = JsonArray.create(); + Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values, new AtomicInteger(), phexpIgnoreCase); assertEquals(expected, exp.toString()); assertEquals(expectedNum, expNum.toString()); assertEquals(expectedIgnoreCase, expIgnoreCase.toString()); + assertEquals(JsonArray.create().add("a"), phexp); + assertEquals(JsonArray.create().add(1), phexpNum); + assertEquals(JsonArray.create().add("b"), phexpIgnoreCase); } @Test public void testCONTAINING() throws Exception { Part.Type keyword = Part.Type.CONTAINING; Iterator values = Arrays.asList("a", 1, "b").iterator(); - String expected = "doc.field LIKE \"%a%\""; - String expectedNum = "doc.field LIKE 1"; - String expectedIgnoreCase = "LOWER(doc.field) LIKE LOWER(\"%b%\")"; + String expected = "doc.field LIKE '%' || $0 || '%'"; + String expectedNum = "doc.field LIKE '%' || $0 || '%'"; + String expectedIgnoreCase = "LOWER(doc.field) LIKE '%' || LOWER($0) || '%'"; - Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); - Expression expNum = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); - Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values); + JsonArray phexp = JsonArray.create(); + Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexp); + JsonArray phexpNum = JsonArray.create(); + Expression expNum = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexpNum); + JsonArray phexpIgnoreCase = JsonArray.create(); + Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values, new AtomicInteger(), phexpIgnoreCase); assertEquals(expected, exp.toString()); assertEquals(expectedNum, expNum.toString()); assertEquals(expectedIgnoreCase, expIgnoreCase.toString()); + assertEquals(JsonArray.create().add("a"), phexp); + assertEquals(JsonArray.create().add(1), phexpNum); + assertEquals(JsonArray.create().add("b"), phexpIgnoreCase); } @Test public void testNOT_IN() throws Exception { Part.Type keyword = Part.Type.NOT_IN; Iterator values = Arrays.asList("a", 1, "b").iterator(); - String expected = "doc.field NOT IN [\"a\"]"; - String expectedNum = "doc.field NOT IN [1]"; - String expectedIgnoreCase = "LOWER(doc.field) NOT IN [\"b\"]"; + String expected = "doc.field NOT IN $0"; + String expectedNum = "doc.field NOT IN $0"; + String expectedIgnoreCase = "LOWER(doc.field) NOT IN $0"; - Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); - Expression expNum = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); - Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values); + JsonArray phexp = JsonArray.create(); + Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexp); + JsonArray phexpNum = JsonArray.create(); + Expression expNum = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexpNum); + JsonArray phexpIgnoreCase = JsonArray.create(); + Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values, new AtomicInteger(), phexpIgnoreCase); assertEquals(expected, exp.toString()); assertEquals(expectedNum, expNum.toString()); assertEquals(expectedIgnoreCase, expIgnoreCase.toString()); + assertEquals(JsonArray.create().add(JsonArray.create().add("a")), phexp); + assertEquals(JsonArray.create().add(JsonArray.create().add(1)), phexpNum); + assertEquals(JsonArray.create().add(JsonArray.create().add("b")), phexpIgnoreCase); } @Test @@ -297,14 +391,18 @@ public class N1qlQueryCreatorTest { List val1 = Arrays.asList("av1", "av2"); List val2 = Arrays.asList("bv1", "bv2"); Iterator values = Arrays.asList(val1, val2).iterator(); - String expected = "doc.field NOT IN [\"av1\",\"av2\"]"; - String expectedIgnoreCase = "LOWER(doc.field) NOT IN [\"bv1\",\"bv2\"]"; + String expected = "doc.field NOT IN $0"; + String expectedIgnoreCase = "LOWER(doc.field) NOT IN $0"; - Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); - Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values); + JsonArray phexp = JsonArray.create(); + Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexp); + JsonArray phexpIgnoreCase = JsonArray.create(); + Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values, new AtomicInteger(), phexpIgnoreCase); assertEquals(expected, exp.toString()); assertEquals(expectedIgnoreCase, expIgnoreCase.toString()); + assertEquals(JsonArray.create().add(JsonArray.create().add("av1").add("av2")), phexp); + assertEquals(JsonArray.create().add(JsonArray.create().add("bv1").add("bv2")), phexpIgnoreCase); } @Test @@ -313,31 +411,41 @@ public class N1qlQueryCreatorTest { String[] val1 = {"av1", "av2"}; String[] val2 = {"bv1", "bv2"}; Iterator values = Arrays.asList(val1, val2).iterator(); - String expected = "doc.field NOT IN [\"av1\",\"av2\"]"; - String expectedIgnoreCase = "LOWER(doc.field) NOT IN [\"bv1\",\"bv2\"]"; + String expected = "doc.field NOT IN $0"; + String expectedIgnoreCase = "LOWER(doc.field) NOT IN $0"; - Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); - Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values); + JsonArray phexp = JsonArray.create(); + Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexp); + JsonArray phexpIgnoreCase = JsonArray.create(); + Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values, new AtomicInteger(), phexpIgnoreCase); assertEquals(expected, exp.toString()); assertEquals(expectedIgnoreCase, expIgnoreCase.toString()); + assertEquals(JsonArray.create().add(JsonArray.create().add("av1").add("av2")), phexp); + assertEquals(JsonArray.create().add(JsonArray.create().add("bv1").add("bv2")), phexpIgnoreCase); } @Test public void testIN() throws Exception { Part.Type keyword = Part.Type.IN; Iterator values = Arrays.asList("a", 1, "b").iterator(); - String expected = "doc.field IN [\"a\"]"; - String expectedNum = "doc.field IN [1]"; - String expectedIgnoreCase = "LOWER(doc.field) IN [\"b\"]"; + String expected = "doc.field IN $0"; + String expectedNum = "doc.field IN $0"; + String expectedIgnoreCase = "LOWER(doc.field) IN $0"; - Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); - Expression expNum = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); - Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values); + JsonArray phexp = JsonArray.create(); + Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexp); + JsonArray phexpNum = JsonArray.create(); + Expression expNum = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexpNum); + JsonArray phexpIgnoreCase = JsonArray.create(); + Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values, new AtomicInteger(), phexpIgnoreCase); assertEquals(expected, exp.toString()); assertEquals(expectedNum, expNum.toString()); assertEquals(expectedIgnoreCase, expIgnoreCase.toString()); + assertEquals(JsonArray.create().add(JsonArray.create().add("a")), phexp); + assertEquals(JsonArray.create().add(JsonArray.create().add(1)), phexpNum); + assertEquals(JsonArray.create().add(JsonArray.create().add("b")), phexpIgnoreCase); } @Test @@ -346,14 +454,18 @@ public class N1qlQueryCreatorTest { List val1 = Arrays.asList("av1", "av2"); List val2 = Arrays.asList("bv1", "bv2"); Iterator values = Arrays.asList(val1, val2).iterator(); - String expected = "doc.field IN [\"av1\",\"av2\"]"; - String expectedIgnoreCase = "LOWER(doc.field) IN [\"bv1\",\"bv2\"]"; + String expected = "doc.field IN $0"; + String expectedIgnoreCase = "LOWER(doc.field) IN $0"; - Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); - Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values); + JsonArray phexp = JsonArray.create(); + Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexp); + JsonArray phexpIgnoreCase = JsonArray.create(); + Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values, new AtomicInteger(), phexpIgnoreCase); assertEquals(expected, exp.toString()); assertEquals(expectedIgnoreCase, expIgnoreCase.toString()); + assertEquals(JsonArray.create().add(JsonArray.create().add("av1").add("av2")), phexp); + assertEquals(JsonArray.create().add(JsonArray.create().add("bv1").add("bv2")), phexpIgnoreCase); } @Test @@ -362,14 +474,18 @@ public class N1qlQueryCreatorTest { String[] val1 = {"av1", "av2"}; String[] val2 = {"bv1", "bv2"}; Iterator values = Arrays.asList(val1, val2).iterator(); - String expected = "doc.field IN [\"av1\",\"av2\"]"; - String expectedIgnoreCase = "LOWER(doc.field) IN [\"bv1\",\"bv2\"]"; + String expected = "doc.field IN $0"; + String expectedIgnoreCase = "LOWER(doc.field) IN $0"; - Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); - Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values); + JsonArray phexp = JsonArray.create(); + Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexp); + JsonArray phexpIgnoreCase = JsonArray.create(); + Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values, new AtomicInteger(), phexpIgnoreCase); assertEquals(expected, exp.toString()); assertEquals(expectedIgnoreCase, expIgnoreCase.toString()); + assertEquals(JsonArray.create().add(JsonArray.create().add("av1").add("av2")), phexp); + assertEquals(JsonArray.create().add(JsonArray.create().add("bv1").add("bv2")), phexpIgnoreCase); } @Test(expected = IllegalArgumentException.class) @@ -377,7 +493,7 @@ public class N1qlQueryCreatorTest { Part.Type keyword = Part.Type.NEAR; Iterator values = Arrays.asList("a", 1, "b").iterator(); - Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values); + Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values, new AtomicInteger(), JsonArray.create());; } @Test(expected = IllegalArgumentException.class) @@ -385,24 +501,30 @@ public class N1qlQueryCreatorTest { Part.Type keyword = Part.Type.WITHIN; Iterator values = Arrays.asList("a", 1, "b").iterator(); - Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); + Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), JsonArray.create());; } @Test public void testREGEX() throws Exception { Part.Type keyword = Part.Type.REGEX; Iterator values = Arrays.asList("a", 1, "b").iterator(); - String expected = "REGEXP_LIKE(doc.field, \"a\")"; - String expectedNum = "REGEXP_LIKE(doc.field, \"1\")"; - String expectedIgnoreCase = "REGEXP_LIKE(doc.field, \"b\")"; + String expected = "REGEXP_LIKE(doc.field, $0)"; + String expectedNum = "REGEXP_LIKE(doc.field, $0)"; + String expectedIgnoreCase = "REGEXP_LIKE(LOWER(doc.field), $0)"; - Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); - Expression expNum = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); - Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values); + JsonArray phexp = JsonArray.create(); + Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexp); + JsonArray phexpNum = JsonArray.create(); + Expression expNum = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexpNum); + JsonArray phexpIgnoreCase = JsonArray.create(); + Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values, new AtomicInteger(), phexpIgnoreCase); assertEquals(expected, exp.toString()); assertEquals(expectedNum, expNum.toString()); assertEquals(expectedIgnoreCase, expIgnoreCase.toString()); + assertEquals(JsonArray.create().add("a"), phexp); + assertEquals(JsonArray.create().add("1"), phexpNum); + assertEquals(JsonArray.create().add("b"), phexpIgnoreCase); } @Test @@ -413,13 +535,19 @@ public class N1qlQueryCreatorTest { String expectedNum = "doc.field IS NOT MISSING"; String expectedIgnoreCase = "LOWER(doc.field) IS NOT MISSING"; - Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); - Expression expNum = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); - Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values); + JsonArray phexp = JsonArray.create(); + Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexp); + JsonArray phexpNum = JsonArray.create(); + Expression expNum = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexpNum); + JsonArray phexpIgnoreCase = JsonArray.create(); + Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values, new AtomicInteger(), phexpIgnoreCase); assertEquals(expected, exp.toString()); assertEquals(expectedNum, expNum.toString()); assertEquals(expectedIgnoreCase, expIgnoreCase.toString()); + assertEquals(JsonArray.create(), phexp); + assertEquals(JsonArray.create(), phexpNum); + assertEquals(JsonArray.create(), phexpIgnoreCase); } @Test @@ -430,13 +558,19 @@ public class N1qlQueryCreatorTest { String expectedNum = "doc.field = TRUE"; String expectedIgnoreCase = "LOWER(doc.field) = TRUE"; - Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); - Expression expNum = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); - Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values); + JsonArray phexp = JsonArray.create(); + Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexp); + JsonArray phexpNum = JsonArray.create(); + Expression expNum = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexpNum); + JsonArray phexpIgnoreCase = JsonArray.create(); + Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values, new AtomicInteger(), phexpIgnoreCase); assertEquals(expected, exp.toString()); assertEquals(expectedNum, expNum.toString()); assertEquals(expectedIgnoreCase, expIgnoreCase.toString()); + assertEquals(JsonArray.create(), phexp); + assertEquals(JsonArray.create(), phexpNum); + assertEquals(JsonArray.create(), phexpIgnoreCase); } @Test @@ -447,30 +581,42 @@ public class N1qlQueryCreatorTest { String expectedNum = "doc.field = FALSE"; String expectedIgnoreCase = "LOWER(doc.field) = FALSE"; - Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); - Expression expNum = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); - Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values); + JsonArray phexp = JsonArray.create(); + Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexp); + JsonArray phexpNum = JsonArray.create(); + Expression expNum = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexpNum); + JsonArray phexpIgnoreCase = JsonArray.create(); + Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values, new AtomicInteger(), phexpIgnoreCase); assertEquals(expected, exp.toString()); assertEquals(expectedNum, expNum.toString()); assertEquals(expectedIgnoreCase, expIgnoreCase.toString()); + assertEquals(JsonArray.create(), phexp); + assertEquals(JsonArray.create(), phexpNum); + assertEquals(JsonArray.create(), phexpIgnoreCase); } @Test public void testNEGATING_SIMPLE_PROPERTY() throws Exception { Part.Type keyword = Part.Type.NEGATING_SIMPLE_PROPERTY; Iterator values = Arrays.asList("a", 1, "b").iterator(); - String expected = "doc.field != \"a\""; - String expectedNum = "doc.field != 1"; - String expectedIgnoreCase = "LOWER(doc.field) != LOWER(\"b\")"; + String expected = "doc.field != $0"; + String expectedNum = "doc.field != $0"; + String expectedIgnoreCase = "LOWER(doc.field) != LOWER($0)"; - Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); - Expression expNum = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); - Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values); + JsonArray phexp = JsonArray.create(); + Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexp); + JsonArray phexpNum = JsonArray.create(); + Expression expNum = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexpNum); + JsonArray phexpIgnoreCase = JsonArray.create(); + Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values, new AtomicInteger(), phexpIgnoreCase); assertEquals(expected, exp.toString()); assertEquals(expectedNum, expNum.toString()); assertEquals(expectedIgnoreCase, expIgnoreCase.toString()); + assertEquals(JsonArray.create().add("a"), phexp); + assertEquals(JsonArray.create().add(1), phexpNum); + assertEquals(JsonArray.create().add("b"), phexpIgnoreCase); } enum TestEnum { @@ -481,19 +627,27 @@ public class N1qlQueryCreatorTest { public void testSIMPLE_PROPERTY() throws Exception { Part.Type keyword = Part.Type.SIMPLE_PROPERTY; Iterator values = Arrays.asList("a", 1, "b", TestEnum.TEST).iterator(); - String expected = "doc.field = \"a\""; - String expectedNum = "doc.field = 1"; - String expectedIgnoreCase = "LOWER(doc.field) = LOWER(\"b\")"; - String expectedEnum = "doc.field = \"TEST\""; + String expected = "doc.field = $0"; + String expectedNum = "doc.field = $0"; + String expectedIgnoreCase = "LOWER(doc.field) = LOWER($0)"; + String expectedEnum = "doc.field = $0"; - Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); - Expression expNum = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); - Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values); - Expression expEnum = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values); + JsonArray phexp = JsonArray.create(); + Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexp); + JsonArray phexpNum = JsonArray.create(); + Expression expNum = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexpNum); + JsonArray phexpIgnoreCase = JsonArray.create(); + Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values, new AtomicInteger(), phexpIgnoreCase); + JsonArray phexpEnum = JsonArray.create(); + Expression expEnum = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values, new AtomicInteger(), phexpEnum); assertEquals(expected, exp.toString()); assertEquals(expectedNum, expNum.toString()); assertEquals(expectedIgnoreCase, expIgnoreCase.toString()); assertEquals(expectedEnum, expEnum.toString()); + assertEquals(JsonArray.create().add("a"), phexp); + assertEquals(JsonArray.create().add(1), phexpNum); + assertEquals(JsonArray.create().add("b"), phexpIgnoreCase); + assertEquals(JsonArray.create().add("TEST"), phexpEnum); } } \ No newline at end of file diff --git a/src/test/java/org/springframework/data/couchbase/repository/query/PartTreeN1qBasedQueryTest.java b/src/test/java/org/springframework/data/couchbase/repository/query/PartTreeN1qBasedQueryTest.java index 5d5a45b1..1f08649a 100644 --- a/src/test/java/org/springframework/data/couchbase/repository/query/PartTreeN1qBasedQueryTest.java +++ b/src/test/java/org/springframework/data/couchbase/repository/query/PartTreeN1qBasedQueryTest.java @@ -26,6 +26,7 @@ import java.util.Collection; import java.util.List; import java.util.Optional; +import com.couchbase.client.java.document.json.JsonObject; import org.junit.Test; import org.springframework.core.convert.converter.Converter; import org.springframework.data.couchbase.core.Beer; @@ -99,7 +100,7 @@ public class PartTreeN1qBasedQueryTest { PartTreeN1qlBasedQuery query = new PartTreeN1qlBasedQuery(queryMethod, couchbaseOperations); Statement statement = query.getCount(accessor, new Object[] { "value", pr }); - assertEquals("SELECT COUNT(*) AS count FROM `default` WHERE (name = \"value\") " + assertEquals("SELECT COUNT(*) AS count FROM `default` WHERE (name = $1) " + "AND `_class` = \"org.springframework.data.couchbase.core.Beer\"", statement.toString()); } @@ -144,7 +145,7 @@ public class PartTreeN1qBasedQueryTest { PartTreeN1qlBasedQuery query = new PartTreeN1qlBasedQuery(queryMethod, couchbaseOperations); Statement statement = query.getCount(accessor, new Object[] { "value", pr }); - assertEquals("SELECT COUNT(*) AS count FROM `default` WHERE (name = \"value\") " + assertEquals("SELECT COUNT(*) AS count FROM `default` WHERE (name = $1) " + "AND `_class` = \"org.springframework.data.couchbase.core.Beer\"", statement.toString()); }