Skip to content

Commit 37113c6

Browse files
authored
DATACOUCH-588 - Part 2 of 2 refactoring for paging and projection. (#1080)
* DATACOUCH-588 - Part 2 of framework changes. Add support for projection and distinct. (#1040) Support for projection is only for properties of the top-level entity. For instance, in UserSubmission, only the properties below can be specified in the projection. Projection support does not provide means of specifying something like address.street - you can only project (or not project) the whole address property. However, the address type in your resultType could have a subset of the properties in Address. If the corresponding submissions in the resultType contained only the userId property public class UserSubmission extends ComparableEntity { private String id; private String username; private List<String> roles; private Address address; private List<Submission> submissions; Support for Distinct - I have appropriated the MongoDB model for Distinct. It defines a separate DistinctOperationSupport class (within ExecutableFindByQuerySupport) which supports the distinct( distinctFields ) api and execution. The DistinctOperationSupport class has only a distinctFields member, and a 'delegate' member, which is an ExecutableFindByQuerySupport object. TBH, I don't see the advantage over simply adding a distinctFields member to ExecutableFindByQuerySupport Amend #1 - changes as discussed in Pull Request - clean up test entity types Amend #2 - Eliminate DistinctOperationSupport class. In MongoDB, only distinct on a single field is supported, so the returnType from distinct was very different from the returnType of other query operations (all(), one() etc. (but so is count(), and it doesn't need it's own class)). In Couchbase, distinct on any fields in the entity is allowed - so the returned type could be the domainType or resultType. And as(resultType) still allows any resultType to be specified. This makes it unnecessary to have combinations of interfaces such as DistinctWithProjection and DistinctWithQuery. - Clean up the interfaces in ExecutableFindByQuery. There are two types of interfaces (a) the TerminatingFindByQuery which has the one(), oneValue() first(), firstValue(), all(), count(), exists() and stream(); and (b) the option interfaces (FindByQueryWithConsistency etc), which are essentially with-er interfaces. The changes are: 1) make all the with-er interfaces base interfaces instead of chaining them together. (I don't know why there isn't simply one interface with all the with-er methods). 2) make the ExecutableFindByQuery interface extend the Terminating interface and all the with-er interfaces. Amend #3 - Add execution support for collections Amend #4 - Add tests for collections. This includes a new CollectionAwareIntegrationTests class which extends a new JavaIntegratationTests class which extends the existing ClusterAwareIntegrationTests. - Fixed up several issues collections issues that were uncovered by the tests. - Did further cleanup of OperationSupport interfaces. Amend #5 - Revert changes to interfaces in *Operation - Sorted interfaces in same order for consistency (because of the chaining of interfaces, fluent methods must be called in order). Co-authored-by: mikereiche <[email protected]> * DATACOUCH-588 - after cherry-pick, remove reference to 4.2 method deleteAllById(). Original pull request #1040
1 parent 570792d commit 37113c6

File tree

78 files changed

+2419
-589
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

78 files changed

+2419
-589
lines changed

pom.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,14 @@
197197
<version>${kotlin}</version>
198198
<scope>test</scope>
199199
</dependency>
200+
201+
<dependency>
202+
<groupId>org.awaitility</groupId>
203+
<artifactId>awaitility</artifactId>
204+
<version>4.0.3</version>
205+
<scope>test</scope>
206+
</dependency>
207+
200208
</dependencies>
201209

202210
<repositories>

src/main/java/org/springframework/data/couchbase/core/ExecutableExistsByIdOperation.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,17 @@
1818
import java.util.Collection;
1919
import java.util.Map;
2020

21+
import org.springframework.data.couchbase.core.support.OneAndAllExists;
22+
import org.springframework.data.couchbase.core.support.WithCollection;
23+
2124
public interface ExecutableExistsByIdOperation {
2225

2326
/**
2427
* Checks if the document exists in the bucket.
2528
*/
2629
ExecutableExistsById existsById();
2730

28-
interface TerminatingExistsById {
31+
interface TerminatingExistsById extends OneAndAllExists {
2932

3033
/**
3134
* Performs the operation on the ID given.
@@ -45,7 +48,7 @@ interface TerminatingExistsById {
4548

4649
}
4750

48-
interface ExistsByIdWithCollection extends TerminatingExistsById {
51+
interface ExistsByIdWithCollection extends TerminatingExistsById, WithCollection {
4952

5053
/**
5154
* Allows to specify a different collection than the default one configured.

src/main/java/org/springframework/data/couchbase/core/ExecutableFindByAnalyticsOperation.java

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,15 @@
1919
import java.util.Optional;
2020
import java.util.stream.Stream;
2121

22-
import com.couchbase.client.java.analytics.AnalyticsScanConsistency;
23-
import com.couchbase.client.java.query.QueryScanConsistency;
2422
import org.springframework.dao.IncorrectResultSizeDataAccessException;
2523
import org.springframework.data.couchbase.core.query.AnalyticsQuery;
24+
import org.springframework.data.couchbase.core.support.OneAndAll;
25+
import org.springframework.data.couchbase.core.support.WithAnalyticsConsistency;
26+
import org.springframework.data.couchbase.core.support.WithAnalyticsQuery;
2627
import org.springframework.lang.Nullable;
2728

29+
import com.couchbase.client.java.analytics.AnalyticsScanConsistency;
30+
2831
public interface ExecutableFindByAnalyticsOperation {
2932

3033
/**
@@ -34,7 +37,7 @@ public interface ExecutableFindByAnalyticsOperation {
3437
*/
3538
<T> ExecutableFindByAnalytics<T> findByAnalytics(Class<T> domainType);
3639

37-
interface TerminatingFindByAnalytics<T> {
40+
interface TerminatingFindByAnalytics<T> extends OneAndAll<T> {
3841

3942
/**
4043
* Get exactly zero or one result.
@@ -102,7 +105,7 @@ default Optional<T> first() {
102105

103106
}
104107

105-
interface FindByAnalyticsWithQuery<T> extends TerminatingFindByAnalytics<T> {
108+
interface FindByAnalyticsWithQuery<T> extends TerminatingFindByAnalytics<T>, WithAnalyticsQuery<T> {
106109

107110
/**
108111
* Set the filter for the analytics query to be used.
@@ -114,17 +117,30 @@ interface FindByAnalyticsWithQuery<T> extends TerminatingFindByAnalytics<T> {
114117

115118
}
116119

120+
@Deprecated
117121
interface FindByAnalyticsConsistentWith<T> extends FindByAnalyticsWithQuery<T> {
118122

119123
/**
120124
* Allows to override the default scan consistency.
121125
*
122126
* @param scanConsistency the custom scan consistency to use for this analytics query.
123127
*/
128+
@Deprecated
124129
FindByAnalyticsWithQuery<T> consistentWith(AnalyticsScanConsistency scanConsistency);
125130

126131
}
127132

128-
interface ExecutableFindByAnalytics<T> extends FindByAnalyticsConsistentWith<T> {}
133+
interface FindByAnalyticsWithConsistency<T> extends FindByAnalyticsConsistentWith<T>, WithAnalyticsConsistency<T> {
134+
135+
/**
136+
* Allows to override the default scan consistency.
137+
*
138+
* @param scanConsistency the custom scan consistency to use for this analytics query.
139+
*/
140+
FindByAnalyticsConsistentWith<T> withConsistency(AnalyticsScanConsistency scanConsistency);
141+
142+
}
143+
144+
interface ExecutableFindByAnalytics<T> extends FindByAnalyticsWithConsistency<T> {}
129145

130146
}

src/main/java/org/springframework/data/couchbase/core/ExecutableFindByAnalyticsOperationSupport.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,10 @@
1515
*/
1616
package org.springframework.data.couchbase.core;
1717

18-
import org.springframework.data.couchbase.core.ReactiveFindByAnalyticsOperationSupport.ReactiveFindByAnalyticsSupport;
19-
2018
import java.util.List;
2119
import java.util.stream.Stream;
2220

21+
import org.springframework.data.couchbase.core.ReactiveFindByAnalyticsOperationSupport.ReactiveFindByAnalyticsSupport;
2322
import org.springframework.data.couchbase.core.query.AnalyticsQuery;
2423

2524
import com.couchbase.client.java.analytics.AnalyticsScanConsistency;
@@ -79,10 +78,16 @@ public TerminatingFindByAnalytics<T> matching(final AnalyticsQuery query) {
7978
}
8079

8180
@Override
81+
@Deprecated
8282
public FindByAnalyticsWithQuery<T> consistentWith(final AnalyticsScanConsistency scanConsistency) {
8383
return new ExecutableFindByAnalyticsSupport<>(template, domainType, query, scanConsistency);
8484
}
8585

86+
@Override
87+
public FindByAnalyticsWithConsistency<T> withConsistency(final AnalyticsScanConsistency scanConsistency) {
88+
return new ExecutableFindByAnalyticsSupport<>(template, domainType, query, scanConsistency);
89+
}
90+
8691
@Override
8792
public Stream<T> stream() {
8893
return reactiveSupport.all().toStream();

src/main/java/org/springframework/data/couchbase/core/ExecutableFindByIdOperation.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717

1818
import java.util.Collection;
1919

20+
import org.springframework.data.couchbase.core.support.OneAndAllId;
21+
import org.springframework.data.couchbase.core.support.WithCollection;
22+
import org.springframework.data.couchbase.core.support.WithProjectionId;
23+
2024
public interface ExecutableFindByIdOperation {
2125

2226
/**
@@ -26,7 +30,7 @@ public interface ExecutableFindByIdOperation {
2630
*/
2731
<T> ExecutableFindById<T> findById(Class<T> domainType);
2832

29-
interface TerminatingFindById<T> {
33+
interface TerminatingFindById<T> extends OneAndAllId<T> {
3034

3135
/**
3236
* Finds one document based on the given ID.
@@ -46,7 +50,7 @@ interface TerminatingFindById<T> {
4650

4751
}
4852

49-
interface FindByIdWithCollection<T> extends TerminatingFindById<T> {
53+
interface FindByIdWithCollection<T> extends TerminatingFindById<T>, WithCollection<T> {
5054

5155
/**
5256
* Allows to specify a different collection than the default one configured.
@@ -57,7 +61,7 @@ interface FindByIdWithCollection<T> extends TerminatingFindById<T> {
5761

5862
}
5963

60-
interface FindByIdWithProjection<T> extends FindByIdWithCollection<T> {
64+
interface FindByIdWithProjection<T> extends FindByIdWithCollection<T>, WithProjectionId<T> {
6165

6266
/**
6367
* Load only certain fields for the document.

src/main/java/org/springframework/data/couchbase/core/ExecutableFindByIdOperationSupport.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,11 @@
1515
*/
1616
package org.springframework.data.couchbase.core;
1717

18-
import org.springframework.data.couchbase.core.ReactiveFindByIdOperationSupport.ReactiveFindByIdSupport;
19-
2018
import java.util.Arrays;
2119
import java.util.Collection;
2220
import java.util.List;
2321

22+
import org.springframework.data.couchbase.core.ReactiveFindByIdOperationSupport.ReactiveFindByIdSupport;
2423
import org.springframework.util.Assert;
2524

2625
public class ExecutableFindByIdOperationSupport implements ExecutableFindByIdOperation {

src/main/java/org/springframework/data/couchbase/core/ExecutableFindByQueryOperation.java

Lines changed: 75 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@
2121

2222
import org.springframework.dao.IncorrectResultSizeDataAccessException;
2323
import org.springframework.data.couchbase.core.query.Query;
24+
import org.springframework.data.couchbase.core.query.QueryCriteriaDefinition;
25+
import org.springframework.data.couchbase.core.support.OneAndAll;
26+
import org.springframework.data.couchbase.core.support.WithCollection;
27+
import org.springframework.data.couchbase.core.support.WithConsistency;
28+
import org.springframework.data.couchbase.core.support.WithDistinct;
29+
import org.springframework.data.couchbase.core.support.WithProjection;
30+
import org.springframework.data.couchbase.core.support.WithQuery;
2431
import org.springframework.lang.Nullable;
2532

2633
import com.couchbase.client.java.query.QueryScanConsistency;
@@ -34,7 +41,7 @@ public interface ExecutableFindByQueryOperation {
3441
*/
3542
<T> ExecutableFindByQuery<T> findByQuery(Class<T> domainType);
3643

37-
interface TerminatingFindByQuery<T> {
44+
interface TerminatingFindByQuery<T> extends OneAndAll<T> {
3845
/**
3946
* Get exactly zero or one result.
4047
*
@@ -107,7 +114,7 @@ default Optional<T> first() {
107114
* @author Christoph Strobl
108115
* @since 2.0
109116
*/
110-
interface FindByQueryWithQuery<T> extends TerminatingFindByQuery<T> {
117+
interface FindByQueryWithQuery<T> extends TerminatingFindByQuery<T>, WithQuery<T> {
111118

112119
/**
113120
* Set the filter for the query to be used.
@@ -117,30 +124,90 @@ interface FindByQueryWithQuery<T> extends TerminatingFindByQuery<T> {
117124
*/
118125
TerminatingFindByQuery<T> matching(Query query);
119126

127+
/**
128+
* Set the filter {@link QueryCriteriaDefinition criteria} to be used.
129+
*
130+
* @param criteria must not be {@literal null}.
131+
* @return new instance of {@link ExecutableFindByQuery}.
132+
* @throws IllegalArgumentException if criteria is {@literal null}.
133+
*/
134+
default TerminatingFindByQuery<T> matching(QueryCriteriaDefinition criteria) {
135+
return matching(Query.query(criteria));
136+
}
137+
138+
}
139+
140+
interface FindByQueryInCollection<T> extends FindByQueryWithQuery<T>, WithCollection<T> {
141+
142+
/**
143+
* Allows to override the default scan consistency.
144+
*
145+
* @param collection the collection to use for this query.
146+
*/
147+
FindByQueryWithQuery<T> inCollection(String collection);
148+
120149
}
121150

122-
interface FindByQueryConsistentWith<T> extends FindByQueryWithQuery<T> {
151+
@Deprecated
152+
interface FindByQueryConsistentWith<T> extends FindByQueryInCollection<T> {
123153

124154
/**
125155
* Allows to override the default scan consistency.
126156
*
127157
* @param scanConsistency the custom scan consistency to use for this query.
128158
*/
129-
FindByQueryConsistentWith<T> consistentWith(QueryScanConsistency scanConsistency);
159+
@Deprecated
160+
FindByQueryInCollection<T> consistentWith(QueryScanConsistency scanConsistency);
130161

131162
}
132163

133-
interface FindByQueryInCollection<T> extends FindByQueryConsistentWith<T> {
164+
interface FindByQueryWithConsistency<T> extends FindByQueryConsistentWith<T>, WithConsistency<T> {
134165

135166
/**
136167
* Allows to override the default scan consistency.
137168
*
138-
* @param collection the collection to use for this query.
169+
* @param scanConsistency the custom scan consistency to use for this query.
170+
*/
171+
FindByQueryConsistentWith<T> withConsistency(QueryScanConsistency scanConsistency);
172+
173+
}
174+
175+
/**
176+
* Result type override (Optional).
177+
*/
178+
interface FindByQueryWithProjection<T> extends FindByQueryWithConsistency<T> {
179+
180+
/**
181+
* Define the target type fields should be mapped to. <br />
182+
* Skip this step if you are anyway only interested in the original domain type.
183+
*
184+
* @param returnType must not be {@literal null}.
185+
* @return new instance of {@link FindByQueryWithProjection}.
186+
* @throws IllegalArgumentException if returnType is {@literal null}.
187+
*/
188+
<R> FindByQueryWithConsistency<R> as(Class<R> returnType);
189+
}
190+
191+
/**
192+
* Distinct Find support.
193+
*/
194+
interface FindByQueryWithDistinct<T> extends FindByQueryWithProjection<T>, WithDistinct<T> {
195+
196+
/**
197+
* Finds the distinct values for a specified {@literal field} across a single collection
198+
*
199+
* @param distinctFields name of the field. Must not be {@literal null}.
200+
* @return new instance of {@link ExecutableFindByQuery}.
201+
* @throws IllegalArgumentException if field is {@literal null}.
139202
*/
140-
FindByQueryInCollection<T> inCollection(String collection);
203+
FindByQueryWithProjection<T> distinct(String[] distinctFields);
141204

142205
}
143206

144-
interface ExecutableFindByQuery<T> extends FindByQueryInCollection<T> {}
207+
/**
208+
* {@link ExecutableFindByQuery} provides methods for constructing lookup operations in a fluent way.
209+
*/
210+
211+
interface ExecutableFindByQuery<T> extends FindByQueryWithDistinct<T> {}
145212

146213
}

0 commit comments

Comments
 (0)