Skip to content

Commit f466780

Browse files
committed
Specifying withExpiry(Duration) on findById() uses getTouchAndRead().
Closes #982.
1 parent dffd203 commit f466780

16 files changed

+161
-68
lines changed

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

+13-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package org.springframework.data.couchbase.core;
1717

18+
import java.time.Duration;
1819
import java.util.Collection;
1920

2021
import org.springframework.data.couchbase.core.support.OneAndAllId;
@@ -24,6 +25,7 @@
2425
import org.springframework.data.couchbase.core.support.InScope;
2526

2627
import com.couchbase.client.java.kv.GetOptions;
28+
import org.springframework.data.couchbase.core.support.WithExpiry;
2729

2830
/**
2931
* Get Operations
@@ -120,11 +122,21 @@ interface FindByIdWithProjection<T> extends FindByIdInScope<T>, WithProjectionId
120122
FindByIdInScope<T> project(String... fields);
121123
}
122124

125+
interface FindByIdWithExpiry<T> extends FindByIdWithProjection<T>, WithExpiry<T> {
126+
/**
127+
* Load only certain fields for the document.
128+
*
129+
* @param expiry the projected fields to load.
130+
*/
131+
@Override
132+
FindByIdWithProjection<T> withExpiry(Duration expiry);
133+
}
134+
123135
/**
124136
* Provides methods for constructing query operations in a fluent way.
125137
*
126138
* @param <T> the entity type to use for the results
127139
*/
128-
interface ExecutableFindById<T> extends FindByIdWithProjection<T> {}
140+
interface ExecutableFindById<T> extends FindByIdWithExpiry<T> {}
129141

130142
}

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

+16-7
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package org.springframework.data.couchbase.core;
1717

18+
import java.time.Duration;
1819
import java.util.Arrays;
1920
import java.util.Collection;
2021
import java.util.List;
@@ -34,7 +35,7 @@ public class ExecutableFindByIdOperationSupport implements ExecutableFindByIdOpe
3435

3536
@Override
3637
public <T> ExecutableFindById<T> findById(Class<T> domainType) {
37-
return new ExecutableFindByIdSupport<>(template, domainType, null, null, null, null);
38+
return new ExecutableFindByIdSupport<>(template, domainType, null, null, null, null, null);
3839
}
3940

