Skip to content

Commit 4faa072

Browse files
committed
Add type-safe property paths overloads (#2126) (#2128)
Fixes #2126 Signed-off-by: Emilien Bevierre <emilien.bevierre@couchbase.com>
1 parent d29f5d2 commit 4faa072

30 files changed

Lines changed: 1030 additions & 18 deletions

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@
1616
package org.springframework.data.couchbase.core;
1717

1818
import java.time.Duration;
19+
import java.util.Arrays;
1920
import java.util.Collection;
2021

22+
import org.springframework.data.core.TypedPropertyPath;
2123
import org.springframework.data.couchbase.core.support.OneAndAllId;
2224
import org.springframework.data.couchbase.core.support.InCollection;
2325
import org.springframework.data.couchbase.core.support.WithGetOptions;
@@ -33,6 +35,7 @@
3335
*
3436
* @author Christoph Strobl
3537
* @author Tigran Babloyan
38+
* @author Emilien Bevierre
3639
* @since 2.0
3740
*/
3841
public interface ExecutableFindByIdOperation {
@@ -122,6 +125,17 @@ interface FindByIdWithProjection<T> extends FindByIdInScope<T>, WithProjectionId
122125
*/
123126
@Override
124127
FindByIdInScope<T> project(String... fields);
128+
129+
/**
130+
* Type-safe variant of {@link #project(String...)} using property paths.
131+
*
132+
* @param fields the property paths to project.
133+
* @since 6.1
134+
*/
135+
@SuppressWarnings("unchecked")
136+
default FindByIdInScope<T> project(TypedPropertyPath<T, ?>... fields) {
137+
return project(Arrays.stream(fields).map(TypedPropertyPath::toDotPath).toArray(String[]::new));
138+
}
125139
}
126140

127141
interface FindByIdWithExpiry<T> extends FindByIdWithProjection<T>, WithExpiry<T> {

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

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

18+
import org.springframework.data.core.TypedPropertyPath;
1819
import java.time.Duration;
1920
import java.util.Arrays;
2021
import java.util.Collection;
@@ -98,6 +99,13 @@ public FindByIdInScope<T> project(String... fields) {
9899
return new ExecutableFindByIdSupport<>(template, domainType, scope, collection, options, Arrays.asList(fields), expiry, lockDuration);
99100
}
100101

102+
@Override
103+
@SafeVarargs
104+
// maps property references to stored field names (honoring @Field aliases) via the converter
105+
public final FindByIdInScope<T> project(TypedPropertyPath<T, ?>... fields) {
106+
return project(PropertyPathSupport.getMappedFieldPaths(template.getConverter(), fields));
107+
}
108+
101109
@Override
102110
public FindByIdWithProjection<T> withExpiry(final Duration expiry) {
103111
return new ExecutableFindByIdSupport<>(template, domainType, scope, collection, options, fields,

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

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

18+
import java.util.Arrays;
1819
import java.util.List;
1920
import java.util.Optional;
2021
import java.util.stream.Stream;
2122

2223
import org.springframework.dao.IncorrectResultSizeDataAccessException;
24+
25+
import org.springframework.data.core.TypedPropertyPath;
2326
import org.springframework.data.couchbase.core.query.Query;
2427
import org.springframework.data.couchbase.core.query.QueryCriteriaDefinition;
2528
import org.springframework.data.couchbase.core.support.InCollection;
@@ -38,6 +41,7 @@
3841
* Query Operations
3942
*
4043
* @author Christoph Strobl
44+
* @author Emilien Bevierre
4145
* @since 2.0
4246
*/
4347
public interface ExecutableFindByQueryOperation {
@@ -270,6 +274,17 @@ interface FindByQueryWithProjecting<T> extends FindByQueryWithProjection<T> {
270274
* @throws IllegalArgumentException if returnType is {@literal null}.
271275
*/
272276
FindByQueryWithProjection<T> project(String[] fields);
277+
278+
/**
279+
* Type-safe variant of {@link #project(String[])} using property paths.
280+
*
281+
* @param fields the property paths to project.
282+
* @since 6.1
283+
*/
284+
@SuppressWarnings("unchecked")
285+
default FindByQueryWithProjection<T> project(TypedPropertyPath<T, ?>... fields) {
286+
return project(Arrays.stream(fields).map(TypedPropertyPath::toDotPath).toArray(String[]::new));
287+
}
273288
}
274289

275290
/**
@@ -288,6 +303,17 @@ interface FindByQueryWithDistinct<T> extends FindByQueryWithProjecting<T>, WithD
288303
*/
289304
@Override
290305
FindByQueryWithProjection<T> distinct(String[] distinctFields);
306+
307+
/**
308+
* Type-safe variant of {@link #distinct(String[])} using property paths.
309+
*
310+
* @param distinctFields the property paths for distinct fields.
311+
* @since 6.1
312+
*/
313+
@SuppressWarnings("unchecked")
314+
default FindByQueryWithProjection<T> distinct(TypedPropertyPath<T, ?>... distinctFields) {
315+
return distinct(Arrays.stream(distinctFields).map(TypedPropertyPath::toDotPath).toArray(String[]::new));
316+
}
291317
}
292318

293319
/**

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

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

18+
import org.springframework.data.core.TypedPropertyPath;
1819
import java.util.List;
1920
import java.util.stream.Stream;
2021

@@ -147,6 +148,20 @@ public FindByQueryWithProjection<T> distinct(final String[] distinctFields) {
147148
collection, options, dFields, fields);
148149
}
149150

151+
@Override
152+
@SafeVarargs
153+
// maps property references to stored field names (honoring @Field aliases) via the converter
154+
public final FindByQueryWithProjection<T> project(TypedPropertyPath<T, ?>... fields) {
155+
return project(PropertyPathSupport.getMappedFieldPaths(template.getConverter(), fields));
156+
}
157+
158+
@Override
159+
@SafeVarargs
160+
// maps property references to stored field names (honoring @Field aliases) via the converter
161+
public final FindByQueryWithProjection<T> distinct(TypedPropertyPath<T, ?>... distinctFields) {
162+
return distinct(PropertyPathSupport.getMappedFieldPaths(template.getConverter(), distinctFields));
163+
}
164+
150165
@Override
151166
public Stream<T> stream() {
152167
return reactiveSupport.all().toStream();

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.util.stream.Stream;
2222

2323
import org.springframework.dao.IncorrectResultSizeDataAccessException;
24+
import org.springframework.data.core.TypedPropertyPath;
2425
import org.springframework.data.couchbase.core.support.InCollection;
2526
import org.springframework.data.couchbase.core.support.InScope;
2627
import org.springframework.data.couchbase.core.support.WithSearchConsistency;
@@ -170,6 +171,9 @@ interface FindBySearchWithSkip<T> extends FindBySearchWithLimit<T> {
170171

171172
interface FindBySearchWithSort<T> extends FindBySearchWithSkip<T> {
172173
FindBySearchWithSkip<T> withSort(SearchSort... sort);
174+
175+
<P> FindBySearchWithSkip<T> withSort(TypedPropertyPath<P, ?> property,
176+
TypedPropertyPath<P, ?>... additionalProperties);
173177
}
174178

175179
interface FindBySearchWithHighlight<T> extends FindBySearchWithSort<T> {
@@ -178,6 +182,14 @@ interface FindBySearchWithHighlight<T> extends FindBySearchWithSort<T> {
178182
default FindBySearchWithSort<T> withHighlight(String... fields) {
179183
return withHighlight(HighlightStyle.SERVER_DEFAULT, fields);
180184
}
185+
186+
<P> FindBySearchWithSort<T> withHighlight(HighlightStyle style, TypedPropertyPath<P, ?> field,
187+
TypedPropertyPath<P, ?>... additionalFields);
188+
189+
default <P> FindBySearchWithSort<T> withHighlight(TypedPropertyPath<P, ?> field,
190+
TypedPropertyPath<P, ?>... additionalFields) {
191+
return withHighlight(HighlightStyle.SERVER_DEFAULT, field, additionalFields);
192+
}
181193
}
182194

183195
interface FindBySearchWithFacets<T> extends FindBySearchWithHighlight<T> {
@@ -186,6 +198,9 @@ interface FindBySearchWithFacets<T> extends FindBySearchWithHighlight<T> {
186198

187199
interface FindBySearchWithFields<T> extends FindBySearchWithFacets<T> {
188200
FindBySearchWithFacets<T> withFields(String... fields);
201+
202+
<P> FindBySearchWithFacets<T> withFields(TypedPropertyPath<P, ?> field,
203+
TypedPropertyPath<P, ?>... additionalFields);
189204
}
190205

191206
interface FindBySearchWithProjection<T> extends FindBySearchWithFields<T> {

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

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.util.Map;
2020
import java.util.stream.Stream;
2121

22+
import org.springframework.data.core.TypedPropertyPath;
2223
import org.springframework.data.couchbase.core.ReactiveFindBySearchOperationSupport.ReactiveFindBySearchSupport;
2324
import org.springframework.data.couchbase.core.query.OptionsBuilder;
2425
import org.springframework.util.Assert;
@@ -190,8 +191,8 @@ public FindBySearchWithOptions<T> inCollection(final String collection) {
190191
@Override
191192
public FindBySearchWithQuery<T> withOptions(final SearchOptions options) {
192193
return new ExecutableFindBySearchSupport<>(template, domainType, returnType, indexName, searchRequest,
193-
scanConsistency, scope, collection, options != null ? options : this.options, sort,
194-
highlightStyle, highlightFields, facets, fields, limitSkip);
194+
scanConsistency, scope, collection, options != null ? options : this.options, sort, highlightStyle,
195+
highlightFields, facets, fields, limitSkip);
195196
}
196197

197198
@Override
@@ -219,11 +220,23 @@ public FindBySearchWithSkip<T> withSort(SearchSort... sort) {
219220
fields, limitSkip);
220221
}
221222

223+
@Override
224+
public <P> FindBySearchWithSkip<T> withSort(TypedPropertyPath<P, ?> property,
225+
TypedPropertyPath<P, ?>... additionalProperties) {
226+
return withSort(PropertyPathSupport.toSearchSorts(template.getConverter(), property, additionalProperties));
227+
}
228+
222229
@Override
223230
public FindBySearchWithSort<T> withHighlight(HighlightStyle style, String... fields) {
224231
return new ExecutableFindBySearchSupport<>(template, domainType, returnType, indexName, searchRequest,
225-
scanConsistency, scope, collection, options, sort, style, fields, facets,
226-
this.fields, limitSkip);
232+
scanConsistency, scope, collection, options, sort, style, fields, facets, this.fields, limitSkip);
233+
}
234+
235+
@Override
236+
public <P> FindBySearchWithSort<T> withHighlight(HighlightStyle style, TypedPropertyPath<P, ?> field,
237+
TypedPropertyPath<P, ?>... additionalFields) {
238+
return withHighlight(style,
239+
PropertyPathSupport.getMappedFieldPaths(template.getConverter(), field, additionalFields));
227240
}
228241

229242
@Override
@@ -239,5 +252,11 @@ public FindBySearchWithFacets<T> withFields(String... fields) {
239252
scanConsistency, scope, collection, options, sort, highlightStyle, highlightFields, facets,
240253
fields, limitSkip);
241254
}
255+
256+
@Override
257+
public <P> FindBySearchWithFacets<T> withFields(TypedPropertyPath<P, ?> field,
258+
TypedPropertyPath<P, ?>... additionalFields) {
259+
return withFields(PropertyPathSupport.getMappedFieldPaths(template.getConverter(), field, additionalFields));
260+
}
242261
}
243262
}

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

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,20 @@
1919
import com.couchbase.client.java.kv.MutateInOptions;
2020
import com.couchbase.client.java.kv.PersistTo;
2121
import com.couchbase.client.java.kv.ReplicateTo;
22+
import org.springframework.data.core.TypedPropertyPath;
2223
import org.springframework.data.couchbase.core.support.*;
2324
import reactor.core.publisher.Flux;
2425
import reactor.core.publisher.Mono;
2526

2627
import java.time.Duration;
28+
import java.util.Arrays;
2729
import java.util.Collection;
2830

2931
/**
3032
* Mutate In Operations
3133
*
3234
* @author Tigran Babloyan
35+
* @author Emilien Bevierre
3336
* @since 5.1
3437
*/
3538
public interface ExecutableMutateInByIdOperation {
@@ -98,6 +101,42 @@ interface MutateInByIdWithPaths<T> extends TerminatingMutateInById<T>, WithMutat
98101
* By default the CAS value is not provided.
99102
*/
100103
MutateInByIdWithPaths<T> withCasProvided();
104+
105+
/**
106+
* Type-safe variant of {@link #withRemovePaths(String...)} using property paths.
107+
* @since 6.1
108+
*/
109+
@SuppressWarnings("unchecked")
110+
default MutateInByIdWithPaths<T> withRemovePaths(TypedPropertyPath<T, ?>... removePaths) {
111+
return withRemovePaths(Arrays.stream(removePaths).map(TypedPropertyPath::toDotPath).toArray(String[]::new));
112+
}
113+
114+
/**
115+
* Type-safe variant of {@link #withInsertPaths(String...)} using property paths.
116+
* @since 6.1
117+
*/
118+
@SuppressWarnings("unchecked")
119+
default MutateInByIdWithPaths<T> withInsertPaths(TypedPropertyPath<T, ?>... insertPaths) {
120+
return withInsertPaths(Arrays.stream(insertPaths).map(TypedPropertyPath::toDotPath).toArray(String[]::new));
121+
}
122+
123+
/**
124+
* Type-safe variant of {@link #withUpsertPaths(String...)} using property paths.
125+
* @since 6.1
126+
*/
127+
@SuppressWarnings("unchecked")
128+
default MutateInByIdWithPaths<T> withUpsertPaths(TypedPropertyPath<T, ?>... upsertPaths) {
129+
return withUpsertPaths(Arrays.stream(upsertPaths).map(TypedPropertyPath::toDotPath).toArray(String[]::new));
130+
}
131+
132+
/**
133+
* Type-safe variant of {@link #withReplacePaths(String...)} using property paths.
134+
* @since 6.1
135+
*/
136+
@SuppressWarnings("unchecked")
137+
default MutateInByIdWithPaths<T> withReplacePaths(TypedPropertyPath<T, ?>... replacePaths) {
138+
return withReplacePaths(Arrays.stream(replacePaths).map(TypedPropertyPath::toDotPath).toArray(String[]::new));
139+
}
101140
}
102141

103142
/**

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

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

18+
import org.springframework.data.core.TypedPropertyPath;
1819
import java.time.Duration;
1920
import java.util.ArrayList;
2021
import java.util.Arrays;
@@ -178,6 +179,35 @@ public MutateInByIdWithDurability<T> withReplacePaths(final String... replacePat
178179
durabilityLevel, expiry, removePaths, upsertPaths, insertPaths, Arrays.asList(replacePaths), provideCas);
179180
}
180181

182+
183+
@Override
184+
@SafeVarargs
185+
// maps property references to stored field names (honoring @Field aliases) via the converter
186+
public final MutateInByIdWithPaths<T> withRemovePaths(TypedPropertyPath<T, ?>... removePaths) {
187+
return withRemovePaths(PropertyPathSupport.getMappedFieldPaths(template.getConverter(), removePaths));
188+
}
189+
190+
@Override
191+
@SafeVarargs
192+
// maps property references to stored field names (honoring @Field aliases) via the converter
193+
public final MutateInByIdWithPaths<T> withUpsertPaths(TypedPropertyPath<T, ?>... upsertPaths) {
194+
return withUpsertPaths(PropertyPathSupport.getMappedFieldPaths(template.getConverter(), upsertPaths));
195+
}
196+
197+
@Override
198+
@SafeVarargs
199+
// maps property references to stored field names (honoring @Field aliases) via the converter
200+
public final MutateInByIdWithPaths<T> withInsertPaths(TypedPropertyPath<T, ?>... insertPaths) {
201+
return withInsertPaths(PropertyPathSupport.getMappedFieldPaths(template.getConverter(), insertPaths));
202+
}
203+
204+
@Override
205+
@SafeVarargs
206+
// maps property references to stored field names (honoring @Field aliases) via the converter
207+
public final MutateInByIdWithPaths<T> withReplacePaths(TypedPropertyPath<T, ?>... replacePaths) {
208+
return withReplacePaths(PropertyPathSupport.getMappedFieldPaths(template.getConverter(), replacePaths));
209+
}
210+
181211
@Override
182212
public MutateInByIdWithPaths<T> withCasProvided() {
183213
return new ExecutableMutateInByIdSupport<>(template, domainType, scope, collection, options, persistTo, replicateTo,

0 commit comments

Comments
 (0)