DATACASS-146 - Polish.

This commit is contained in:
John Blum
2017-09-11 18:08:02 -07:00
parent 0ee5190f09
commit 1cb5a8bd99
22 changed files with 201 additions and 164 deletions

View File

@@ -29,8 +29,9 @@ import com.datastax.driver.core.ConsistencyLevel;
* Annotation to declare a {@link ConsistencyLevel} for CQL queries executed through query methods.
*
* @author Mark Paluch
* @since 2.0
* @see org.springframework.data.annotation.QueryAnnotation
* @see org.springframework.data.cassandra.core.cql.QueryOptions
* @since 2.0
*/
@Target({ ElementType.ANNOTATION_TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@@ -39,7 +40,8 @@ import com.datastax.driver.core.ConsistencyLevel;
public @interface Consistency {
/**
* @return the {@link ConsistencyLevel} applied to the query executed using a query method.
* @return the {@link ConsistencyLevel} applied to the query executed using a Repository query method.
*/
ConsistencyLevel value();
}

View File

@@ -36,6 +36,7 @@ import com.datastax.driver.core.Statement;
*
* @author Mark Paluch
* @author John Blum
* @see org.springframework.data.cassandra.repository.query.CassandraRepositoryQuerySupport
*/
public abstract class AbstractCassandraQuery extends CassandraRepositoryQuerySupport {
@@ -78,12 +79,17 @@ public abstract class AbstractCassandraQuery extends CassandraRepositoryQuerySup
CassandraQueryExecution queryExecution = getExecution(new ResultProcessingConverter(resultProcessor,
getOperations().getConverter().getMappingContext(), getEntityInstantiators()));
Class<?> resultType = resolveResultType(resultProcessor);
return queryExecution.execute(statement, resultType);
}
private Class<?> resolveResultType(ResultProcessor resultProcessor) {
CassandraReturnedType returnedType = new CassandraReturnedType(resultProcessor.getReturnedType(),
getOperations().getConverter().getCustomConversions());
Class<?> resultType = (returnedType.isProjecting() ? returnedType.getDomainType() : returnedType.getReturnedType());
return queryExecution.execute(statement, resultType);
return (returnedType.isProjecting() ? returnedType.getDomainType() : returnedType.getReturnedType());
}
/**

View File

@@ -18,7 +18,6 @@ package org.springframework.data.cassandra.repository.query;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import org.reactivestreams.Publisher;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.cassandra.core.CassandraOperations;
import org.springframework.data.cassandra.core.ReactiveCassandraOperations;
@@ -31,12 +30,15 @@ import org.springframework.data.repository.query.RepositoryQuery;
import org.springframework.data.repository.query.ResultProcessor;
import org.springframework.util.Assert;
import org.reactivestreams.Publisher;
import com.datastax.driver.core.Statement;
/**
* Base class for reactive {@link RepositoryQuery} implementations for Cassandra.
*
* @author Mark Paluch
* @see org.springframework.data.cassandra.repository.query.CassandraRepositoryQuerySupport
* @since 2.0
*/
public abstract class AbstractReactiveCassandraQuery extends CassandraRepositoryQuerySupport {
@@ -78,28 +80,19 @@ public abstract class AbstractReactiveCassandraQuery extends CassandraRepository
*/
@Override
public Object execute(Object[] parameters) {
return (getQueryMethod().hasReactiveWrapperParameter() ? executeDeferred(parameters)
: execute(new ReactiveCassandraParameterAccessor(getQueryMethod(), parameters)));
return (getQueryMethod().hasReactiveWrapperParameter() ? executeDeferred(parameters) : executeNow(parameters));
}
/**
* Creates a string query using the given {@link ParameterAccessor}
*
* @param accessor must not be {@literal null}.
*/
protected abstract Statement createQuery(CassandraParameterAccessor accessor);
@SuppressWarnings("unchecked")
private Object executeDeferred(Object[] parameters) {
ReactiveCassandraParameterAccessor accessor = new ReactiveCassandraParameterAccessor(getQueryMethod(), parameters);
return (getQueryMethod().isCollectionQuery() ? Flux.defer(() -> (Publisher<Object>) execute(accessor))
: Mono.defer(() -> (Mono<Object>) execute(accessor)));
return (getQueryMethod().isCollectionQuery() ? Flux.defer(() -> (Publisher<Object>) execute(parameters))
: Mono.defer(() -> (Mono<Object>) execute(parameters)));
}
private Object execute(CassandraParameterAccessor parameterAccessor) {
private Object executeNow(Object[] parameters) {
ReactiveCassandraParameterAccessor parameterAccessor =
new ReactiveCassandraParameterAccessor(getQueryMethod(), parameters);
CassandraParameterAccessor convertingParameterAccessor = new ConvertingParameterAccessor(
getReactiveCassandraOperations().getConverter(), parameterAccessor);
@@ -112,14 +105,26 @@ public abstract class AbstractReactiveCassandraQuery extends CassandraRepository
ReactiveCassandraQueryExecution queryExecution = getExecution(new ResultProcessingConverter(resultProcessor,
getReactiveCassandraOperations().getConverter().getMappingContext(), getEntityInstantiators()));
CassandraReturnedType returnedType = new CassandraReturnedType(resultProcessor.getReturnedType(),
getReactiveCassandraOperations().getConverter().getCustomConversions());
Class<?> resultType = (returnedType.isProjecting() ? returnedType.getDomainType() : returnedType.getReturnedType());
Class<?> resultType = resolveResultType(resultProcessor);
return queryExecution.execute(statement, resultType);
}
private Class<?> resolveResultType(ResultProcessor resultProcessor) {
CassandraReturnedType returnedType = new CassandraReturnedType(resultProcessor.getReturnedType(),
getReactiveCassandraOperations().getConverter().getCustomConversions());
return (returnedType.isProjecting() ? returnedType.getDomainType() : returnedType.getReturnedType());
}
/**
* Creates a string query using the given {@link ParameterAccessor}
*
* @param accessor must not be {@literal null}.
*/
protected abstract Statement createQuery(CassandraParameterAccessor accessor);
/**
* Returns the execution instance to use.
*

View File

@@ -31,6 +31,17 @@ import com.datastax.driver.core.DataType;
*/
public interface CassandraParameterAccessor extends ParameterAccessor {
/**
* Returns the {@link CassandraType} for the declared method parameter.
*
* @param index the parameter index
* @return the Cassandra {@link CassandraType} or {@literal null}.
* @see org.springframework.data.cassandra.core.mapping.CassandraSimpleTypeHolder
* @see org.springframework.data.cassandra.core.mapping.CassandraType
*/
@Nullable
CassandraType findCassandraType(int index);
/**
* Returns the Cassandra {@link DataType} for the declared parameter if the type is a
* {@link org.springframework.data.cassandra.core.mapping.CassandraSimpleTypeHolder simple type}. Parameter types may
@@ -44,17 +55,6 @@ public interface CassandraParameterAccessor extends ParameterAccessor {
*/
DataType getDataType(int index);
/**
* Returns the {@link CassandraType} for the declared method parameter.
*
* @param index the parameter index
* @return the Cassandra {@link CassandraType} or {@literal null}.
* @see org.springframework.data.cassandra.core.mapping.CassandraSimpleTypeHolder
* @see org.springframework.data.cassandra.core.mapping.CassandraType
*/
@Nullable
CassandraType findCassandraType(int index);
/**
* The actual parameter type (after unwrapping).
*
@@ -72,11 +72,12 @@ public interface CassandraParameterAccessor extends ParameterAccessor {
Object[] getValues();
/**
* Returns the {@link QueryOptions} associated of the associated query method.
* Returns the {@link QueryOptions} associated with the associated Repository query method.
*
* @return the {@link QueryOptions} or {@literal null} if none.
* @since 2.0
*/
@Nullable
QueryOptions getQueryOptions();
}

View File

@@ -49,14 +49,14 @@ public class CassandraParameters extends Parameters<CassandraParameters, Cassand
* @param method must not be {@literal null}.
*/
public CassandraParameters(Method method) {
super(method);
List<Class<?>> parameterTypes = Arrays.asList(method.getParameterTypes());
this.queryOptionsIndex = parameterTypes.indexOf(QueryOptions.class);
this.queryOptionsIndex = Arrays.asList(method.getParameterTypes()).indexOf(QueryOptions.class);
}
private CassandraParameters(List<CassandraParameter> originals, @Nullable Integer queryOptionsIndex) {
super(originals);
this.queryOptionsIndex = queryOptionsIndex;
@@ -85,7 +85,7 @@ public class CassandraParameters extends Parameters<CassandraParameters, Cassand
* @since 2.0
*/
public int getQueryOptionsIndex() {
return queryOptionsIndex != null ? queryOptionsIndex : -1;
return (queryOptionsIndex != null ? queryOptionsIndex : -1);
}
/**
@@ -129,7 +129,7 @@ public class CassandraParameters extends Parameters<CassandraParameters, Cassand
*/
@Nullable
public CassandraType getCassandraType() {
return cassandraType;
return this.cassandraType;
}
/* (non-Javadoc)
@@ -137,7 +137,7 @@ public class CassandraParameters extends Parameters<CassandraParameters, Cassand
*/
@Override
public Class<?> getType() {
return parameterType;
return this.parameterType;
}
/**

View File

@@ -49,6 +49,7 @@ public class CassandraParametersParameterAccessor extends ParametersParameterAcc
public CassandraParametersParameterAccessor(CassandraQueryMethod method, Object... values) {
super(method.getParameters(), values);
this.values = Arrays.asList(values);
}
@@ -98,7 +99,7 @@ public class CassandraParametersParameterAccessor extends ParametersParameterAcc
*/
@Override
public Object[] getValues() {
return values.toArray();
return this.values.toArray();
}
/*
@@ -111,15 +112,7 @@ public class CassandraParametersParameterAccessor extends ParametersParameterAcc
int queryOptionsIndex = getParameters().getQueryOptionsIndex();
if (queryOptionsIndex == -1) {
return null;
}
Object value = getValue(queryOptionsIndex);
if (value == null) {
return null;
}
Object value = (queryOptionsIndex != -1 ? getValue(queryOptionsIndex) : null);
return (QueryOptions) value;
}

View File

@@ -20,8 +20,6 @@ import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.data.cassandra.core.mapping.CassandraMappingContext;
import org.springframework.data.cassandra.core.mapping.CassandraPersistentProperty;
@@ -38,6 +36,9 @@ import org.springframework.data.repository.query.parser.Part.Type;
import org.springframework.data.repository.query.parser.PartTree;
import org.springframework.util.Assert;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.datastax.driver.core.querybuilder.Clause;
/**
@@ -60,13 +61,13 @@ class CassandraQueryCreator extends AbstractQueryCreator<Query, CriteriaDefiniti
* {@link MappingContext}.
*
* @param tree must not be {@literal null}.
* @param accessor must not be {@literal null}.
* @param parameterAccessor must not be {@literal null}.
* @param mappingContext must not be {@literal null}.
*/
public CassandraQueryCreator(PartTree tree, CassandraParameterAccessor accessor,
public CassandraQueryCreator(PartTree tree, CassandraParameterAccessor parameterAccessor,
MappingContext<?, CassandraPersistentProperty> mappingContext) {
super(tree, accessor);
super(tree, parameterAccessor);
Assert.notNull(mappingContext, "CassandraMappingContext must not be null");

View File

@@ -101,22 +101,22 @@ public class CassandraQueryMethod extends QueryMethod {
@SuppressWarnings("unchecked")
public CassandraEntityMetadata<?> getEntityInformation() {
if (entityMetadata == null) {
if (this.entityMetadata == null) {
Class<?> returnedObjectType = getReturnedObjectType();
Class<?> domainClass = getDomainClass();
if (ClassUtils.isPrimitiveOrWrapper(returnedObjectType)) {
this.entityMetadata = new SimpleCassandraEntityMetadata<>((Class<Object>) domainClass,
mappingContext.getRequiredPersistentEntity(domainClass));
this.mappingContext.getRequiredPersistentEntity(domainClass));
} else {
CassandraPersistentEntity<?> returnedEntity = mappingContext.getPersistentEntity(returnedObjectType);
CassandraPersistentEntity<?> managedEntity = mappingContext.getRequiredPersistentEntity(domainClass);
CassandraPersistentEntity<?> returnedEntity = this.mappingContext.getPersistentEntity(returnedObjectType);
CassandraPersistentEntity<?> managedEntity = this.mappingContext.getRequiredPersistentEntity(domainClass);
returnedEntity = returnedEntity == null || returnedEntity.getType().isInterface() ? managedEntity
: returnedEntity;
returnedEntity = returnedEntity == null || returnedEntity.getType().isInterface()
? managedEntity : returnedEntity;
this.entityMetadata = new SimpleCassandraEntityMetadata<>((Class<Object>) returnedEntity.getType(),
managedEntity);
@@ -147,7 +147,7 @@ public class CassandraQueryMethod extends QueryMethod {
* Returns whether the method has an annotated query.
*/
public boolean hasAnnotatedQuery() {
return query.map(Query::value).filter(StringUtils::hasText).isPresent();
return this.query.map(Query::value).filter(StringUtils::hasText).isPresent();
}
/**
@@ -158,7 +158,7 @@ public class CassandraQueryMethod extends QueryMethod {
*/
@Nullable
public String getAnnotatedQuery() {
return query.map(Query::value).orElse(null);
return this.query.map(Query::value).orElse(null);
}
/**
@@ -177,7 +177,7 @@ public class CassandraQueryMethod extends QueryMethod {
* @throws IllegalStateException if the required annotation was not found.
*/
public ConsistencyLevel getRequiredAnnotatedConsistencyLevel() throws IllegalStateException {
return consistency.map(Consistency::value)
return this.consistency.map(Consistency::value)
.orElseThrow(() -> new IllegalStateException("No @Consistency annotation found"));
}
@@ -189,7 +189,7 @@ public class CassandraQueryMethod extends QueryMethod {
* @throws IllegalStateException in case query method has no annotated query.
*/
public String getRequiredAnnotatedQuery() {
return query.map(Query::value)
return this.query.map(Query::value)
.orElseThrow(() -> new IllegalStateException("Query method " + this + " has no annotated query"));
}
@@ -199,7 +199,7 @@ public class CassandraQueryMethod extends QueryMethod {
* @return the optional query annotation.
*/
Optional<Query> getQueryAnnotation() {
return query;
return this.query;
}
@Override
@@ -211,7 +211,7 @@ public class CassandraQueryMethod extends QueryMethod {
* @return the return type for this {@link QueryMethod}.
*/
public TypeInformation<?> getReturnType() {
return ClassTypeInformation.fromReturnTypeOf(method);
return ClassTypeInformation.fromReturnTypeOf(this.method);
}
/**
@@ -220,6 +220,7 @@ public class CassandraQueryMethod extends QueryMethod {
public boolean isResultSetQuery() {
TypeInformation<?> actualType = getReturnType().getActualType();
return actualType != null && ResultSet.class.isAssignableFrom(actualType.getType());
}
}

View File

@@ -15,12 +15,10 @@
*/
package org.springframework.data.cassandra.repository.query;
import lombok.RequiredArgsConstructor;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import lombok.RequiredArgsConstructor;
import org.springframework.data.cassandra.core.CassandraOperations;
import org.springframework.data.convert.CustomConversions;
import org.springframework.data.convert.EntityInstantiators;
@@ -29,11 +27,15 @@ import org.springframework.data.repository.query.ReturnedType;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Base class for Cassandra {@link RepositoryQuery} implementations providing common infrastructure such as
* {@link EntityInstantiators} and {@link QueryStatementCreator}.
*
* @author Mark Paluch
* @see org.springframework.data.repository.query.RepositoryQuery
* @since 2.0
*/
public abstract class CassandraRepositoryQuerySupport implements RepositoryQuery {
@@ -86,31 +88,31 @@ public abstract class CassandraRepositoryQuerySupport implements RepositoryQuery
boolean isProjecting() {
if (!returnedType.isProjecting()) {
if (!this.returnedType.isProjecting()) {
return false;
}
// Spring Data Cassandra allows List<Map<String, Object> and Map<String, Object> declarations
// on query methods so we don't want to let projection kick in
if (ClassUtils.isAssignable(Map.class, returnedType.getReturnedType())) {
if (ClassUtils.isAssignable(Map.class, this.returnedType.getReturnedType())) {
return false;
}
// Type conversion using registered conversions is handled on template level
if (customConversions.hasCustomWriteTarget(returnedType.getReturnedType())) {
if (this.customConversions.hasCustomWriteTarget(this.returnedType.getReturnedType())) {
return false;
}
// Don't apply projection on Cassandra simple types
return !customConversions.isSimpleType(returnedType.getReturnedType());
return !this.customConversions.isSimpleType(this.returnedType.getReturnedType());
}
Class<?> getDomainType() {
return returnedType.getDomainType();
return this.returnedType.getDomainType();
}
Class<?> getReturnedType() {
return returnedType.getReturnedType();
return this.returnedType.getReturnedType();
}
}
}

View File

@@ -41,6 +41,7 @@ import com.datastax.driver.core.TypeCodec;
* convert parameters.
*
* @author Mark Paluch
* @see org.springframework.data.cassandra.repository.query.ConvertingParameterAccessor
* @since 1.5
*/
class ConvertingParameterAccessor implements CassandraParameterAccessor {
@@ -62,7 +63,7 @@ class ConvertingParameterAccessor implements CassandraParameterAccessor {
*/
@Override
public Pageable getPageable() {
return delegate.getPageable();
return this.delegate.getPageable();
}
/* (non-Javadoc)
@@ -70,7 +71,7 @@ class ConvertingParameterAccessor implements CassandraParameterAccessor {
*/
@Override
public Sort getSort() {
return delegate.getSort();
return this.delegate.getSort();
}
/* (non-Javadoc)
@@ -78,7 +79,7 @@ class ConvertingParameterAccessor implements CassandraParameterAccessor {
*/
@Override
public Optional<Class<?>> getDynamicProjection() {
return delegate.getDynamicProjection();
return this.delegate.getDynamicProjection();
}
/* (non-Javadoc)
@@ -86,15 +87,7 @@ class ConvertingParameterAccessor implements CassandraParameterAccessor {
*/
@Override
public Object getBindableValue(int index) {
return potentiallyConvert(index, delegate.getBindableValue(index));
}
/* (non-Javadoc)
* @see org.springframework.data.cassandra.repository.query.CassandraParameterAccessor#getDataType(int)
*/
@Override
public DataType getDataType(int index) {
return delegate.getDataType(index);
return potentiallyConvert(index, this.delegate.getBindableValue(index));
}
/* (non-Javadoc)
@@ -102,7 +95,15 @@ class ConvertingParameterAccessor implements CassandraParameterAccessor {
*/
@Override
public CassandraType findCassandraType(int index) {
return delegate.findCassandraType(index);
return this.delegate.findCassandraType(index);
}
/* (non-Javadoc)
* @see org.springframework.data.cassandra.repository.query.CassandraParameterAccessor#getDataType(int)
*/
@Override
public DataType getDataType(int index) {
return this.delegate.getDataType(index);
}
@@ -111,7 +112,7 @@ class ConvertingParameterAccessor implements CassandraParameterAccessor {
*/
@Override
public Class<?> getParameterType(int index) {
return delegate.getParameterType(index);
return this.delegate.getParameterType(index);
}
/* (non-Javadoc)
@@ -120,7 +121,7 @@ class ConvertingParameterAccessor implements CassandraParameterAccessor {
@Nullable
@Override
public QueryOptions getQueryOptions() {
return delegate.getQueryOptions();
return this.delegate.getQueryOptions();
}
/* (non-Javadoc)
@@ -128,14 +129,14 @@ class ConvertingParameterAccessor implements CassandraParameterAccessor {
*/
@Override
public boolean hasBindableNullValue() {
return delegate.hasBindableNullValue();
return this.delegate.hasBindableNullValue();
}
/* (non-Javadoc)
* @see org.springframework.data.repository.query.ParameterAccessor#iterator()
*/
public Iterator<Object> iterator() {
return new ConvertingIterator(delegate.iterator());
return new ConvertingIterator(this.delegate.iterator());
}
/* (non-Javadoc)
@@ -143,7 +144,7 @@ class ConvertingParameterAccessor implements CassandraParameterAccessor {
*/
@Override
public Object[] getValues() {
return delegate.getValues();
return this.delegate.getValues();
}
@SuppressWarnings("unchecked")
@@ -154,21 +155,23 @@ class ConvertingParameterAccessor implements CassandraParameterAccessor {
return null;
}
return converter.convertToColumnType(bindableValue, findTypeInformation(index, bindableValue, null));
return this.converter.convertToColumnType(bindableValue,
findTypeInformation(index, bindableValue, null));
}
@SuppressWarnings("unchecked")
@Nullable
private Object potentiallyConvert(int index, @Nullable Object bindableValue, CassandraPersistentProperty property) {
return (bindableValue == null ? null
: converter.convertToColumnType(bindableValue, findTypeInformation(index, bindableValue, property)));
return (bindableValue == null ? null : this.converter.convertToColumnType(bindableValue,
findTypeInformation(index, bindableValue, property)));
}
private TypeInformation<?> findTypeInformation(int index, Object bindableValue,
@Nullable CassandraPersistentProperty property) {
if (delegate.findCassandraType(index) != null) {
if (this.delegate.findCassandraType(index) != null) {
TypeCodec<?> typeCodec = CodecRegistry.DEFAULT_INSTANCE.codecFor(getDataType(index, property));
if (typeCodec.getJavaType().getType() instanceof Class<?>) {
@@ -195,7 +198,7 @@ class ConvertingParameterAccessor implements CassandraParameterAccessor {
*/
DataType getDataType(int index, @Nullable CassandraPersistentProperty property) {
CassandraType cassandraType = delegate.findCassandraType(index);
CassandraType cassandraType = this.delegate.findCassandraType(index);
if (cassandraType != null) {
return CassandraSimpleTypeHolder.getDataTypeFor(cassandraType.type());
@@ -272,7 +275,7 @@ class ConvertingParameterAccessor implements CassandraParameterAccessor {
* @see java.util.Iterator#hasNext()
*/
public boolean hasNext() {
return delegate.hasNext();
return this.delegate.hasNext();
}
/*
@@ -281,7 +284,7 @@ class ConvertingParameterAccessor implements CassandraParameterAccessor {
*/
@Nullable
public Object next() {
return potentiallyConvert(index++, delegate.next());
return potentiallyConvert(this.index++, this.delegate.next());
}
/*
@@ -289,7 +292,7 @@ class ConvertingParameterAccessor implements CassandraParameterAccessor {
* @see java.util.Iterator#remove()
*/
public void remove() {
delegate.remove();
this.delegate.remove();
}
/* (non-Javadoc)
@@ -298,7 +301,7 @@ class ConvertingParameterAccessor implements CassandraParameterAccessor {
@Nullable
@Override
public Object nextConverted(CassandraPersistentProperty property) {
return potentiallyConvert(index++, delegate.next(), property);
return potentiallyConvert(this.index++, this.delegate.next(), property);
}
}
@@ -316,5 +319,6 @@ class ConvertingParameterAccessor implements CassandraParameterAccessor {
*/
@Nullable
Object nextConverted(CassandraPersistentProperty property);
}
}

View File

@@ -34,6 +34,7 @@ import com.datastax.driver.core.Statement;
*
* @author Matthew Adams
* @author Mark Paluch
* @see org.springframework.data.cassandra.repository.query.AbstractCassandraQuery
*/
public class PartTreeCassandraQuery extends AbstractCassandraQuery {

View File

@@ -15,12 +15,10 @@
*/
package org.springframework.data.cassandra.repository.query;
import lombok.RequiredArgsConstructor;
import java.util.Optional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import lombok.RequiredArgsConstructor;
import org.springframework.data.cassandra.core.StatementFactory;
import org.springframework.data.cassandra.core.cql.QueryOptions;
import org.springframework.data.cassandra.core.cql.QueryOptionsUtil;
@@ -31,6 +29,9 @@ import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.repository.query.QueryCreationException;
import org.springframework.data.repository.query.parser.PartTree;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.datastax.driver.core.RegularStatement;
import com.datastax.driver.core.SimpleStatement;
import com.datastax.driver.core.Statement;
@@ -72,7 +73,7 @@ class QueryStatementCreator {
query = query.limit(tree.getMaxResults());
}
if (queryMethod.getQueryAnnotation().map(org.springframework.data.cassandra.repository.Query::allowFiltering)
if (this.queryMethod.getQueryAnnotation().map(org.springframework.data.cassandra.repository.Query::allowFiltering)
.orElse(false)) {
query = query.withAllowFiltering();
@@ -82,13 +83,14 @@ class QueryStatementCreator {
if (queryOptions.isPresent()) {
query = Optional.ofNullable(parameterAccessor.getQueryOptions()).map(query::queryOptions).orElse(query);
} else if (queryMethod.hasConsistencyLevel()) {
query = query.queryOptions(
QueryOptions.builder().consistencyLevel(queryMethod.getRequiredAnnotatedConsistencyLevel()).build());
} else if (this.queryMethod.hasConsistencyLevel()) {
query = query.queryOptions(QueryOptions.builder()
.consistencyLevel(this.queryMethod.getRequiredAnnotatedConsistencyLevel())
.build());
}
CassandraPersistentEntity<?> persistentEntity = mappingContext
.getRequiredPersistentEntity(queryMethod.getDomainClass());
CassandraPersistentEntity<?> persistentEntity =
mappingContext.getRequiredPersistentEntity(queryMethod.getDomainClass());
RegularStatement statement = statementFactory.select(query, persistentEntity);
@@ -114,7 +116,7 @@ class QueryStatementCreator {
try {
SimpleStatement boundQuery = stringBasedQuery.bindQuery(parameterAccessor, queryMethod);
SimpleStatement boundQuery = stringBasedQuery.bindQuery(parameterAccessor, this.queryMethod);
Optional<QueryOptions> queryOptions = Optional.ofNullable(parameterAccessor.getQueryOptions());
@@ -123,8 +125,8 @@ class QueryStatementCreator {
if (queryOptions.isPresent()) {
queryToUse = Optional.ofNullable(parameterAccessor.getQueryOptions())
.map(it -> QueryOptionsUtil.addQueryOptions(boundQuery, it)).orElse(boundQuery);
} else if (queryMethod.hasConsistencyLevel()) {
queryToUse.setConsistencyLevel(queryMethod.getRequiredAnnotatedConsistencyLevel());
} else if (this.queryMethod.hasConsistencyLevel()) {
queryToUse.setConsistencyLevel(this.queryMethod.getRequiredAnnotatedConsistencyLevel());
}
if (LOG.isDebugEnabled()) {
@@ -133,7 +135,7 @@ class QueryStatementCreator {
return queryToUse;
} catch (RuntimeException e) {
throw QueryCreationException.create(queryMethod, e);
throw QueryCreationException.create(this.queryMethod, e);
}
}
}

View File

@@ -31,6 +31,7 @@ import com.datastax.driver.core.Statement;
* Reactive PartTree {@link RepositoryQuery} implementation for Cassandra.
*
* @author Mark Paluch
* @see org.springframework.data.cassandra.repository.query.AbstractReactiveCassandraQuery
* @since 2.0
*/
public class ReactivePartTreeCassandraQuery extends AbstractReactiveCassandraQuery {
@@ -94,6 +95,6 @@ public class ReactivePartTreeCassandraQuery extends AbstractReactiveCassandraQue
*/
@Override
protected Statement createQuery(CassandraParameterAccessor parameterAccessor) {
return getQueryStatementCreator().select(statementFactory, getTree(), getMappingContext(), parameterAccessor);
return getQueryStatementCreator().select(getStatementFactory(), getTree(), getMappingContext(), parameterAccessor);
}
}

View File

@@ -30,8 +30,9 @@ import com.datastax.driver.core.SimpleStatement;
* index-based and expression parameters that are resolved during query execution.
*
* @author Mark Paluch
* @since 2.0
* @see org.springframework.data.cassandra.repository.Query
* @see org.springframework.data.cassandra.repository.query.AbstractReactiveCassandraQuery
* @since 2.0
*/
public class ReactiveStringBasedCassandraQuery extends AbstractReactiveCassandraQuery {

View File

@@ -31,6 +31,7 @@ import com.datastax.driver.core.SimpleStatement;
* @author Matthew Adams
* @author Mark Paluch
* @see org.springframework.data.cassandra.repository.Query
* @see org.springframework.data.cassandra.repository.query.AbstractCassandraQuery
*/
public class StringBasedCassandraQuery extends AbstractCassandraQuery {

View File

@@ -113,6 +113,7 @@ class StringBasedQuery {
int startIndex = 0;
int currentPosition = 0;
int parameterIndex = 0;
Matcher matcher = ARGUMENT_PLACEHOLDER_PATTERN.matcher(input);
while (currentPosition < input.length()) {
@@ -147,11 +148,12 @@ class StringBasedQuery {
private static final char CURRLY_BRACE_OPEN = '{';
private static final char CURRLY_BRACE_CLOSE = '}';
private static final Pattern INDEX_PARAMETER_BINDING_PATTERN = Pattern.compile("\\?(\\d+)");
private static final Pattern NAMED_PARAMETER_BINDING_PATTERN = Pattern.compile("\\:(\\w+)");
private static final Pattern INDEX_BASED_EXPRESSION_PATTERN = Pattern.compile("\\?\\#\\{");
private static final Pattern NAME_BASED_EXPRESSION_PATTERN = Pattern.compile("\\:\\#\\{");
private static final String ARGUMENT_PLACEHOLDER = "?_param_?";
/**
@@ -221,8 +223,7 @@ class StringBasedQuery {
.expression(input.substring(exprStart + 3, currentPosition - 1), true));
} else {
if (matcher.pattern() == INDEX_PARAMETER_BINDING_PATTERN) {
bindings
.add(ExpressionEvaluatingParameterBinder.ParameterBinding.indexed(Integer.parseInt(matcher.group(1))));
bindings.add(ExpressionEvaluatingParameterBinder.ParameterBinding.indexed(Integer.parseInt(matcher.group(1))));
} else {
bindings.add(ExpressionEvaluatingParameterBinder.ParameterBinding.named(matcher.group(1)));
}

View File

@@ -15,12 +15,12 @@
*/
package org.springframework.data.cassandra.repository.support;
import lombok.experimental.UtilityClass;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import lombok.experimental.UtilityClass;
import org.springframework.data.cassandra.core.convert.CassandraConverter;
import org.springframework.data.cassandra.core.mapping.CassandraPersistentEntity;

View File

@@ -15,16 +15,16 @@
*/
package org.springframework.data.cassandra.repository.query;
import static org.assertj.core.api.Assertions.*;
import static org.assertj.core.api.Assertions.assertThat;
import java.lang.reflect.Method;
import java.util.List;
import com.datastax.driver.core.policies.DowngradingConsistencyRetryPolicy;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.data.cassandra.core.cql.QueryOptions;
import org.springframework.data.cassandra.core.mapping.CassandraMappingContext;
import org.springframework.data.cassandra.core.mapping.CassandraType;
@@ -33,10 +33,12 @@ import org.springframework.data.projection.ProjectionFactory;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.data.repository.core.support.DefaultRepositoryMetadata;
import org.threeten.bp.LocalDateTime;
import com.datastax.driver.core.DataType;
import com.datastax.driver.core.DataType.Name;
import com.datastax.driver.core.policies.DowngradingConsistencyRetryPolicy;
/**
* Unit tests for {@link CassandraParametersParameterAccessor}.

View File

@@ -15,8 +15,8 @@
*/
package org.springframework.data.cassandra.repository.query;
import static org.assertj.core.api.Assertions.*;
import static org.mockito.Mockito.*;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.when;
import java.lang.reflect.Method;
import java.util.Arrays;
@@ -30,6 +30,7 @@ import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.data.cassandra.core.CassandraOperations;
import org.springframework.data.cassandra.core.convert.CassandraConverter;
import org.springframework.data.cassandra.core.convert.MappingCassandraConverter;

View File

@@ -15,18 +15,15 @@
*/
package org.springframework.data.cassandra.repository.query;
import static org.assertj.core.api.Assertions.*;
import static org.mockito.Mockito.*;
import com.datastax.driver.core.ConsistencyLevel;
import org.springframework.data.cassandra.repository.Consistency;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import rx.Single;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.when;
import java.lang.reflect.Method;
import java.util.Arrays;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -34,12 +31,14 @@ import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.data.cassandra.core.ReactiveCassandraOperations;
import org.springframework.data.cassandra.core.convert.MappingCassandraConverter;
import org.springframework.data.cassandra.core.cql.QueryOptions;
import org.springframework.data.cassandra.core.mapping.CassandraMappingContext;
import org.springframework.data.cassandra.core.mapping.UserTypeResolver;
import org.springframework.data.cassandra.domain.Person;
import org.springframework.data.cassandra.repository.Consistency;
import org.springframework.data.cassandra.repository.MapIdCassandraRepository;
import org.springframework.data.cassandra.repository.Query;
import org.springframework.data.projection.ProjectionFactory;
@@ -47,8 +46,11 @@ import org.springframework.data.projection.SpelAwareProxyProjectionFactory;
import org.springframework.data.repository.core.support.DefaultRepositoryMetadata;
import org.springframework.util.ClassUtils;
import com.datastax.driver.core.ConsistencyLevel;
import com.datastax.driver.core.Statement;
import rx.Single;
/**
* Unit tests for {@link ReactivePartTreeCassandraQuery}.
*

View File

@@ -15,16 +15,16 @@
*/
package org.springframework.data.cassandra.repository.query;
import static org.assertj.core.api.Assertions.*;
import static org.assertj.core.api.Assertions.assertThat;
import java.lang.reflect.Method;
import com.datastax.driver.core.ConsistencyLevel;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.data.cassandra.ReactiveSession;
import org.springframework.data.cassandra.core.ReactiveCassandraOperations;
import org.springframework.data.cassandra.core.convert.MappingCassandraConverter;
@@ -45,6 +45,7 @@ import org.springframework.util.ReflectionUtils;
import com.datastax.driver.core.Cluster;
import com.datastax.driver.core.Configuration;
import com.datastax.driver.core.ConsistencyLevel;
import com.datastax.driver.core.SimpleStatement;
/**
@@ -96,12 +97,13 @@ public class ReactiveStringBasedCassandraQueryUnitTests {
QueryOptions queryOptions = QueryOptions.builder().fetchSize(777).build();
ReactiveStringBasedCassandraQuery cassandraQuery = getQueryMethod("findByLastname", QueryOptions.class,
String.class);
CassandraParametersParameterAccessor accessor = new CassandraParametersParameterAccessor(
cassandraQuery.getQueryMethod(), queryOptions, "White");
ReactiveStringBasedCassandraQuery cassandraQuery =
getQueryMethod("findByLastname", QueryOptions.class, String.class);
SimpleStatement actual = cassandraQuery.createQuery(accessor);
CassandraParametersParameterAccessor parameterAccessor =
new CassandraParametersParameterAccessor(cassandraQuery.getQueryMethod(), queryOptions, "White");
SimpleStatement actual = cassandraQuery.createQuery(parameterAccessor);
assertThat(actual.toString()).isEqualTo("SELECT * FROM person WHERE lastname=?;");
assertThat(actual.getObject(0)).isEqualTo("White");
@@ -112,10 +114,11 @@ public class ReactiveStringBasedCassandraQueryUnitTests {
public void shouldApplyConsistencyLevel() {
ReactiveStringBasedCassandraQuery cassandraQuery = getQueryMethod("findByLastname", String.class);
CassandraParametersParameterAccessor accessor = new CassandraParametersParameterAccessor(
cassandraQuery.getQueryMethod(), "Matthews");
SimpleStatement actual = cassandraQuery.createQuery(accessor);
CassandraParametersParameterAccessor parameterAccessor =
new CassandraParametersParameterAccessor(cassandraQuery.getQueryMethod(), "Matthews");
SimpleStatement actual = cassandraQuery.createQuery(parameterAccessor);
assertThat(actual.toString()).isEqualTo("SELECT * FROM person WHERE lastname=?;");
assertThat(actual.getObject(0)).isEqualTo("Matthews");
@@ -125,8 +128,9 @@ public class ReactiveStringBasedCassandraQueryUnitTests {
private ReactiveStringBasedCassandraQuery getQueryMethod(String name, Class<?>... args) {
Method method = ReflectionUtils.findMethod(SampleRepository.class, name, args);
ReactiveCassandraQueryMethod queryMethod = new ReactiveCassandraQueryMethod(method, metadata, factory,
converter.getMappingContext());
ReactiveCassandraQueryMethod queryMethod =
new ReactiveCassandraQueryMethod(method, metadata, factory, converter.getMappingContext());
return new ReactiveStringBasedCassandraQuery(queryMethod, operations, PARSER,
new ExtensionAwareEvaluationContextProvider());

View File

@@ -15,8 +15,8 @@
*/
package org.springframework.data.cassandra.repository.query;
import static org.assertj.core.api.Assertions.*;
import static org.mockito.Mockito.*;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.when;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -27,12 +27,12 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import com.datastax.driver.core.ConsistencyLevel;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.data.cassandra.core.CassandraOperations;
import org.springframework.data.cassandra.core.convert.MappingCassandraConverter;
import org.springframework.data.cassandra.core.cql.CqlIdentifier;
@@ -55,6 +55,7 @@ import org.springframework.data.repository.query.QueryCreationException;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.util.ReflectionUtils;
import com.datastax.driver.core.ConsistencyLevel;
import com.datastax.driver.core.DataType;
import com.datastax.driver.core.SimpleStatement;
import com.datastax.driver.core.UDTValue;
@@ -85,6 +86,7 @@ public class StringBasedCassandraQueryUnitTests {
public void setUp() {
CassandraMappingContext mappingContext = new CassandraMappingContext();
mappingContext.setUserTypeResolver(userTypeResolver);
this.metadata = AbstractRepositoryMetadata.getMetadata(SampleRepository.class);
@@ -344,10 +346,11 @@ public class StringBasedCassandraQueryUnitTests {
QueryOptions queryOptions = QueryOptions.builder().fetchSize(777).build();
StringBasedCassandraQuery cassandraQuery = getQueryMethod("findByLastname", QueryOptions.class, String.class);
CassandraParametersParameterAccessor accessor = new CassandraParametersParameterAccessor(
cassandraQuery.getQueryMethod(), queryOptions, "Matthews");
SimpleStatement actual = cassandraQuery.createQuery(accessor);
CassandraParametersParameterAccessor parameterAccessor =
new CassandraParametersParameterAccessor(cassandraQuery.getQueryMethod(), queryOptions, "Matthews");
SimpleStatement actual = cassandraQuery.createQuery(parameterAccessor);
assertThat(actual.toString()).isEqualTo("SELECT * FROM person WHERE lastname = ?;");
assertThat(actual.getObject(0)).isEqualTo("Matthews");
@@ -358,10 +361,11 @@ public class StringBasedCassandraQueryUnitTests {
public void shouldApplyConsistencyLevel() {
StringBasedCassandraQuery cassandraQuery = getQueryMethod("findByLastname", String.class);
CassandraParametersParameterAccessor accessor = new CassandraParametersParameterAccessor(
cassandraQuery.getQueryMethod(), "Matthews");
SimpleStatement actual = cassandraQuery.createQuery(accessor);
CassandraParametersParameterAccessor parameterAccessor =
new CassandraParametersParameterAccessor(cassandraQuery.getQueryMethod(), "Matthews");
SimpleStatement actual = cassandraQuery.createQuery(parameterAccessor);
assertThat(actual.toString()).isEqualTo("SELECT * FROM person WHERE lastname = ?;");
assertThat(actual.getObject(0)).isEqualTo("Matthews");
@@ -371,8 +375,10 @@ public class StringBasedCassandraQueryUnitTests {
private StringBasedCassandraQuery getQueryMethod(String name, Class<?>... args) {
Method method = ReflectionUtils.findMethod(SampleRepository.class, name, args);
CassandraQueryMethod queryMethod = new CassandraQueryMethod(method, metadata, factory,
converter.getMappingContext());
CassandraQueryMethod queryMethod =
new CassandraQueryMethod(method, metadata, factory, converter.getMappingContext());
return new StringBasedCassandraQuery(queryMethod, operations, PARSER,
new ExtensionAwareEvaluationContextProvider());
}