4041
static class ExecutableFindByIdSupport<T> implements ExecutableFindById<T> {
@@ -45,18 +46,20 @@ static class ExecutableFindByIdSupport<T> implements ExecutableFindById<T> {
4546
private final String collection;
4647
private final GetOptions options;
4748
private final List<String> fields;
49+
private final Duration expiry;
4850
private final ReactiveFindByIdSupport<T> reactiveSupport;
4951

5052
ExecutableFindByIdSupport(CouchbaseTemplate template, Class<T> domainType, String scope, String collection,
51-
GetOptions options, List<String> fields) {
53+
GetOptions options, List<String> fields, Duration expiry) {
5254
this.template = template;
5355
this.domainType = domainType;
5456
this.scope = scope;
5557
this.collection = collection;
5658
this.options = options;
5759
this.fields = fields;
60+
this.expiry = expiry;
5861
this.reactiveSupport = new ReactiveFindByIdSupport<>(template.reactive(), domainType, scope, collection, options,
59-
fields, new NonReactiveSupportWrapper(template.support()));
62+
fields, expiry, new NonReactiveSupportWrapper(template.support()));
6063
}
6164

6265
@Override
@@ -72,23 +75,29 @@ public Collection<? extends T> all(final Collection<String> ids) {
7275
@Override
7376
public TerminatingFindById<T> withOptions(final GetOptions options) {
7477
Assert.notNull(options, "Options must not be null.");
75-
return new ExecutableFindByIdSupport<>(template, domainType, scope, collection, options, fields);
78+
return new ExecutableFindByIdSupport<>(template, domainType, scope, collection, options, fields, expiry);
7679
}
7780

7881
@Override
7982
public FindByIdWithOptions<T> inCollection(final String collection) {
80-
return new ExecutableFindByIdSupport<>(template, domainType, scope, collection, options, fields);
83+
return new ExecutableFindByIdSupport<>(template, domainType, scope, collection, options, fields, expiry);
8184
}
8285

8386
@Override
8487
public FindByIdInCollection<T> inScope(final String scope) {
85-
return new ExecutableFindByIdSupport<>(template, domainType, scope, collection, options, fields);
88+
return new ExecutableFindByIdSupport<>(template, domainType, scope, collection, options, fields, expiry);
8689
}
8790

8891
@Override
8992
public FindByIdInScope<T> project(String... fields) {
9093
Assert.notEmpty(fields, "Fields must not be null.");
91-
return new ExecutableFindByIdSupport<>(template, domainType, scope, collection, options, Arrays.asList(fields));
94+
return new ExecutableFindByIdSupport<>(template, domainType, scope, collection, options, Arrays.asList(fields), expiry);
95+
}
96+
97+
@Override
98+
public FindByIdWithProjection<T> withExpiry(final Duration expiry) {
99+
return new ExecutableFindByIdSupport<>(template, domainType, scope, collection, options, fields,
100+
expiry);
92101
}
93102

94103
}

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

+2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import org.springframework.data.couchbase.core.support.InCollection;
2222
import org.springframework.data.couchbase.core.support.InScope;
2323
import org.springframework.data.couchbase.core.support.OneAndAllEntity;
24+
import org.springframework.data.couchbase.core.support.WithDurability;
25+
import org.springframework.data.couchbase.core.support.WithExpiry;
2426
import org.springframework.data.couchbase.core.support.WithInsertOptions;
2527

2628
import com.couchbase.client.core.msg.kv.DurabilityLevel;

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

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.springframework.data.couchbase.core.support.InCollection;
2222
import org.springframework.data.couchbase.core.support.InScope;
2323
import org.springframework.data.couchbase.core.support.OneAndAllId;
24+
import org.springframework.data.couchbase.core.support.WithDurability;
2425
import org.springframework.data.couchbase.core.support.WithRemoveOptions;
2526

2627
import com.couchbase.client.core.msg.kv.DurabilityLevel;

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

+2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import org.springframework.data.couchbase.core.support.InCollection;
2222
import org.springframework.data.couchbase.core.support.InScope;
2323
import org.springframework.data.couchbase.core.support.OneAndAllEntity;
24+
import org.springframework.data.couchbase.core.support.WithDurability;
25+
import org.springframework.data.couchbase.core.support.WithExpiry;
2426
import org.springframework.data.couchbase.core.support.WithReplaceOptions;
2527

2628
import com.couchbase.client.core.msg.kv.DurabilityLevel;

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

+2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import org.springframework.data.couchbase.core.support.InCollection;
2222
import org.springframework.data.couchbase.core.support.InScope;
2323
import org.springframework.data.couchbase.core.support.OneAndAllEntity;
24+
import org.springframework.data.couchbase.core.support.WithDurability;
25+
import org.springframework.data.couchbase.core.support.WithExpiry;
2426
import org.springframework.data.couchbase.core.support.WithUpsertOptions;
2527

2628
import com.couchbase.client.core.msg.kv.DurabilityLevel;

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

+13-1
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,13 @@
1818
import reactor.core.publisher.Flux;
1919
import reactor.core.publisher.Mono;
2020

21+
import java.time.Duration;
2122
import java.util.Collection;
2223

2324
import org.springframework.data.couchbase.core.support.InCollection;
2425
import org.springframework.data.couchbase.core.support.InScope;
2526
import org.springframework.data.couchbase.core.support.OneAndAllIdReactive;
27+
import org.springframework.data.couchbase.core.support.WithExpiry;
2628
import org.springframework.data.couchbase.core.support.WithGetOptions;
2729
import org.springframework.data.couchbase.core.support.WithProjectionId;
2830

@@ -124,11 +126,21 @@ interface FindByIdWithProjection<T> extends FindByIdInScope<T>, WithProjectionId
124126

125127
}
126128

129+
interface FindByIdWithExpiry<T> extends FindByIdWithProjection<T>, WithExpiry<T> {
130+
/**
131+
* Load only certain fields for the document.
132+
*
133+
* @param expiry the projected fields to load.
134+
*/
135+
@Override
136+
FindByIdWithProjection<T> withExpiry(Duration expiry);
137+
}
138+
127139
/**
128140
* Provides methods for constructing query operations in a fluent way.
129141
*
130142
* @param <T> the entity type to use for the results
131143
*/
132-
interface ReactiveFindById<T> extends FindByIdWithProjection<T> {}
144+
interface ReactiveFindById<T> extends FindByIdWithExpiry<T> {}
133145

134146
}

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

+45-19
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,12 @@
1515
*/
1616
package org.springframework.data.couchbase.core;
1717

18-
import static com.couchbase.client.java.kv.GetOptions.getOptions;
18+
import static com.couchbase.client.java.kv.GetAndTouchOptions.getAndTouchOptions;
1919

2020
import reactor.core.publisher.Flux;
2121
import reactor.core.publisher.Mono;
2222

23+
import java.time.Duration;
2324
import java.util.Arrays;
2425
import java.util.Collection;
2526
import java.util.List;
@@ -30,7 +31,9 @@
3031
import org.springframework.util.Assert;
3132

