Skip to content

Commit 7cde6b9

Browse files
authored
Scopes and collections for repositories (#1149)
* Add support for scopes and collections for repositories. Adds DynamicProxyable and DynamicInvocationHandler to set scope/collection/options on PseudoArgs when calling operations via repository interfaces. Closes #963. Co-authored-by: mikereiche <michael.reiche@couchbase.com>
1 parent 9621c49 commit 7cde6b9

File tree

97 files changed

+2615
-960
lines changed

Some content is hidden

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

97 files changed

+2615
-960
lines changed

src/main/java/org/springframework/data/couchbase/SimpleCouchbaseClientFactory.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2020 the original author or authors
2+
* Copyright 2012-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,6 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16-
1716
package org.springframework.data.couchbase;
1817

1918
import java.util.function.Supplier;
@@ -33,6 +32,9 @@
3332

3433
/**
3534
* The default implementation of a {@link CouchbaseClientFactory}.
35+
*
36+
* @author Michael Nitschinger
37+
* @author Michael Reiche
3638
*/
3739
public class SimpleCouchbaseClientFactory implements CouchbaseClientFactory {
3840

@@ -74,7 +76,7 @@ private SimpleCouchbaseClientFactory(final Supplier<Cluster> cluster, final Stri
7476

7577
@Override
7678
public CouchbaseClientFactory withScope(final String scopeName) {
77-
return new SimpleCouchbaseClientFactory(cluster, bucket.name(), scopeName);
79+
return new SimpleCouchbaseClientFactory(cluster, bucket.name(), scopeName != null ? scopeName : getScope().name());
7880
}
7981

8082
@Override

src/main/java/org/springframework/data/couchbase/config/AbstractCouchbaseConfiguration.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import java.util.HashSet;
2323
import java.util.Set;
2424

25-
import org.springframework.beans.factory.annotation.Autowired;
2625
import org.springframework.beans.factory.config.BeanDefinition;
2726
import org.springframework.context.annotation.Bean;
2827
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;

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

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
import org.springframework.data.couchbase.core.mapping.CouchbaseMappingContext;
2929
import org.springframework.data.couchbase.core.mapping.CouchbasePersistentEntity;
3030
import org.springframework.data.couchbase.core.mapping.CouchbasePersistentProperty;
31-
import org.springframework.data.couchbase.core.support.PseudoArgs;
3231
import org.springframework.data.mapping.context.MappingContext;
3332
import org.springframework.lang.Nullable;
3433

@@ -107,13 +106,25 @@ public <T> ExecutableFindByAnalytics<T> findByAnalytics(Class<T> domainType) {
107106
}
108107

109108
@Override
109+
@Deprecated
110110
public ExecutableRemoveById removeById() {
111-
return new ExecutableRemoveByIdOperationSupport(this).removeById();
111+
return removeById(null);
112112
}
113113

114114
@Override
115+
public ExecutableRemoveById removeById(Class<?> domainType) {
116+
return new ExecutableRemoveByIdOperationSupport(this).removeById(domainType);
117+
}
118+
119+
@Override
120+
@Deprecated
115121
public ExecutableExistsById existsById() {
116-
return new ExecutableExistsByIdOperationSupport(this).existsById();
122+
return existsById(null);
123+
}
124+
125+
@Override
126+
public ExecutableExistsById existsById(Class<?> domainType) {
127+
return new ExecutableExistsByIdOperationSupport(this).existsById(domainType);
117128
}
118129

119130
@Override

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

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

1818
package org.springframework.data.couchbase.core;
1919

20+
import org.slf4j.Logger;
21+
import org.slf4j.LoggerFactory;
2022
import org.springframework.beans.BeansException;
2123
import org.springframework.context.ApplicationContext;
2224
import org.springframework.context.ApplicationContextAware;
@@ -38,9 +40,6 @@
3840
import org.springframework.data.mapping.model.ConvertingPropertyAccessor;
3941
import org.springframework.util.Assert;
4042

41-
import org.slf4j.Logger;
42-
import org.slf4j.LoggerFactory;
43-
4443
/**
4544
* Internal encode/decode support for CouchbaseTemplate.
4645
*

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,14 @@ public interface ExecutableExistsByIdOperation {
3636
/**
3737
* Checks if the document exists in the bucket.
3838
*/
39+
@Deprecated
3940
ExecutableExistsById existsById();
4041

42+
/**
43+
* Checks if the document exists in the bucket.
44+
*/
45+
ExecutableExistsById existsById(Class<?> domainType);
46+
4147
/**
4248
* Terminating operations invoking the actual execution.
4349
*/
@@ -78,7 +84,6 @@ interface ExistsByIdWithOptions<T> extends TerminatingExistsById, WithExistsOpti
7884
}
7985

8086
/**
81-
*
8287
* Fluent method to specify the collection.
8388
*
8489
* @param <T> the entity type to use for the results.

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

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,26 +32,34 @@ public class ExecutableExistsByIdOperationSupport implements ExecutableExistsByI
3232
}
3333

3434
@Override
35+
@Deprecated
3536
public ExecutableExistsById existsById() {
36-
return new ExecutableExistsByIdSupport(template, null, null, null);
37+
return existsById(null);
38+
}
39+
40+
@Override
41+
public ExecutableExistsById existsById(Class<?> domainType) {
42+
return new ExecutableExistsByIdSupport(template, domainType, null, null, null);
3743
}
3844

3945
static class ExecutableExistsByIdSupport implements ExecutableExistsById {
4046

4147
private final CouchbaseTemplate template;
48+
private final Class<?> domainType;
4249
private final String scope;
4350
private final String collection;
4451
private final ExistsOptions options;
4552

4653
private final ReactiveExistsByIdSupport reactiveSupport;
4754

48-
ExecutableExistsByIdSupport(final CouchbaseTemplate template, final String scope, final String collection,
49-
final ExistsOptions options) {
55+
ExecutableExistsByIdSupport(final CouchbaseTemplate template, final Class<?> domainType, final String scope,
56+
final String collection, final ExistsOptions options) {
5057
this.template = template;
58+
this.domainType = domainType;
5159
this.scope = scope;
5260
this.collection = collection;
5361
this.options = options;
54-
this.reactiveSupport = new ReactiveExistsByIdSupport(template.reactive(), scope, collection, options);
62+
this.reactiveSupport = new ReactiveExistsByIdSupport(template.reactive(), domainType, scope, collection, options);
5563
}
5664

5765
@Override
@@ -66,20 +74,18 @@ public Map<String, Boolean> all(final Collection<String> ids) {
6674

6775
@Override
6876
public ExistsByIdWithOptions inCollection(final String collection) {
69-
Assert.hasText(collection, "Collection must not be null nor empty.");
70-
return new ExecutableExistsByIdSupport(template, scope, collection, options);
77+
return new ExecutableExistsByIdSupport(template, domainType, scope, collection, options);
7178
}
7279

7380
@Override
7481
public TerminatingExistsById withOptions(final ExistsOptions options) {
7582
Assert.notNull(options, "Options must not be null.");
76-
return new ExecutableExistsByIdSupport(template, scope, collection, options);
83+
return new ExecutableExistsByIdSupport(template, domainType, scope, collection, options);
7784
}
7885

7986
@Override
8087
public ExistsByIdInCollection inScope(final String scope) {
81-
Assert.hasText(scope, "Scope must not be null nor empty.");
82-
return new ExecutableExistsByIdSupport(template, scope, collection, options);
88+
return new ExecutableExistsByIdSupport(template, domainType, scope, collection, options);
8389
}
8490
}
8591

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,14 +97,12 @@ public FindByAnalyticsWithQuery<T> withOptions(final AnalyticsOptions options) {
9797

9898
@Override
9999
public FindByAnalyticsInCollection<T> inScope(final String scope) {
100-
Assert.hasText(scope, "Scope must not be null nor empty.");
101100
return new ExecutableFindByAnalyticsSupport<>(template, domainType, returnType, query, scanConsistency, scope,
102101
collection, options);
103102
}
104103

105104
@Override
106105
public FindByAnalyticsWithConsistency<T> inCollection(final String collection) {
107-
Assert.hasText(collection, "Collection must not be null nor empty.");
108106
return new ExecutableFindByAnalyticsSupport<>(template, domainType, returnType, query, scanConsistency, scope,
109107
collection, options);
110108
}

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,19 +77,17 @@ public TerminatingFindById<T> withOptions(final GetOptions options) {
7777

7878
@Override
7979
public FindByIdWithOptions<T> inCollection(final String collection) {
80-
Assert.hasText(collection, "Collection must not be null nor empty.");
8180
return new ExecutableFindByIdSupport<>(template, domainType, scope, collection, options, fields);
8281
}
8382

8483
@Override
8584
public FindByIdInCollection<T> inScope(final String scope) {
86-
Assert.hasText(scope, "Scope must not be null nor empty.");
8785
return new ExecutableFindByIdSupport<>(template, domainType, scope, collection, options, fields);
8886
}
8987

9088
@Override
9189
public FindByIdInScope<T> project(String... fields) {
92-
Assert.notEmpty(fields, "Fields must not be null nor empty.");
90+
Assert.notEmpty(fields, "Fields must not be null.");
9391
return new ExecutableFindByIdSupport<>(template, domainType, scope, collection, options, Arrays.asList(fields));
9492
}
9593

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

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@ static class ExecutableFindByQuerySupport<T> implements ExecutableFindByQuery<T>
6868
this.returnType = returnType;
6969
this.query = query;
7070
this.reactiveSupport = new ReactiveFindByQuerySupport<T>(template.reactive(), domainType, returnType, query,
71-
scanConsistency, scope, collection, options, distinctFields, new NonReactiveSupportWrapper(template.support()));
71+
scanConsistency, scope, collection, options, distinctFields,
72+
new NonReactiveSupportWrapper(template.support()));
7273
this.scanConsistency = scanConsistency;
7374
this.scope = scope;
7475
this.collection = collection;
@@ -126,8 +127,12 @@ public <R> FindByQueryWithConsistency<R> as(final Class<R> returnType) {
126127
@Override
127128
public FindByQueryWithProjection<T> distinct(final String[] distinctFields) {
128129
Assert.notNull(distinctFields, "distinctFields must not be null!");
130+
// Coming from an annotation, this cannot be null.
131+
// But a non-null but empty distinctFields means distinct on all fields
132+
// So to indicate do not use distinct, we use {"-"} from the annotation, and here we change it to null.
133+
String[] dFields = distinctFields.length == 1 && "-".equals(distinctFields[0]) ? null : distinctFields;
129134
return new ExecutableFindByQuerySupport<>(template, domainType, returnType, query, scanConsistency, scope,
130-
collection, options, distinctFields);
135+
collection, options, dFields);
131136
}
132137

133138
@Override
@@ -154,14 +159,12 @@ public TerminatingFindByQuery<T> withOptions(final QueryOptions options) {
154159

155160
@Override
156161
public FindByQueryInCollection<T> inScope(final String scope) {
157-
Assert.hasText(scope, "Scope must not be null nor empty.");
158162
return new ExecutableFindByQuerySupport<>(template, domainType, returnType, query, scanConsistency, scope,
159163
collection, options, distinctFields);
160164
}
161165

162166
@Override
163167
public FindByQueryWithConsistency<T> inCollection(final String collection) {
164-
Assert.hasText(collection, "Collection must not be null nor empty.");
165168
return new ExecutableFindByQuerySupport<>(template, domainType, returnType, query, scanConsistency, scope,
166169
collection, options, distinctFields);
167170
}

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

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@
1818
import java.util.Collection;
1919

2020
import org.springframework.data.couchbase.core.ReactiveFindFromReplicasByIdOperationSupport.ReactiveFindFromReplicasByIdSupport;
21+
import org.springframework.util.Assert;
2122

2223
import com.couchbase.client.java.kv.GetAnyReplicaOptions;
23-
import org.springframework.util.Assert;
2424

2525
public class ExecutableFindFromReplicasByIdOperationSupport implements ExecutableFindFromReplicasByIdOperation {
2626

@@ -54,7 +54,7 @@ static class ExecutableFindFromReplicasByIdSupport<T> implements ExecutableFindF
5454
this.options = options;
5555
this.returnType = returnType;
5656
this.reactiveSupport = new ReactiveFindFromReplicasByIdSupport<>(template.reactive(), domainType, returnType,
57-
scope, collection, options, new NonReactiveSupportWrapper(template.support()));
57+
scope, collection, options, new NonReactiveSupportWrapper(template.support()));
5858
}
5959

6060
@Override
@@ -75,13 +75,11 @@ public TerminatingFindFromReplicasById<T> withOptions(final GetAnyReplicaOptions
7575

7676
@Override
7777
public FindFromReplicasByIdWithOptions<T> inCollection(final String collection) {
78-
Assert.hasText(collection, "Collection must not be null nor empty.");
7978
return new ExecutableFindFromReplicasByIdSupport<>(template, domainType, returnType, scope, collection, options);
8079
}
8180

8281
@Override
8382
public FindFromReplicasByIdInCollection<T> inScope(final String scope) {
84-
Assert.hasText(scope, "Scope must not be null nor empty.");
8583
return new ExecutableFindFromReplicasByIdSupport<>(template, domainType, returnType, scope, collection, options);
8684
}
8785

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,14 +89,12 @@ public TerminatingInsertById<T> withOptions(final InsertOptions options) {
8989

9090
@Override
9191
public InsertByIdInCollection<T> inScope(final String scope) {
92-
Assert.hasText(scope, "Scope must not be null nor empty.");
9392
return new ExecutableInsertByIdSupport<>(template, domainType, scope, collection, options, persistTo, replicateTo,
9493
durabilityLevel, expiry);
9594
}
9695

9796
@Override
9897
public InsertByIdWithOptions<T> inCollection(final String collection) {
99-
Assert.hasText(collection, "Collection must not be null nor empty.");
10098
return new ExecutableInsertByIdSupport<>(template, domainType, scope, collection, options, persistTo, replicateTo,
10199
durabilityLevel, expiry);
102100
}

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
import java.util.Collection;
1919
import java.util.List;
2020

21-
import org.springframework.data.couchbase.core.query.WithConsistency;
2221
import org.springframework.data.couchbase.core.support.InCollection;
2322
import org.springframework.data.couchbase.core.support.InScope;
2423
import org.springframework.data.couchbase.core.support.OneAndAllId;
@@ -39,6 +38,12 @@ public interface ExecutableRemoveByIdOperation {
3938
/**
4039
* Removes a document.
4140
*/
41+
ExecutableRemoveById removeById(Class<?> domainType);
42+
43+
/**
44+
* Removes a document.
45+
*/
46+
@Deprecated
4247
ExecutableRemoveById removeById();
4348

4449
/**

0 commit comments

Comments
 (0)