From ed2b576261521ae2c9dbb7f5ab0d72ba183a312d Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Thu, 13 Sep 2012 10:54:23 +0200 Subject: [PATCH] DATAMONGO-538 - Query API can now work with Sort and Pageable from Spring Data Commons. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduced with(Sort sort) and with(Pageable pageable) on Query. Deprecated sort() method and the custom Sort class. Deprecated QueryUtils.applyPagination(…) and ….applySorting(…) and changed internal calls to this to use the Query API directly. Some JavaDoc polishing. --- .../data/mongodb/core/query/Query.java | 82 +++++++++++++++++-- .../data/mongodb/core/query/Sort.java | 13 ++- .../repository/query/AbstractMongoQuery.java | 12 +-- .../repository/query/MongoQueryCreator.java | 3 +- .../mongodb/repository/query/QueryUtils.java | 15 ++-- .../query/StringBasedMongoQuery.java | 4 +- .../support/SimpleMongoRepository.java | 10 +-- .../core/query/BasicQueryUnitTests.java | 7 +- .../data/mongodb/core/query/QueryTests.java | 26 ++++++ .../data/mongodb/core/query/SortTests.java | 6 +- 10 files changed, 139 insertions(+), 39 deletions(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Query.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Query.java index c92fa335d..e4edae82f 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Query.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Query.java @@ -1,5 +1,5 @@ /* - * Copyright 2010-2011 the original author or authors. + * Copyright 2010-2012 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. @@ -22,17 +22,25 @@ import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; import org.springframework.data.mongodb.InvalidMongoDbApiUsageException; import org.springframework.util.Assert; import com.mongodb.BasicDBObject; import com.mongodb.DBObject; +/** + * @author Thomas Risberg + * @author Oliver Gierke + */ public class Query { private LinkedHashMap criteria = new LinkedHashMap(); private Field fieldSpec; - private Sort sort; + private Sort coreSort; + @SuppressWarnings("deprecation") + private org.springframework.data.mongodb.core.query.Sort sort; private int skip; private int limit; private String hint; @@ -96,14 +104,61 @@ public class Query { return this; } - public Sort sort() { + /** + * Returns a {@link org.springframework.data.mongodb.core.query.Sort} instance to define ordering properties. + * + * @deprecated use {@link #with(Sort)} instead + * @return + */ + @Deprecated + public org.springframework.data.mongodb.core.query.Sort sort() { if (this.sort == null) { - this.sort = new Sort(); + this.sort = new org.springframework.data.mongodb.core.query.Sort(); } return this.sort; } + /** + * Sets the given pagination information on the {@link Query} instance. Will transparently set {@code skip} and + * {@code limit} as well as applying the {@link Sort} instance defined with the {@link Pageable}. + * + * @param pageable + * @return + */ + public Query with(Pageable pageable) { + + if (pageable == null) { + return this; + } + + this.limit = pageable.getPageSize(); + this.skip = pageable.getOffset(); + + return with(pageable.getSort()); + } + + /** + * Adds a {@link Sort} to the {@link Query} instance. + * + * @param sort + * @return + */ + public Query with(Sort sort) { + + if (sort == null) { + return this; + } + + if (this.coreSort == null) { + this.coreSort = sort; + } else { + this.coreSort = this.coreSort.and(sort); + } + + return this; + } + public DBObject getQueryObject() { DBObject dbo = new BasicDBObject(); for (String k : criteria.keySet()) { @@ -121,11 +176,26 @@ public class Query { return fieldSpec.getFieldsObject(); } + @SuppressWarnings("deprecation") public DBObject getSortObject() { - if (this.sort == null) { + + if (this.coreSort == null && this.sort == null) { return null; } - return this.sort.getSortObject(); + + DBObject dbo = new BasicDBObject(); + + if (this.coreSort != null) { + for (org.springframework.data.domain.Sort.Order order : this.coreSort) { + dbo.put(order.getProperty(), order.isAscending() ? 1 : -1); + } + } + + if (this.sort != null) { + dbo.putAll(this.sort.getSortObject()); + } + + return dbo; } public int getSkip() { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Sort.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Sort.java index 61d8d0d58..a53682254 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Sort.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Sort.java @@ -1,5 +1,5 @@ /* - * Copyright 2010-2011 the original author or authors. + * Copyright 2010-2012 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. @@ -21,6 +21,15 @@ import java.util.Map; import com.mongodb.BasicDBObject; import com.mongodb.DBObject; +/** + * Helper class to define sorting criterias for a Query instance. + * + * @author Thomas Risberg + * @author Oliver Gierke + * @deprecated use {@link org.springframework.data.domain.Sort} instead. See + * {@link Query#with(org.springframework.data.domain.Sort)}. + */ +@Deprecated public class Sort { private Map fieldSpec = new LinkedHashMap(); @@ -40,7 +49,7 @@ public class Sort { public DBObject getSortObject() { DBObject dbo = new BasicDBObject(); for (String k : fieldSpec.keySet()) { - dbo.put(k, (fieldSpec.get(k).equals(Order.ASCENDING) ? 1 : -1)); + dbo.put(k, fieldSpec.get(k).equals(Order.ASCENDING) ? 1 : -1); } return dbo; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/AbstractMongoQuery.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/AbstractMongoQuery.java index a51f9a0c1..562338a5b 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/AbstractMongoQuery.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/AbstractMongoQuery.java @@ -15,8 +15,6 @@ */ package org.springframework.data.mongodb.repository.query; -import static org.springframework.data.mongodb.repository.query.QueryUtils.*; - import java.util.List; import org.springframework.data.domain.PageImpl; @@ -145,12 +143,7 @@ public abstract class AbstractMongoQuery implements RepositoryQuery { */ @Override public Object execute(Query query) { - - if (pageable != null) { - query = applyPagination(query, pageable); - } - - return readCollection(query); + return readCollection(query.with(pageable)); } } @@ -185,8 +178,7 @@ public abstract class AbstractMongoQuery implements RepositoryQuery { MongoEntityInformation metadata = method.getEntityInformation(); long count = operations.count(query, metadata.getCollectionName()); - List result = operations.find(applyPagination(query, pageable), metadata.getJavaType(), - metadata.getCollectionName()); + List result = operations.find(query.with(pageable), metadata.getJavaType(), metadata.getCollectionName()); return new PageImpl(result, pageable, count); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryCreator.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryCreator.java index 00c5c9128..978cebe3a 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryCreator.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryCreator.java @@ -147,8 +147,7 @@ class MongoQueryCreator extends AbstractQueryCreator { return null; } - Query query = new Query(criteria); - QueryUtils.applySorting(query, sort); + Query query = new Query(criteria).with(sort); if (LOG.isDebugEnabled()) { LOG.debug("Created query " + query); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/QueryUtils.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/QueryUtils.java index febd36774..f769e7c52 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/QueryUtils.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/QueryUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2010-2011 the original author or authors. + * Copyright 2010-2012 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. @@ -15,12 +15,13 @@ */ package org.springframework.data.mongodb.repository.query; -import com.mongodb.DBCursor; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort.Order; import org.springframework.data.mongodb.core.query.Query; +import com.mongodb.DBCursor; + /** * Collection of utility methods to apply sorting and pagination to a {@link DBCursor}. * @@ -36,10 +37,12 @@ public abstract class QueryUtils { * Applies the given {@link Pageable} to the given {@link Query}. Will do nothing if {@link Pageable} is * {@literal null}. * - * @param query + * @deprecated use {@link Query#with(Pageable)}. + * @param query must not be {@literal null}. * @param pageable * @return */ + @Deprecated public static Query applyPagination(Query query, Pageable pageable) { if (pageable == null) { @@ -49,16 +52,18 @@ public abstract class QueryUtils { query.limit(pageable.getPageSize()); query.skip(pageable.getOffset()); - return applySorting(query, pageable.getSort()); + return query.with(pageable.getSort()); } /** * Applies the given {@link Sort} to the {@link Query}. Will do nothing if {@link Sort} is {@literal null}. * - * @param query + * @deprecated use {@link Query#with(Pageable)}. + * @param query must not be {@literal null}. * @param sort * @return */ + @Deprecated public static Query applySorting(Query query, Sort sort) { if (sort == null) { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/StringBasedMongoQuery.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/StringBasedMongoQuery.java index c2e17af60..71ae4ff81 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/StringBasedMongoQuery.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/StringBasedMongoQuery.java @@ -1,5 +1,5 @@ /* - * Copyright 2011 the original author or authors. + * Copyright 2011-2012 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. @@ -73,7 +73,7 @@ public class StringBasedMongoQuery extends AbstractMongoQuery { query = new BasicQuery(queryString); } - QueryUtils.applySorting(query, accessor.getSort()); + query.with(accessor.getSort()); if (LOG.isDebugEnabled()) { LOG.debug(String.format("Created query %s", query.getQueryObject())); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/SimpleMongoRepository.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/SimpleMongoRepository.java index b171e6b66..804b98cc0 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/SimpleMongoRepository.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/SimpleMongoRepository.java @@ -1,5 +1,5 @@ /* - * Copyright 2010-2011 the original author or authors. + * Copyright 2010-2012 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. @@ -34,7 +34,6 @@ import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.repository.MongoRepository; import org.springframework.data.mongodb.repository.query.MongoEntityInformation; -import org.springframework.data.mongodb.repository.query.QueryUtils; import org.springframework.util.Assert; /** @@ -200,7 +199,7 @@ public class SimpleMongoRepository implements MongoR public Page findAll(final Pageable pageable) { Long count = count(); - List list = findAll(QueryUtils.applyPagination(new Query(), pageable)); + List list = findAll(new Query().with(pageable)); return new PageImpl(list, pageable, count); } @@ -209,9 +208,8 @@ public class SimpleMongoRepository implements MongoR * (non-Javadoc) * @see org.springframework.data.repository.PagingAndSortingRepository#findAll(org.springframework.data.domain.Sort) */ - public List findAll(final Sort sort) { - - return findAll(QueryUtils.applySorting(new Query(), sort)); + public List findAll(Sort sort) { + return findAll(new Query().with(sort)); } private List findAll(Query query) { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/BasicQueryUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/BasicQueryUnitTests.java index 5325d7bd4..5e4f3317e 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/BasicQueryUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/BasicQueryUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2011 the original author or authors. + * Copyright 2011-2012 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. @@ -15,11 +15,12 @@ */ package org.springframework.data.mongodb.core.query; -import static org.junit.Assert.*; import static org.hamcrest.CoreMatchers.*; +import static org.junit.Assert.*; import static org.springframework.data.mongodb.core.query.Criteria.*; import org.junit.Test; +import org.springframework.data.domain.Sort.Direction; import com.mongodb.BasicDBObject; import com.mongodb.DBObject; @@ -51,7 +52,7 @@ public class BasicQueryUnitTests { BasicQuery query = new BasicQuery("{}"); query.setSortObject(new BasicDBObject("name", -1)); - query.sort().on("lastname", Order.ASCENDING); + query.with(new org.springframework.data.domain.Sort(Direction.ASC, "lastname")); DBObject sortReference = new BasicDBObject("name", -1); sortReference.put("lastname", 1); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/QueryTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/QueryTests.java index c60d9010f..76bdda8d2 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/QueryTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/QueryTests.java @@ -15,10 +15,13 @@ */ package org.springframework.data.mongodb.core.query; +import static org.hamcrest.CoreMatchers.*; +import static org.junit.Assert.*; import static org.springframework.data.mongodb.core.query.Criteria.*; import org.junit.Assert; import org.junit.Test; +import org.springframework.data.domain.Sort.Direction; import org.springframework.data.mongodb.InvalidMongoDbApiUsageException; public class QueryTests { @@ -144,4 +147,27 @@ public class QueryTests { String expected = "{ \"name\" : { \"$regex\" : \"b.*\" , \"$options\" : \"i\"}}"; Assert.assertEquals(expected, q.getQueryObject().toString()); } + + /** + * @see DATAMONGO-538 + */ + @Test + @SuppressWarnings("deprecation") + public void addsDeprecatedSortCorrectly() { + + Query query = new Query(); + query.sort().on("foo", Order.DESCENDING); + + assertThat(query.getSortObject().toString(), is("{ \"foo\" : -1}")); + } + + /** + * @see DATAMONGO-538 + */ + @Test + public void addsSortCorrectly() { + + Query query = new Query().with(new org.springframework.data.domain.Sort(Direction.DESC, "foo")); + assertThat(query.getSortObject().toString(), is("{ \"foo\" : -1}")); + } } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/SortTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/SortTests.java index c357000a6..e460d2ef9 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/SortTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/SortTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2010-2011 the original author or authors. + * Copyright 2010-2012 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. @@ -15,13 +15,13 @@ */ package org.springframework.data.mongodb.core.query; -import static org.springframework.data.mongodb.core.query.Order.*; import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.*; +import static org.springframework.data.mongodb.core.query.Order.*; import org.junit.Test; -import org.springframework.data.mongodb.core.query.Sort; +@SuppressWarnings("deprecation") public class SortTests { @Test