Skip to content

Commit 88bf5fa

Browse files
committed
Datacouch 1599 add rangescan support (#1738)
* Add RangeScan to Template. Closes #1599. * Add RangeScan support. Closes #1599.
1 parent 79fbef0 commit 88bf5fa

15 files changed

+1113
-19
lines changed

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,11 @@ public <T> ExecutableRemoveByQuery<T> removeByQuery(Class<T> domainType) {
158158
return new ExecutableRemoveByQueryOperationSupport(this).removeByQuery(domainType);
159159
}
160160

161+
@Override
162+
public <T> ExecutableRangeScan<T> rangeScan(Class<T> domainType) {
163+
return new ExecutableRangeScanOperationSupport(this).rangeScan(domainType);
164+
}
165+
161166
@Override
162167
public String getBucketName() {
163168
return clientFactory.getBucket().name();
Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
/*
2+
* Copyright 2012-2023 the original author or authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.couchbase.core;
17+
18+
import java.util.stream.Stream;
19+
20+
import org.springframework.data.couchbase.core.support.ConsistentWith;
21+
import org.springframework.data.couchbase.core.support.InCollection;
22+
import org.springframework.data.couchbase.core.support.InScope;
23+
import org.springframework.data.couchbase.core.support.WithBatchByteLimit;
24+
import org.springframework.data.couchbase.core.support.WithBatchItemLimit;
25+
import org.springframework.data.couchbase.core.support.WithScanOptions;
26+
import org.springframework.data.couchbase.core.support.WithScanSort;
27+
28+
import com.couchbase.client.java.kv.MutationState;
29+
import com.couchbase.client.java.kv.ScanOptions;
30+
31+
/**
32+
* Get Operations
33+
*
34+
* @author Michael Reiche
35+
*/
36+
public interface ExecutableRangeScanOperation {
37+
38+
/**
39+
* Loads a document from a bucket.
40+
*
41+
* @param domainType the entity type to use for the results.
42+
*/
43+
<T> ExecutableRangeScan<T> rangeScan(Class<T> domainType);
44+
45+
/**
46+
* Terminating operations invoking the actual execution.
47+
*
48+
* @param <T> the entity type to use for the results.
49+
*/
50+
interface TerminatingRangeScan<T> /*extends OneAndAllId<T>*/ {
51+
52+
/**
53+
* Range Scan
54+
*
55+
* @param upper
56+
* @param lower
57+
* @return the list of found entities.
58+
*/
59+
Stream<T> rangeScan(String lower, String upper);
60+
61+
/**
62+
* Range Scan Ids
63+
*
64+
* @param upper
65+
* @param lower
66+
* @return the list of found keys.
67+
*/
68+
Stream<String> rangeScanIds(String lower, String upper);
69+
70+
/**
71+
* Range Scan
72+
*
73+
* @param limit
74+
* @param seed
75+
* @return the list of found entities.
76+
*/
77+
Stream<T> samplingScan(Long limit, Long... seed);
78+
79+
/**
80+
* Range Scan Ids
81+
*
82+
* @param limit
83+
* @param seed
84+
* @return the list of keys
85+
*/
86+
Stream<String> samplingScanIds(Long limit, Long... seed);
87+
}
88+
89+
/**
90+
* Fluent method to specify options.
91+
*
92+
* @param <T> the entity type to use for the results.
93+
*/
94+
interface RangeScanWithOptions<T> extends TerminatingRangeScan<T>, WithScanOptions<T> {
95+
/**
96+
* Fluent method to specify options to use for execution
97+
*
98+
* @param options options to use for execution
99+
*/
100+
@Override
101+
TerminatingRangeScan<T> withOptions(ScanOptions options);
102+
}
103+
104+
/**
105+
* Fluent method to specify the collection.
106+
*
107+
* @param <T> the entity type to use for the results.
108+
*/
109+
interface RangeScanInCollection<T> extends RangeScanWithOptions<T>, InCollection<T> {
110+
/**
111+
* With a different collection
112+
*
113+
* @param collection the collection to use.
114+
*/
115+
@Override
116+
RangeScanWithOptions<T> inCollection(String collection);
117+
}
118+
119+
/**
120+
* Fluent method to specify the scope.
121+
*
122+
* @param <T> the entity type to use for the results.
123+
*/
124+
interface RangeScanInScope<T> extends RangeScanInCollection<T>, InScope<T> {
125+
/**
126+
* With a different scope
127+
*
128+
* @param scope the scope to use.
129+
*/
130+
@Override
131+
RangeScanInCollection<T> inScope(String scope);
132+
}
133+
134+
135+
136+
interface RangeScanWithSort<T> extends RangeScanInScope<T>, WithScanSort<T> {
137+
/**
138+
* sort
139+
*
140+
* @param sort
141+
*/
142+
@Override
143+
RangeScanInScope<T> withSort(Object sort);
144+
}
145+
146+
/**
147+
* Fluent method to specify scan consistency. Scan consistency may also come from an annotation.
148+
*
149+
* @param <T> the entity type to use for the results.
150+
*/
151+
interface RangeScanConsistentWith<T> extends RangeScanWithSort<T>, ConsistentWith<T> {
152+
153+
/**
154+
* Allows to override the default scan consistency.
155+
*
156+
* @param mutationState the custom scan consistency to use for this query.
157+
*/
158+
@Override
159+
RangeScanWithSort<T> consistentWith(MutationState mutationState);
160+
}
161+
162+
/**
163+
* Fluent method to specify a return type different than the the entity type to use for the results.
164+
*
165+
* @param <T> the entity type to use for the results.
166+
*/
167+
interface RangeScanWithProjection<T> extends RangeScanConsistentWith<T> {
168+
169+
/**
170+
* Define the target type fields should be mapped to. <br />
171+
* Skip this step if you are only interested in the original the entity type to use for the results.
172+
*
173+
* @param returnType must not be {@literal null}.
174+
* @return new instance of {@link ExecutableFindByQueryOperation.FindByQueryWithProjection}.
175+
* @throws IllegalArgumentException if returnType is {@literal null}.
176+
*/
177+
<R> RangeScanConsistentWith<R> as(Class<R> returnType);
178+
}
179+
180+
interface RangeScanWithBatchItemLimit<T> extends RangeScanWithProjection<T>, WithBatchItemLimit<T> {
181+
182+
/**
183+
* determines if result are just ids or ids plus contents
184+
*
185+
* @param batchByteLimit must not be {@literal null}.
186+
* @return new instance of {@link RangeScanWithProjection}.
187+
* @throws IllegalArgumentException if returnType is {@literal null}.
188+
*/
189+
@Override
190+
RangeScanWithProjection<T> withBatchItemLimit(Integer batchByteLimit);
191+
}
192+
193+
interface RangeScanWithBatchByteLimit<T> extends RangeScanWithBatchItemLimit<T>, WithBatchByteLimit<T> {
194+
195+
/**
196+
* determines if result are just ids or ids plus contents
197+
*
198+
* @param batchByteLimit must not be {@literal null}.
199+
* @return new instance of {@link RangeScanWithProjection}.
200+
* @throws IllegalArgumentException if returnType is {@literal null}.
201+
*/
202+
@Override
203+
RangeScanWithBatchItemLimit<T> withBatchByteLimit(Integer batchByteLimit);
204+
}
205+
206+
/**
207+
* Provides methods for constructing query operations in a fluent way.
208+
*
209+
* @param <T> the entity type to use for the results
210+
*/
211+
interface ExecutableRangeScan<T> extends RangeScanWithBatchByteLimit<T> {}
212+
213+
}
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
/*
2+
* Copyright 2012-2023 the original author or authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.couchbase.core;
17+
18+
import java.util.stream.Stream;
19+
20+
import org.springframework.data.couchbase.core.ReactiveRangeScanOperationSupport.ReactiveRangeScanSupport;
21+
import org.springframework.data.couchbase.core.query.OptionsBuilder;
22+
import org.springframework.util.Assert;
23+
24+
import com.couchbase.client.java.kv.MutationState;
25+
import com.couchbase.client.java.kv.ScanOptions;
26+
27+
public class ExecutableRangeScanOperationSupport implements ExecutableRangeScanOperation {
28+
29+
private final CouchbaseTemplate template;
30+
31+
ExecutableRangeScanOperationSupport(CouchbaseTemplate template) {
32+
this.template = template;
33+
}
34+
35+
@Override
36+
public <T> ExecutableRangeScan<T> rangeScan(Class<T> domainType) {
37+
return new ExecutableRangeScanSupport<>(template, domainType, OptionsBuilder.getScopeFrom(domainType),
38+
OptionsBuilder.getCollectionFrom(domainType), null, null, null, null, null);
39+
}
40+
41+
static class ExecutableRangeScanSupport<T> implements ExecutableRangeScan<T> {
42+
43+
private final CouchbaseTemplate template;
44+
private final Class<T> domainType;
45+
private final String scope;
46+
private final String collection;
47+
private final ScanOptions options;
48+
private final Object sort;
49+
private final MutationState mutationState;
50+
private final Integer batchItemLimit;
51+
private final Integer batchByteLimit;
52+
private final ReactiveRangeScanSupport<T> reactiveSupport;
53+
54+
ExecutableRangeScanSupport(CouchbaseTemplate template, Class<T> domainType, String scope, String collection,
55+
ScanOptions options, Object sort, MutationState mutationState,
56+
Integer batchItemLimit, Integer batchByteLimit) {
57+
this.template = template;
58+
this.domainType = domainType;
59+
this.scope = scope;
60+
this.collection = collection;
61+
this.options = options;
62+
this.sort = sort;
63+
this.mutationState = mutationState;
64+
this.batchItemLimit = batchItemLimit;
65+
this.batchByteLimit = batchByteLimit;
66+
this.reactiveSupport = new ReactiveRangeScanSupport<>(template.reactive(), domainType, scope, collection, options,
67+
sort, mutationState, batchItemLimit, batchByteLimit,
68+
new NonReactiveSupportWrapper(template.support()));
69+
}
70+
71+
@Override
72+
public TerminatingRangeScan<T> withOptions(final ScanOptions options) {
73+
Assert.notNull(options, "Options must not be null.");
74+
return new ExecutableRangeScanSupport<>(template, domainType, scope, collection, options, sort,
75+
mutationState, batchItemLimit, batchByteLimit);
76+
}
77+
78+
@Override
79+
public RangeScanWithOptions<T> inCollection(final String collection) {
80+
return new ExecutableRangeScanSupport<>(template, domainType, scope,
81+
collection != null ? collection : this.collection, options, sort, mutationState,
82+
batchItemLimit, batchByteLimit);
83+
}
84+
85+
@Override
86+
public RangeScanInCollection<T> inScope(final String scope) {
87+
return new ExecutableRangeScanSupport<>(template, domainType, scope != null ? scope : this.scope, collection,
88+
options, sort, mutationState, batchItemLimit, batchByteLimit);
89+
}
90+
91+
@Override
92+
public RangeScanInScope<T> withSort(Object sort) {
93+
return new ExecutableRangeScanSupport<>(template, domainType, scope, collection, options, sort,
94+
mutationState, batchItemLimit, batchByteLimit);
95+
}
96+
97+
@Override
98+
public RangeScanWithSort<T> consistentWith(MutationState mutationState) {
99+
return new ExecutableRangeScanSupport<>(template, domainType, scope, collection, options, sort,
100+
mutationState, batchItemLimit, batchByteLimit);
101+
}
102+
103+
@Override
104+
public <R> RangeScanConsistentWith<R> as(Class<R> returnType) {
105+
return new ExecutableRangeScanSupport<>(template, returnType, scope, collection, options, sort,
106+
mutationState, batchItemLimit, batchByteLimit);
107+
}
108+
109+
@Override
110+
public RangeScanWithProjection<T> withBatchItemLimit(Integer batchItemLimit) {
111+
return new ExecutableRangeScanSupport<>(template, domainType, scope, collection, options, sort,
112+
mutationState, batchItemLimit, batchByteLimit);
113+
}
114+
115+
@Override
116+
public RangeScanWithBatchItemLimit<T> withBatchByteLimit(Integer batchByteLimit) {
117+
return new ExecutableRangeScanSupport<>(template, domainType, scope, collection, options, sort,
118+
mutationState, batchItemLimit, batchByteLimit);
119+
}
120+
121+
@Override
122+
public Stream<T> rangeScan(String lower, String upper) {
123+
return reactiveSupport.rangeScan(lower, upper, false, null, null).toStream();
124+
}
125+
126+
@Override
127+
public Stream<String> rangeScanIds(String lower, String upper) {
128+
return reactiveSupport.rangeScanIds(lower, upper, false, null, null).toStream();
129+
}
130+
131+
@Override
132+
public Stream<T> samplingScan(Long limit, Long... seed) {
133+
return reactiveSupport.sampleScan(limit, seed).toStream();
134+
}
135+
136+
@Override
137+
public Stream<String> samplingScanIds(Long limit, Long... seed) {
138+
return reactiveSupport.sampleScanIds(limit, seed).toStream();
139+
}
140+
141+
}
142+
143+
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,5 @@
2222
public interface FluentCouchbaseOperations extends ExecutableUpsertByIdOperation, ExecutableInsertByIdOperation,
2323
ExecutableReplaceByIdOperation, ExecutableFindByIdOperation, ExecutableFindFromReplicasByIdOperation,
2424
ExecutableFindByQueryOperation, ExecutableFindByAnalyticsOperation, ExecutableExistsByIdOperation,
25-
ExecutableRemoveByIdOperation, ExecutableRemoveByQueryOperation, ExecutableMutateInByIdOperation {}
25+
ExecutableRemoveByIdOperation, ExecutableRemoveByQueryOperation, ExecutableMutateInByIdOperation,
26+
ExecutableRangeScanOperation {}

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,11 @@ public <T> ReactiveMutateInById<T> mutateInById(Class<T> domainType) {
190190
return new ReactiveMutateInByIdOperationSupport(this).mutateInById(domainType);
191191
}
192192

193+
@Override
194+
public <T> ReactiveRangeScan<T> rangeScan(Class<T> domainType) {
195+
return new ReactiveRangeScanOperationSupport(this).rangeScan(domainType);
196+
}
197+
193198
@Override
194199
public String getBucketName() {
195200
return clientFactory.getBucket().name();

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,5 @@
2222
public interface ReactiveFluentCouchbaseOperations extends ReactiveUpsertByIdOperation, ReactiveInsertByIdOperation,
2323
ReactiveReplaceByIdOperation, ReactiveFindByIdOperation, ReactiveExistsByIdOperation,
2424
ReactiveFindByAnalyticsOperation, ReactiveFindFromReplicasByIdOperation, ReactiveFindByQueryOperation,
25-
ReactiveRemoveByIdOperation, ReactiveRemoveByQueryOperation, ReactiveMutateInByIdOperation {}
25+
ReactiveRemoveByIdOperation, ReactiveRemoveByQueryOperation, ReactiveMutateInByIdOperation,
26+
ReactiveRangeScanOperation {}

0 commit comments

Comments
 (0)