DATACOUCH-64 - Enable dynamic queries on repositories.
This changeset adds dynamic queries that can be annotated with @View and also provide a custom Query param to change properties at runtime if needed.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013 the original author or authors.
|
||||
* Copyright 2013, 2014 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.
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.data.couchbase.repository.query;
|
||||
|
||||
import org.springframework.data.repository.core.EntityInformation;
|
||||
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@@ -26,4 +27,5 @@ import java.io.Serializable;
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
public interface CouchbaseEntityInformation<T, ID extends Serializable> extends EntityInformation<T, ID> {
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2013, 2014 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 org.springframework.data.couchbase.core.mapping.CouchbasePersistentEntity;
|
||||
import org.springframework.data.couchbase.core.mapping.CouchbasePersistentProperty;
|
||||
import org.springframework.data.couchbase.core.view.View;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.repository.core.RepositoryMetadata;
|
||||
import org.springframework.data.repository.query.QueryMethod;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* Represents a query method with couchbase extensions.
|
||||
*
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
public class CouchbaseQueryMethod extends QueryMethod {
|
||||
|
||||
private final Method method;
|
||||
private final MappingContext<? extends CouchbasePersistentEntity<?>, CouchbasePersistentProperty> mappingContext;
|
||||
|
||||
public CouchbaseQueryMethod(Method method, RepositoryMetadata metadata,
|
||||
MappingContext<? extends CouchbasePersistentEntity<?>, CouchbasePersistentProperty> mappingContext) {
|
||||
super(method, metadata);
|
||||
|
||||
this.method = method;
|
||||
this.mappingContext = mappingContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the method has a @View annotation.
|
||||
*
|
||||
* @return true if it has the annotation, false otherwise.
|
||||
*/
|
||||
public boolean hasViewAnnotation() {
|
||||
return getViewAnnotation() != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the @View annoation if set, null otherwise.
|
||||
*
|
||||
* @return the view annotation of present.
|
||||
*/
|
||||
public View getViewAnnotation() {
|
||||
return method.getAnnotation(View.class);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright 2013, 2014 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 com.couchbase.client.protocol.views.Query;
|
||||
import org.springframework.data.couchbase.core.CouchbaseOperations;
|
||||
import org.springframework.data.repository.query.QueryMethod;
|
||||
import org.springframework.data.repository.query.RepositoryQuery;
|
||||
|
||||
/**
|
||||
* Execute a repository query through the View mechanism.
|
||||
*
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
public class ViewBasedCouchbaseQuery implements RepositoryQuery {
|
||||
|
||||
private final CouchbaseQueryMethod method;
|
||||
private final CouchbaseOperations operations;
|
||||
|
||||
public ViewBasedCouchbaseQuery(CouchbaseQueryMethod method, CouchbaseOperations operations) {
|
||||
this.method = method;
|
||||
this.operations = operations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object execute(Object[] runtimeParams) {
|
||||
Query query = null;
|
||||
for (Object param : runtimeParams) {
|
||||
if (param instanceof Query) {
|
||||
query = (Query) param;
|
||||
} else {
|
||||
throw new IllegalStateException("Unknown query param: " + param);
|
||||
}
|
||||
}
|
||||
|
||||
if (query == null) {
|
||||
query = new Query();
|
||||
}
|
||||
query.setReduce(false);
|
||||
|
||||
return operations.findByView(designDocName(), viewName(), query, method.getEntityInformation().getJavaType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryMethod getQueryMethod() {
|
||||
return method;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the best-guess design document name.
|
||||
*
|
||||
* @return the design document name.
|
||||
*/
|
||||
private String designDocName() {
|
||||
if (method.hasViewAnnotation()) {
|
||||
return method.getViewAnnotation().designDocument();
|
||||
} else {
|
||||
return method.getEntityInformation().getJavaType().getSimpleName().toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the best-guess view name.
|
||||
*
|
||||
* @return the view name.
|
||||
*/
|
||||
private String viewName() {
|
||||
if (method.hasViewAnnotation()) {
|
||||
return method.getViewAnnotation().viewName();
|
||||
} else {
|
||||
return method.getName();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -19,14 +19,21 @@ package org.springframework.data.couchbase.repository.support;
|
||||
import org.springframework.data.couchbase.core.CouchbaseOperations;
|
||||
import org.springframework.data.couchbase.core.mapping.CouchbasePersistentEntity;
|
||||
import org.springframework.data.couchbase.core.mapping.CouchbasePersistentProperty;
|
||||
import org.springframework.data.couchbase.core.view.View;
|
||||
import org.springframework.data.couchbase.repository.query.CouchbaseEntityInformation;
|
||||
import org.springframework.data.couchbase.repository.query.CouchbaseQueryMethod;
|
||||
import org.springframework.data.couchbase.repository.query.ViewBasedCouchbaseQuery;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mapping.model.MappingException;
|
||||
import org.springframework.data.repository.core.NamedQueries;
|
||||
import org.springframework.data.repository.core.RepositoryMetadata;
|
||||
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
|
||||
import org.springframework.data.repository.query.QueryLookupStrategy;
|
||||
import org.springframework.data.repository.query.RepositoryQuery;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* Factory to create {@link SimpleCouchbaseRepository} instances.
|
||||
@@ -112,4 +119,20 @@ public class CouchbaseRepositoryFactory extends RepositoryFactorySupport {
|
||||
return SimpleCouchbaseRepository.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected QueryLookupStrategy getQueryLookupStrategy(QueryLookupStrategy.Key key) {
|
||||
return new CouchbaseQueryLookupStrategy();
|
||||
}
|
||||
|
||||
/**
|
||||
* Currently, only views are supported. N1QL support to be added.
|
||||
*/
|
||||
private class CouchbaseQueryLookupStrategy implements QueryLookupStrategy {
|
||||
@Override
|
||||
public RepositoryQuery resolveQuery(Method method, RepositoryMetadata metadata, NamedQueries namedQueries) {
|
||||
CouchbaseQueryMethod queryMethod = new CouchbaseQueryMethod(method, metadata, mappingContext);
|
||||
return new ViewBasedCouchbaseQuery(queryMethod, couchbaseOperations);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user