3233
import com.couchbase.client.core.error.DocumentNotFoundException;
34+
import com.couchbase.client.java.CommonOptions;
3335
import com.couchbase.client.java.codec.RawJsonTranscoder;
36+
import com.couchbase.client.java.kv.GetAndTouchOptions;
3437
import com.couchbase.client.java.kv.GetOptions;
3538

3639
public class ReactiveFindByIdOperationSupport implements ReactiveFindByIdOperation {
@@ -44,7 +47,7 @@ public class ReactiveFindByIdOperationSupport implements ReactiveFindByIdOperati
4447

4548
@Override
4649
public <T> ReactiveFindById<T> findById(Class<T> domainType) {
47-
return new ReactiveFindByIdSupport<>(template, domainType, null, null, null, null, template.support());
50+
return new ReactiveFindByIdSupport<>(template, domainType, null, null, null, null, null, template.support());
4851
}
4952

5053
static class ReactiveFindByIdSupport<T> implements ReactiveFindById<T> {
@@ -53,36 +56,53 @@ static class ReactiveFindByIdSupport<T> implements ReactiveFindById<T> {
5356
private final Class<T> domainType;
5457
private final String scope;
5558
private final String collection;
56-
private final GetOptions options;
59+
private final CommonOptions<?> options;
5760
private final List<String> fields;
5861
private final ReactiveTemplateSupport support;
62+
private final Duration expiry;
5963

6064
ReactiveFindByIdSupport(ReactiveCouchbaseTemplate template, Class<T> domainType, String scope, String collection,
61-
GetOptions options, List<String> fields, ReactiveTemplateSupport support) {
65+
CommonOptions<?> options, List<String> fields, Duration expiry, ReactiveTemplateSupport support) {
6266
this.template = template;
6367
this.domainType = domainType;
6468
this.scope = scope;
6569
this.collection = collection;
6670
this.options = options;
6771
this.fields = fields;
72+
this.expiry = expiry;
6873
this.support = support;
6974
}
7075

7176
@Override
7277
public Mono<T> one(final String id) {
73-
GetOptions gOptions = options != null ? options : getOptions();
74-
if (gOptions.build().transcoder() == null) {
75-
gOptions.transcoder(RawJsonTranscoder.INSTANCE);
76-
}
77-
if (fields != null && !fields.isEmpty()) {
78-
gOptions.project(fields);
78+
PseudoArgs<?> pArgs;
79+
if (expiry != null) {
80+
GetAndTouchOptions getAndTouchOptions = options != null ? (GetAndTouchOptions) options : getAndTouchOptions();
81+
if (getAndTouchOptions.build().transcoder() == null) {
82+
getAndTouchOptions.transcoder(RawJsonTranscoder.INSTANCE);
83+
}
84+
pArgs = new PseudoArgs(template, scope, collection, getAndTouchOptions, domainType);
85+
} else {
86+
GetOptions getOptions = options != null ? (GetOptions) options : GetOptions.getOptions();
87+
if (getOptions.build().transcoder() == null) {
88+
getOptions.transcoder(RawJsonTranscoder.INSTANCE);
89+
}
90+
if (fields != null && !fields.isEmpty()) {
91+
getOptions.project(fields);
92+
}
93+
pArgs = new PseudoArgs(template, scope, collection, getOptions, domainType);
94+
7995
}
80-
PseudoArgs<GetOptions> pArgs = new PseudoArgs(template, scope, collection, gOptions, domainType);
8196
LOG.trace("findById {}", pArgs);
82-
return Mono.just(id)
83-
.flatMap(docId -> template.getCouchbaseClientFactory().withScope(pArgs.getScope())
84-
.getCollection(pArgs.getCollection()).reactive().get(docId, pArgs.getOptions()))
85-
.flatMap(result -> support.decodeEntity(id, result.contentAs(String.class), result.cas(), domainType))
97+
return Mono.just(id).flatMap(docId -> {
98+
if (expiry != null) {
99+
return template.getCouchbaseClientFactory().withScope(pArgs.getScope()).getCollection(pArgs.getCollection())
100+
.reactive().getAndTouch(docId, expiry, (GetAndTouchOptions) pArgs.getOptions());
101+
} else {
102+
return template.getCouchbaseClientFactory().withScope(pArgs.getScope()).getCollection(pArgs.getCollection())
103+
.reactive().get(docId, (GetOptions) pArgs.getOptions());
104+
}
105+
}).flatMap(result -> support.decodeEntity(id, result.contentAs(String.class), result.cas(), domainType))
86106
.onErrorResume(throwable -> {
87107
if (throwable instanceof RuntimeException) {
88108
if (throwable instanceof DocumentNotFoundException) {
@@ -107,25 +127,31 @@ public Flux<? extends T> all(final Collection<String> ids) {
107127
@Override
108128
public TerminatingFindById<T> withOptions(final GetOptions options) {
109129
Assert.notNull(options, "Options must not be null.");
110-
return new ReactiveFindByIdSupport<>(template, domainType, scope, collection, options, fields, support);
130+
return new ReactiveFindByIdSupport<>(template, domainType, scope, collection, options, fields, expiry, support);
111131
}
112132

113133
@Override
114134
public FindByIdWithOptions<T> inCollection(final String collection) {
115-
return new ReactiveFindByIdSupport<>(template, domainType, scope, collection, options, fields, support);
135+
return new ReactiveFindByIdSupport<>(template, domainType, scope, collection, options, fields, expiry, support);
116136
}
117137

118138
@Override
119139
public FindByIdInCollection<T> inScope(final String scope) {
120-
return new ReactiveFindByIdSupport<>(template, domainType, scope, collection, options, fields, support);
140+
return new ReactiveFindByIdSupport<>(template, domainType, scope, collection, options, fields, expiry, support);
121141
}
122142

123143
@Override
124144
public FindByIdInScope<T> project(String... fields) {
125145
Assert.notNull(fields, "Fields must not be null");
126146
return new ReactiveFindByIdSupport<>(template, domainType, scope, collection, options, Arrays.asList(fields),
127-
support);
147+
expiry, support);
148+
}
149+
150+
@Override
151+
public FindByIdWithProjection<T> withExpiry(final Duration expiry) {
152+
return new ReactiveFindByIdSupport<>(template, domainType, scope, collection, options, fields, expiry, support);
128153
}
154+
129155
}
130156

131157
}

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

+2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
import org.springframework.data.couchbase.core.support.InCollection;
2525
import org.springframework.data.couchbase.core.support.InScope;
2626
import org.springframework.data.couchbase.core.support.OneAndAllEntityReactive;
27+
import org.springframework.data.couchbase.core.support.WithDurability;
28+
import org.springframework.data.couchbase.core.support.WithExpiry;
2729
import org.springframework.data.couchbase.core.support.WithInsertOptions;
2830

2931
import com.couchbase.client.core.msg.kv.DurabilityLevel;

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

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.springframework.data.couchbase.core.support.InCollection;
2424
import org.springframework.data.couchbase.core.support.InScope;
2525
import org.springframework.data.couchbase.core.support.OneAndAllIdReactive;
26+
import org.springframework.data.couchbase.core.support.WithDurability;
2627
import org.springframework.data.couchbase.core.support.WithRemoveOptions;
2728

2829
import com.couchbase.client.core.msg.kv.DurabilityLevel;

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

+2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
import org.springframework.data.couchbase.core.support.InCollection;
2525
import org.springframework.data.couchbase.core.support.InScope;
2626
import org.springframework.data.couchbase.core.support.OneAndAllEntityReactive;
27+
import org.springframework.data.couchbase.core.support.WithDurability;
28+
import org.springframework.data.couchbase.core.support.WithExpiry;
2729
import org.springframework.data.couchbase.core.support.WithReplaceOptions;
2830

2931
import com.couchbase.client.core.msg.kv.DurabilityLevel;

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

+3-1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
import org.springframework.data.couchbase.core.support.InCollection;
2525
import org.springframework.data.couchbase.core.support.InScope;
2626
import org.springframework.data.couchbase.core.support.OneAndAllEntityReactive;
27+
import org.springframework.data.couchbase.core.support.WithDurability;
28+
import org.springframework.data.couchbase.core.support.WithExpiry;
2729
import org.springframework.data.couchbase.core.support.WithUpsertOptions;
2830

2931
import com.couchbase.client.core.msg.kv.DurabilityLevel;
@@ -39,7 +41,6 @@
3941
*/
4042
public interface ReactiveUpsertByIdOperation {
4143

42-
4344
/**
4445
* Upsert using the KV service.
4546
*
@@ -118,6 +119,7 @@ interface UpsertByIdInScope<T> extends UpsertByIdInCollection<T>, InScope<Object
118119
interface UpsertByIdWithDurability<T> extends UpsertByIdInScope<T>, WithDurability<T> {
119120
@Override
120121
UpsertByIdInCollection<T> withDurability(DurabilityLevel durabilityLevel);
122+
121123
@Override
122124
UpsertByIdInCollection<T> withDurability(PersistTo persistTo, ReplicateTo replicateTo);
123125

src/main/java/org/springframework/data/couchbase/core/WithDurability.java renamed to src/main/java/org/springframework/data/couchbase/core/support/WithDurability.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2020 the original author or authors
2+
* Copyright 2020-2021 the original author or authors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -13,7 +13,7 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16-
package org.springframework.data.couchbase.core;
16+
package org.springframework.data.couchbase.core.support;
1717

1818
import com.couchbase.client.core.msg.kv.DurabilityLevel;
1919
import com.couchbase.client.java.kv.PersistTo;

0 commit comments

Comments
 (0)