diff --git a/src/main/java/org/springframework/data/couchbase/core/CouchbaseOperations.java b/src/main/java/org/springframework/data/couchbase/core/CouchbaseOperations.java index 08bb6351..a688d5e6 100644 --- a/src/main/java/org/springframework/data/couchbase/core/CouchbaseOperations.java +++ b/src/main/java/org/springframework/data/couchbase/core/CouchbaseOperations.java @@ -18,7 +18,10 @@ package org.springframework.data.couchbase.core; import java.util.Collection; +import java.util.List; +import com.couchbase.client.protocol.views.Query; +import com.couchbase.client.protocol.views.ViewResponse; import org.springframework.data.couchbase.core.convert.CouchbaseConverter; /** @@ -114,6 +117,42 @@ public interface CouchbaseOperations { */ T findById(String id, Class entityClass); + /** + * Query a View for a list of documents of type T. + * + *

There is no need to {@link Query#setIncludeDocs(boolean)} explicitely, + * because it will be set to true all the time. It is valid to pass in a + * empty constructed {@link Query} object.

+ * + *

This method does not work with reduced views, because they by design + * do not contain references to original objects. Use the provided + * {@link #queryView} method for more flexibility and direct access.

+ * + * @param design the name of the design document. + * @param view the name of the view. + * @param query the Query object to customize the view query. + * @param entityClass the entity to map to. + * @return the converted collection + */ + List findByView(String design, String view, Query query, Class entityClass); + + + /** + * Query a View with direct access to the {@link ViewResponse}. + * + *

This method is available to ease the working with views by still wrapping + * exceptions into the Spring infrastructure.

+ * + *

It is especially needed if you want to run reduced view queries, because + * they can't be mapped onto entities directly.

+ * + * @param design the name of the design document. + * @param view the name of the view. + * @param query the Query object to customize the view query. + * @return + */ + ViewResponse queryView(String design, String view, Query query); + /** * Checks if the given document exists. * diff --git a/src/main/java/org/springframework/data/couchbase/core/CouchbaseTemplate.java b/src/main/java/org/springframework/data/couchbase/core/CouchbaseTemplate.java index 957cd31b..6609cbf6 100644 --- a/src/main/java/org/springframework/data/couchbase/core/CouchbaseTemplate.java +++ b/src/main/java/org/springframework/data/couchbase/core/CouchbaseTemplate.java @@ -16,13 +16,12 @@ package org.springframework.data.couchbase.core; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; +import java.util.*; +import com.couchbase.client.protocol.views.Query; +import com.couchbase.client.protocol.views.View; +import com.couchbase.client.protocol.views.ViewResponse; +import com.couchbase.client.protocol.views.ViewRow; import net.spy.memcached.internal.OperationFuture; import org.springframework.data.couchbase.core.convert.CouchbaseConverter; @@ -158,6 +157,42 @@ public class CouchbaseTemplate implements CouchbaseOperations { return couchbaseConverter.read(entityClass, converted); } + + @Override + public List findByView(final String designName, final String viewName, + final Query query, final Class entityClass) { + + if (!query.willIncludeDocs()) { + query.setIncludeDocs(true); + } + if (query.willReduce()) { + query.setReduce(false); + } + + ViewResponse response = queryView(designName, viewName, query); + + List result = new ArrayList(response.size()); + for (ViewRow row : response) { + ConvertedCouchbaseDocument converted = + new ConvertedCouchbaseDocument(row.getId(), (String) row.getDocument()); + result.add(couchbaseConverter.read(entityClass, converted)); + } + + return result; + } + + @Override + public ViewResponse queryView(final String designName, final String viewName, + final Query query) { + return execute(new BucketCallback() { + @Override + public ViewResponse doInBucket() { + View view = client.getView(designName, viewName); + return client.query(view, query); + } + }); + } + public void remove(final Object objectToRemove) { ensureNotIterable(objectToRemove); diff --git a/src/main/java/org/springframework/data/couchbase/repository/support/SimpleCouchbaseRepository.java b/src/main/java/org/springframework/data/couchbase/repository/support/SimpleCouchbaseRepository.java index a2241e57..b3039d87 100644 --- a/src/main/java/org/springframework/data/couchbase/repository/support/SimpleCouchbaseRepository.java +++ b/src/main/java/org/springframework/data/couchbase/repository/support/SimpleCouchbaseRepository.java @@ -16,9 +16,16 @@ package org.springframework.data.couchbase.repository.support; +import com.couchbase.client.protocol.views.ComplexKey; +import com.couchbase.client.protocol.views.Query; +import com.couchbase.client.protocol.views.ViewResponse; +import com.couchbase.client.protocol.views.ViewRow; import org.springframework.data.couchbase.core.CouchbaseOperations; import org.springframework.data.couchbase.repository.CouchbaseRepository; import org.springframework.data.couchbase.repository.query.CouchbaseEntityInformation; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; import org.springframework.util.Assert; import java.io.Serializable; @@ -98,22 +105,55 @@ public class SimpleCouchbaseRepository implements Co @Override public Iterable findAll() { - throw new UnsupportedOperationException("findAll is not supported in the current version!"); + String design = entityInformation.getJavaType().getSimpleName().toLowerCase(); + String view = "all"; + + return couchbaseOperations.findByView(design, view, new Query().setReduce(false), + entityInformation.getJavaType()); } @Override - public Iterable findAll(Iterable ids) { - throw new UnsupportedOperationException("findAll is not supported in the current version!"); + public Iterable findAll(final Iterable ids) { + String design = entityInformation.getJavaType().getSimpleName().toLowerCase(); + String view = "all"; + + Query query = new Query(); + query.setReduce(false); + query.setKeys(ComplexKey.of(ids)); + + return couchbaseOperations.findByView(design, view, query, entityInformation.getJavaType()); } @Override public long count() { - throw new UnsupportedOperationException("count is not supported in the current version!"); + String design = entityInformation.getJavaType().getSimpleName().toLowerCase(); + String view = "all"; + + Query query = new Query(); + query.setReduce(true); + + ViewResponse response = couchbaseOperations.queryView(design, view, query); + + long count = 0; + for (ViewRow row : response) { + count += Long.parseLong(row.getValue()); + } + + return count; } @Override public void deleteAll() { - throw new UnsupportedOperationException("deleteAll is not supported in the current version!"); + String design = entityInformation.getJavaType().getSimpleName().toLowerCase(); + String view = "all"; + + Query query = new Query(); + query.setReduce(false); + + ViewResponse response = couchbaseOperations.queryView(design, view, query); + for (ViewRow row : response) { + couchbaseOperations.remove(row.getId()); + } } protected CouchbaseOperations getCouchbaseOperations() {