DATACOUCH-296 Add support for delete n1ql queries
Changes to support delete query by query derivation and SpEL based queries. - Adds a N1qlMutateQueryCreator which constucts the delete query using dsl. - Adds new SpEL values delete and returning required for delete queries. Original pull request: #144.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013 the original author or authors.
|
||||
* Copyright 2013-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -45,6 +45,7 @@ import java.util.List;
|
||||
* This tests PaginAndSortingRepository features in the Couchbase connector.
|
||||
*
|
||||
* @author Simon Baslé
|
||||
* @author Subhashni Balakrishnan
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = IntegrationTestApplicationConfig.class)
|
||||
@@ -185,4 +186,12 @@ public class N1qlCouchbaseRepositoryTests {
|
||||
Sort sort = new Sort(Sort.Direction.DESC, "attendees");
|
||||
List<Party> parties = partyRepository.findParties(sort);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteQuery() {
|
||||
partyRepository.save(new Party("testDeleteQuery", "delete", "delete", null, 0, null));
|
||||
List<Party> partyList = partyRepository.removeByDescriptionOrName("delete", "delete");
|
||||
assertTrue(partyList.size() == 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -120,4 +120,19 @@ public class N1qlPlaceholderTests {
|
||||
"one over the other in findAllWithMixedParamsInQuery", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deleteQueryTest() {
|
||||
String included = "90";
|
||||
String excluded = "New Year";
|
||||
int max = 200;
|
||||
List<Party> result = partyRepository.removeWithPositionalParams(excluded, included, max);
|
||||
|
||||
assertEquals(10, result.size());
|
||||
for (Party party : result) {
|
||||
assertTrue(party.getDescription().contains(included));
|
||||
assertFalse(party.getDescription().contains(excluded));
|
||||
assertTrue(party.getAttendees() < max);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright 2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.couchbase.repository;
|
||||
|
||||
import java.util.Date;
|
||||
@@ -14,6 +30,7 @@ import org.springframework.data.repository.query.Param;
|
||||
|
||||
/**
|
||||
* @author Simon Baslé
|
||||
* @author Subhashni Balakrishnan
|
||||
*/
|
||||
@ViewIndexed(designDoc = "party", viewName = "all")
|
||||
@N1qlSecondaryIndexed(indexName = "party")
|
||||
@@ -59,10 +76,15 @@ public interface PartyRepository extends CouchbaseRepository<Party, String> {
|
||||
" AND `desc` NOT LIKE '%' || $1 || '%'")
|
||||
List<Party> findAllWithPositionalParams(String ex, String inc, long minimumAttendees);
|
||||
|
||||
@Query("#{#n1ql.delete} WHERE #{#n1ql.filter} AND `desc` LIKE '%' || $2 || '%' AND attendees < $3" +
|
||||
" AND `desc` NOT LIKE '%' || $1 || '%' #{#n1ql.returning}")
|
||||
List<Party> removeWithPositionalParams(String ex, String inc, long minimumAttendees);
|
||||
|
||||
@Query("#{#n1ql.selectEntity} WHERE #{#n1ql.filter} AND `desc` LIKE '%' || $2 || '%' AND attendees >= $3" +
|
||||
" AND `desc` NOT LIKE '%' || $1 || '%' AND `desc` != \"this is \\\"$excluded\\\"\"")
|
||||
List<Party> findAllWithPositionalParamsAndQuotedNamedParams(@Param("excluded") String ex, @Param("included") String inc, @Param("min") long min);
|
||||
|
||||
List<Party> findByDescriptionOrName(String description, String name);
|
||||
|
||||
List<Party> removeByDescriptionOrName(String description, String name);
|
||||
}
|
||||
|
||||
@@ -113,7 +113,8 @@ While the exposed methods provide you with a great variety of access patterns, v
|
||||
=== N1QL based querying
|
||||
As of version `4.0`, Couchbase Server ships with a new query language called `N1QL`. In `Spring-Data-Couchbase 2.0`, N1QL is the default way of doing queries and will allow you to fully derive queries from a method name.
|
||||
|
||||
Prerequisite is to have a N1QL-compatible cluster and to have created a PRIMARY INDEX on the bucket where the entities will be stored.
|
||||
Prerequisite is to have a N1QL-compatible cluster and to have created a PRIMARY INDEX on the bucket where the entities will be stored. DML queries
|
||||
are supported from Couchbase server version `4.1`.
|
||||
|
||||
WARNING: If it is detected at configuration time that the cluster doesn't support N1QL while there are `@Query` annotated methods or non-annotated methods in your repository interface, a `UnsupportedCouchbaseFeatureException` will be thrown.
|
||||
|
||||
@@ -142,6 +143,8 @@ A few N1QL-specific values are provided through SpEL:
|
||||
- `#n1ql.filter` in the WHERE clause adds a criteria matching the entity type with the field that Spring Data uses to store type information.
|
||||
- `#n1ql.bucket` will be replaced by the name of the bucket the entity is stored in, escaped in backticks.
|
||||
- `#n1ql.fields` will be replaced by the list of fields (eg. for a SELECT clause) necessary to reconstruct the entity.
|
||||
- `#n1ql.delete` will be replaced by the `delete from` statement.
|
||||
- `#n1ql.returning` will be replaced by returning clause needed for reconstructing entity.
|
||||
|
||||
IMPORTANT: We recommend that you always use the `selectEntity` SpEL and a WHERE clause with a `filter` SpEL (since otherwise your query could be impacted by entities from other repositories).
|
||||
|
||||
@@ -206,6 +209,15 @@ This could be useful to craft a query according to the role of the connected use
|
||||
"role = '?#{hasRole('ROLE_ADMIN') ? 'public_admin' : 'admin'}'")
|
||||
List<UserInfo> findAllAdmins(); //only ROLE_ADMIN users will see hidden admins
|
||||
----
|
||||
|
||||
Delete query example:
|
||||
[source,java]
|
||||
----
|
||||
@Query("#{#n1ql.delete} WHERE #{#n1ql.filter} AND " +
|
||||
"username = $1 #{#n1ql.returning}")
|
||||
UserInfo removeUser(String username);
|
||||
----
|
||||
|
||||
****
|
||||
|
||||
The second method uses Spring-Data's query derivation mechanism to build a N1QL query from the method name and parameters. This will produce a query looking like this: `SELECT ... FROM ... WHERE firstName = "valueOfFnameAtRuntime"`. You can combine these criteria, even do a count with a name like `countByFirstname` or a limit with a name like `findFirst3ByLastname`...
|
||||
|
||||
@@ -123,10 +123,6 @@ public abstract class AbstractN1qlBasedQuery implements RepositoryQuery {
|
||||
protected Object executeDependingOnType(N1qlQuery query, N1qlQuery countQuery, QueryMethod queryMethod,
|
||||
Pageable pageable, Class<?> typeToRead) {
|
||||
|
||||
if (queryMethod.isModifyingQuery()) {
|
||||
throw new UnsupportedOperationException("Modifying queries not yet supported");
|
||||
}
|
||||
|
||||
if (queryMethod.isPageQuery()) {
|
||||
return executePaged(query, countQuery, pageable, typeToRead);
|
||||
} else if (queryMethod.isSliceQuery()) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2015 the original author or authors
|
||||
* Copyright 2012-2017 the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -23,8 +23,11 @@ import org.springframework.data.couchbase.core.convert.CouchbaseConverter;
|
||||
/**
|
||||
* An {@link Iterator Iterator<Object>} that {@link CouchbaseConverter#convertForWriteIfNeeded(Object) converts}
|
||||
* values to their stored Class if warranted.
|
||||
*
|
||||
* @author Simon Baslé
|
||||
* @author Subhashni Balakrishnan
|
||||
*/
|
||||
class ConvertingIterator implements Iterator<Object> {
|
||||
public class ConvertingIterator implements Iterator<Object> {
|
||||
private final Iterator<Object> delegate;
|
||||
private final CouchbaseConverter converter;
|
||||
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright 2017 the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.couchbase.repository.query;
|
||||
|
||||
import java.util.Iterator;
|
||||
import com.couchbase.client.java.query.dsl.Expression;
|
||||
import com.couchbase.client.java.query.dsl.path.*;
|
||||
import org.springframework.data.couchbase.core.convert.CouchbaseConverter;
|
||||
import org.springframework.data.couchbase.repository.query.support.N1qlQueryCreatorUtils;
|
||||
import org.springframework.data.couchbase.repository.query.support.N1qlUtils;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.repository.query.ParameterAccessor;
|
||||
import org.springframework.data.repository.query.parser.AbstractQueryCreator;
|
||||
import org.springframework.data.repository.query.parser.Part;
|
||||
import org.springframework.data.repository.query.parser.PartTree;
|
||||
|
||||
/**
|
||||
* N1qlMutateQueryCreator allows to create queries for delete operations.
|
||||
*
|
||||
* See {@link N1qlQueryCreator} for part types supported
|
||||
*
|
||||
* @author Subhashni Balakrishnan
|
||||
*/
|
||||
public class N1qlMutateQueryCreator extends AbstractQueryCreator<MutateLimitPath, Expression> {
|
||||
private final MutateWherePath mutateFrom;
|
||||
private final CouchbaseConverter converter;
|
||||
private final CouchbaseQueryMethod queryMethod;
|
||||
private final ParameterAccessor accessor;
|
||||
|
||||
public N1qlMutateQueryCreator(PartTree tree, ParameterAccessor parameters, MutateWherePath mutateFrom,
|
||||
CouchbaseConverter converter, CouchbaseQueryMethod queryMethod) {
|
||||
super(tree, parameters);
|
||||
this.mutateFrom = mutateFrom;
|
||||
this.converter = converter;
|
||||
this.queryMethod = queryMethod;
|
||||
this.accessor = parameters;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Expression create(Part part, Iterator<Object> iterator) {
|
||||
return N1qlQueryCreatorUtils.prepareExpression(this.converter, part, iterator);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Expression and(Part part, Expression base, Iterator<Object> iterator) {
|
||||
if (base == null) {
|
||||
return create(part, iterator);
|
||||
}
|
||||
|
||||
return base.and(create(part, iterator));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Expression or(Expression base, Expression criteria) {
|
||||
return base.or(criteria);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MutateLimitPath complete(Expression criteria, Sort sort) {
|
||||
Expression whereCriteria = N1qlUtils.createWhereFilterForEntity(criteria, this.converter, this.queryMethod.getEntityInformation());
|
||||
return mutateFrom.where(whereCriteria);
|
||||
}
|
||||
}
|
||||
@@ -16,27 +16,19 @@
|
||||
|
||||
package org.springframework.data.couchbase.repository.query;
|
||||
|
||||
import static com.couchbase.client.java.query.dsl.Expression.s;
|
||||
import static com.couchbase.client.java.query.dsl.Expression.x;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.couchbase.client.java.document.json.JsonArray;
|
||||
import com.couchbase.client.java.query.dsl.Expression;
|
||||
import com.couchbase.client.java.query.dsl.functions.PatternMatchingFunctions;
|
||||
import com.couchbase.client.java.query.dsl.functions.StringFunctions;
|
||||
import com.couchbase.client.java.query.dsl.path.LimitPath;
|
||||
import com.couchbase.client.java.query.dsl.path.OrderByPath;
|
||||
import com.couchbase.client.java.query.dsl.path.WherePath;
|
||||
|
||||
import org.springframework.data.couchbase.core.convert.CouchbaseConverter;
|
||||
import org.springframework.data.couchbase.core.mapping.CouchbasePersistentProperty;
|
||||
import org.springframework.data.couchbase.repository.query.support.N1qlQueryCreatorUtils;
|
||||
import org.springframework.data.couchbase.repository.query.support.N1qlUtils;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.geo.GeoResult;
|
||||
import org.springframework.data.mapping.context.PersistentPropertyPath;
|
||||
import org.springframework.data.repository.query.ParameterAccessor;
|
||||
import org.springframework.data.repository.query.parser.AbstractQueryCreator;
|
||||
import org.springframework.data.repository.query.parser.Part;
|
||||
@@ -88,6 +80,7 @@ import org.springframework.data.repository.query.parser.PartTree;
|
||||
* </p>
|
||||
*
|
||||
* @author Simon Baslé
|
||||
* @author Subhashni Balakrishnan
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
public class N1qlQueryCreator extends AbstractQueryCreator<LimitPath, Expression> {
|
||||
@@ -108,7 +101,7 @@ public class N1qlQueryCreator extends AbstractQueryCreator<LimitPath, Expression
|
||||
|
||||
@Override
|
||||
protected Expression create(Part part, Iterator<Object> iterator) {
|
||||
return prepareExpression(part, iterator);
|
||||
return N1qlQueryCreatorUtils.prepareExpression(converter, part, iterator);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -144,161 +137,4 @@ public class N1qlQueryCreator extends AbstractQueryCreator<LimitPath, Expression
|
||||
return selectFromWhere;
|
||||
}
|
||||
|
||||
protected Expression prepareExpression(Part part, Iterator<Object> iterator) {
|
||||
PersistentPropertyPath<CouchbasePersistentProperty> path = N1qlUtils.getPathWithAlternativeFieldNames(
|
||||
this.converter, part.getProperty());
|
||||
ConvertingIterator parameterValues = new ConvertingIterator(iterator, converter);
|
||||
|
||||
//get the whole doted path with fieldNames instead of potentially wrong propNames
|
||||
String fieldNamePath = N1qlUtils.getDottedPathWithAlternativeFieldNames(path);
|
||||
|
||||
//deal with ignore case
|
||||
boolean ignoreCase = false;
|
||||
Class<?> leafType = converter.getWriteClassFor(path.getLeafProperty().getType());
|
||||
boolean isString = leafType == String.class;
|
||||
if (part.shouldIgnoreCase() == Part.IgnoreCaseType.WHEN_POSSIBLE) {
|
||||
ignoreCase = isString;
|
||||
} else if (part.shouldIgnoreCase() == Part.IgnoreCaseType.ALWAYS) {
|
||||
if (!isString) {
|
||||
throw new IllegalArgumentException(String.format("Part %s must be of type String but was %s", fieldNamePath, leafType));
|
||||
}
|
||||
ignoreCase = true;
|
||||
}
|
||||
|
||||
return createExpression(part.getType(), fieldNamePath, ignoreCase, parameterValues);
|
||||
}
|
||||
|
||||
protected static Expression createExpression(Part.Type partType, String fieldNamePath, boolean ignoreCase, Iterator<Object> parameterValues) {
|
||||
//create the left hand side of the expression, taking ignoreCase into account
|
||||
Expression left = ignoreCase ? StringFunctions.lower(x(fieldNamePath)) : x(fieldNamePath);
|
||||
|
||||
switch (partType) {
|
||||
case BETWEEN:
|
||||
return left.between(leftAndRight(parameterValues, ignoreCase));
|
||||
case IS_NOT_NULL:
|
||||
return left.isNotNull();
|
||||
case IS_NULL:
|
||||
return left.isNull();
|
||||
case NEGATING_SIMPLE_PROPERTY:
|
||||
return left.ne(right(parameterValues, ignoreCase));
|
||||
case SIMPLE_PROPERTY:
|
||||
return left.eq(right(parameterValues, ignoreCase));
|
||||
case BEFORE:
|
||||
case LESS_THAN:
|
||||
return left.lt(right(parameterValues, ignoreCase));
|
||||
case LESS_THAN_EQUAL:
|
||||
return left.lte(right(parameterValues, ignoreCase));
|
||||
case GREATER_THAN_EQUAL:
|
||||
return left.gte(right(parameterValues, ignoreCase));
|
||||
case AFTER:
|
||||
case GREATER_THAN:
|
||||
return left.gt(right(parameterValues, ignoreCase));
|
||||
case NOT_LIKE:
|
||||
return left.notLike(right(parameterValues, ignoreCase));
|
||||
case LIKE:
|
||||
return left.like(right(parameterValues, ignoreCase));
|
||||
case STARTING_WITH:
|
||||
return left.like(like(parameterValues, ignoreCase, false, true));
|
||||
case ENDING_WITH:
|
||||
return left.like(like(parameterValues, ignoreCase, true, false));
|
||||
case NOT_CONTAINING:
|
||||
return left.notLike(like(parameterValues, ignoreCase, true, true));
|
||||
case CONTAINING:
|
||||
return left.like(like(parameterValues, ignoreCase, true, true));
|
||||
case NOT_IN:
|
||||
return left.notIn(rightArray(parameterValues));
|
||||
case IN:
|
||||
return left.in(rightArray(parameterValues));
|
||||
case TRUE:
|
||||
return left.eq(true);
|
||||
case FALSE:
|
||||
return left.eq(false);
|
||||
case REGEX:
|
||||
return regexp(fieldNamePath, parameterValues);
|
||||
case EXISTS:
|
||||
return left.isNotMissing();
|
||||
case WITHIN:
|
||||
case NEAR:
|
||||
default:
|
||||
throw new IllegalArgumentException("Unsupported keyword in N1QL query derivation");
|
||||
}
|
||||
}
|
||||
|
||||
protected static Expression regexp(String left, Iterator<Object> parameterValues) {
|
||||
Object next = parameterValues.next();
|
||||
|
||||
String pattern;
|
||||
if (next == null) {
|
||||
pattern = "";
|
||||
} else {
|
||||
pattern = String.valueOf(next);
|
||||
}
|
||||
return PatternMatchingFunctions.regexpLike(left, pattern);
|
||||
}
|
||||
|
||||
protected static Expression leftAndRight(Iterator<Object> parameterValues, boolean ignoreCase) {
|
||||
return right(parameterValues, ignoreCase).and(right(parameterValues, ignoreCase));
|
||||
}
|
||||
|
||||
protected static Expression like(Iterator<Object> parameterValues, boolean ignoreCase,
|
||||
boolean anyPrefix, boolean anySuffix) {
|
||||
Object next = parameterValues.next();
|
||||
if (next == null) {
|
||||
return Expression.NULL();
|
||||
}
|
||||
|
||||
Expression converted;
|
||||
if (next instanceof String) {
|
||||
String pattern = (String) next;
|
||||
if (anyPrefix) {
|
||||
pattern = "%" + pattern;
|
||||
}
|
||||
if (anySuffix) {
|
||||
pattern = pattern + "%";
|
||||
}
|
||||
converted = s(pattern);
|
||||
|
||||
} else {
|
||||
converted = x(String.valueOf(next));
|
||||
}
|
||||
|
||||
if (ignoreCase) {
|
||||
return StringFunctions.lower(converted);
|
||||
}
|
||||
return converted;
|
||||
}
|
||||
|
||||
protected static Expression right(Iterator<Object> parameterValues, boolean ignoreCase) {
|
||||
Object next = parameterValues.next();
|
||||
if (next == null) {
|
||||
return Expression.NULL();
|
||||
}
|
||||
|
||||
Expression converted;
|
||||
if (next instanceof String) {
|
||||
converted = s((String) next);
|
||||
} else {
|
||||
converted = x(String.valueOf(next));
|
||||
}
|
||||
|
||||
if (ignoreCase) {
|
||||
return StringFunctions.lower(converted);
|
||||
}
|
||||
return converted;
|
||||
}
|
||||
|
||||
protected static JsonArray rightArray(Iterator<Object> parameterValues) {
|
||||
Object next = parameterValues.next();
|
||||
|
||||
Object[] values;
|
||||
if (next instanceof Collection) {
|
||||
values = ((Collection<?>) next).toArray();
|
||||
} else if (next.getClass().isArray()) {
|
||||
values = (Object[]) next;
|
||||
} else {
|
||||
values = new Object[] {next};
|
||||
}
|
||||
return JsonArray.from(values);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,9 +16,11 @@
|
||||
|
||||
package org.springframework.data.couchbase.repository.query;
|
||||
|
||||
import static com.couchbase.client.java.query.Delete.deleteFrom;
|
||||
import static com.couchbase.client.java.query.Select.select;
|
||||
import static com.couchbase.client.java.query.dsl.Expression.i;
|
||||
import static com.couchbase.client.java.query.dsl.functions.AggregateFunctions.count;
|
||||
import static org.springframework.data.couchbase.repository.query.support.N1qlUtils.createReturningExpressionForDelete;
|
||||
import com.couchbase.client.java.document.json.JsonArray;
|
||||
import com.couchbase.client.java.document.json.JsonValue;
|
||||
import com.couchbase.client.java.query.Statement;
|
||||
@@ -26,7 +28,8 @@ import com.couchbase.client.java.query.dsl.Expression;
|
||||
import com.couchbase.client.java.query.dsl.path.FromPath;
|
||||
import com.couchbase.client.java.query.dsl.path.LimitPath;
|
||||
import com.couchbase.client.java.query.dsl.path.WherePath;
|
||||
|
||||
import com.couchbase.client.java.query.dsl.path.MutateLimitPath;
|
||||
import com.couchbase.client.java.query.dsl.path.DeleteUsePath;
|
||||
import org.springframework.data.couchbase.core.CouchbaseOperations;
|
||||
import org.springframework.data.couchbase.repository.query.support.N1qlUtils;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
@@ -71,30 +74,40 @@ public class PartTreeN1qlBasedQuery extends AbstractN1qlBasedQuery {
|
||||
String bucketName = getCouchbaseOperations().getCouchbaseBucket().name();
|
||||
Expression bucket = N1qlUtils.escapedBucket(bucketName);
|
||||
|
||||
FromPath select;
|
||||
if (partTree.isCountProjection()) {
|
||||
select = select(count("*"));
|
||||
if (partTree.isDelete()) {
|
||||
DeleteUsePath deleteUsePath = deleteFrom(bucket);
|
||||
N1qlMutateQueryCreator queryCreator = new N1qlMutateQueryCreator(partTree, accessor, deleteUsePath, getCouchbaseOperations().getConverter(), getQueryMethod());
|
||||
MutateLimitPath mutateFromWhereOrderBy = queryCreator.createQuery();
|
||||
if (partTree.isLimiting()) {
|
||||
return mutateFromWhereOrderBy.limit(partTree.getMaxResults());
|
||||
} else {
|
||||
return mutateFromWhereOrderBy.returning(createReturningExpressionForDelete(bucketName));
|
||||
}
|
||||
} else {
|
||||
FromPath select;
|
||||
if (partTree.isCountProjection()) {
|
||||
select = select(count("*"));
|
||||
} else {
|
||||
select = N1qlUtils.createSelectClauseForEntity(bucketName, returnedType, this.getCouchbaseOperations().getConverter());
|
||||
}
|
||||
WherePath selectFrom = select.from(bucket);
|
||||
}
|
||||
WherePath selectFrom = select.from(bucket);
|
||||
N1qlQueryCreator queryCreator = new N1qlQueryCreator(partTree, accessor, selectFrom,
|
||||
getCouchbaseOperations().getConverter(), getQueryMethod());
|
||||
LimitPath selectFromWhereOrderBy = queryCreator.createQuery();
|
||||
|
||||
N1qlQueryCreator queryCreator = new N1qlQueryCreator(partTree, accessor, selectFrom,
|
||||
getCouchbaseOperations().getConverter(), getQueryMethod());
|
||||
LimitPath selectFromWhereOrderBy = queryCreator.createQuery();
|
||||
|
||||
if (queryMethod.isPageQuery()) {
|
||||
Pageable pageable = accessor.getPageable();
|
||||
Assert.notNull(pageable, "Pageable must not be null!");
|
||||
return selectFromWhereOrderBy.limit(pageable.getPageSize()).offset(Math.toIntExact(pageable.getOffset()));
|
||||
} else if (queryMethod.isSliceQuery() && accessor.getPageable().isPaged()) {
|
||||
Pageable pageable = accessor.getPageable();
|
||||
Assert.notNull(pageable, "Pageable must not be null!");
|
||||
return selectFromWhereOrderBy.limit(pageable.getPageSize() + 1).offset(Math.toIntExact(pageable.getOffset()));
|
||||
} else if (partTree.isLimiting()) {
|
||||
return selectFromWhereOrderBy.limit(partTree.getMaxResults());
|
||||
} else {
|
||||
return selectFromWhereOrderBy;
|
||||
if (queryMethod.isPageQuery()) {
|
||||
Pageable pageable = accessor.getPageable();
|
||||
Assert.notNull(pageable, "Pageable must not be null!");
|
||||
return selectFromWhereOrderBy.limit(pageable.getPageSize()).offset(Math.toIntExact(pageable.getOffset()));
|
||||
} else if (queryMethod.isSliceQuery() && accessor.getPageable().isPaged()) {
|
||||
Pageable pageable = accessor.getPageable();
|
||||
Assert.notNull(pageable, "Pageable must not be null!");
|
||||
return selectFromWhereOrderBy.limit(pageable.getPageSize() + 1).offset(Math.toIntExact(pageable.getOffset()));
|
||||
} else if (partTree.isLimiting()) {
|
||||
return selectFromWhereOrderBy.limit(partTree.getMaxResults());
|
||||
} else {
|
||||
return selectFromWhereOrderBy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package org.springframework.data.couchbase.repository.query;
|
||||
|
||||
import static com.couchbase.client.java.query.Delete.deleteFrom;
|
||||
import static com.couchbase.client.java.query.dsl.Expression.i;
|
||||
import static org.springframework.data.couchbase.core.support.TemplateUtils.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -27,6 +29,7 @@ import com.couchbase.client.java.document.json.JsonArray;
|
||||
import com.couchbase.client.java.document.json.JsonObject;
|
||||
import com.couchbase.client.java.document.json.JsonValue;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.data.couchbase.repository.query.support.N1qlUtils;
|
||||
import org.springframework.data.repository.query.Parameter;
|
||||
import org.springframework.data.repository.query.ParameterAccessor;
|
||||
import org.springframework.data.repository.query.QueryMethod;
|
||||
@@ -71,6 +74,22 @@ public class StringBasedN1qlQueryParser {
|
||||
*/
|
||||
public static final String SPEL_FILTER = "#" + SPEL_PREFIX + ".filter";
|
||||
|
||||
/**
|
||||
* Use this variable in a SpEL expression in a {@link org.springframework.data.couchbase.core.query.Query @Query}
|
||||
* annotation's inline statement. This will be replaced by the correct <code>delete</code> expression needed
|
||||
* Eg. <code>"#{{@value SPEL_DELETE}} WHERE test = true"</code>.
|
||||
* Note this only makes sense once, as the beginning of the statement.
|
||||
*/
|
||||
public static final String SPEL_DELETE = "#" + SPEL_PREFIX + ".delete";
|
||||
|
||||
/**
|
||||
* Use this variable in a SpEL expression in a {@link org.springframework.data.couchbase.core.query.Query @Query}
|
||||
* annotation's inline statement. This will be replaced by the correct <code>returning</code> clause needed
|
||||
* for entity mapping. Eg. <code>"#{{@value SPEL_RETURNING}} WHERE test = true"</code>.
|
||||
* Note this only makes sense once, as the beginning of the statement.
|
||||
*/
|
||||
public static final String SPEL_RETURNING = "#" + SPEL_PREFIX + ".returning";
|
||||
|
||||
/** regexp that detect $named placeholder (starts with a letter, then alphanum chars) */
|
||||
public static final Pattern NAMED_PLACEHOLDER_PATTERN = Pattern.compile("\\W(\\$\\p{Alpha}\\p{Alnum}*)\\b");
|
||||
|
||||
@@ -116,10 +135,12 @@ public class StringBasedN1qlQueryParser {
|
||||
} else {
|
||||
selectEntity = "SELECT " + entity + ", " + b + ".* FROM " + b;
|
||||
}
|
||||
|
||||
String typeSelection = "`" + typeField + "` = \"" + typeValue.getName() + "\"";
|
||||
|
||||
return new N1qlSpelValues(selectEntity, entity, b, typeSelection);
|
||||
String delete = deleteFrom(i(bucketName)).toString();
|
||||
String returning = " returning " + N1qlUtils.createReturningExpressionForDelete(bucketName).toString();
|
||||
|
||||
return new N1qlSpelValues(selectEntity, entity, b, typeSelection, delete, returning);
|
||||
}
|
||||
|
||||
//this static method can be used to test the parsing behavior for Couchbase specific spel variables
|
||||
@@ -265,17 +286,30 @@ public class StringBasedN1qlQueryParser {
|
||||
public final String bucket;
|
||||
|
||||
/**
|
||||
* <code>#{{@value SPEL_FILTER}.
|
||||
* <code>#{{@value SPEL_FILTER}}.
|
||||
* filter</code> will be replaced by an expression allowing to select only entries matching the entity in a WHERE clause.
|
||||
*/
|
||||
public final String filter;
|
||||
|
||||
public N1qlSpelValues(String selectClause, String entityFields, String bucket, String filter) {
|
||||
/**
|
||||
* <code>#{{@value SPEL_DELETE}}.
|
||||
* delete</code> will be replaced by a delete expression.
|
||||
*/
|
||||
public final String delete;
|
||||
|
||||
/**
|
||||
* <code>#{{@value SPEL_RETURNING}}.
|
||||
* returning</code> will be replaced by a returning expression allowing to return the entity and meta information on deletes.
|
||||
*/
|
||||
public final String returning;
|
||||
|
||||
public N1qlSpelValues(String selectClause, String entityFields, String bucket, String filter, String delete, String returning) {
|
||||
this.selectEntity = selectClause;
|
||||
this.fields = entityFields;
|
||||
this.bucket = bucket;
|
||||
this.filter = filter;
|
||||
this.delete = delete;
|
||||
this.returning = returning;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,6 +16,13 @@
|
||||
|
||||
package org.springframework.data.couchbase.repository.query;
|
||||
|
||||
import static com.couchbase.client.java.query.Delete.deleteFrom;
|
||||
import static com.couchbase.client.java.query.dsl.Expression.i;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.couchbase.client.java.document.json.JsonValue;
|
||||
import com.couchbase.client.java.query.N1qlQuery;
|
||||
|
||||
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
* Copyright 2017 the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.couchbase.repository.query.support;
|
||||
|
||||
import static com.couchbase.client.java.query.dsl.Expression.*;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.couchbase.client.java.document.json.JsonArray;
|
||||
import com.couchbase.client.java.query.dsl.Expression;
|
||||
import com.couchbase.client.java.query.dsl.functions.PatternMatchingFunctions;
|
||||
import com.couchbase.client.java.query.dsl.functions.StringFunctions;
|
||||
import org.springframework.data.couchbase.core.convert.CouchbaseConverter;
|
||||
import org.springframework.data.couchbase.core.mapping.CouchbasePersistentProperty;
|
||||
import org.springframework.data.couchbase.repository.query.ConvertingIterator;
|
||||
import org.springframework.data.mapping.context.PersistentPropertyPath;
|
||||
import org.springframework.data.repository.query.parser.Part;
|
||||
|
||||
/**
|
||||
* Utils for creating part tree expressions
|
||||
*
|
||||
* @author Subhashni Balakrishnan
|
||||
*/
|
||||
public class N1qlQueryCreatorUtils {
|
||||
public static Expression prepareExpression(CouchbaseConverter converter, Part part, Iterator<Object> iterator) {
|
||||
PersistentPropertyPath<CouchbasePersistentProperty> path = N1qlUtils.getPathWithAlternativeFieldNames(
|
||||
converter, part.getProperty());
|
||||
ConvertingIterator parameterValues = new ConvertingIterator(iterator, converter);
|
||||
|
||||
//get the whole doted path with fieldNames instead of potentially wrong propNames
|
||||
String fieldNamePath = N1qlUtils.getDottedPathWithAlternativeFieldNames(path);
|
||||
|
||||
//deal with ignore case
|
||||
boolean ignoreCase = false;
|
||||
Class<?> leafType = converter.getWriteClassFor(path.getLeafProperty().getType());
|
||||
boolean isString = leafType == String.class;
|
||||
if (part.shouldIgnoreCase() == Part.IgnoreCaseType.WHEN_POSSIBLE) {
|
||||
ignoreCase = isString;
|
||||
} else if (part.shouldIgnoreCase() == Part.IgnoreCaseType.ALWAYS) {
|
||||
if (!isString) {
|
||||
throw new IllegalArgumentException(String.format("Part %s must be of type String but was %s", fieldNamePath, leafType));
|
||||
}
|
||||
ignoreCase = true;
|
||||
}
|
||||
|
||||
return createExpression(part.getType(), fieldNamePath, ignoreCase, parameterValues);
|
||||
}
|
||||
|
||||
|
||||
public static Expression createExpression(Part.Type partType, String fieldNamePath, boolean ignoreCase, Iterator<Object> parameterValues) {
|
||||
//create the left hand side of the expression, taking ignoreCase into account
|
||||
Expression left = ignoreCase ? StringFunctions.lower(x(fieldNamePath)) : x(fieldNamePath);
|
||||
|
||||
switch (partType) {
|
||||
case BETWEEN:
|
||||
return left.between(leftAndRight(parameterValues, ignoreCase));
|
||||
case IS_NOT_NULL:
|
||||
return left.isNotNull();
|
||||
case IS_NULL:
|
||||
return left.isNull();
|
||||
case NEGATING_SIMPLE_PROPERTY:
|
||||
return left.ne(right(parameterValues, ignoreCase));
|
||||
case SIMPLE_PROPERTY:
|
||||
return left.eq(right(parameterValues, ignoreCase));
|
||||
case BEFORE:
|
||||
case LESS_THAN:
|
||||
return left.lt(right(parameterValues, ignoreCase));
|
||||
case LESS_THAN_EQUAL:
|
||||
return left.lte(right(parameterValues, ignoreCase));
|
||||
case GREATER_THAN_EQUAL:
|
||||
return left.gte(right(parameterValues, ignoreCase));
|
||||
case AFTER:
|
||||
case GREATER_THAN:
|
||||
return left.gt(right(parameterValues, ignoreCase));
|
||||
case NOT_LIKE:
|
||||
return left.notLike(right(parameterValues, ignoreCase));
|
||||
case LIKE:
|
||||
return left.like(right(parameterValues, ignoreCase));
|
||||
case STARTING_WITH:
|
||||
return left.like(like(parameterValues, ignoreCase, false, true));
|
||||
case ENDING_WITH:
|
||||
return left.like(like(parameterValues, ignoreCase, true, false));
|
||||
case NOT_CONTAINING:
|
||||
return left.notLike(like(parameterValues, ignoreCase, true, true));
|
||||
case CONTAINING:
|
||||
return left.like(like(parameterValues, ignoreCase, true, true));
|
||||
case NOT_IN:
|
||||
return left.notIn(rightArray(parameterValues));
|
||||
case IN:
|
||||
return left.in(rightArray(parameterValues));
|
||||
case TRUE:
|
||||
return left.eq(true);
|
||||
case FALSE:
|
||||
return left.eq(false);
|
||||
case REGEX:
|
||||
return regexp(fieldNamePath, parameterValues);
|
||||
case EXISTS:
|
||||
return left.isNotMissing();
|
||||
case WITHIN:
|
||||
case NEAR:
|
||||
default:
|
||||
throw new IllegalArgumentException("Unsupported keyword in N1QL query derivation");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected static Expression regexp(String left, Iterator<Object> parameterValues) {
|
||||
Object next = parameterValues.next();
|
||||
|
||||
String pattern;
|
||||
if (next == null) {
|
||||
pattern = "";
|
||||
} else {
|
||||
pattern = String.valueOf(next);
|
||||
}
|
||||
return PatternMatchingFunctions.regexpLike(left, pattern);
|
||||
}
|
||||
|
||||
protected static Expression leftAndRight(Iterator<Object> parameterValues, boolean ignoreCase) {
|
||||
return right(parameterValues, ignoreCase).and(right(parameterValues, ignoreCase));
|
||||
}
|
||||
|
||||
protected static Expression like(Iterator<Object> parameterValues, boolean ignoreCase,
|
||||
boolean anyPrefix, boolean anySuffix) {
|
||||
Object next = parameterValues.next();
|
||||
if (next == null) {
|
||||
return Expression.NULL();
|
||||
}
|
||||
|
||||
Expression converted;
|
||||
if (next instanceof String) {
|
||||
String pattern = (String) next;
|
||||
if (anyPrefix) {
|
||||
pattern = "%" + pattern;
|
||||
}
|
||||
if (anySuffix) {
|
||||
pattern = pattern + "%";
|
||||
}
|
||||
converted = s(pattern);
|
||||
|
||||
} else {
|
||||
converted = x(String.valueOf(next));
|
||||
}
|
||||
|
||||
if (ignoreCase) {
|
||||
return StringFunctions.lower(converted);
|
||||
}
|
||||
return converted;
|
||||
}
|
||||
|
||||
protected static Expression right(Iterator<Object> parameterValues, boolean ignoreCase) {
|
||||
Object next = parameterValues.next();
|
||||
if (next == null) {
|
||||
return Expression.NULL();
|
||||
}
|
||||
|
||||
Expression converted;
|
||||
if (next instanceof String) {
|
||||
converted = s((String) next);
|
||||
} else {
|
||||
converted = x(String.valueOf(next));
|
||||
}
|
||||
|
||||
if (ignoreCase) {
|
||||
return StringFunctions.lower(converted);
|
||||
}
|
||||
return converted;
|
||||
}
|
||||
|
||||
protected static JsonArray rightArray(Iterator<Object> parameterValues) {
|
||||
Object next = parameterValues.next();
|
||||
|
||||
Object[] values;
|
||||
if (next instanceof Collection) {
|
||||
values = ((Collection<?>) next).toArray();
|
||||
} else if (next.getClass().isArray()) {
|
||||
values = (Object[]) next;
|
||||
} else {
|
||||
values = new Object[] {next};
|
||||
}
|
||||
return JsonArray.from(values);
|
||||
}
|
||||
}
|
||||
@@ -123,6 +123,32 @@ public class N1qlUtils {
|
||||
return select(propertiesExp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the returning clause for N1ql deletes with all attributes of the entity and meta information
|
||||
*
|
||||
* @param bucketName the bucket that stores the entity documents (will be escaped).
|
||||
* @return the needed returning clause of the statement.
|
||||
*/
|
||||
public static Expression createReturningExpressionForDelete(String bucketName) {
|
||||
Expression fullEntity = path(i(bucketName), "*");
|
||||
Expression metaId = path(meta(i(bucketName)), "id").as(SELECT_ID);
|
||||
Expression metaCas = path(meta(i(bucketName)), "cas").as(SELECT_CAS);
|
||||
List<Expression> expList = new ArrayList<Expression>();
|
||||
expList.add(fullEntity);
|
||||
expList.add(metaId);
|
||||
expList.add(metaCas);
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Expression exp: expList) {
|
||||
if (sb.length() != 0) {
|
||||
sb.append(", ");
|
||||
}
|
||||
sb.append(exp.toString());
|
||||
}
|
||||
|
||||
return x(sb.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Produce a {@link Statement} that corresponds to the SELECT clause for looking for Spring Data entities
|
||||
* stored in Couchbase. Notably it will select the content of the document AND its id and cas.
|
||||
|
||||
@@ -222,28 +222,6 @@ public class AbstractN1qlBasedQueryTest {
|
||||
verify(mock, never()).executeSingleProjection(any(N1qlQuery.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldThrowWhenModifyingType() throws Exception {
|
||||
|
||||
Method method = SampleRepository.class.getMethod("modifyingMethod");
|
||||
CouchbaseQueryMethod queryMethod = spy(new CouchbaseQueryMethod(method, metadata, projectionFactory, context));
|
||||
when(queryMethod.isModifyingQuery()).thenReturn(true);
|
||||
|
||||
N1qlQuery query = Mockito.mock(N1qlQuery.class);
|
||||
Pageable pageable = Mockito.mock(Pageable.class);
|
||||
AbstractN1qlBasedQuery mock = mock(AbstractN1qlBasedQuery.class);
|
||||
when(mock.executeDependingOnType(any(N1qlQuery.class), any(N1qlQuery.class), any(QueryMethod.class), any(Pageable.class),
|
||||
any(Class.class))).thenCallRealMethod();
|
||||
|
||||
try { mock.executeDependingOnType(query, query, queryMethod, pageable, Sample.class); fail(); } catch (UnsupportedOperationException e) { }
|
||||
verify(mock, never()).executeCollection(any(N1qlQuery.class), any(Class.class));
|
||||
verify(mock, never()).executeEntity(any(N1qlQuery.class), any(Class.class));
|
||||
verify(mock, never()).executeStream(any(N1qlQuery.class), any(Class.class));
|
||||
verify(mock, never()).executePaged(any(N1qlQuery.class), any(N1qlQuery.class), any(Pageable.class), any(Class.class));
|
||||
verify(mock, never()).executeSliced(any(N1qlQuery.class), any(N1qlQuery.class), any(Pageable.class), any(Class.class));
|
||||
verify(mock, never()).executeSingleProjection(any(N1qlQuery.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldExecuteSingleProjectionWhenRandomObjectReturnType() throws Exception {
|
||||
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
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 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;
|
||||
@@ -24,9 +27,9 @@ public class N1qlQueryCreatorTest {
|
||||
String expectedNum = "doc.field BETWEEN 1 AND 2";
|
||||
String expectedIgnoreCase = "LOWER(doc.field) BETWEEN LOWER(\"c\") AND LOWER(\"d\")";
|
||||
|
||||
Expression exp = createExpression(keyword, "doc.field", false, values);
|
||||
Expression expNum = createExpression(keyword, "doc.field", false, values);
|
||||
Expression expIgnoreCase = createExpression(keyword, "doc.field", true, values);
|
||||
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);
|
||||
|
||||
assertEquals(expected, exp.toString());
|
||||
assertEquals(expectedNum, expNum.toString());
|
||||
@@ -41,9 +44,9 @@ public class N1qlQueryCreatorTest {
|
||||
String expectedNum = "doc.field IS NOT NULL";
|
||||
String expectedIgnoreCase = "LOWER(doc.field) IS NOT NULL";
|
||||
|
||||
Expression exp = createExpression(keyword, "doc.field", false, values);
|
||||
Expression expNum = createExpression(keyword, "doc.field", false, values);
|
||||
Expression expIgnoreCase = createExpression(keyword, "doc.field", true, values);
|
||||
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);
|
||||
|
||||
assertEquals(expected, exp.toString());
|
||||
assertEquals(expectedNum, expNum.toString());
|
||||
@@ -58,9 +61,9 @@ public class N1qlQueryCreatorTest {
|
||||
String expectedNum = "doc.field IS NULL";
|
||||
String expectedIgnoreCase = "LOWER(doc.field) IS NULL";
|
||||
|
||||
Expression exp = createExpression(keyword, "doc.field", false, values);
|
||||
Expression expNum = createExpression(keyword, "doc.field", false, values);
|
||||
Expression expIgnoreCase = createExpression(keyword, "doc.field", true, values);
|
||||
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);
|
||||
|
||||
assertEquals(expected, exp.toString());
|
||||
assertEquals(expectedNum, expNum.toString());
|
||||
@@ -75,9 +78,9 @@ public class N1qlQueryCreatorTest {
|
||||
String expectedNum = "doc.field < 1";
|
||||
String expectedIgnoreCase = "LOWER(doc.field) < LOWER(\"b\")";
|
||||
|
||||
Expression exp = createExpression(keyword, "doc.field", false, values);
|
||||
Expression expNum = createExpression(keyword, "doc.field", false, values);
|
||||
Expression expIgnoreCase = createExpression(keyword, "doc.field", true, values);
|
||||
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);
|
||||
|
||||
assertEquals(expected, exp.toString());
|
||||
assertEquals(expectedNum, expNum.toString());
|
||||
@@ -92,9 +95,9 @@ public class N1qlQueryCreatorTest {
|
||||
String expectedNum = "doc.field <= 1";
|
||||
String expectedIgnoreCase = "LOWER(doc.field) <= LOWER(\"b\")";
|
||||
|
||||
Expression exp = createExpression(keyword, "doc.field", false, values);
|
||||
Expression expNum = createExpression(keyword, "doc.field", false, values);
|
||||
Expression expIgnoreCase = createExpression(keyword, "doc.field", true, values);
|
||||
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);
|
||||
|
||||
assertEquals(expected, exp.toString());
|
||||
assertEquals(expectedNum, expNum.toString());
|
||||
@@ -109,9 +112,9 @@ public class N1qlQueryCreatorTest {
|
||||
String expectedNum = "doc.field > 1";
|
||||
String expectedIgnoreCase = "LOWER(doc.field) > LOWER(\"b\")";
|
||||
|
||||
Expression exp = createExpression(keyword, "doc.field", false, values);
|
||||
Expression expNum = createExpression(keyword, "doc.field", false, values);
|
||||
Expression expIgnoreCase = createExpression(keyword, "doc.field", true, values);
|
||||
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);
|
||||
|
||||
assertEquals(expected, exp.toString());
|
||||
assertEquals(expectedNum, expNum.toString());
|
||||
@@ -126,9 +129,9 @@ public class N1qlQueryCreatorTest {
|
||||
String expectedNum = "doc.field >= 1";
|
||||
String expectedIgnoreCase = "LOWER(doc.field) >= LOWER(\"b\")";
|
||||
|
||||
Expression exp = createExpression(keyword, "doc.field", false, values);
|
||||
Expression expNum = createExpression(keyword, "doc.field", false, values);
|
||||
Expression expIgnoreCase = createExpression(keyword, "doc.field", true, values);
|
||||
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);
|
||||
|
||||
assertEquals(expected, exp.toString());
|
||||
assertEquals(expectedNum, expNum.toString());
|
||||
@@ -143,9 +146,9 @@ public class N1qlQueryCreatorTest {
|
||||
String expectedNum = "doc.field < 1";
|
||||
String expectedIgnoreCase = "LOWER(doc.field) < LOWER(\"b\")";
|
||||
|
||||
Expression exp = createExpression(keyword, "doc.field", false, values);
|
||||
Expression expNum = createExpression(keyword, "doc.field", false, values);
|
||||
Expression expIgnoreCase = createExpression(keyword, "doc.field", true, values);
|
||||
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);
|
||||
|
||||
assertEquals(expected, exp.toString());
|
||||
assertEquals(expectedNum, expNum.toString());
|
||||
@@ -160,9 +163,9 @@ public class N1qlQueryCreatorTest {
|
||||
String expectedNum = "doc.field > 1";
|
||||
String expectedIgnoreCase = "LOWER(doc.field) > LOWER(\"b\")";
|
||||
|
||||
Expression exp = createExpression(keyword, "doc.field", false, values);
|
||||
Expression expNum = createExpression(keyword, "doc.field", false, values);
|
||||
Expression expIgnoreCase = createExpression(keyword, "doc.field", true, values);
|
||||
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);
|
||||
|
||||
assertEquals(expected, exp.toString());
|
||||
assertEquals(expectedNum, expNum.toString());
|
||||
@@ -177,9 +180,9 @@ public class N1qlQueryCreatorTest {
|
||||
String expectedNum = "doc.field NOT LIKE 1";
|
||||
String expectedIgnoreCase = "LOWER(doc.field) NOT LIKE LOWER(\"b\")";
|
||||
|
||||
Expression exp = createExpression(keyword, "doc.field", false, values);
|
||||
Expression expNum = createExpression(keyword, "doc.field", false, values);
|
||||
Expression expIgnoreCase = createExpression(keyword, "doc.field", true, values);
|
||||
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);
|
||||
|
||||
assertEquals(expected, exp.toString());
|
||||
assertEquals(expectedNum, expNum.toString());
|
||||
@@ -194,9 +197,9 @@ public class N1qlQueryCreatorTest {
|
||||
String expectedNum = "doc.field LIKE 1";
|
||||
String expectedIgnoreCase = "LOWER(doc.field) LIKE LOWER(\"b\")";
|
||||
|
||||
Expression exp = createExpression(keyword, "doc.field", false, values);
|
||||
Expression expNum = createExpression(keyword, "doc.field", false, values);
|
||||
Expression expIgnoreCase = createExpression(keyword, "doc.field", true, values);
|
||||
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);
|
||||
|
||||
assertEquals(expected, exp.toString());
|
||||
assertEquals(expectedNum, expNum.toString());
|
||||
@@ -211,9 +214,9 @@ public class N1qlQueryCreatorTest {
|
||||
String expectedNum = "doc.field LIKE 1";
|
||||
String expectedIgnoreCase = "LOWER(doc.field) LIKE LOWER(\"b%\")";
|
||||
|
||||
Expression exp = createExpression(keyword, "doc.field", false, values);
|
||||
Expression expNum = createExpression(keyword, "doc.field", false, values);
|
||||
Expression expIgnoreCase = createExpression(keyword, "doc.field", true, values);
|
||||
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);
|
||||
|
||||
assertEquals(expected, exp.toString());
|
||||
assertEquals(expectedNum, expNum.toString());
|
||||
@@ -228,9 +231,9 @@ public class N1qlQueryCreatorTest {
|
||||
String expectedNum = "doc.field LIKE 1";
|
||||
String expectedIgnoreCase = "LOWER(doc.field) LIKE LOWER(\"%b\")";
|
||||
|
||||
Expression exp = createExpression(keyword, "doc.field", false, values);
|
||||
Expression expNum = createExpression(keyword, "doc.field", false, values);
|
||||
Expression expIgnoreCase = createExpression(keyword, "doc.field", true, values);
|
||||
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);
|
||||
|
||||
assertEquals(expected, exp.toString());
|
||||
assertEquals(expectedNum, expNum.toString());
|
||||
@@ -245,9 +248,9 @@ public class N1qlQueryCreatorTest {
|
||||
String expectedNum = "doc.field NOT LIKE 1";
|
||||
String expectedIgnoreCase = "LOWER(doc.field) NOT LIKE LOWER(\"%b%\")";
|
||||
|
||||
Expression exp = createExpression(keyword, "doc.field", false, values);
|
||||
Expression expNum = createExpression(keyword, "doc.field", false, values);
|
||||
Expression expIgnoreCase = createExpression(keyword, "doc.field", true, values);
|
||||
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);
|
||||
|
||||
assertEquals(expected, exp.toString());
|
||||
assertEquals(expectedNum, expNum.toString());
|
||||
@@ -262,9 +265,9 @@ public class N1qlQueryCreatorTest {
|
||||
String expectedNum = "doc.field LIKE 1";
|
||||
String expectedIgnoreCase = "LOWER(doc.field) LIKE LOWER(\"%b%\")";
|
||||
|
||||
Expression exp = createExpression(keyword, "doc.field", false, values);
|
||||
Expression expNum = createExpression(keyword, "doc.field", false, values);
|
||||
Expression expIgnoreCase = createExpression(keyword, "doc.field", true, values);
|
||||
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);
|
||||
|
||||
assertEquals(expected, exp.toString());
|
||||
assertEquals(expectedNum, expNum.toString());
|
||||
@@ -279,9 +282,9 @@ public class N1qlQueryCreatorTest {
|
||||
String expectedNum = "doc.field NOT IN [1]";
|
||||
String expectedIgnoreCase = "LOWER(doc.field) NOT IN [\"b\"]";
|
||||
|
||||
Expression exp = createExpression(keyword, "doc.field", false, values);
|
||||
Expression expNum = createExpression(keyword, "doc.field", false, values);
|
||||
Expression expIgnoreCase = createExpression(keyword, "doc.field", true, values);
|
||||
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);
|
||||
|
||||
assertEquals(expected, exp.toString());
|
||||
assertEquals(expectedNum, expNum.toString());
|
||||
@@ -297,8 +300,8 @@ public class N1qlQueryCreatorTest {
|
||||
String expected = "doc.field NOT IN [\"av1\",\"av2\"]";
|
||||
String expectedIgnoreCase = "LOWER(doc.field) NOT IN [\"bv1\",\"bv2\"]";
|
||||
|
||||
Expression exp = createExpression(keyword, "doc.field", false, values);
|
||||
Expression expIgnoreCase = createExpression(keyword, "doc.field", true, values);
|
||||
Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values);
|
||||
Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values);
|
||||
|
||||
assertEquals(expected, exp.toString());
|
||||
assertEquals(expectedIgnoreCase, expIgnoreCase.toString());
|
||||
@@ -313,8 +316,8 @@ public class N1qlQueryCreatorTest {
|
||||
String expected = "doc.field NOT IN [\"av1\",\"av2\"]";
|
||||
String expectedIgnoreCase = "LOWER(doc.field) NOT IN [\"bv1\",\"bv2\"]";
|
||||
|
||||
Expression exp = createExpression(keyword, "doc.field", false, values);
|
||||
Expression expIgnoreCase = createExpression(keyword, "doc.field", true, values);
|
||||
Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values);
|
||||
Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values);
|
||||
|
||||
assertEquals(expected, exp.toString());
|
||||
assertEquals(expectedIgnoreCase, expIgnoreCase.toString());
|
||||
@@ -328,9 +331,9 @@ public class N1qlQueryCreatorTest {
|
||||
String expectedNum = "doc.field IN [1]";
|
||||
String expectedIgnoreCase = "LOWER(doc.field) IN [\"b\"]";
|
||||
|
||||
Expression exp = createExpression(keyword, "doc.field", false, values);
|
||||
Expression expNum = createExpression(keyword, "doc.field", false, values);
|
||||
Expression expIgnoreCase = createExpression(keyword, "doc.field", true, values);
|
||||
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);
|
||||
|
||||
assertEquals(expected, exp.toString());
|
||||
assertEquals(expectedNum, expNum.toString());
|
||||
@@ -346,8 +349,8 @@ public class N1qlQueryCreatorTest {
|
||||
String expected = "doc.field IN [\"av1\",\"av2\"]";
|
||||
String expectedIgnoreCase = "LOWER(doc.field) IN [\"bv1\",\"bv2\"]";
|
||||
|
||||
Expression exp = createExpression(keyword, "doc.field", false, values);
|
||||
Expression expIgnoreCase = createExpression(keyword, "doc.field", true, values);
|
||||
Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values);
|
||||
Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values);
|
||||
|
||||
assertEquals(expected, exp.toString());
|
||||
assertEquals(expectedIgnoreCase, expIgnoreCase.toString());
|
||||
@@ -362,8 +365,8 @@ public class N1qlQueryCreatorTest {
|
||||
String expected = "doc.field IN [\"av1\",\"av2\"]";
|
||||
String expectedIgnoreCase = "LOWER(doc.field) IN [\"bv1\",\"bv2\"]";
|
||||
|
||||
Expression exp = createExpression(keyword, "doc.field", false, values);
|
||||
Expression expIgnoreCase = createExpression(keyword, "doc.field", true, values);
|
||||
Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values);
|
||||
Expression expIgnoreCase = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values);
|
||||
|
||||
assertEquals(expected, exp.toString());
|
||||
assertEquals(expectedIgnoreCase, expIgnoreCase.toString());
|
||||
@@ -374,7 +377,7 @@ public class N1qlQueryCreatorTest {
|
||||
Part.Type keyword = Part.Type.NEAR;
|
||||
Iterator<Object> values = Arrays.<Object>asList("a", 1, "b").iterator();
|
||||
|
||||
Expression exp = createExpression(keyword, "doc.field", true, values);
|
||||
Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", true, values);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
@@ -382,7 +385,7 @@ public class N1qlQueryCreatorTest {
|
||||
Part.Type keyword = Part.Type.WITHIN;
|
||||
Iterator<Object> values = Arrays.<Object>asList("a", 1, "b").iterator();
|
||||
|
||||
Expression exp = createExpression(keyword, "doc.field", false, values);
|
||||
Expression exp = N1qlQueryCreatorUtils.createExpression(keyword, "doc.field", false, values);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -393,9 +396,9 @@ public class N1qlQueryCreatorTest {
|
||||
String expectedNum = "REGEXP_LIKE(doc.field, \"1\")";
|
||||
String expectedIgnoreCase = "REGEXP_LIKE(doc.field, \"b\")";
|
||||
|
||||
Expression exp = createExpression(keyword, "doc.field", false, values);
|
||||
Expression expNum = createExpression(keyword, "doc.field", false, values);
|
||||
Expression expIgnoreCase = createExpression(keyword, "doc.field", true, values);
|
||||
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);
|
||||
|
||||
assertEquals(expected, exp.toString());
|
||||
assertEquals(expectedNum, expNum.toString());
|
||||
@@ -410,9 +413,9 @@ public class N1qlQueryCreatorTest {
|
||||
String expectedNum = "doc.field IS NOT MISSING";
|
||||
String expectedIgnoreCase = "LOWER(doc.field) IS NOT MISSING";
|
||||
|
||||
Expression exp = createExpression(keyword, "doc.field", false, values);
|
||||
Expression expNum = createExpression(keyword, "doc.field", false, values);
|
||||
Expression expIgnoreCase = createExpression(keyword, "doc.field", true, values);
|
||||
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);
|
||||
|
||||
assertEquals(expected, exp.toString());
|
||||
assertEquals(expectedNum, expNum.toString());
|
||||
@@ -427,9 +430,9 @@ public class N1qlQueryCreatorTest {
|
||||
String expectedNum = "doc.field = TRUE";
|
||||
String expectedIgnoreCase = "LOWER(doc.field) = TRUE";
|
||||
|
||||
Expression exp = createExpression(keyword, "doc.field", false, values);
|
||||
Expression expNum = createExpression(keyword, "doc.field", false, values);
|
||||
Expression expIgnoreCase = createExpression(keyword, "doc.field", true, values);
|
||||
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);
|
||||
|
||||
assertEquals(expected, exp.toString());
|
||||
assertEquals(expectedNum, expNum.toString());
|
||||
@@ -444,9 +447,9 @@ public class N1qlQueryCreatorTest {
|
||||
String expectedNum = "doc.field = FALSE";
|
||||
String expectedIgnoreCase = "LOWER(doc.field) = FALSE";
|
||||
|
||||
Expression exp = createExpression(keyword, "doc.field", false, values);
|
||||
Expression expNum = createExpression(keyword, "doc.field", false, values);
|
||||
Expression expIgnoreCase = createExpression(keyword, "doc.field", true, values);
|
||||
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);
|
||||
|
||||
assertEquals(expected, exp.toString());
|
||||
assertEquals(expectedNum, expNum.toString());
|
||||
@@ -461,9 +464,9 @@ public class N1qlQueryCreatorTest {
|
||||
String expectedNum = "doc.field != 1";
|
||||
String expectedIgnoreCase = "LOWER(doc.field) != LOWER(\"b\")";
|
||||
|
||||
Expression exp = createExpression(keyword, "doc.field", false, values);
|
||||
Expression expNum = createExpression(keyword, "doc.field", false, values);
|
||||
Expression expIgnoreCase = createExpression(keyword, "doc.field", true, values);
|
||||
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);
|
||||
|
||||
assertEquals(expected, exp.toString());
|
||||
assertEquals(expectedNum, expNum.toString());
|
||||
@@ -478,9 +481,9 @@ public class N1qlQueryCreatorTest {
|
||||
String expectedNum = "doc.field = 1";
|
||||
String expectedIgnoreCase = "LOWER(doc.field) = LOWER(\"b\")";
|
||||
|
||||
Expression exp = createExpression(keyword, "doc.field", false, values);
|
||||
Expression expNum = createExpression(keyword, "doc.field", false, values);
|
||||
Expression expIgnoreCase = createExpression(keyword, "doc.field", true, values);
|
||||
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);
|
||||
|
||||
assertEquals(expected, exp.toString());
|
||||
assertEquals(expectedNum, expNum.toString());
|
||||
|
||||
@@ -63,4 +63,25 @@ public class StringN1QlBasedQueryTest {
|
||||
|
||||
assertEquals("SELECT COUNT(*) AS " + CountFragment.COUNT_ALIAS + " FROM `B` WHERE true", parsed);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeletePlaceholder() throws Exception {
|
||||
String statement = spel(SPEL_DELETE) + " WHERE test = 1 AND " + spel(SPEL_FILTER);
|
||||
String parsed = new StringBasedN1qlQueryParser(statement, null, "B", "_class", String.class)
|
||||
.doParse(SPEL_PARSER, SPEL_EVALUATION_CONTEXT, true);
|
||||
|
||||
assertEquals("DELETE FROM `B` WHERE test = 1 AND `_class` = "
|
||||
+ "\"java.lang.String\"", parsed);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReturningPlaceholder() throws Exception {
|
||||
String statement = spel(SPEL_DELETE) + " WHERE test = 1 AND " + spel(SPEL_FILTER) + spel(SPEL_RETURNING) ;
|
||||
String parsed = new StringBasedN1qlQueryParser(statement, null, "B", "_class", String.class)
|
||||
.doParse(SPEL_PARSER, SPEL_EVALUATION_CONTEXT, true);
|
||||
|
||||
assertEquals("DELETE FROM `B` WHERE test = 1 AND `_class` = "
|
||||
+ "\"java.lang.String\" returning `B`.*, META(`B`).id AS _ID, META(`B`).cas AS _CAS", parsed);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user