Rework the handling of annotations for scope and collection.
The scope and collection repository annotations were not being passed on to derived and @Query remove operations. The handling of scope and collection annotations has been reworked in: 1) CrudMethodMetadataProcessor 2) All the *OperationSuppport constructors - the initial scope and collection is taken from the domainEntity class. 3) PseudoArgs 4) AbstractCouchbaseQuery/AbstractReactiveCouchbaseQuery add the scope/collection to the remove operation (analogous to the find Operation). 5) Scope/Collection is passed as args to the execute() method - even though this is redundant at the moment. Closes #1441.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2021 the original author or authors
|
||||
* Copyright 2012-2022 the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,6 +19,7 @@ import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.data.couchbase.core.ReactiveExistsByIdOperationSupport.ReactiveExistsByIdSupport;
|
||||
import org.springframework.data.couchbase.core.query.OptionsBuilder;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.couchbase.client.java.kv.ExistsOptions;
|
||||
@@ -39,7 +40,8 @@ public class ExecutableExistsByIdOperationSupport implements ExecutableExistsByI
|
||||
|
||||
@Override
|
||||
public ExecutableExistsById existsById(Class<?> domainType) {
|
||||
return new ExecutableExistsByIdSupport(template, domainType, null, null, null);
|
||||
return new ExecutableExistsByIdSupport(template, domainType, OptionsBuilder.getScopeFrom(domainType),
|
||||
OptionsBuilder.getCollectionFrom(domainType), null);
|
||||
}
|
||||
|
||||
static class ExecutableExistsByIdSupport implements ExecutableExistsById {
|
||||
@@ -74,7 +76,8 @@ public class ExecutableExistsByIdOperationSupport implements ExecutableExistsByI
|
||||
|
||||
@Override
|
||||
public ExistsByIdWithOptions inCollection(final String collection) {
|
||||
return new ExecutableExistsByIdSupport(template, domainType, scope, collection, options);
|
||||
return new ExecutableExistsByIdSupport(template, domainType, scope,
|
||||
collection != null ? collection : this.collection, options);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -85,7 +88,8 @@ public class ExecutableExistsByIdOperationSupport implements ExecutableExistsByI
|
||||
|
||||
@Override
|
||||
public ExistsByIdInCollection inScope(final String scope) {
|
||||
return new ExecutableExistsByIdSupport(template, domainType, scope, collection, options);
|
||||
return new ExecutableExistsByIdSupport(template, domainType, scope != null ? scope : this.scope, collection,
|
||||
options);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2021 the original author or authors
|
||||
* Copyright 2012-2022 the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -20,6 +20,7 @@ import java.util.stream.Stream;
|
||||
|
||||
import org.springframework.data.couchbase.core.ReactiveFindByAnalyticsOperationSupport.ReactiveFindByAnalyticsSupport;
|
||||
import org.springframework.data.couchbase.core.query.AnalyticsQuery;
|
||||
import org.springframework.data.couchbase.core.query.OptionsBuilder;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.couchbase.client.java.analytics.AnalyticsOptions;
|
||||
@@ -37,7 +38,8 @@ public class ExecutableFindByAnalyticsOperationSupport implements ExecutableFind
|
||||
|
||||
@Override
|
||||
public <T> ExecutableFindByAnalytics<T> findByAnalytics(final Class<T> domainType) {
|
||||
return new ExecutableFindByAnalyticsSupport<>(template, domainType, domainType, ALL_QUERY, null, null, null, null);
|
||||
return new ExecutableFindByAnalyticsSupport<>(template, domainType, domainType, ALL_QUERY, null,
|
||||
OptionsBuilder.getScopeFrom(domainType), OptionsBuilder.getCollectionFrom(domainType), null);
|
||||
}
|
||||
|
||||
static class ExecutableFindByAnalyticsSupport<T> implements ExecutableFindByAnalytics<T> {
|
||||
@@ -97,14 +99,14 @@ public class ExecutableFindByAnalyticsOperationSupport implements ExecutableFind
|
||||
|
||||
@Override
|
||||
public FindByAnalyticsInCollection<T> inScope(final String scope) {
|
||||
return new ExecutableFindByAnalyticsSupport<>(template, domainType, returnType, query, scanConsistency, scope,
|
||||
collection, options);
|
||||
return new ExecutableFindByAnalyticsSupport<>(template, domainType, returnType, query, scanConsistency,
|
||||
scope != null ? scope : this.scope, collection, options);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FindByAnalyticsWithConsistency<T> inCollection(final String collection) {
|
||||
return new ExecutableFindByAnalyticsSupport<>(template, domainType, returnType, query, scanConsistency, scope,
|
||||
collection, options);
|
||||
collection != null ? collection : this.collection, options);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2021 the original author or authors
|
||||
* Copyright 2012-2022 the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,6 +21,7 @@ import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.couchbase.core.ReactiveFindByIdOperationSupport.ReactiveFindByIdSupport;
|
||||
import org.springframework.data.couchbase.core.query.OptionsBuilder;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.couchbase.client.java.kv.GetOptions;
|
||||
@@ -35,7 +36,8 @@ public class ExecutableFindByIdOperationSupport implements ExecutableFindByIdOpe
|
||||
|
||||
@Override
|
||||
public <T> ExecutableFindById<T> findById(Class<T> domainType) {
|
||||
return new ExecutableFindByIdSupport<>(template, domainType, null, null, null, null, null);
|
||||
return new ExecutableFindByIdSupport<>(template, domainType, OptionsBuilder.getScopeFrom(domainType),
|
||||
OptionsBuilder.getCollectionFrom(domainType),null, null, null);
|
||||
}
|
||||
|
||||
static class ExecutableFindByIdSupport<T> implements ExecutableFindById<T> {
|
||||
@@ -80,12 +82,12 @@ public class ExecutableFindByIdOperationSupport implements ExecutableFindByIdOpe
|
||||
|
||||
@Override
|
||||
public FindByIdWithOptions<T> inCollection(final String collection) {
|
||||
return new ExecutableFindByIdSupport<>(template, domainType, scope, collection, options, fields, expiry);
|
||||
return new ExecutableFindByIdSupport<>(template, domainType, scope, collection != null ? collection : this.collection, options, fields, expiry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FindByIdInCollection<T> inScope(final String scope) {
|
||||
return new ExecutableFindByIdSupport<>(template, domainType, scope, collection, options, fields, expiry);
|
||||
return new ExecutableFindByIdSupport<>(template, domainType, scope != null ? scope : this.scope, collection, options, fields, expiry);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2021 the original author or authors
|
||||
* Copyright 2012-2022 the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,6 +19,7 @@ import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.springframework.data.couchbase.core.ReactiveFindByQueryOperationSupport.ReactiveFindByQuerySupport;
|
||||
import org.springframework.data.couchbase.core.query.OptionsBuilder;
|
||||
import org.springframework.data.couchbase.core.query.Query;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -43,8 +44,8 @@ public class ExecutableFindByQueryOperationSupport implements ExecutableFindByQu
|
||||
|
||||
@Override
|
||||
public <T> ExecutableFindByQuery<T> findByQuery(final Class<T> domainType) {
|
||||
return new ExecutableFindByQuerySupport<T>(template, domainType, domainType, ALL_QUERY, null, null, null, null,
|
||||
null, null);
|
||||
return new ExecutableFindByQuerySupport<T>(template, domainType, domainType, ALL_QUERY, null,
|
||||
OptionsBuilder.getScopeFrom(domainType), OptionsBuilder.getCollectionFrom(domainType), null, null, null);
|
||||
}
|
||||
|
||||
static class ExecutableFindByQuerySupport<T> implements ExecutableFindByQuery<T> {
|
||||
@@ -174,14 +175,14 @@ public class ExecutableFindByQueryOperationSupport implements ExecutableFindByQu
|
||||
|
||||
@Override
|
||||
public FindByQueryInCollection<T> inScope(final String scope) {
|
||||
return new ExecutableFindByQuerySupport<>(template, domainType, returnType, query, scanConsistency, scope,
|
||||
collection, options, distinctFields, fields);
|
||||
return new ExecutableFindByQuerySupport<>(template, domainType, returnType, query, scanConsistency,
|
||||
scope != null ? scope : this.scope, collection, options, distinctFields, fields);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FindByQueryWithConsistency<T> inCollection(final String collection) {
|
||||
return new ExecutableFindByQuerySupport<>(template, domainType, returnType, query, scanConsistency, scope,
|
||||
collection, options, distinctFields, fields);
|
||||
collection != null ? collection : this.collection, options, distinctFields, fields);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2021 the original author or authors
|
||||
* Copyright 2012-2022 the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,6 +18,7 @@ package org.springframework.data.couchbase.core;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.data.couchbase.core.ReactiveFindFromReplicasByIdOperationSupport.ReactiveFindFromReplicasByIdSupport;
|
||||
import org.springframework.data.couchbase.core.query.OptionsBuilder;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.couchbase.client.java.kv.GetAnyReplicaOptions;
|
||||
@@ -32,7 +33,8 @@ public class ExecutableFindFromReplicasByIdOperationSupport implements Executabl
|
||||
|
||||
@Override
|
||||
public <T> ExecutableFindFromReplicasById<T> findFromReplicasById(Class<T> domainType) {
|
||||
return new ExecutableFindFromReplicasByIdSupport<>(template, domainType, domainType, null, null, null);
|
||||
return new ExecutableFindFromReplicasByIdSupport<>(template, domainType, domainType,
|
||||
OptionsBuilder.getScopeFrom(domainType), OptionsBuilder.getCollectionFrom(domainType), null);
|
||||
}
|
||||
|
||||
static class ExecutableFindFromReplicasByIdSupport<T> implements ExecutableFindFromReplicasById<T> {
|
||||
@@ -75,12 +77,14 @@ public class ExecutableFindFromReplicasByIdOperationSupport implements Executabl
|
||||
|
||||
@Override
|
||||
public FindFromReplicasByIdWithOptions<T> inCollection(final String collection) {
|
||||
return new ExecutableFindFromReplicasByIdSupport<>(template, domainType, returnType, scope, collection, options);
|
||||
return new ExecutableFindFromReplicasByIdSupport<>(template, domainType, returnType, scope,
|
||||
collection != null ? collection : this.collection, options);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FindFromReplicasByIdInCollection<T> inScope(final String scope) {
|
||||
return new ExecutableFindFromReplicasByIdSupport<>(template, domainType, returnType, scope, collection, options);
|
||||
return new ExecutableFindFromReplicasByIdSupport<>(template, domainType, returnType,
|
||||
scope != null ? scope : this.scope, collection, options);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import java.time.Duration;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.data.couchbase.core.ReactiveInsertByIdOperationSupport.ReactiveInsertByIdSupport;
|
||||
import org.springframework.data.couchbase.core.query.OptionsBuilder;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.couchbase.client.core.msg.kv.DurabilityLevel;
|
||||
@@ -37,8 +38,9 @@ public class ExecutableInsertByIdOperationSupport implements ExecutableInsertByI
|
||||
@Override
|
||||
public <T> ExecutableInsertById<T> insertById(final Class<T> domainType) {
|
||||
Assert.notNull(domainType, "DomainType must not be null!");
|
||||
return new ExecutableInsertByIdSupport<>(template, domainType, null, null, null, PersistTo.NONE, ReplicateTo.NONE,
|
||||
DurabilityLevel.NONE, null);
|
||||
return new ExecutableInsertByIdSupport<>(template, domainType, OptionsBuilder.getScopeFrom(domainType),
|
||||
OptionsBuilder.getCollectionFrom(domainType), null, PersistTo.NONE, ReplicateTo.NONE, DurabilityLevel.NONE,
|
||||
null);
|
||||
}
|
||||
|
||||
static class ExecutableInsertByIdSupport<T> implements ExecutableInsertById<T> {
|
||||
@@ -89,14 +91,14 @@ public class ExecutableInsertByIdOperationSupport implements ExecutableInsertByI
|
||||
|
||||
@Override
|
||||
public InsertByIdInCollection<T> inScope(final String scope) {
|
||||
return new ExecutableInsertByIdSupport<>(template, domainType, scope, collection, options, persistTo, replicateTo,
|
||||
durabilityLevel, expiry);
|
||||
return new ExecutableInsertByIdSupport<>(template, domainType, scope != null ? scope : this.scope, collection,
|
||||
options, persistTo, replicateTo, durabilityLevel, expiry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InsertByIdWithOptions<T> inCollection(final String collection) {
|
||||
return new ExecutableInsertByIdSupport<>(template, domainType, scope, collection, options, persistTo, replicateTo,
|
||||
durabilityLevel, expiry);
|
||||
return new ExecutableInsertByIdSupport<>(template, domainType, scope,
|
||||
collection != null ? collection : this.collection, options, persistTo, replicateTo, durabilityLevel, expiry);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -19,6 +19,7 @@ import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.couchbase.core.ReactiveRemoveByIdOperationSupport.ReactiveRemoveByIdSupport;
|
||||
import org.springframework.data.couchbase.core.query.OptionsBuilder;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.couchbase.client.core.msg.kv.DurabilityLevel;
|
||||
@@ -42,7 +43,9 @@ public class ExecutableRemoveByIdOperationSupport implements ExecutableRemoveByI
|
||||
|
||||
@Override
|
||||
public ExecutableRemoveById removeById(Class<?> domainType) {
|
||||
return new ExecutableRemoveByIdSupport(template, domainType, null, null, null, PersistTo.NONE, ReplicateTo.NONE,
|
||||
|
||||
return new ExecutableRemoveByIdSupport(template, domainType, OptionsBuilder.getScopeFrom(domainType),
|
||||
OptionsBuilder.getCollectionFrom(domainType), null, PersistTo.NONE, ReplicateTo.NONE,
|
||||
DurabilityLevel.NONE, null);
|
||||
}
|
||||
|
||||
@@ -87,7 +90,7 @@ public class ExecutableRemoveByIdOperationSupport implements ExecutableRemoveByI
|
||||
|
||||
@Override
|
||||
public RemoveByIdWithOptions inCollection(final String collection) {
|
||||
return new ExecutableRemoveByIdSupport(template, domainType, scope, collection, options, persistTo, replicateTo,
|
||||
return new ExecutableRemoveByIdSupport(template, domainType, scope, collection != null ? collection : this.collection, options, persistTo, replicateTo,
|
||||
durabilityLevel, cas);
|
||||
}
|
||||
|
||||
@@ -115,7 +118,7 @@ public class ExecutableRemoveByIdOperationSupport implements ExecutableRemoveByI
|
||||
|
||||
@Override
|
||||
public RemoveByIdInCollection inScope(final String scope) {
|
||||
return new ExecutableRemoveByIdSupport(template, domainType, scope, collection, options, persistTo, replicateTo,
|
||||
return new ExecutableRemoveByIdSupport(template, domainType, scope != null ? scope : this.scope, collection, options, persistTo, replicateTo,
|
||||
durabilityLevel, cas);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2021 the original author or authors
|
||||
* Copyright 2012-2022 the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,6 +18,7 @@ package org.springframework.data.couchbase.core;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.couchbase.core.ReactiveRemoveByQueryOperationSupport.ReactiveRemoveByQuerySupport;
|
||||
import org.springframework.data.couchbase.core.query.OptionsBuilder;
|
||||
import org.springframework.data.couchbase.core.query.Query;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -36,7 +37,8 @@ public class ExecutableRemoveByQueryOperationSupport implements ExecutableRemove
|
||||
|
||||
@Override
|
||||
public <T> ExecutableRemoveByQuery<T> removeByQuery(Class<T> domainType) {
|
||||
return new ExecutableRemoveByQuerySupport<>(template, domainType, ALL_QUERY, null, null, null, null);
|
||||
return new ExecutableRemoveByQuerySupport<>(template, domainType, ALL_QUERY, null,
|
||||
OptionsBuilder.getScopeFrom(domainType), OptionsBuilder.getCollectionFrom(domainType), null);
|
||||
}
|
||||
|
||||
static class ExecutableRemoveByQuerySupport<T> implements ExecutableRemoveByQuery<T> {
|
||||
@@ -89,8 +91,8 @@ public class ExecutableRemoveByQueryOperationSupport implements ExecutableRemove
|
||||
|
||||
@Override
|
||||
public RemoveByQueryWithConsistency<T> inCollection(final String collection) {
|
||||
return new ExecutableRemoveByQuerySupport<>(template, domainType, query, scanConsistency, scope, collection,
|
||||
options);
|
||||
return new ExecutableRemoveByQuerySupport<>(template, domainType, query, scanConsistency, scope,
|
||||
collection != null ? collection : this.collection, options);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -102,8 +104,8 @@ public class ExecutableRemoveByQueryOperationSupport implements ExecutableRemove
|
||||
|
||||
@Override
|
||||
public RemoveByQueryInCollection<T> inScope(final String scope) {
|
||||
return new ExecutableRemoveByQuerySupport<>(template, domainType, query, scanConsistency, scope, collection,
|
||||
options);
|
||||
return new ExecutableRemoveByQuerySupport<>(template, domainType, query, scanConsistency,
|
||||
scope != null ? scope : this.scope, collection, options);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2021 the original author or authors
|
||||
* Copyright 2012-2022 the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,6 +19,7 @@ import java.time.Duration;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.data.couchbase.core.ReactiveReplaceByIdOperationSupport.ReactiveReplaceByIdSupport;
|
||||
import org.springframework.data.couchbase.core.query.OptionsBuilder;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.couchbase.client.core.msg.kv.DurabilityLevel;
|
||||
@@ -37,8 +38,9 @@ public class ExecutableReplaceByIdOperationSupport implements ExecutableReplaceB
|
||||
@Override
|
||||
public <T> ExecutableReplaceById<T> replaceById(final Class<T> domainType) {
|
||||
Assert.notNull(domainType, "DomainType must not be null!");
|
||||
return new ExecutableReplaceByIdSupport<>(template, domainType, null, null, null, PersistTo.NONE, ReplicateTo.NONE,
|
||||
DurabilityLevel.NONE, null);
|
||||
return new ExecutableReplaceByIdSupport<>(template, domainType, OptionsBuilder.getScopeFrom(domainType),
|
||||
OptionsBuilder.getCollectionFrom(domainType), null, PersistTo.NONE, ReplicateTo.NONE, DurabilityLevel.NONE,
|
||||
null);
|
||||
}
|
||||
|
||||
static class ExecutableReplaceByIdSupport<T> implements ExecutableReplaceById<T> {
|
||||
@@ -82,8 +84,8 @@ public class ExecutableReplaceByIdOperationSupport implements ExecutableReplaceB
|
||||
|
||||
@Override
|
||||
public ReplaceByIdWithOptions<T> inCollection(final String collection) {
|
||||
return new ExecutableReplaceByIdSupport<>(template, domainType, scope, collection, options, persistTo,
|
||||
replicateTo, durabilityLevel, expiry);
|
||||
return new ExecutableReplaceByIdSupport<>(template, domainType, scope,
|
||||
collection != null ? collection : this.collection, options, persistTo, replicateTo, durabilityLevel, expiry);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -117,8 +119,8 @@ public class ExecutableReplaceByIdOperationSupport implements ExecutableReplaceB
|
||||
|
||||
@Override
|
||||
public ReplaceByIdInCollection<T> inScope(final String scope) {
|
||||
return new ExecutableReplaceByIdSupport<>(template, domainType, scope, collection, options, persistTo,
|
||||
replicateTo, durabilityLevel, expiry);
|
||||
return new ExecutableReplaceByIdSupport<>(template, domainType, scope != null ? scope : this.scope, collection,
|
||||
options, persistTo, replicateTo, durabilityLevel, expiry);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2021 the original author or authors
|
||||
* Copyright 2012-2022 the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,6 +19,7 @@ import java.time.Duration;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.data.couchbase.core.ReactiveUpsertByIdOperationSupport.ReactiveUpsertByIdSupport;
|
||||
import org.springframework.data.couchbase.core.query.OptionsBuilder;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.couchbase.client.core.msg.kv.DurabilityLevel;
|
||||
@@ -37,8 +38,9 @@ public class ExecutableUpsertByIdOperationSupport implements ExecutableUpsertByI
|
||||
@Override
|
||||
public <T> ExecutableUpsertById<T> upsertById(final Class<T> domainType) {
|
||||
Assert.notNull(domainType, "DomainType must not be null!");
|
||||
return new ExecutableUpsertByIdSupport<>(template, domainType, null, null, null, PersistTo.NONE, ReplicateTo.NONE,
|
||||
DurabilityLevel.NONE, null);
|
||||
return new ExecutableUpsertByIdSupport<>(template, domainType, OptionsBuilder.getScopeFrom(domainType),
|
||||
OptionsBuilder.getCollectionFrom(domainType), null, PersistTo.NONE, ReplicateTo.NONE, DurabilityLevel.NONE,
|
||||
null);
|
||||
}
|
||||
|
||||
static class ExecutableUpsertByIdSupport<T> implements ExecutableUpsertById<T> {
|
||||
@@ -89,14 +91,14 @@ public class ExecutableUpsertByIdOperationSupport implements ExecutableUpsertByI
|
||||
|
||||
@Override
|
||||
public UpsertByIdInCollection<T> inScope(final String scope) {
|
||||
return new ExecutableUpsertByIdSupport<>(template, domainType, scope, collection, options, persistTo, replicateTo,
|
||||
durabilityLevel, expiry);
|
||||
return new ExecutableUpsertByIdSupport<>(template, domainType, scope != null ? scope : this.scope, collection,
|
||||
options, persistTo, replicateTo, durabilityLevel, expiry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UpsertByIdWithOptions<T> inCollection(final String collection) {
|
||||
return new ExecutableUpsertByIdSupport<>(template, domainType, scope, collection, options, persistTo, replicateTo,
|
||||
durabilityLevel, expiry);
|
||||
return new ExecutableUpsertByIdSupport<>(template, domainType, scope,
|
||||
collection != null ? collection : this.collection, options, persistTo, replicateTo, durabilityLevel, expiry);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2021 the original author or authors
|
||||
* Copyright 2012-2022 the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -49,7 +49,8 @@ public class ReactiveExistsByIdOperationSupport implements ReactiveExistsByIdOpe
|
||||
|
||||
@Override
|
||||
public ReactiveExistsById existsById(Class<?> domainType) {
|
||||
return new ReactiveExistsByIdSupport(template, domainType, null, null, null);
|
||||
return new ReactiveExistsByIdSupport(template, domainType, OptionsBuilder.getScopeFrom(domainType),
|
||||
OptionsBuilder.getCollectionFrom(domainType), null);
|
||||
}
|
||||
|
||||
static class ReactiveExistsByIdSupport implements ReactiveExistsById {
|
||||
@@ -72,7 +73,7 @@ public class ReactiveExistsByIdOperationSupport implements ReactiveExistsByIdOpe
|
||||
@Override
|
||||
public Mono<Boolean> one(final String id) {
|
||||
PseudoArgs<ExistsOptions> pArgs = new PseudoArgs<>(template, scope, collection, options, domainType);
|
||||
LOG.trace("existsById {}", pArgs);
|
||||
LOG.trace("existsById key={} {}", id, pArgs);
|
||||
return Mono.just(id)
|
||||
.flatMap(docId -> template.getCouchbaseClientFactory().withScope(pArgs.getScope())
|
||||
.getCollection(pArgs.getCollection()).reactive().exists(id, buildOptions(pArgs.getOptions()))
|
||||
@@ -98,7 +99,8 @@ public class ReactiveExistsByIdOperationSupport implements ReactiveExistsByIdOpe
|
||||
|
||||
@Override
|
||||
public ExistsByIdWithOptions inCollection(final String collection) {
|
||||
return new ReactiveExistsByIdSupport(template, domainType, scope, collection, options);
|
||||
return new ReactiveExistsByIdSupport(template, domainType, scope,
|
||||
collection != null ? collection : this.collection, options);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -109,7 +111,8 @@ public class ReactiveExistsByIdOperationSupport implements ReactiveExistsByIdOpe
|
||||
|
||||
@Override
|
||||
public ExistsByIdInCollection inScope(final String scope) {
|
||||
return new ReactiveExistsByIdSupport(template, domainType, scope, collection, options);
|
||||
return new ReactiveExistsByIdSupport(template, domainType, scope != null ? scope : this.scope, collection,
|
||||
options);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.data.couchbase.core.query.AnalyticsQuery;
|
||||
import org.springframework.data.couchbase.core.query.OptionsBuilder;
|
||||
import org.springframework.data.couchbase.core.support.TemplateUtils;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -38,7 +39,8 @@ public class ReactiveFindByAnalyticsOperationSupport implements ReactiveFindByAn
|
||||
|
||||
@Override
|
||||
public <T> ReactiveFindByAnalytics<T> findByAnalytics(final Class<T> domainType) {
|
||||
return new ReactiveFindByAnalyticsSupport<>(template, domainType, domainType, ALL_QUERY, null, null, null, null,
|
||||
return new ReactiveFindByAnalyticsSupport<>(template, domainType, domainType, ALL_QUERY, null,
|
||||
OptionsBuilder.getScopeFrom(domainType), OptionsBuilder.getCollectionFrom(domainType), null,
|
||||
template.support());
|
||||
}
|
||||
|
||||
@@ -165,14 +167,14 @@ public class ReactiveFindByAnalyticsOperationSupport implements ReactiveFindByAn
|
||||
|
||||
@Override
|
||||
public FindByAnalyticsInCollection<T> inScope(final String scope) {
|
||||
return new ReactiveFindByAnalyticsSupport<>(template, domainType, returnType, query, scanConsistency, scope,
|
||||
collection, options, support);
|
||||
return new ReactiveFindByAnalyticsSupport<>(template, domainType, returnType, query, scanConsistency,
|
||||
scope != null ? scope : this.scope, collection, options, support);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FindByAnalyticsWithConsistency<T> inCollection(final String collection) {
|
||||
return new ReactiveFindByAnalyticsSupport<>(template, domainType, returnType, query, scanConsistency, scope,
|
||||
collection, options, support);
|
||||
collection != null ? collection : this.collection, options, support);
|
||||
}
|
||||
|
||||
private String assembleEntityQuery(final boolean count) {
|
||||
|
||||
@@ -28,6 +28,7 @@ import java.util.List;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.data.couchbase.core.mapping.CouchbasePersistentEntity;
|
||||
import org.springframework.data.couchbase.core.query.OptionsBuilder;
|
||||
import org.springframework.data.couchbase.core.support.PseudoArgs;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -49,7 +50,8 @@ public class ReactiveFindByIdOperationSupport implements ReactiveFindByIdOperati
|
||||
|
||||
@Override
|
||||
public <T> ReactiveFindById<T> findById(Class<T> domainType) {
|
||||
return new ReactiveFindByIdSupport<>(template, domainType, null, null, null, null, null, template.support());
|
||||
return new ReactiveFindByIdSupport<>(template, domainType, OptionsBuilder.getScopeFrom(domainType),
|
||||
OptionsBuilder.getCollectionFrom(domainType), null, null, null, template.support());
|
||||
}
|
||||
|
||||
static class ReactiveFindByIdSupport<T> implements ReactiveFindById<T> {
|
||||
@@ -80,7 +82,7 @@ public class ReactiveFindByIdOperationSupport implements ReactiveFindByIdOperati
|
||||
|
||||
CommonOptions<?> gOptions = initGetOptions();
|
||||
PseudoArgs<?> pArgs = new PseudoArgs(template, scope, collection, gOptions, domainType);
|
||||
LOG.trace("findById {}", pArgs);
|
||||
LOG.trace("findById key={} {}", id, pArgs);
|
||||
|
||||
return Mono.just(id).flatMap(docId -> {
|
||||
ReactiveCollection reactive = template.getCouchbaseClientFactory().withScope(pArgs.getScope())
|
||||
@@ -120,12 +122,14 @@ public class ReactiveFindByIdOperationSupport implements ReactiveFindByIdOperati
|
||||
|
||||
@Override
|
||||
public FindByIdWithOptions<T> inCollection(final String collection) {
|
||||
return new ReactiveFindByIdSupport<>(template, domainType, scope, collection, options, fields, expiry, support);
|
||||
return new ReactiveFindByIdSupport<>(template, domainType, scope,
|
||||
collection != null ? collection : this.collection, options, fields, expiry, support);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FindByIdInCollection<T> inScope(final String scope) {
|
||||
return new ReactiveFindByIdSupport<>(template, domainType, scope, collection, options, fields, expiry, support);
|
||||
return new ReactiveFindByIdSupport<>(template, domainType, scope != null ? scope : this.scope, collection,
|
||||
options, fields, expiry, support);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -20,6 +20,7 @@ import reactor.core.publisher.Mono;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.data.couchbase.core.query.OptionsBuilder;
|
||||
import org.springframework.data.couchbase.core.query.Query;
|
||||
import org.springframework.data.couchbase.core.support.PseudoArgs;
|
||||
import org.springframework.data.couchbase.core.support.TemplateUtils;
|
||||
@@ -48,8 +49,9 @@ public class ReactiveFindByQueryOperationSupport implements ReactiveFindByQueryO
|
||||
|
||||
@Override
|
||||
public <T> ReactiveFindByQuery<T> findByQuery(final Class<T> domainType) {
|
||||
return new ReactiveFindByQuerySupport<>(template, domainType, domainType, ALL_QUERY, null, null, null, null, null,
|
||||
null, template.support());
|
||||
return new ReactiveFindByQuerySupport<>(template, domainType, domainType, ALL_QUERY, null,
|
||||
OptionsBuilder.getScopeFrom(domainType), OptionsBuilder.getCollectionFrom(domainType), null, null, null,
|
||||
template.support());
|
||||
}
|
||||
|
||||
static class ReactiveFindByQuerySupport<T> implements ReactiveFindByQuery<T> {
|
||||
@@ -107,14 +109,14 @@ public class ReactiveFindByQueryOperationSupport implements ReactiveFindByQueryO
|
||||
|
||||
@Override
|
||||
public FindByQueryInCollection<T> inScope(final String scope) {
|
||||
return new ReactiveFindByQuerySupport<>(template, domainType, returnType, query, scanConsistency, scope,
|
||||
collection, options, distinctFields, fields, support);
|
||||
return new ReactiveFindByQuerySupport<>(template, domainType, returnType, query, scanConsistency,
|
||||
scope != null ? scope : this.scope, collection, options, distinctFields, fields, support);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FindByQueryWithConsistency<T> inCollection(final String collection) {
|
||||
return new ReactiveFindByQuerySupport<>(template, domainType, returnType, query, scanConsistency, scope,
|
||||
collection, options, distinctFields, fields, support);
|
||||
collection != null ? collection : this.collection, options, distinctFields, fields, support);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.util.Collection;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.data.couchbase.core.query.OptionsBuilder;
|
||||
import org.springframework.data.couchbase.core.support.PseudoArgs;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -41,7 +42,8 @@ public class ReactiveFindFromReplicasByIdOperationSupport implements ReactiveFin
|
||||
|
||||
@Override
|
||||
public <T> ReactiveFindFromReplicasById<T> findFromReplicasById(Class<T> domainType) {
|
||||
return new ReactiveFindFromReplicasByIdSupport<>(template, domainType, domainType, null, null, null,
|
||||
return new ReactiveFindFromReplicasByIdSupport<>(template, domainType, domainType,
|
||||
OptionsBuilder.getScopeFrom(domainType), OptionsBuilder.getCollectionFrom(domainType), null,
|
||||
template.support());
|
||||
}
|
||||
|
||||
@@ -73,7 +75,7 @@ public class ReactiveFindFromReplicasByIdOperationSupport implements ReactiveFin
|
||||
garOptions.transcoder(RawJsonTranscoder.INSTANCE);
|
||||
}
|
||||
PseudoArgs<GetAnyReplicaOptions> pArgs = new PseudoArgs<>(template, scope, collection, garOptions, domainType);
|
||||
LOG.trace("getAnyReplica {}", pArgs);
|
||||
LOG.trace("getAnyReplica key={} {}", id, pArgs);
|
||||
return Mono.just(id)
|
||||
.flatMap(docId -> template.getCouchbaseClientFactory().withScope(pArgs.getScope())
|
||||
.getCollection(pArgs.getCollection()).reactive().getAnyReplica(docId, pArgs.getOptions()))
|
||||
@@ -102,14 +104,14 @@ public class ReactiveFindFromReplicasByIdOperationSupport implements ReactiveFin
|
||||
|
||||
@Override
|
||||
public FindFromReplicasByIdWithOptions<T> inCollection(final String collection) {
|
||||
return new ReactiveFindFromReplicasByIdSupport<>(template, domainType, returnType, scope, collection, options,
|
||||
support);
|
||||
return new ReactiveFindFromReplicasByIdSupport<>(template, domainType, returnType, scope,
|
||||
collection != null ? collection : this.collection, options, support);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FindFromReplicasByIdInCollection<T> inScope(final String scope) {
|
||||
return new ReactiveFindFromReplicasByIdSupport<>(template, domainType, returnType, scope, collection, options,
|
||||
support);
|
||||
return new ReactiveFindFromReplicasByIdSupport<>(template, domainType, returnType,
|
||||
scope != null ? scope : this.scope, collection, options, support);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -45,8 +45,9 @@ public class ReactiveInsertByIdOperationSupport implements ReactiveInsertByIdOpe
|
||||
@Override
|
||||
public <T> ReactiveInsertById<T> insertById(final Class<T> domainType) {
|
||||
Assert.notNull(domainType, "DomainType must not be null!");
|
||||
return new ReactiveInsertByIdSupport<>(template, domainType, null, null, null, PersistTo.NONE, ReplicateTo.NONE,
|
||||
DurabilityLevel.NONE, null, template.support());
|
||||
return new ReactiveInsertByIdSupport<>(template, domainType, OptionsBuilder.getScopeFrom(domainType),
|
||||
OptionsBuilder.getCollectionFrom(domainType), null, PersistTo.NONE, ReplicateTo.NONE, DurabilityLevel.NONE,
|
||||
null, template.support());
|
||||
}
|
||||
|
||||
static class ReactiveInsertByIdSupport<T> implements ReactiveInsertById<T> {
|
||||
@@ -80,7 +81,7 @@ public class ReactiveInsertByIdOperationSupport implements ReactiveInsertByIdOpe
|
||||
@Override
|
||||
public Mono<T> one(T object) {
|
||||
PseudoArgs<InsertOptions> pArgs = new PseudoArgs(template, scope, collection, options, domainType);
|
||||
LOG.trace("insertById {}", pArgs);
|
||||
LOG.trace("insertById object={} {}", object, pArgs);
|
||||
return Mono.just(object).flatMap(support::encodeEntity)
|
||||
.flatMap(converted -> template.getCouchbaseClientFactory().withScope(pArgs.getScope())
|
||||
.getCollection(pArgs.getCollection()).reactive()
|
||||
@@ -114,14 +115,15 @@ public class ReactiveInsertByIdOperationSupport implements ReactiveInsertByIdOpe
|
||||
|
||||
@Override
|
||||
public InsertByIdInCollection<T> inScope(final String scope) {
|
||||
return new ReactiveInsertByIdSupport<>(template, domainType, scope, collection, options, persistTo, replicateTo,
|
||||
durabilityLevel, expiry, support);
|
||||
return new ReactiveInsertByIdSupport<>(template, domainType, scope != null ? scope : this.scope, collection,
|
||||
options, persistTo, replicateTo, durabilityLevel, expiry, support);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InsertByIdWithOptions<T> inCollection(final String collection) {
|
||||
return new ReactiveInsertByIdSupport<>(template, domainType, scope, collection, options, persistTo, replicateTo,
|
||||
durabilityLevel, expiry, support);
|
||||
return new ReactiveInsertByIdSupport<>(template, domainType, scope,
|
||||
collection != null ? collection : this.collection, options, persistTo, replicateTo, durabilityLevel, expiry,
|
||||
support);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -48,8 +48,9 @@ public class ReactiveRemoveByIdOperationSupport implements ReactiveRemoveByIdOpe
|
||||
|
||||
@Override
|
||||
public ReactiveRemoveById removeById(Class<?> domainType) {
|
||||
return new ReactiveRemoveByIdSupport(template, domainType, null, null, null, PersistTo.NONE, ReplicateTo.NONE,
|
||||
DurabilityLevel.NONE, null);
|
||||
return new ReactiveRemoveByIdSupport(template, domainType, OptionsBuilder.getScopeFrom(domainType),
|
||||
OptionsBuilder.getCollectionFrom(domainType), null, PersistTo.NONE, ReplicateTo.NONE, DurabilityLevel.NONE,
|
||||
null);
|
||||
}
|
||||
|
||||
static class ReactiveRemoveByIdSupport implements ReactiveRemoveById {
|
||||
@@ -81,7 +82,7 @@ public class ReactiveRemoveByIdOperationSupport implements ReactiveRemoveByIdOpe
|
||||
@Override
|
||||
public Mono<RemoveResult> one(final String id) {
|
||||
PseudoArgs<RemoveOptions> pArgs = new PseudoArgs<>(template, scope, collection, options, domainType);
|
||||
LOG.trace("removeById {}", pArgs);
|
||||
LOG.trace("removeById key={} {}", id, pArgs);
|
||||
return Mono.just(id)
|
||||
.flatMap(docId -> template.getCouchbaseClientFactory().withScope(pArgs.getScope())
|
||||
.getCollection(pArgs.getCollection()).reactive().remove(id, buildRemoveOptions(pArgs.getOptions()))
|
||||
@@ -121,14 +122,14 @@ public class ReactiveRemoveByIdOperationSupport implements ReactiveRemoveByIdOpe
|
||||
|
||||
@Override
|
||||
public RemoveByIdWithDurability inCollection(final String collection) {
|
||||
return new ReactiveRemoveByIdSupport(template, domainType, scope, collection, options, persistTo, replicateTo,
|
||||
durabilityLevel, cas);
|
||||
return new ReactiveRemoveByIdSupport(template, domainType, scope,
|
||||
collection != null ? collection : this.collection, options, persistTo, replicateTo, durabilityLevel, cas);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RemoveByIdInCollection inScope(final String scope) {
|
||||
return new ReactiveRemoveByIdSupport(template, domainType, scope, collection, options, persistTo, replicateTo,
|
||||
durabilityLevel, cas);
|
||||
return new ReactiveRemoveByIdSupport(template, domainType, scope != null ? scope : this.scope, collection,
|
||||
options, persistTo, replicateTo, durabilityLevel, cas);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -22,6 +22,7 @@ import java.util.Optional;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.data.couchbase.core.query.OptionsBuilder;
|
||||
import org.springframework.data.couchbase.core.query.Query;
|
||||
import org.springframework.data.couchbase.core.support.PseudoArgs;
|
||||
import org.springframework.data.couchbase.core.support.TemplateUtils;
|
||||
@@ -44,7 +45,8 @@ public class ReactiveRemoveByQueryOperationSupport implements ReactiveRemoveByQu
|
||||
|
||||
@Override
|
||||
public <T> ReactiveRemoveByQuery<T> removeByQuery(Class<T> domainType) {
|
||||
return new ReactiveRemoveByQuerySupport<>(template, domainType, ALL_QUERY, null, null, null, null);
|
||||
return new ReactiveRemoveByQuerySupport<>(template, domainType, ALL_QUERY, null,
|
||||
OptionsBuilder.getScopeFrom(domainType), OptionsBuilder.getCollectionFrom(domainType), null);
|
||||
}
|
||||
|
||||
static class ReactiveRemoveByQuerySupport<T> implements ReactiveRemoveByQuery<T> {
|
||||
@@ -102,8 +104,8 @@ public class ReactiveRemoveByQueryOperationSupport implements ReactiveRemoveByQu
|
||||
|
||||
@Override
|
||||
public RemoveByQueryWithConsistency<T> inCollection(final String collection) {
|
||||
return new ReactiveRemoveByQuerySupport<>(template, domainType, query, scanConsistency, scope, collection,
|
||||
options);
|
||||
return new ReactiveRemoveByQuerySupport<>(template, domainType, query, scanConsistency, scope,
|
||||
collection != null ? collection : this.collection, options);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -132,8 +134,8 @@ public class ReactiveRemoveByQueryOperationSupport implements ReactiveRemoveByQu
|
||||
|
||||
@Override
|
||||
public RemoveByQueryInCollection<T> inScope(final String scope) {
|
||||
return new ReactiveRemoveByQuerySupport<>(template, domainType, query, scanConsistency, scope, collection,
|
||||
options);
|
||||
return new ReactiveRemoveByQuerySupport<>(template, domainType, query, scanConsistency,
|
||||
scope != null ? scope : this.scope, collection, options);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -45,8 +45,9 @@ public class ReactiveReplaceByIdOperationSupport implements ReactiveReplaceByIdO
|
||||
@Override
|
||||
public <T> ReactiveReplaceById<T> replaceById(final Class<T> domainType) {
|
||||
Assert.notNull(domainType, "DomainType must not be null!");
|
||||
return new ReactiveReplaceByIdSupport<>(template, domainType, null, null, null, PersistTo.NONE, ReplicateTo.NONE,
|
||||
DurabilityLevel.NONE, null, template.support());
|
||||
return new ReactiveReplaceByIdSupport<>(template, domainType, OptionsBuilder.getScopeFrom(domainType),
|
||||
OptionsBuilder.getCollectionFrom(domainType), null, PersistTo.NONE, ReplicateTo.NONE, DurabilityLevel.NONE,
|
||||
null, template.support());
|
||||
}
|
||||
|
||||
static class ReactiveReplaceByIdSupport<T> implements ReactiveReplaceById<T> {
|
||||
@@ -80,7 +81,7 @@ public class ReactiveReplaceByIdOperationSupport implements ReactiveReplaceByIdO
|
||||
@Override
|
||||
public Mono<T> one(T object) {
|
||||
PseudoArgs<ReplaceOptions> pArgs = new PseudoArgs<>(template, scope, collection, options, domainType);
|
||||
LOG.trace("replaceById {}", pArgs);
|
||||
LOG.trace("replaceById object={} {}", object, pArgs);
|
||||
return Mono.just(object).flatMap(support::encodeEntity)
|
||||
.flatMap(converted -> template.getCouchbaseClientFactory().withScope(pArgs.getScope())
|
||||
.getCollection(pArgs.getCollection()).reactive()
|
||||
@@ -115,14 +116,15 @@ public class ReactiveReplaceByIdOperationSupport implements ReactiveReplaceByIdO
|
||||
|
||||
@Override
|
||||
public ReplaceByIdWithDurability<T> inCollection(final String collection) {
|
||||
return new ReactiveReplaceByIdSupport<>(template, domainType, scope, collection, options, persistTo, replicateTo,
|
||||
durabilityLevel, expiry, support);
|
||||
return new ReactiveReplaceByIdSupport<>(template, domainType, scope,
|
||||
collection != null ? collection : this.collection, options, persistTo, replicateTo, durabilityLevel, expiry,
|
||||
support);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReplaceByIdInCollection<T> inScope(final String scope) {
|
||||
return new ReactiveReplaceByIdSupport<>(template, domainType, scope, collection, options, persistTo, replicateTo,
|
||||
durabilityLevel, expiry, support);
|
||||
return new ReactiveReplaceByIdSupport<>(template, domainType, scope != null ? scope : this.scope, collection,
|
||||
options, persistTo, replicateTo, durabilityLevel, expiry, support);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -45,8 +45,9 @@ public class ReactiveUpsertByIdOperationSupport implements ReactiveUpsertByIdOpe
|
||||
@Override
|
||||
public <T> ReactiveUpsertById<T> upsertById(final Class<T> domainType) {
|
||||
Assert.notNull(domainType, "DomainType must not be null!");
|
||||
return new ReactiveUpsertByIdSupport<>(template, domainType, null, null, null, PersistTo.NONE, ReplicateTo.NONE,
|
||||
DurabilityLevel.NONE, null, template.support());
|
||||
return new ReactiveUpsertByIdSupport<>(template, domainType, OptionsBuilder.getScopeFrom(domainType),
|
||||
OptionsBuilder.getCollectionFrom(domainType), null, PersistTo.NONE, ReplicateTo.NONE, DurabilityLevel.NONE,
|
||||
null, template.support());
|
||||
}
|
||||
|
||||
static class ReactiveUpsertByIdSupport<T> implements ReactiveUpsertById<T> {
|
||||
@@ -80,7 +81,7 @@ public class ReactiveUpsertByIdOperationSupport implements ReactiveUpsertByIdOpe
|
||||
@Override
|
||||
public Mono<T> one(T object) {
|
||||
PseudoArgs<UpsertOptions> pArgs = new PseudoArgs(template, scope, collection, options, domainType);
|
||||
LOG.trace("upsertById {}", pArgs);
|
||||
LOG.trace("upsertById object={} {}", object, pArgs);
|
||||
return Mono.just(object).flatMap(support::encodeEntity)
|
||||
.flatMap(converted -> template.getCouchbaseClientFactory().withScope(pArgs.getScope())
|
||||
.getCollection(pArgs.getCollection()).reactive()
|
||||
@@ -114,14 +115,15 @@ public class ReactiveUpsertByIdOperationSupport implements ReactiveUpsertByIdOpe
|
||||
|
||||
@Override
|
||||
public UpsertByIdWithDurability<T> inCollection(final String collection) {
|
||||
return new ReactiveUpsertByIdSupport<>(template, domainType, scope, collection, options, persistTo, replicateTo,
|
||||
durabilityLevel, expiry, support);
|
||||
return new ReactiveUpsertByIdSupport<>(template, domainType, scope,
|
||||
collection != null ? collection : this.collection, options, persistTo, replicateTo, durabilityLevel, expiry,
|
||||
support);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UpsertByIdInCollection<T> inScope(final String scope) {
|
||||
return new ReactiveUpsertByIdSupport<>(template, domainType, scope, collection, options, persistTo, replicateTo,
|
||||
durabilityLevel, expiry, support);
|
||||
return new ReactiveUpsertByIdSupport<>(template, domainType, scope != null ? scope : this.scope, collection,
|
||||
options, persistTo, replicateTo, durabilityLevel, expiry, support);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -53,6 +53,7 @@ import com.couchbase.client.java.query.QueryOptions;
|
||||
* N1qlJoinResolver resolves by converting the join definition to query statement and executing using CouchbaseTemplate
|
||||
*
|
||||
* @author Subhashni Balakrishnan
|
||||
* @author Michael Reiche
|
||||
*/
|
||||
public class N1qlJoinResolver {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(N1qlJoinResolver.class);
|
||||
|
||||
@@ -213,7 +213,7 @@ public class N1QLExpression {
|
||||
* Returned expression results in distinct of the expression
|
||||
*/
|
||||
public static N1QLExpression distinct(N1QLExpression expression) {
|
||||
return x("distinct{" + expression.toString() + "}");
|
||||
return x("distinct{" + expression.toString() + "}");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2021 the original author or authors.
|
||||
* Copyright 2021-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -177,7 +177,7 @@ public class OptionsBuilder {
|
||||
options.cas(cas);
|
||||
}
|
||||
if (LOG.isTraceEnabled()) {
|
||||
LOG.trace("remove options: {}" + toString(options));
|
||||
LOG.trace("remove options: {}", toString(options));
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2021 the original author or authors
|
||||
* Copyright 2021-2022 the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,13 +16,18 @@
|
||||
package org.springframework.data.couchbase.core.support;
|
||||
|
||||
import static org.springframework.data.couchbase.core.query.OptionsBuilder.fromFirst;
|
||||
import static org.springframework.data.couchbase.core.query.OptionsBuilder.getCollectionFrom;
|
||||
import static org.springframework.data.couchbase.core.query.OptionsBuilder.getScopeFrom;
|
||||
|
||||
import org.springframework.data.couchbase.core.ReactiveCouchbaseTemplate;
|
||||
|
||||
import com.couchbase.client.core.io.CollectionIdentifier;
|
||||
|
||||
/**
|
||||
* determine the arguments to be used in the operation from various sources
|
||||
*
|
||||
* @author Michael Reiche
|
||||
*
|
||||
* @param <OPTS>
|
||||
*/
|
||||
public class PseudoArgs<OPTS> {
|
||||
private final OPTS options;
|
||||
private final String scopeName;
|
||||
@@ -53,7 +58,12 @@ public class PseudoArgs<OPTS> {
|
||||
String collectionForQuery = null;
|
||||
OPTS optionsForQuery = null;
|
||||
|
||||
// 1) repository from DynamicProxy via template threadLocal - has precedence over annotation
|
||||
// threadlocal comes from the scope/collection of a repository from DynamicProxy via template threadLocal
|
||||
// it - has precedence over the annotation of the method/entityClass/repositoryClass in the scope/collection args.
|
||||
// note that there is no withScope()/withCollection() for repositories, so the scope/collection args can
|
||||
// only be from annotations when scopeForQuery/collectionForQuery are non-null.
|
||||
//
|
||||
// for templates, there is no threadLocal, therefore scopeForQuery/collectionForQuery are always null
|
||||
|
||||
PseudoArgs<OPTS> threadLocal = (PseudoArgs<OPTS>) template.getPseudoArgs();
|
||||
template.setPseudoArgs(null);
|
||||
@@ -63,8 +73,24 @@ public class PseudoArgs<OPTS> {
|
||||
optionsForQuery = threadLocal.getOptions();
|
||||
}
|
||||
|
||||
scopeForQuery = fromFirst(null, scopeForQuery, scope, getScopeFrom(domainType));
|
||||
collectionForQuery = fromFirst(null, collectionForQuery, collection, getCollectionFrom(domainType));
|
||||
// the scope and collection args can come from
|
||||
// - an annotation on the entity class in creation of the operation
|
||||
// i.e. new ExecutableFindByIdSupport<>(template, domainType, OptionsBuilder.getScopeFrom(domainType),
|
||||
// OptionsBuilder.getCollectionFrom(domainType)...
|
||||
//
|
||||
// - from CouchbaseRepositoryBase.getScope() that checks
|
||||
// 1) crudMethodMetadata
|
||||
// 2) entityClass annotation
|
||||
// 3) repositoryClass annotation
|
||||
// Note that it does not have the method to check for annotations. Only methods implemented in the base class
|
||||
// are processed through the CouchbaseRepository class.
|
||||
//
|
||||
// - from the constructor of AbstractCouchbaseQueryBase.
|
||||
// findOp = (ExecutableFindByQuery<?>) (findOp.inScope(method.getScope()).inCollection(method.getCollection()));
|
||||
// so is it also needed in the execute???
|
||||
|
||||
scopeForQuery = fromFirst(null, scopeForQuery, scope);
|
||||
collectionForQuery = fromFirst(null, collectionForQuery, collection);
|
||||
optionsForQuery = fromFirst(null, options, optionsForQuery);
|
||||
|
||||
// if a collection was specified but no scope, use the scope from the clientFactory
|
||||
|
||||
@@ -37,8 +37,8 @@ import org.springframework.data.couchbase.repository.query.StringN1qlQueryCreato
|
||||
* Also, SpEL in the form <code>#{spelExpression}</code> is supported, including the following N1QL variables that will
|
||||
* be replaced by the underlying {@link CouchbaseTemplate} associated information:
|
||||
* <ul>
|
||||
* <li>{@value StringBasedN1qlQueryParser#SPEL_SELECT_FROM_CLAUSE} (see {@link StringBasedN1qlQueryParser#SPEL_SELECT_FROM_CLAUSE})
|
||||
* </li>
|
||||
* <li>{@value StringBasedN1qlQueryParser#SPEL_SELECT_FROM_CLAUSE} (see
|
||||
* {@link StringBasedN1qlQueryParser#SPEL_SELECT_FROM_CLAUSE})</li>
|
||||
* <li>{@value StringBasedN1qlQueryParser#SPEL_BUCKET} (see {@link StringBasedN1qlQueryParser#SPEL_BUCKET})</li>
|
||||
* <li>{@value StringBasedN1qlQueryParser#SPEL_ENTITY} (see {@link StringBasedN1qlQueryParser#SPEL_ENTITY})</li>
|
||||
* <li>{@value StringBasedN1qlQueryParser#SPEL_FILTER} (see {@link StringBasedN1qlQueryParser#SPEL_FILTER})</li>
|
||||
|
||||
@@ -19,6 +19,7 @@ import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.data.couchbase.core.CouchbaseOperations;
|
||||
import org.springframework.data.couchbase.core.ExecutableFindByQueryOperation.ExecutableFindByQuery;
|
||||
import org.springframework.data.couchbase.core.ExecutableFindByQueryOperation.TerminatingFindByQuery;
|
||||
import org.springframework.data.couchbase.core.ExecutableRemoveByQueryOperation.ExecutableRemoveByQuery;
|
||||
import org.springframework.data.couchbase.core.query.Query;
|
||||
import org.springframework.data.couchbase.repository.query.CouchbaseQueryExecution.DeleteExecution;
|
||||
import org.springframework.data.couchbase.repository.query.CouchbaseQueryExecution.PagedExecution;
|
||||
@@ -42,7 +43,8 @@ import org.springframework.util.Assert;
|
||||
public abstract class AbstractCouchbaseQuery extends AbstractCouchbaseQueryBase<CouchbaseOperations>
|
||||
implements RepositoryQuery {
|
||||
|
||||
private final ExecutableFindByQuery<?> findOperationWithProjection;
|
||||
private final ExecutableFindByQuery<?> findOp;
|
||||
private final ExecutableRemoveByQuery<?> removeOp;
|
||||
|
||||
/**
|
||||
* Creates a new {@link AbstractCouchbaseQuery} from the given {@link ReactiveCouchbaseQueryMethod} and
|
||||
@@ -62,9 +64,10 @@ public abstract class AbstractCouchbaseQuery extends AbstractCouchbaseQueryBase<
|
||||
Assert.notNull(evaluationContextProvider, "QueryMethodEvaluationContextProvider must not be null!");
|
||||
EntityMetadata<?> metadata = method.getEntityInformation();
|
||||
Class<?> type = metadata.getJavaType();
|
||||
ExecutableFindByQuery<?> findOp = operations.findByQuery(type);
|
||||
findOp = (ExecutableFindByQuery<?>) (findOp.inScope(method.getScope()).inCollection(method.getCollection()));
|
||||
this.findOperationWithProjection = findOp;
|
||||
this.findOp = (ExecutableFindByQuery<?>) (operations.findByQuery(type).inScope(method.getScope())
|
||||
.inCollection(method.getCollection()));
|
||||
this.removeOp = (ExecutableRemoveByQuery<?>) (operations.removeByQuery(type).inScope(method.getScope())
|
||||
.inCollection(method.getCollection()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -84,11 +87,11 @@ public abstract class AbstractCouchbaseQuery extends AbstractCouchbaseQueryBase<
|
||||
// query = applyAnnotatedCollationIfPresent(query, accessor); // not yet implemented
|
||||
query = applyQueryMetaAttributesIfPresent(query, typeToRead);
|
||||
|
||||
ExecutableFindByQuery<?> find = findOperationWithProjection;
|
||||
|
||||
CouchbaseQueryExecution execution = getExecution(accessor,
|
||||
new ResultProcessingConverter<>(processor, getOperations(), getInstantiators()), find);
|
||||
return execution.execute(query, processor.getReturnedType().getDomainType(), typeToRead, null);
|
||||
new ResultProcessingConverter<>(processor, getOperations(), getInstantiators()), findOp);
|
||||
// the operation should already have the scope and collection. passing again anyway.
|
||||
return execution.execute(query, processor.getReturnedType().getDomainType(), typeToRead, method.getScope(),
|
||||
method.getCollection());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -108,31 +111,31 @@ public abstract class AbstractCouchbaseQuery extends AbstractCouchbaseQueryBase<
|
||||
* Returns the execution to wrap
|
||||
*
|
||||
* @param accessor must not be {@literal null}.
|
||||
* @param operation must not be {@literal null}.
|
||||
* @param findOp must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
private CouchbaseQueryExecution getExecutionToWrap(ParameterAccessor accessor, ExecutableFindByQuery<?> operation) {
|
||||
|
||||
private CouchbaseQueryExecution getExecutionToWrap(ParameterAccessor accessor, ExecutableFindByQuery<?> findOp) {
|
||||
// the operation (removeOp and findOp) will already have the scope and collection, but set them again anyway
|
||||
if (isDeleteQuery()) {
|
||||
return new DeleteExecution(getOperations(), getQueryMethod());
|
||||
return new DeleteExecution(removeOp);
|
||||
} else if (isTailable(getQueryMethod())) {
|
||||
return (q, t, r, c) -> operation.as(r).matching(q.with(accessor.getPageable())).all(); // s/b tail() instead of
|
||||
// all()
|
||||
return (q, t, r, s, c) -> findOp.as(r).inScope(s).inCollection(c).matching(q.with(accessor.getPageable())).all();
|
||||
} else if (getQueryMethod().isCollectionQuery()) {
|
||||
return (q, t, r, c) -> operation.as(r).matching(q.with(accessor.getPageable())).all();
|
||||
return (q, t, r, s, c) -> findOp.as(r).inScope(s).inCollection(c).matching(q.with(accessor.getPageable())).all();
|
||||
} else if (getQueryMethod().isStreamQuery()) {
|
||||
return (q, t, r, c) -> operation.as(r).matching(q.with(accessor.getPageable())).stream();
|
||||
return (q, t, r, s, c) -> findOp.as(r).inScope(s).inCollection(c).matching(q.with(accessor.getPageable()))
|
||||
.stream();
|
||||
} else if (isCountQuery()) {
|
||||
return (q, t, r, c) -> operation.as(r).matching(q).count();
|
||||
return (q, t, r, s, c) -> findOp.as(r).inScope(s).inCollection(c).matching(q).count();
|
||||
} else if (isExistsQuery()) {
|
||||
return (q, t, r, c) -> operation.as(r).matching(q).exists();
|
||||
return (q, t, r, s, c) -> findOp.as(r).inScope(s).inCollection(c).matching(q).exists();
|
||||
} else if (getQueryMethod().isPageQuery()) {
|
||||
return new PagedExecution(operation, accessor.getPageable());
|
||||
return new PagedExecution(findOp, accessor.getPageable());
|
||||
} else if (getQueryMethod().isSliceQuery()) {
|
||||
return new SlicedExecution(operation, accessor.getPageable());
|
||||
return new SlicedExecution(findOp, accessor.getPageable());
|
||||
} else {
|
||||
return (q, t, r, c) -> {
|
||||
TerminatingFindByQuery<?> find = operation.as(r).matching(q);
|
||||
return (q, t, r, s, c) -> {
|
||||
TerminatingFindByQuery<?> find = findOp.as(r).matching(q);
|
||||
if (isCountQuery()) {
|
||||
return find.count();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2020-2021 the original author or authors.
|
||||
* Copyright 2020-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,6 +19,7 @@ import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.data.couchbase.core.ReactiveCouchbaseOperations;
|
||||
import org.springframework.data.couchbase.core.ReactiveFindByQueryOperation;
|
||||
import org.springframework.data.couchbase.core.ReactiveFindByQueryOperation.ReactiveFindByQuery;
|
||||
import org.springframework.data.couchbase.core.ReactiveRemoveByQueryOperation.ReactiveRemoveByQuery;
|
||||
import org.springframework.data.couchbase.core.query.Query;
|
||||
import org.springframework.data.couchbase.repository.query.ReactiveCouchbaseQueryExecution.DeleteExecution;
|
||||
import org.springframework.data.couchbase.repository.query.ReactiveCouchbaseQueryExecution.ResultProcessingExecution;
|
||||
@@ -41,7 +42,8 @@ import org.springframework.util.Assert;
|
||||
public abstract class AbstractReactiveCouchbaseQuery extends AbstractCouchbaseQueryBase<ReactiveCouchbaseOperations>
|
||||
implements RepositoryQuery {
|
||||
|
||||
private final ReactiveFindByQuery<?> findOperationWithProjection;
|
||||
private final ReactiveFindByQuery<?> findOp;
|
||||
private final ReactiveRemoveByQuery<?> removeOp;
|
||||
|
||||
/**
|
||||
* Creates a new {@link AbstractReactiveCouchbaseQuery} from the given {@link ReactiveCouchbaseQueryMethod} and
|
||||
@@ -62,9 +64,10 @@ public abstract class AbstractReactiveCouchbaseQuery extends AbstractCouchbaseQu
|
||||
|
||||
EntityMetadata<?> metadata = method.getEntityInformation();
|
||||
Class<?> type = metadata.getJavaType();
|
||||
ReactiveFindByQuery<?> findOp = operations.findByQuery(type);
|
||||
findOp = (ReactiveFindByQuery<?>) (findOp.inScope(method.getScope()).inCollection(method.getCollection()));
|
||||
this.findOperationWithProjection = findOp;
|
||||
this.findOp = (ReactiveFindByQuery<?>) (operations.findByQuery(type).inScope(method.getScope())
|
||||
.inCollection(method.getCollection()));
|
||||
this.removeOp = (ReactiveRemoveByQuery<?>) (operations.removeByQuery(type).inScope(method.getScope())
|
||||
.inCollection(method.getCollection()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -83,11 +86,10 @@ public abstract class AbstractReactiveCouchbaseQuery extends AbstractCouchbaseQu
|
||||
// query = applyAnnotatedCollationIfPresent(query, accessor); // not yet implemented
|
||||
query = applyQueryMetaAttributesIfPresent(query, typeToRead);
|
||||
|
||||
ReactiveFindByQuery<?> find = findOperationWithProjection;
|
||||
|
||||
ReactiveCouchbaseQueryExecution execution = getExecution(accessor,
|
||||
new ResultProcessingConverter<>(processor, getOperations(), getInstantiators()), find);
|
||||
return execution.execute(query, processor.getReturnedType().getDomainType(), typeToRead, null);
|
||||
new ResultProcessingConverter<>(processor, getOperations(), getInstantiators()), findOp);
|
||||
return execution.execute(query, processor.getReturnedType().getDomainType(), typeToRead, method.getScope(),
|
||||
method.getCollection());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -113,21 +115,21 @@ public abstract class AbstractReactiveCouchbaseQuery extends AbstractCouchbaseQu
|
||||
ReactiveFindByQuery<?> operation) {
|
||||
|
||||
if (isDeleteQuery()) {
|
||||
return new DeleteExecution(getOperations(), getQueryMethod());
|
||||
return new DeleteExecution(removeOp);
|
||||
} else if (isTailable(getQueryMethod())) {
|
||||
return (q, t, r, c) -> operation.as(r).matching(q.with(accessor.getPageable())).all(); // s/b tail() instead of
|
||||
// all()
|
||||
return (q, t, r, s, c) -> operation.as(r).inScope(s).inCollection(c).matching(q.with(accessor.getPageable()))
|
||||
.all(); // s/b tail()
|
||||
} else if (getQueryMethod().isCollectionQuery()) {
|
||||
return (q, t, r, c) -> operation.as(r).matching(q.with(accessor.getPageable())).all();
|
||||
// } else if (getQueryMethod().isStreamQuery()) {
|
||||
// return (q, t, c) -> operation.matching(q.with(accessor.getPageable())).all().toStream();
|
||||
return (q, t, r, s, c) -> operation.as(r).inScope(s).inCollection(c).matching(q.with(accessor.getPageable()))
|
||||
.all();
|
||||
} else if (isCountQuery()) {
|
||||
return (q, t, r, c) -> operation.as(r).matching(q).count();
|
||||
return (q, t, r, s, c) -> operation.as(r).inScope(s).inCollection(c).matching(q).count();
|
||||
} else if (isExistsQuery()) {
|
||||
return (q, t, r, c) -> operation.as(r).matching(q).exists();
|
||||
return (q, t, r, s, c) -> operation.as(r).inScope(s).inCollection(c).matching(q).exists();
|
||||
} else {
|
||||
return (q, t, r, c) -> {
|
||||
ReactiveFindByQueryOperation.TerminatingFindByQuery<?> find = operation.as(r).matching(q);
|
||||
return (q, t, r, s, c) -> {
|
||||
ReactiveFindByQueryOperation.TerminatingFindByQuery<?> find = operation.as(r).inScope(s).inCollection(c)
|
||||
.matching(q);
|
||||
return isLimiting() ? find.first() : find.one();
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2020 the original author or authors.
|
||||
* Copyright 2020-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,15 +18,14 @@ package org.springframework.data.couchbase.repository.query;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.data.couchbase.core.CouchbaseOperations;
|
||||
import org.springframework.data.couchbase.core.ExecutableFindByQueryOperation.ExecutableFindByQuery;
|
||||
import org.springframework.data.couchbase.core.ExecutableFindByQueryOperation.TerminatingFindByQuery;
|
||||
import org.springframework.data.couchbase.core.ExecutableRemoveByQueryOperation;
|
||||
import org.springframework.data.couchbase.core.query.Query;
|
||||
import org.springframework.data.domain.PageImpl;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Slice;
|
||||
import org.springframework.data.domain.SliceImpl;
|
||||
import org.springframework.data.repository.query.QueryMethod;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -39,20 +38,18 @@ import org.springframework.util.Assert;
|
||||
@FunctionalInterface
|
||||
interface CouchbaseQueryExecution {
|
||||
|
||||
Object execute(Query query, Class<?> type, Class<?> returnType, String collection);
|
||||
Object execute(Query query, Class<?> type, Class<?> returnType, String scope, String collection);
|
||||
|
||||
/**
|
||||
* {@link CouchbaseQueryExecution} removing documents matching the query.
|
||||
*/
|
||||
|
||||
final class DeleteExecution implements CouchbaseQueryExecution {
|
||||
final class DeleteExecution<T> implements CouchbaseQueryExecution {
|
||||
|
||||
private final CouchbaseOperations operations;
|
||||
private final QueryMethod method;
|
||||
private final ExecutableRemoveByQueryOperation.ExecutableRemoveByQuery<T> removeOperation;
|
||||
|
||||
public DeleteExecution(CouchbaseOperations operations, QueryMethod method) {
|
||||
this.operations = operations;
|
||||
this.method = method;
|
||||
public DeleteExecution(ExecutableRemoveByQueryOperation.ExecutableRemoveByQuery<T> removeOperation) {
|
||||
this.removeOperation = removeOperation;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -60,8 +57,8 @@ interface CouchbaseQueryExecution {
|
||||
* @see org.springframework.data.couchbase.repository.query.AbstractCouchbaseQuery.Execution#execute(org.springframework.data.couchbase.core.query.Query, java.lang.Class, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public Object execute(Query query, Class<?> type, Class<?> returnType, String collection) {
|
||||
return operations.removeByQuery(type).matching(query).all();
|
||||
public Object execute(Query query, Class<?> type, Class<?> returnType, String scope, String collection) {
|
||||
return removeOperation.inScope(scope).inCollection(collection).matching(query).all();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -83,8 +80,8 @@ interface CouchbaseQueryExecution {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object execute(Query query, Class<?> type, Class<?> returnType, String collection) {
|
||||
return converter.convert(delegate.execute(query, type, returnType, collection));
|
||||
public Object execute(Query query, Class<?> type, Class<?> returnType, String scope, String collection) {
|
||||
return converter.convert(delegate.execute(query, type, returnType, scope, collection));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,9 +106,10 @@ interface CouchbaseQueryExecution {
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public Object execute(Query query, Class<?> type, Class<?> returnType, String collection) {
|
||||
public Object execute(Query query, Class<?> type, Class<?> returnType, String scope, String collection) {
|
||||
int overallLimit = 0; // query.getLimit();
|
||||
TerminatingFindByQuery<?> matching = operation.as(returnType).matching(query);
|
||||
TerminatingFindByQuery<?> matching = operation.as(returnType).inScope(scope).inCollection(collection)
|
||||
.matching(query);
|
||||
// Adjust limit if page would exceed the overall limit
|
||||
if (overallLimit != 0 && pageable.getOffset() + pageable.getPageSize() > overallLimit) {
|
||||
query.limit((int) (overallLimit - pageable.getOffset()));
|
||||
@@ -141,9 +139,10 @@ interface CouchbaseQueryExecution {
|
||||
* @see org.springframework.data.couchbase.repository.query.CouchbaseQueryExecution#execute(org.springframework.data.couchbase.core.query.Query)
|
||||
*/
|
||||
@Override
|
||||
public Object execute(Query query, Class<?> type, Class<?> returnType, String collection) {
|
||||
public Object execute(Query query, Class<?> type, Class<?> returnType, String scope, String collection) {
|
||||
int overallLimit = 0; // query.getLimit();
|
||||
TerminatingFindByQuery<?> matching = operation.as(returnType).matching(query);
|
||||
TerminatingFindByQuery<?> matching = operation.as(returnType).inScope(scope).inCollection(collection)
|
||||
.matching(query);
|
||||
// Adjust limit if page would exceed the overall limit
|
||||
if (overallLimit != 0 && pageable.getOffset() + pageable.getPageSize() > overallLimit) {
|
||||
query.limit((int) (overallLimit - pageable.getOffset()));
|
||||
@@ -151,7 +150,8 @@ interface CouchbaseQueryExecution {
|
||||
|
||||
List<?> result = matching.all(); // this needs to be done before count, as count clears the skip and limit
|
||||
|
||||
long count = operation.matching(query.skip(-1).limit(-1).withoutSort()).count();
|
||||
long count = operation.inScope(scope).inCollection(collection).matching(query.skip(-1).limit(-1).withoutSort())
|
||||
.count();
|
||||
count = overallLimit != 0 ? Math.min(count, overallLimit) : count;
|
||||
|
||||
return new PageImpl(result, pageable, count);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2021 the original author or authors.
|
||||
* Copyright 2013-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -64,73 +64,6 @@ public class CouchbaseQueryMethod extends QueryMethod {
|
||||
this.repositoryMetadata = metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the method has a @View annotation.
|
||||
*
|
||||
* @return true if it has the annotation, false otherwise.
|
||||
*/
|
||||
public boolean hasViewAnnotation() {
|
||||
return getViewAnnotation() != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the method has a @View annotation with the designDocument and viewName specified.
|
||||
*
|
||||
* @return true if it has the annotation and full view specified.
|
||||
*/
|
||||
public boolean hasViewSpecification() {
|
||||
return hasDesignDoc() && hasViewName();
|
||||
}
|
||||
|
||||
/**
|
||||
* If the method has a @View annotation with the designDocument specified.
|
||||
*
|
||||
* @return true if it has the design document specified.
|
||||
*/
|
||||
public boolean hasDesignDoc() {
|
||||
View annotation = getViewAnnotation();
|
||||
if (annotation == null) {
|
||||
return false;
|
||||
}
|
||||
return StringUtils.hasText(annotation.designDocument());
|
||||
}
|
||||
|
||||
/**
|
||||
* If the method has a @View annotation with the viewName specified.
|
||||
*
|
||||
* @return true if it has the view name specified.
|
||||
*/
|
||||
public boolean hasViewName() {
|
||||
View annotation = getViewAnnotation();
|
||||
if (annotation == null) {
|
||||
return false;
|
||||
}
|
||||
return StringUtils.hasText(annotation.viewName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the @View annotation if set, null otherwise.
|
||||
*
|
||||
* @return the view annotation of present.
|
||||
*/
|
||||
public View getViewAnnotation() {
|
||||
return method.getAnnotation(View.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the method has a @Dimensional annotation, false otherwise.
|
||||
*/
|
||||
public boolean hasDimensionalAnnotation() {
|
||||
return getDimensionalAnnotation() != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the @Dimensional annotation if set, null otherwise.
|
||||
*/
|
||||
public Dimensional getDimensionalAnnotation() {
|
||||
return AnnotationUtils.findAnnotation(method, Dimensional.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* If the method has a @Query annotation.
|
||||
*
|
||||
@@ -196,33 +129,6 @@ public class CouchbaseQueryMethod extends QueryMethod {
|
||||
return AnnotatedElementUtils.findMergedAnnotation(method, annotationClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Caution: findMergedAnnotation() will return the default if there are any annotations but not this annotation
|
||||
*
|
||||
* @return annotation
|
||||
*/
|
||||
public <A extends Annotation> A getClassAnnotation(Class<A> annotationClass) {
|
||||
return AnnotatedElementUtils.findMergedAnnotation(method.getDeclaringClass(), annotationClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Caution: findMergedAnnotation() will return the default if there are any annotations but not this annotation
|
||||
*
|
||||
* @return annotation
|
||||
*/
|
||||
public <A extends Annotation> A getEntityAnnotation(Class<A> annotationClass) {
|
||||
return AnnotatedElementUtils.findMergedAnnotation(getEntityInformation().getJavaType(), annotationClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Caution: findMergedAnnotation() will return the default if there are any annotations but not this annotation
|
||||
*
|
||||
* @return annotation
|
||||
*/
|
||||
public <A extends Annotation> A getRepositoryAnnotation(Class<A> annotationClass) {
|
||||
return AnnotatedElementUtils.findMergedAnnotation(repositoryMetadata.getRepositoryInterface(), annotationClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the query string declared in a {@link Query} annotation or {@literal null} if neither the annotation found
|
||||
* nor the attribute was specified.
|
||||
|
||||
@@ -62,6 +62,10 @@ public class N1qlRepositoryQueryExecutor {
|
||||
final ParameterAccessor accessor = new ParametersParameterAccessor(queryMethod.getParameters(), parameters);
|
||||
|
||||
// counterpart to ReactiveN1qlRespositoryQueryExecutor,
|
||||
|
||||
String scope = queryMethod.getScope();
|
||||
String collection = queryMethod.getCollection();
|
||||
|
||||
Query query;
|
||||
ExecutableFindByQuery q;
|
||||
if (queryMethod.hasN1qlAnnotation()) {
|
||||
@@ -74,16 +78,16 @@ public class N1qlRepositoryQueryExecutor {
|
||||
}
|
||||
|
||||
ExecutableFindByQuery<?> operation = (ExecutableFindByQuery<?>) operations.findByQuery(domainClass)
|
||||
.withConsistency(buildQueryScanConsistency());
|
||||
.withConsistency(buildQueryScanConsistency()).inScope(scope).inCollection(collection);
|
||||
if (queryMethod.isCountQuery()) {
|
||||
return operation.matching(query).count();
|
||||
return operation.inScope(scope).inCollection(collection).matching(query).count();
|
||||
} else if (queryMethod.isCollectionQuery()) {
|
||||
return operation.matching(query).all();
|
||||
return operation.inScope(scope).inCollection(collection).matching(query).all();
|
||||
} else if (queryMethod.isPageQuery()) {
|
||||
Pageable p = accessor.getPageable();
|
||||
return new CouchbaseQueryExecution.PagedExecution(operation, p).execute(query, null, null, null);
|
||||
return new CouchbaseQueryExecution.PagedExecution(operation, p).execute(query, null, null, scope, collection);
|
||||
} else {
|
||||
return operation.matching(query).oneValue();
|
||||
return operation.inScope(scope).inCollection(collection).matching(query).oneValue();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2020 the original author or authors.
|
||||
* Copyright 2020-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,7 +16,7 @@
|
||||
package org.springframework.data.couchbase.repository.query;
|
||||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.data.couchbase.core.ReactiveCouchbaseOperations;
|
||||
import org.springframework.data.couchbase.core.ReactiveRemoveByQueryOperation.ReactiveRemoveByQuery;
|
||||
import org.springframework.data.couchbase.core.query.Query;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -31,7 +31,7 @@ import org.springframework.util.Assert;
|
||||
@FunctionalInterface
|
||||
interface ReactiveCouchbaseQueryExecution {
|
||||
|
||||
Object execute(Query query, Class<?> type, Class<?> returnType, String collection);
|
||||
Object execute(Query query, Class<?> type, Class<?> returnType, String scope, String collection);
|
||||
|
||||
/**
|
||||
* {@link ReactiveCouchbaseQueryExecution} removing documents matching the query.
|
||||
@@ -39,12 +39,10 @@ interface ReactiveCouchbaseQueryExecution {
|
||||
|
||||
final class DeleteExecution implements ReactiveCouchbaseQueryExecution {
|
||||
|
||||
private final ReactiveCouchbaseOperations operations;
|
||||
private final CouchbaseQueryMethod method;
|
||||
private final ReactiveRemoveByQuery removeOp;
|
||||
|
||||
public DeleteExecution(ReactiveCouchbaseOperations operations, CouchbaseQueryMethod method) {
|
||||
this.operations = operations;
|
||||
this.method = method;
|
||||
public DeleteExecution(ReactiveRemoveByQuery<?> removeOp) {
|
||||
this.removeOp = removeOp;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -52,8 +50,8 @@ interface ReactiveCouchbaseQueryExecution {
|
||||
* @see org.springframework.data.couchbase.repository.query.AbstractCouchbaseQuery.Execution#execute(org.springframework.data.couchbase.core.query.Query, java.lang.Class, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public Object execute(Query query, Class<?> type, Class<?> returnType, String collection) {
|
||||
return operations.removeByQuery(type)/*.inCollection(collection)*/.matching(query).all();
|
||||
public Object execute(Query query, Class<?> type, Class<?> returnType, String scope, String collection) {
|
||||
return removeOp.inScope(scope).inCollection(collection).matching(query).all();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -75,8 +73,8 @@ interface ReactiveCouchbaseQueryExecution {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object execute(Query query, Class<?> type, Class<?> returnType, String collection) {
|
||||
return converter.convert(delegate.execute(query, type, returnType, collection));
|
||||
public Object execute(Query query, Class<?> type, Class<?> returnType, String scope, String collection) {
|
||||
return converter.convert(delegate.execute(query, type, returnType, scope, collection));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -42,6 +42,10 @@ public class CouchbaseRepositoryBase<T, ID> {
|
||||
this.repositoryInterface = repositoryInterface;
|
||||
}
|
||||
|
||||
public Class<?> getRepositoryInterface() {
|
||||
return repositoryInterface;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the information for the underlying template.
|
||||
*
|
||||
@@ -71,7 +75,7 @@ public class CouchbaseRepositoryBase<T, ID> {
|
||||
protected String getScope() {
|
||||
String fromAnnotation = OptionsBuilder.annotationString(Scope.class, CollectionIdentifier.DEFAULT_SCOPE,
|
||||
new AnnotatedElement[] { getJavaType(), repositoryInterface });
|
||||
String fromMetadata = crudMethodMetadata.getScope();
|
||||
String fromMetadata = crudMethodMetadata != null ? crudMethodMetadata.getScope() : null;
|
||||
return OptionsBuilder.fromFirst(CollectionIdentifier.DEFAULT_SCOPE, fromMetadata, fromAnnotation);
|
||||
}
|
||||
|
||||
@@ -86,7 +90,7 @@ public class CouchbaseRepositoryBase<T, ID> {
|
||||
protected String getCollection() {
|
||||
String fromAnnotation = OptionsBuilder.annotationString(Collection.class, CollectionIdentifier.DEFAULT_COLLECTION,
|
||||
new AnnotatedElement[] { getJavaType(), repositoryInterface });
|
||||
String fromMetadata = crudMethodMetadata.getCollection();
|
||||
String fromMetadata = crudMethodMetadata != null ? crudMethodMetadata.getCollection() : null;
|
||||
return OptionsBuilder.fromFirst(CollectionIdentifier.DEFAULT_COLLECTION, fromMetadata, fromAnnotation);
|
||||
}
|
||||
|
||||
@@ -104,7 +108,7 @@ public class CouchbaseRepositoryBase<T, ID> {
|
||||
* \@ScanConsistency(query=QueryScanConsistency.REQUEST_PLUS)<br>
|
||||
* List<T> findAll();<br>
|
||||
*/
|
||||
QueryScanConsistency buildQueryScanConsistency() {
|
||||
QueryScanConsistency getQueryScanConsistency() {
|
||||
ScanConsistency sc = crudMethodMetadata.getScanConsistency();
|
||||
QueryScanConsistency fromMeta = sc != null ? sc.query() : null;
|
||||
QueryScanConsistency fromAnnotation = OptionsBuilder.annotationAttribute(ScanConsistency.class, "query",
|
||||
|
||||
@@ -53,6 +53,7 @@ import com.couchbase.client.java.query.QueryScanConsistency;
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
* @author Jens Schauder
|
||||
* @author Michael Reiche
|
||||
*/
|
||||
class CrudMethodMetadataPostProcessor implements RepositoryProxyPostProcessor, BeanClassLoaderAware {
|
||||
|
||||
@@ -137,6 +138,9 @@ class CrudMethodMetadataPostProcessor implements RepositoryProxyPostProcessor, B
|
||||
|
||||
Method method = invocation.getMethod();
|
||||
|
||||
// this skips collecting metadata for methods defined in the repository by the user because
|
||||
// the repository class is accessible by the repository method
|
||||
|
||||
if (!implementations.contains(method)) {
|
||||
return invocation.proceed();
|
||||
}
|
||||
@@ -155,7 +159,7 @@ class CrudMethodMetadataPostProcessor implements RepositoryProxyPostProcessor, B
|
||||
|
||||
if (methodMetadata == null) {
|
||||
|
||||
methodMetadata = new DefaultCrudMethodMetadata(method);
|
||||
methodMetadata = new DefaultCrudMethodMetadata(invocation, method);
|
||||
CrudMethodMetadata tmp = metadataCache.putIfAbsent(method, methodMetadata);
|
||||
|
||||
if (tmp != null) {
|
||||
@@ -196,7 +200,7 @@ class CrudMethodMetadataPostProcessor implements RepositoryProxyPostProcessor, B
|
||||
*
|
||||
* @param method must not be {@literal null}.
|
||||
*/
|
||||
DefaultCrudMethodMetadata(Method method) {
|
||||
DefaultCrudMethodMetadata(MethodInvocation invocation, Method method) {
|
||||
Assert.notNull(method, "Method must not be null!");
|
||||
this.method = method;
|
||||
String n = method.getName();
|
||||
@@ -210,11 +214,15 @@ class CrudMethodMetadataPostProcessor implements RepositoryProxyPostProcessor, B
|
||||
}
|
||||
|
||||
AnnotatedElement[] annotated = new AnnotatedElement[] { method, method.getDeclaringClass() };
|
||||
|
||||
this.scanConsistency = OptionsBuilder.annotation(ScanConsistency.class, "query", QueryScanConsistency.NOT_BOUNDED,
|
||||
annotated);
|
||||
|
||||
this.scope = OptionsBuilder.annotationString(Scope.class, CollectionIdentifier.DEFAULT_SCOPE, annotated);
|
||||
|
||||
this.collection = OptionsBuilder.annotationString(Collection.class, CollectionIdentifier.DEFAULT_COLLECTION,
|
||||
annotated);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2021 the original author or authors.
|
||||
* Copyright 2013-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -151,13 +151,13 @@ public class SimpleCouchbaseRepository<T, ID> extends CouchbaseRepositoryBase<T,
|
||||
|
||||
@Override
|
||||
public long count() {
|
||||
return operations.findByQuery(getJavaType()).withConsistency(buildQueryScanConsistency()).inScope(getScope())
|
||||
return operations.findByQuery(getJavaType()).withConsistency(getQueryScanConsistency()).inScope(getScope())
|
||||
.inCollection(getCollection()).count();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteAll() {
|
||||
operations.removeByQuery(getJavaType()).withConsistency(buildQueryScanConsistency()).inScope(getScope())
|
||||
operations.removeByQuery(getJavaType()).withConsistency(getQueryScanConsistency()).inScope(getScope())
|
||||
.inCollection(getCollection()).all();
|
||||
}
|
||||
|
||||
@@ -189,7 +189,7 @@ public class SimpleCouchbaseRepository<T, ID> extends CouchbaseRepositoryBase<T,
|
||||
* @return the list of found entities, already executed.
|
||||
*/
|
||||
private List<T> findAll(Query query) {
|
||||
return operations.findByQuery(getJavaType()).withConsistency(buildQueryScanConsistency()).inScope(getScope())
|
||||
return operations.findByQuery(getJavaType()).withConsistency(getQueryScanConsistency()).inScope(getScope())
|
||||
.inCollection(getCollection()).matching(query).all();
|
||||
}
|
||||
|
||||
|
||||
@@ -227,18 +227,18 @@ public class SimpleReactiveCouchbaseRepository<T, ID> extends CouchbaseRepositor
|
||||
|
||||
@Override
|
||||
public Mono<Void> deleteAll() {
|
||||
return operations.removeByQuery(getJavaType()).withConsistency(buildQueryScanConsistency()).inScope(getScope())
|
||||
return operations.removeByQuery(getJavaType()).withConsistency(getQueryScanConsistency()).inScope(getScope())
|
||||
.inCollection(getCollection()).all().then();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Long> count() {
|
||||
return operations.findByQuery(getJavaType()).withConsistency(buildQueryScanConsistency()).inScope(getScope())
|
||||
return operations.findByQuery(getJavaType()).withConsistency(getQueryScanConsistency()).inScope(getScope())
|
||||
.inCollection(getCollection()).count();
|
||||
}
|
||||
|
||||
private Flux<T> findAll(Query query) {
|
||||
return operations.findByQuery(getJavaType()).withConsistency(buildQueryScanConsistency()).inScope(getScope())
|
||||
return operations.findByQuery(getJavaType()).withConsistency(getQueryScanConsistency()).inScope(getScope())
|
||||
.inCollection(getCollection()).matching(query).all();
|
||||
}
|
||||
|
||||
|
||||
@@ -58,8 +58,6 @@ import com.couchbase.client.java.query.QueryScanConsistency;
|
||||
* @author Michael Reiche
|
||||
*/
|
||||
@Repository
|
||||
// @Scope("repositoryScope")
|
||||
// @ScanConsistency(query = QueryScanConsistency.REQUEST_PLUS)
|
||||
public interface AirportRepository extends CouchbaseRepository<Airport, String>, DynamicProxyable<AirportRepository> {
|
||||
|
||||
@ScanConsistency(query = QueryScanConsistency.REQUEST_PLUS)
|
||||
@@ -104,6 +102,11 @@ public interface AirportRepository extends CouchbaseRepository<Airport, String>,
|
||||
@ScanConsistency(query = QueryScanConsistency.REQUEST_PLUS)
|
||||
List<RemoveResult> deleteByIata(String iata);
|
||||
|
||||
@Query("#{#n1ql.delete} WHERE #{#n1ql.filter} and iata = $1 #{#n1ql.returning}")
|
||||
@ScanConsistency(query = QueryScanConsistency.REQUEST_PLUS)
|
||||
@Collection("bogus_collection")
|
||||
List<RemoveResult> deleteByIataAnnotated(String iata);
|
||||
|
||||
@Query("SELECT __cas, * from #{#n1ql.bucket} where iata = $1")
|
||||
@ScanConsistency(query = QueryScanConsistency.REQUEST_PLUS)
|
||||
List<Airport> getAllByIataNoID(String iata);
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.couchbase.domain;
|
||||
|
||||
import org.springframework.data.couchbase.repository.Collection;
|
||||
|
||||
/**
|
||||
* AirportRepository with collection annotation
|
||||
*
|
||||
* @author Michael Reiche
|
||||
*/
|
||||
@Collection("my_collection2")
|
||||
public interface AirportRepositoryAnnotated extends AirportRepository {}
|
||||
@@ -105,7 +105,7 @@ public class FluxTest extends JavaIntegrationTests {
|
||||
static List<String> keyList = Arrays.asList("a", "b", "c", "d", "e");
|
||||
static Collection collection;
|
||||
static ReactiveCollection rCollection;
|
||||
@Autowired ReactiveAirportRepository airportRepository; // intellij flags "Could not Autowire", but it runs ok.
|
||||
@Autowired ReactiveAirportRepository reactiveAirportRepository; // intellij flags "Could not Autowire", runs ok.
|
||||
|
||||
AtomicInteger rCat = new AtomicInteger(0);
|
||||
AtomicInteger rFlat = new AtomicInteger(0);
|
||||
@@ -136,7 +136,7 @@ public class FluxTest extends JavaIntegrationTests {
|
||||
listOfLists.add(list);
|
||||
}
|
||||
Flux<Object> af = Flux.fromIterable(listOfLists).concatMap(catalogToStore -> Flux.fromIterable(catalogToStore)
|
||||
.parallel(4).runOn(Schedulers.parallel()).concatMap((entity) -> airportRepository.save(entity)));
|
||||
.parallel(4).runOn(Schedulers.parallel()).concatMap((entity) -> reactiveAirportRepository.save(entity)));
|
||||
List<Object> saved = af.collectList().block();
|
||||
System.out.println("results.size() : " + saved.size());
|
||||
|
||||
@@ -152,7 +152,7 @@ public class FluxTest extends JavaIntegrationTests {
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
}
|
||||
List<Airport> airports = airportRepository.findAll().collectList().block();
|
||||
List<Airport> airports = reactiveAirportRepository.findAll().collectList().block();
|
||||
assertEquals(0, airports.size(), "should have been all deleted");
|
||||
}
|
||||
|
||||
@@ -164,11 +164,11 @@ public class FluxTest extends JavaIntegrationTests {
|
||||
for (int i = 0; i < 5; i++) {
|
||||
list.add(a.withId(UUID.randomUUID().toString()));
|
||||
}
|
||||
Flux<Object> af = Flux.fromIterable(list).concatMap((entity) -> airportRepository.save(entity));
|
||||
Flux<Object> af = Flux.fromIterable(list).concatMap((entity) -> reactiveAirportRepository.save(entity));
|
||||
List<Object> saved = af.collectList().block();
|
||||
System.out.println("results.size() : " + saved.size());
|
||||
Flux<Pair<String, Mono<Airport>>> pairFlux = Flux.fromIterable(list)
|
||||
.map((airport) -> Pair.of(airport.getId(), airportRepository.findById(airport.getId())));
|
||||
.map((airport) -> Pair.of(airport.getId(), reactiveAirportRepository.findById(airport.getId())));
|
||||
List<Pair<String, Mono<Airport>>> airportPairs = pairFlux.collectList().block();
|
||||
for (Pair<String, Mono<Airport>> airportPair : airportPairs) {
|
||||
System.out.println("id: " + airportPair.getFirst() + " airport: " + airportPair.getSecond().block());
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2017-2021 the original author or authors.
|
||||
* Copyright 2017-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,6 +21,8 @@ import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.springframework.data.couchbase.core.RemoveResult;
|
||||
import org.springframework.data.couchbase.repository.Collection;
|
||||
import org.springframework.data.couchbase.repository.DynamicProxyable;
|
||||
import org.springframework.data.couchbase.repository.Query;
|
||||
import org.springframework.data.couchbase.repository.ReactiveCouchbaseRepository;
|
||||
@@ -99,6 +101,15 @@ public interface ReactiveAirportRepository
|
||||
@ScanConsistency(query = QueryScanConsistency.REQUEST_PLUS)
|
||||
Mono<Airport> findByIata(String iata);
|
||||
|
||||
@Query("#{#n1ql.delete} WHERE #{#n1ql.filter} and iata = $1 #{#n1ql.returning}")
|
||||
@ScanConsistency(query = QueryScanConsistency.REQUEST_PLUS)
|
||||
Flux<RemoveResult> deleteByIata(String iata);
|
||||
|
||||
@Query("#{#n1ql.delete} WHERE #{#n1ql.filter} and iata = $1 #{#n1ql.returning}")
|
||||
@ScanConsistency(query = QueryScanConsistency.REQUEST_PLUS)
|
||||
@Collection("bogus_collection")
|
||||
Flux<RemoveResult> deleteByIataAnnotated(String iata);
|
||||
|
||||
// This is not efficient. See findAllByIataLike for efficient reactive paging
|
||||
default public Mono<Page<Airport>> findAllAirportsPaged(Pageable pageable) {
|
||||
return count().flatMap(airportCount -> {
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.couchbase.domain;
|
||||
|
||||
import org.springframework.data.couchbase.repository.Collection;
|
||||
|
||||
/**
|
||||
* AirportRepository with collection annotation
|
||||
*
|
||||
* @author Michael Reiche
|
||||
*/
|
||||
@Collection("my_collection2")
|
||||
public interface ReactiveAirportRepositoryAnnotated extends ReactiveAirportRepository {}
|
||||
@@ -142,6 +142,8 @@ public class CouchbaseRepositoryQueryIntegrationTests extends ClusterAwareIntegr
|
||||
super.beforeEach();
|
||||
couchbaseTemplate.removeByQuery(User.class).withConsistency(REQUEST_PLUS).all();
|
||||
couchbaseTemplate.findByQuery(User.class).withConsistency(REQUEST_PLUS).all();
|
||||
couchbaseTemplate.removeByQuery(Airport.class).withConsistency(REQUEST_PLUS).all();
|
||||
couchbaseTemplate.findByQuery(Airport.class).withConsistency(REQUEST_PLUS).all();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -60,7 +60,7 @@ public class ReactiveCouchbaseRepositoryKeyValueIntegrationTests extends Cluster
|
||||
|
||||
@Autowired ReactiveUserRepository userRepository;
|
||||
|
||||
@Autowired ReactiveAirportRepository airportRepository;
|
||||
@Autowired ReactiveAirportRepository reactiveAirportRepository;
|
||||
|
||||
@Autowired ReactiveAirlineRepository airlineRepository;
|
||||
|
||||
@@ -108,13 +108,13 @@ public class ReactiveCouchbaseRepositoryKeyValueIntegrationTests extends Cluster
|
||||
Airport vie = null;
|
||||
try {
|
||||
vie = new Airport("airports::vie", "vie", "low2");
|
||||
Airport saved = airportRepository.save(vie).block();
|
||||
Airport airport1 = airportRepository.findById(saved.getId()).block();
|
||||
Airport saved = reactiveAirportRepository.save(vie).block();
|
||||
Airport airport1 = reactiveAirportRepository.findById(saved.getId()).block();
|
||||
assertEquals(airport1, saved);
|
||||
assertEquals(saved.getCreatedBy(), ReactiveNaiveAuditorAware.AUDITOR); // ReactiveNaiveAuditorAware will provide
|
||||
// this
|
||||
} finally {
|
||||
airportRepository.delete(vie).block();
|
||||
reactiveAirportRepository.delete(vie).block();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ public class ReactiveCouchbaseRepositoryQueryIntegrationTests extends JavaIntegr
|
||||
|
||||
@Autowired CouchbaseClientFactory clientFactory;
|
||||
|
||||
@Autowired ReactiveAirportRepository airportRepository; // intellij flags "Could not Autowire", but it runs ok.
|
||||
@Autowired ReactiveAirportRepository reactiveAirportRepository; // intellij flags "Could not Autowire", runs ok.
|
||||
@Autowired ReactiveUserRepository userRepository; // intellij flags "Could not Autowire", but it runs ok.
|
||||
|
||||
@Test
|
||||
@@ -81,18 +81,18 @@ public class ReactiveCouchbaseRepositoryQueryIntegrationTests extends JavaIntegr
|
||||
Airport jfk = null;
|
||||
try {
|
||||
vie = new Airport("airports::vie", "vie", "low1");
|
||||
airportRepository.save(vie).block();
|
||||
reactiveAirportRepository.save(vie).block();
|
||||
jfk = new Airport("airports::jfk", "JFK", "xxxx");
|
||||
airportRepository.save(jfk).block();
|
||||
reactiveAirportRepository.save(jfk).block();
|
||||
|
||||
List<Airport> all = airportRepository.findAll().toStream().collect(Collectors.toList());
|
||||
List<Airport> all = reactiveAirportRepository.findAll().toStream().collect(Collectors.toList());
|
||||
|
||||
assertFalse(all.isEmpty());
|
||||
assertTrue(all.stream().anyMatch(a -> a.getId().equals("airports::vie")));
|
||||
assertTrue(all.stream().anyMatch(a -> a.getId().equals("airports::jfk")));
|
||||
} finally {
|
||||
airportRepository.delete(vie).block();
|
||||
airportRepository.delete(jfk).block();
|
||||
reactiveAirportRepository.delete(vie).block();
|
||||
reactiveAirportRepository.delete(jfk).block();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,20 +101,20 @@ public class ReactiveCouchbaseRepositoryQueryIntegrationTests extends JavaIntegr
|
||||
Airport vie = null;
|
||||
try {
|
||||
vie = new Airport("airports::vie", "vie", "low2");
|
||||
airportRepository.save(vie).block();
|
||||
List<Airport> airports1 = airportRepository.findAllByIata("vie").collectList().block();
|
||||
reactiveAirportRepository.save(vie).block();
|
||||
List<Airport> airports1 = reactiveAirportRepository.findAllByIata("vie").collectList().block();
|
||||
assertEquals(1, airports1.size());
|
||||
List<Airport> airports2 = airportRepository.findAllByIata("vie").collectList().block();
|
||||
List<Airport> airports2 = reactiveAirportRepository.findAllByIata("vie").collectList().block();
|
||||
assertEquals(1, airports2.size());
|
||||
vie = airportRepository.save(vie).block();
|
||||
List<Airport> airports = airportRepository.findAllByIata("vie").collectList().block();
|
||||
vie = reactiveAirportRepository.save(vie).block();
|
||||
List<Airport> airports = reactiveAirportRepository.findAllByIata("vie").collectList().block();
|
||||
assertEquals(1, airports.size());
|
||||
Airport airport1 = airportRepository.findById(airports.get(0).getId()).block();
|
||||
Airport airport1 = reactiveAirportRepository.findById(airports.get(0).getId()).block();
|
||||
assertEquals(airport1.getIata(), vie.getIata());
|
||||
Airport airport2 = airportRepository.findByIata(airports.get(0).getIata()).block();
|
||||
Airport airport2 = reactiveAirportRepository.findByIata(airports.get(0).getIata()).block();
|
||||
assertEquals(airport1.getId(), vie.getId());
|
||||
} finally {
|
||||
airportRepository.delete(vie).block();
|
||||
reactiveAirportRepository.delete(vie).block();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,27 +133,27 @@ public class ReactiveCouchbaseRepositoryQueryIntegrationTests extends JavaIntegr
|
||||
@Test
|
||||
void limitTest() {
|
||||
Airport vie = new Airport("airports::vie", "vie", "low3");
|
||||
Airport saved1 = airportRepository.save(vie).block();
|
||||
Airport saved2 = airportRepository.save(vie.withId(UUID.randomUUID().toString())).block();
|
||||
Airport saved1 = reactiveAirportRepository.save(vie).block();
|
||||
Airport saved2 = reactiveAirportRepository.save(vie.withId(UUID.randomUUID().toString())).block();
|
||||
try {
|
||||
airportRepository.findAll().collectList().block(); // findAll has QueryScanConsistency;
|
||||
Mono<Airport> airport = airportRepository.findPolicySnapshotByPolicyIdAndEffectiveDateTime("any", 0);
|
||||
reactiveAirportRepository.findAll().collectList().block(); // findAll has QueryScanConsistency;
|
||||
Mono<Airport> airport = reactiveAirportRepository.findPolicySnapshotByPolicyIdAndEffectiveDateTime("any", 0);
|
||||
System.out.println("------------------------------");
|
||||
System.out.println(airport.block());
|
||||
System.out.println("------------------------------");
|
||||
Flux<Airport> airports = airportRepository.findPolicySnapshotAll();
|
||||
Flux<Airport> airports = reactiveAirportRepository.findPolicySnapshotAll();
|
||||
System.out.println(airports.collectList().block());
|
||||
System.out.println("------------------------------");
|
||||
Mono<Airport> ap = getPolicyByIdAndEffectiveDateTime("x", Instant.now());
|
||||
System.out.println(ap.block());
|
||||
} finally {
|
||||
airportRepository.delete(saved1).block();
|
||||
airportRepository.delete(saved2).block();
|
||||
reactiveAirportRepository.delete(saved1).block();
|
||||
reactiveAirportRepository.delete(saved2).block();
|
||||
}
|
||||
}
|
||||
|
||||
public Mono<Airport> getPolicyByIdAndEffectiveDateTime(String policyId, Instant effectiveDateTime) {
|
||||
return airportRepository
|
||||
return reactiveAirportRepository
|
||||
.findPolicySnapshotByPolicyIdAndEffectiveDateTime(policyId, effectiveDateTime.toEpochMilli())
|
||||
// .map(Airport::getEntity)
|
||||
.doOnError(
|
||||
@@ -177,36 +177,36 @@ public class ReactiveCouchbaseRepositoryQueryIntegrationTests extends JavaIntegr
|
||||
Callable<Boolean>[] suppliers = new Callable[iatas.size()];
|
||||
for (String iata : iatas) {
|
||||
Airport airport = new Airport("airports::" + iata, iata, iata.toLowerCase() /* lcao */);
|
||||
airportRepository.save(airport).block();
|
||||
reactiveAirportRepository.save(airport).block();
|
||||
}
|
||||
|
||||
int page = 0;
|
||||
|
||||
airportRepository.findAllByIataLike("S%", PageRequest.of(page++, 2)).as(StepVerifier::create) //
|
||||
reactiveAirportRepository.findAllByIataLike("S%", PageRequest.of(page++, 2)).as(StepVerifier::create) //
|
||||
.expectNextMatches(a -> {
|
||||
return iatas.contains(a.getIata());
|
||||
}).expectNextMatches(a -> iatas.contains(a.getIata())).verifyComplete();
|
||||
|
||||
airportRepository.findAllByIataLike("S%", PageRequest.of(page++, 2)).as(StepVerifier::create) //
|
||||
reactiveAirportRepository.findAllByIataLike("S%", PageRequest.of(page++, 2)).as(StepVerifier::create) //
|
||||
.expectNextMatches(a -> iatas.contains(a.getIata())).verifyComplete();
|
||||
|
||||
Long airportCount = airportRepository.count().block();
|
||||
Long airportCount = reactiveAirportRepository.count().block();
|
||||
assertEquals(iatas.size(), airportCount);
|
||||
|
||||
airportCount = airportRepository.countByIataIn("JFK", "IAD", "SFO").block();
|
||||
airportCount = reactiveAirportRepository.countByIataIn("JFK", "IAD", "SFO").block();
|
||||
assertEquals(3, airportCount);
|
||||
|
||||
airportCount = airportRepository.countByIcaoAndIataIn("jfk", "JFK", "IAD", "SFO", "XXX").block();
|
||||
airportCount = reactiveAirportRepository.countByIcaoAndIataIn("jfk", "JFK", "IAD", "SFO", "XXX").block();
|
||||
assertEquals(1, airportCount);
|
||||
|
||||
airportCount = airportRepository.countByIataIn("XXX").block();
|
||||
airportCount = reactiveAirportRepository.countByIataIn("XXX").block();
|
||||
assertEquals(0, airportCount);
|
||||
|
||||
} finally {
|
||||
for (String iata : iatas) {
|
||||
Airport airport = new Airport("airports::" + iata, iata, iata.toLowerCase() /* lcao */);
|
||||
try {
|
||||
airportRepository.delete(airport).block();
|
||||
reactiveAirportRepository.delete(airport).block();
|
||||
} catch (DataRetrievalFailureException drfe) {
|
||||
System.out.println("Failed to delete: " + airport);
|
||||
}
|
||||
@@ -224,17 +224,17 @@ public class ReactiveCouchbaseRepositoryQueryIntegrationTests extends JavaIntegr
|
||||
|
||||
try {
|
||||
// This failed once against Capella - not sure why.
|
||||
airportRepository.saveAll(asList(vienna, frankfurt, losAngeles)).blockLast();
|
||||
reactiveAirportRepository.saveAll(asList(vienna, frankfurt, losAngeles)).blockLast();
|
||||
|
||||
airportRepository.deleteAllById(asList(vienna.getId(), losAngeles.getId())).as(StepVerifier::create)
|
||||
reactiveAirportRepository.deleteAllById(asList(vienna.getId(), losAngeles.getId())).as(StepVerifier::create)
|
||||
.verifyComplete();
|
||||
|
||||
airportRepository.findAll().as(StepVerifier::create).expectNext(frankfurt).verifyComplete();
|
||||
reactiveAirportRepository.findAll().as(StepVerifier::create).expectNext(frankfurt).verifyComplete();
|
||||
|
||||
} finally {
|
||||
List<Airport> airports = airportRepository.findAll().collectList().block(); // .as(StepVerifier::create).expectNext(frankfurt).verifyComplete();
|
||||
List<Airport> airports = reactiveAirportRepository.findAll().collectList().block(); // .as(StepVerifier::create).expectNext(frankfurt).verifyComplete();
|
||||
System.out.println(airports);
|
||||
airportRepository.deleteAll().block();
|
||||
reactiveAirportRepository.deleteAll().block();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -246,14 +246,14 @@ public class ReactiveCouchbaseRepositoryQueryIntegrationTests extends JavaIntegr
|
||||
Airport losAngeles = new Airport("airports::lax", "lax", "KLAX");
|
||||
|
||||
try {
|
||||
airportRepository.saveAll(asList(vienna, frankfurt, losAngeles)).blockLast();
|
||||
reactiveAirportRepository.saveAll(asList(vienna, frankfurt, losAngeles)).blockLast();
|
||||
|
||||
airportRepository.deleteAll().as(StepVerifier::create).verifyComplete();
|
||||
reactiveAirportRepository.deleteAll().as(StepVerifier::create).verifyComplete();
|
||||
|
||||
airportRepository.findAll().as(StepVerifier::create).verifyComplete();
|
||||
reactiveAirportRepository.findAll().as(StepVerifier::create).verifyComplete();
|
||||
|
||||
} finally {
|
||||
airportRepository.deleteAll().block();
|
||||
reactiveAirportRepository.deleteAll().block();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -263,13 +263,13 @@ public class ReactiveCouchbaseRepositoryQueryIntegrationTests extends JavaIntegr
|
||||
Airport vienna = new Airport("airports::vie", "vie", "LOWW");
|
||||
|
||||
try {
|
||||
Airport ap = airportRepository.save(vienna).block();
|
||||
Airport ap = reactiveAirportRepository.save(vienna).block();
|
||||
assertEquals(vienna.getId(), ap.getId(), "should have saved what was provided");
|
||||
airportRepository.delete(vienna).as(StepVerifier::create).verifyComplete();
|
||||
reactiveAirportRepository.delete(vienna).as(StepVerifier::create).verifyComplete();
|
||||
|
||||
airportRepository.findAll().as(StepVerifier::create).verifyComplete();
|
||||
reactiveAirportRepository.findAll().as(StepVerifier::create).verifyComplete();
|
||||
} finally {
|
||||
airportRepository.deleteAll().block();
|
||||
reactiveAirportRepository.deleteAll().block();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package org.springframework.data.couchbase.repository.query;
|
||||
|
||||
import static com.couchbase.client.core.io.CollectionIdentifier.DEFAULT_SCOPE;
|
||||
import static com.couchbase.client.java.query.QueryScanConsistency.REQUEST_PLUS;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
@@ -29,13 +30,12 @@ import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.dao.DataRetrievalFailureException;
|
||||
import org.springframework.data.couchbase.domain.Address;
|
||||
import org.springframework.data.couchbase.domain.AddressAnnotated;
|
||||
import org.springframework.data.couchbase.domain.Airport;
|
||||
import org.springframework.data.couchbase.domain.AirportRepository;
|
||||
import org.springframework.data.couchbase.domain.AirportRepositoryAnnotated;
|
||||
import org.springframework.data.couchbase.domain.Config;
|
||||
import org.springframework.data.couchbase.domain.User;
|
||||
import org.springframework.data.couchbase.domain.UserCol;
|
||||
@@ -48,13 +48,19 @@ import org.springframework.data.couchbase.util.Capabilities;
|
||||
import org.springframework.data.couchbase.util.ClusterType;
|
||||
import org.springframework.data.couchbase.util.CollectionAwareIntegrationTests;
|
||||
import org.springframework.data.couchbase.util.IgnoreWhen;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
|
||||
import com.couchbase.client.core.error.IndexFailureException;
|
||||
import com.couchbase.client.core.io.CollectionIdentifier;
|
||||
import com.couchbase.client.java.json.JsonArray;
|
||||
import com.couchbase.client.java.query.QueryOptions;
|
||||
import com.couchbase.client.java.query.QueryScanConsistency;
|
||||
|
||||
/**
|
||||
* Repository Query Tests with Collections
|
||||
*
|
||||
* @author Michael Reiche
|
||||
*/
|
||||
@SpringJUnitConfig(Config.class)
|
||||
@IgnoreWhen(missesCapabilities = { Capabilities.QUERY, Capabilities.COLLECTIONS }, clusterTypes = ClusterType.MOCKED)
|
||||
public class CouchbaseRepositoryQueryCollectionIntegrationTests extends CollectionAwareIntegrationTests {
|
||||
|
||||
@@ -62,6 +68,7 @@ public class CouchbaseRepositoryQueryCollectionIntegrationTests extends Collecti
|
||||
@Autowired UserColRepository userColRepository; // initialized in beforeEach()
|
||||
@Autowired UserSubmissionAnnotatedRepository userSubmissionAnnotatedRepository; // initialized in beforeEach()
|
||||
@Autowired UserSubmissionUnannotatedRepository userSubmissionUnannotatedRepository; // initialized in beforeEach()
|
||||
@Autowired AirportRepositoryAnnotated airportRepositoryAnnotated;
|
||||
|
||||
@BeforeAll
|
||||
public static void beforeAll() {
|
||||
@@ -86,14 +93,9 @@ public class CouchbaseRepositoryQueryCollectionIntegrationTests extends Collecti
|
||||
// then do processing for this class
|
||||
couchbaseTemplate.removeByQuery(User.class).inCollection(collectionName).all();
|
||||
couchbaseTemplate.removeByQuery(UserCol.class).inScope(otherScope).inCollection(otherCollection).all();
|
||||
ApplicationContext ac = new AnnotationConfigApplicationContext(Config.class);
|
||||
// seems that @Autowired is not adequate, so ...
|
||||
airportRepository = (AirportRepository) ac.getBean("airportRepository");
|
||||
userColRepository = (UserColRepository) ac.getBean("userColRepository");
|
||||
userSubmissionAnnotatedRepository = (UserSubmissionAnnotatedRepository) ac
|
||||
.getBean("userSubmissionAnnotatedRepository");
|
||||
userSubmissionUnannotatedRepository = (UserSubmissionUnannotatedRepository) ac
|
||||
.getBean("userSubmissionUnannotatedRepository");
|
||||
couchbaseTemplate.removeByQuery(Airport.class).inCollection(collectionName).all();
|
||||
couchbaseTemplate.removeByQuery(Airport.class).inCollection(collectionName2).all();
|
||||
couchbaseTemplate.findByQuery(Airport.class).withConsistency(REQUEST_PLUS).inCollection(collectionName).all();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
@@ -149,8 +151,7 @@ public class CouchbaseRepositoryQueryCollectionIntegrationTests extends Collecti
|
||||
|
||||
// valid scope, collection in options
|
||||
Airport airport2 = ar.withCollection(collectionName)
|
||||
.withOptions(QueryOptions.queryOptions().scanConsistency(QueryScanConsistency.REQUEST_PLUS))
|
||||
.iata(vie.getIata());
|
||||
.withOptions(QueryOptions.queryOptions().scanConsistency(REQUEST_PLUS)).iata(vie.getIata());
|
||||
assertEquals(saved, airport2);
|
||||
|
||||
// given bad collectionName in fluent
|
||||
@@ -159,8 +160,7 @@ public class CouchbaseRepositoryQueryCollectionIntegrationTests extends Collecti
|
||||
// given bad scopeName in fluent
|
||||
assertThrows(IndexFailureException.class, () -> ar.withScope("bogusScope").iata(vie.getIata()));
|
||||
|
||||
Airport airport6 = ar.withOptions(QueryOptions.queryOptions().scanConsistency(QueryScanConsistency.REQUEST_PLUS))
|
||||
.iata(vie.getIata());
|
||||
Airport airport6 = ar.withOptions(QueryOptions.queryOptions().scanConsistency(REQUEST_PLUS)).iata(vie.getIata());
|
||||
assertEquals(saved, airport6);
|
||||
|
||||
} catch (Exception e) {
|
||||
@@ -180,8 +180,8 @@ public class CouchbaseRepositoryQueryCollectionIntegrationTests extends Collecti
|
||||
try {
|
||||
Airport saved = ar.save(vie);
|
||||
|
||||
Airport airport3 = ar.withOptions(
|
||||
QueryOptions.queryOptions().scanConsistency(QueryScanConsistency.REQUEST_PLUS).parameters(positionalParams))
|
||||
Airport airport3 = ar
|
||||
.withOptions(QueryOptions.queryOptions().scanConsistency(REQUEST_PLUS).parameters(positionalParams))
|
||||
.iata(vie.getIata());
|
||||
assertEquals(saved, airport3);
|
||||
|
||||
@@ -278,8 +278,7 @@ public class CouchbaseRepositoryQueryCollectionIntegrationTests extends Collecti
|
||||
address1 = couchbaseTemplate.insertById(AddressAnnotated.class).inScope(scopeName).one(address1);
|
||||
address2 = couchbaseTemplate.insertById(AddressAnnotated.class).inScope(scopeName).one(address2);
|
||||
address3 = couchbaseTemplate.insertById(AddressAnnotated.class).inScope(scopeName).one(address3);
|
||||
couchbaseTemplate.findByQuery(AddressAnnotated.class).withConsistency(QueryScanConsistency.REQUEST_PLUS)
|
||||
.inScope(scopeName).all();
|
||||
couchbaseTemplate.findByQuery(AddressAnnotated.class).withConsistency(REQUEST_PLUS).inScope(scopeName).all();
|
||||
|
||||
// scope for AddressesAnnotated in N1qlJoin comes from userSubmissionAnnotatedRepository.
|
||||
List<UserSubmissionAnnotated> users = userSubmissionAnnotatedRepository.findByUsername(user.getUsername());
|
||||
@@ -333,8 +332,7 @@ public class CouchbaseRepositoryQueryCollectionIntegrationTests extends Collecti
|
||||
address1 = couchbaseTemplate.insertById(AddressAnnotated.class).inScope(scopeName).one(address1);
|
||||
address2 = couchbaseTemplate.insertById(AddressAnnotated.class).inScope(scopeName).one(address2);
|
||||
address3 = couchbaseTemplate.insertById(AddressAnnotated.class).inScope(scopeName).one(address3);
|
||||
couchbaseTemplate.findByQuery(AddressAnnotated.class).withConsistency(QueryScanConsistency.REQUEST_PLUS)
|
||||
.inScope(scopeName).all();
|
||||
couchbaseTemplate.findByQuery(AddressAnnotated.class).withConsistency(REQUEST_PLUS).inScope(scopeName).all();
|
||||
|
||||
// scope for AddressesAnnotated in N1qlJoin comes from userSubmissionAnnotatedRepository.
|
||||
List<UserSubmissionUnannotated> users = userSubmissionUnannotatedRepository.findByUsername(user.getUsername());
|
||||
@@ -359,4 +357,58 @@ public class CouchbaseRepositoryQueryCollectionIntegrationTests extends Collecti
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void stringDeleteCollectionTest() {
|
||||
Airport airport = new Airport(loc(), "vie", "abc");
|
||||
Airport otherAirport = new Airport(loc(), "xxx", "xyz");
|
||||
try {
|
||||
airport = airportRepository.withScope(scopeName).withCollection(collectionName).save(airport);
|
||||
otherAirport = airportRepository.withScope(scopeName).withCollection(collectionName).save(otherAirport);
|
||||
assertEquals(1,
|
||||
airportRepository.withScope(scopeName).withCollection(collectionName).deleteByIata(airport.getIata()).size());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
} finally {
|
||||
airportRepository.withScope(scopeName).withCollection(collectionName).deleteById(otherAirport.getId());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void stringDeleteWithRepositoryAnnotationTest() {
|
||||
Airport airport = new Airport(loc(), "vie", "abc");
|
||||
Airport otherAirport = new Airport(loc(), "xxx", "xyz");
|
||||
try {
|
||||
airport = airportRepositoryAnnotated.withScope(scopeName).save(airport);
|
||||
otherAirport = airportRepositoryAnnotated.withScope(scopeName).save(otherAirport);
|
||||
// don't specify a collection - should get collection from AirportRepositoryAnnotated
|
||||
assertEquals(1, airportRepositoryAnnotated.withScope(scopeName).deleteByIata(airport.getIata()).size());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
} finally {
|
||||
// this will fail if the above didn't use collectionName2
|
||||
airportRepository.withScope(scopeName).withCollection(collectionName2).deleteById(otherAirport.getId());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void stringDeleteWithMethodAnnotationTest() {
|
||||
Airport airport = new Airport(loc(), "vie", "abc");
|
||||
Airport otherAirport = new Airport(loc(), "xxx", "xyz");
|
||||
try {
|
||||
Airport airportSaved = airportRepositoryAnnotated.withScope(scopeName).save(airport);
|
||||
Airport otherAirportSaved = airportRepositoryAnnotated.withScope(scopeName).save(otherAirport);
|
||||
// don't specify a collection - should get collection from deleteByIataAnnotated method
|
||||
assertThrows(IndexFailureException.class, () -> assertEquals(1,
|
||||
airportRepositoryAnnotated.withScope(scopeName).deleteByIataAnnotated(airport.getIata()).size()));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
} finally {
|
||||
// this will fail if the above didn't use collectionName2
|
||||
airportRepository.withScope(scopeName).withCollection(collectionName2).deleteById(otherAirport.getId());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2017-2021 the original author or authors.
|
||||
* Copyright 2017-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -26,12 +26,11 @@ import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.dao.DataRetrievalFailureException;
|
||||
import org.springframework.data.couchbase.domain.Airport;
|
||||
import org.springframework.data.couchbase.domain.Config;
|
||||
import org.springframework.data.couchbase.domain.ReactiveAirportRepository;
|
||||
import org.springframework.data.couchbase.domain.ReactiveAirportRepositoryAnnotated;
|
||||
import org.springframework.data.couchbase.domain.ReactiveUserColRepository;
|
||||
import org.springframework.data.couchbase.domain.User;
|
||||
import org.springframework.data.couchbase.domain.UserCol;
|
||||
@@ -45,11 +44,19 @@ import com.couchbase.client.core.io.CollectionIdentifier;
|
||||
import com.couchbase.client.java.json.JsonArray;
|
||||
import com.couchbase.client.java.query.QueryOptions;
|
||||
import com.couchbase.client.java.query.QueryScanConsistency;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
|
||||
/**
|
||||
* Reactive Repository Query Tests with Collections
|
||||
*
|
||||
* @author Michael Reiche
|
||||
*/
|
||||
@SpringJUnitConfig(Config.class)
|
||||
@IgnoreWhen(missesCapabilities = { Capabilities.QUERY, Capabilities.COLLECTIONS }, clusterTypes = ClusterType.MOCKED)
|
||||
public class ReactiveCouchbaseRepositoryQueryCollectionIntegrationTests extends CollectionAwareIntegrationTests {
|
||||
|
||||
@Autowired ReactiveAirportRepository airportRepository;
|
||||
@Autowired ReactiveAirportRepository reactiveAirportRepository;
|
||||
@Autowired ReactiveAirportRepositoryAnnotated reactiveAirportRepositoryAnnotated;
|
||||
@Autowired ReactiveUserColRepository userColRepository;
|
||||
|
||||
@BeforeAll
|
||||
@@ -75,11 +82,6 @@ public class ReactiveCouchbaseRepositoryQueryCollectionIntegrationTests extends
|
||||
// then do processing for this class
|
||||
couchbaseTemplate.removeByQuery(User.class).inCollection(collectionName).all();
|
||||
couchbaseTemplate.removeByQuery(UserCol.class).inScope(otherScope).inCollection(otherCollection).all();
|
||||
|
||||
ApplicationContext ac = new AnnotationConfigApplicationContext(Config.class);
|
||||
// seems that @Autowired is not adequate, so ...
|
||||
airportRepository = (ReactiveAirportRepository) ac.getBean("reactiveAirportRepository");
|
||||
userColRepository = (ReactiveUserColRepository) ac.getBean("reactiveUserColRepository");
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
@@ -94,7 +96,7 @@ public class ReactiveCouchbaseRepositoryQueryCollectionIntegrationTests extends
|
||||
@Test
|
||||
public void myTest() {
|
||||
|
||||
ReactiveAirportRepository ar = airportRepository.withScope(scopeName).withCollection(collectionName);
|
||||
ReactiveAirportRepository ar = reactiveAirportRepository.withScope(scopeName).withCollection(collectionName);
|
||||
Airport vie = new Airport("airports::vie", "vie", "loww");
|
||||
try {
|
||||
Airport saved = ar.save(vie).block();
|
||||
@@ -119,7 +121,7 @@ public class ReactiveCouchbaseRepositoryQueryCollectionIntegrationTests extends
|
||||
|
||||
Airport vie = new Airport("airports::vie", "vie", "loww");
|
||||
// create proxy with scope, collection
|
||||
ReactiveAirportRepository ar = airportRepository.withScope(scopeName).withCollection(collectionName);
|
||||
ReactiveAirportRepository ar = reactiveAirportRepository.withScope(scopeName).withCollection(collectionName);
|
||||
try {
|
||||
Airport saved = ar.save(vie).block();
|
||||
|
||||
@@ -150,7 +152,7 @@ public class ReactiveCouchbaseRepositoryQueryCollectionIntegrationTests extends
|
||||
void findBySimplePropertyWithOptions() {
|
||||
|
||||
Airport vie = new Airport("airports::vie", "vie", "loww");
|
||||
ReactiveAirportRepository ar = airportRepository.withScope(scopeName).withCollection(collectionName);
|
||||
ReactiveAirportRepository ar = reactiveAirportRepository.withScope(scopeName).withCollection(collectionName);
|
||||
JsonArray positionalParams = JsonArray.create().add("\"this parameter will be overridden\"");
|
||||
try {
|
||||
Airport saved = ar.save(vie).block();
|
||||
@@ -212,4 +214,59 @@ public class ReactiveCouchbaseRepositoryQueryCollectionIntegrationTests extends
|
||||
} catch (DataRetrievalFailureException drfe) {}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void stringDeleteCollectionTest() {
|
||||
Airport airport = new Airport(loc(), "vie", "abc");
|
||||
Airport otherAirport = new Airport(loc(), "xxx", "xyz");
|
||||
try {
|
||||
airport = reactiveAirportRepository.withScope(scopeName).withCollection(collectionName).save(airport).block();
|
||||
otherAirport = reactiveAirportRepository.withScope(scopeName).withCollection(collectionName).save(otherAirport).block();
|
||||
assertEquals(1,
|
||||
reactiveAirportRepository.withScope(scopeName).withCollection(collectionName).deleteByIata(airport.getIata()).collectList().block().size());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
} finally {
|
||||
reactiveAirportRepository.withScope(scopeName).withCollection(collectionName).deleteById(otherAirport.getId());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void stringDeleteWithRepositoryAnnotationTest() {
|
||||
Airport airport = new Airport(loc(), "vie", "abc");
|
||||
Airport otherAirport = new Airport(loc(), "xxx", "xyz");
|
||||
try {
|
||||
airport = reactiveAirportRepositoryAnnotated.withScope(scopeName).save(airport).block();
|
||||
otherAirport = reactiveAirportRepositoryAnnotated.withScope(scopeName).save(otherAirport).block();
|
||||
// don't specify a collection - should get collection from AirportRepositoryAnnotated
|
||||
assertEquals(1, reactiveAirportRepositoryAnnotated.withScope(scopeName).deleteByIata(airport.getIata()).collectList().block().size());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
} finally {
|
||||
// this will fail if the above didn't use collectionName2
|
||||
reactiveAirportRepository.withScope(scopeName).withCollection(collectionName2).deleteById(otherAirport.getId());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void stringDeleteWithMethodAnnotationTest() {
|
||||
Airport airport = new Airport(loc(), "vie", "abc");
|
||||
Airport otherAirport = new Airport(loc(), "xxx", "xyz");
|
||||
try {
|
||||
Airport airportSaved = reactiveAirportRepositoryAnnotated.withScope(scopeName).save(airport).block();
|
||||
Airport otherAirportSaved = reactiveAirportRepositoryAnnotated.withScope(scopeName).save(otherAirport).block();
|
||||
// don't specify a collection - should get collection from deleteByIataAnnotated method
|
||||
assertThrows(IndexFailureException.class, () -> assertEquals(1,
|
||||
reactiveAirportRepositoryAnnotated.withScope(scopeName).deleteByIataAnnotated(airport.getIata()).collectList().block().size()));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
} finally {
|
||||
// this will fail if the above didn't use collectionName2
|
||||
reactiveAirportRepository.withScope(scopeName).withCollection(collectionName2).deleteById(otherAirport.getId());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
package org.springframework.data.couchbase.repository.query;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.springframework.data.couchbase.config.BeanNames.COUCHBASE_TEMPLATE;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Optional;
|
||||
@@ -25,15 +24,12 @@ import java.util.UUID;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration;
|
||||
import org.springframework.data.couchbase.core.CouchbaseTemplate;
|
||||
import org.springframework.data.couchbase.core.ExecutableFindByQueryOperation.ExecutableFindByQuery;
|
||||
import org.springframework.data.couchbase.core.convert.CouchbaseConverter;
|
||||
import org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter;
|
||||
import org.springframework.data.couchbase.core.mapping.CouchbaseMappingContext;
|
||||
import org.springframework.data.couchbase.core.mapping.CouchbasePersistentEntity;
|
||||
import org.springframework.data.couchbase.core.mapping.CouchbasePersistentProperty;
|
||||
import org.springframework.data.couchbase.core.query.Query;
|
||||
@@ -70,18 +66,13 @@ import com.couchbase.client.java.query.QueryScanConsistency;
|
||||
@IgnoreWhen(clusterTypes = ClusterType.MOCKED)
|
||||
class StringN1qlQueryCreatorIntegrationTests extends ClusterAwareIntegrationTests {
|
||||
|
||||
MappingContext<? extends CouchbasePersistentEntity<?>, CouchbasePersistentProperty> context;
|
||||
CouchbaseConverter converter;
|
||||
CouchbaseTemplate couchbaseTemplate;
|
||||
@Autowired MappingContext<? extends CouchbasePersistentEntity<?>, CouchbasePersistentProperty> context;
|
||||
@Autowired CouchbaseConverter converter;
|
||||
@Autowired CouchbaseTemplate couchbaseTemplate;
|
||||
static NamedQueries namedQueries = new PropertiesBasedNamedQueries(new Properties());
|
||||
|
||||
@BeforeEach
|
||||
public void beforeEach() {
|
||||
context = new CouchbaseMappingContext();
|
||||
converter = new MappingCouchbaseConverter(context);
|
||||
ApplicationContext ac = new AnnotationConfigApplicationContext(Config.class);
|
||||
couchbaseTemplate = (CouchbaseTemplate) ac.getBean(COUCHBASE_TEMPLATE);
|
||||
}
|
||||
public void beforeEach() {}
|
||||
|
||||
@Test
|
||||
@IgnoreWhen(missesCapabilities = Capabilities.QUERY, clusterTypes = ClusterType.MOCKED)
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
@@ -215,4 +216,14 @@ public abstract class ClusterAwareIntegrationTests {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return unique identifier for line - to use as key for documents to identify where they were created
|
||||
*/
|
||||
public static String loc() {
|
||||
String uuid = UUID.randomUUID().toString();
|
||||
String uid = uuid.substring(uuid.length() - 4);
|
||||
StackTraceElement ste = Thread.currentThread().getStackTrace()[2];
|
||||
return ste.getClassName() + ":" + ste.getMethodName() + ":" + ste.getLineNumber() + ":" + uid;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
- log additional debug info during automatic index creation
|
||||
-->
|
||||
|
||||
<logger name="org.springframework.data.couchbase.core" level="debug"/>"
|
||||
<logger name="org.springframework.data.couchbase.core" level="trace"/>"
|
||||
<logger name="org.springframework.data.couchbase.repository.query" level="debug"/>
|
||||
<logger name="org.springframework.data.couchbase.repository.query.SpatialViewQueryCreator" level="trace"/>
|
||||
<logger name="org.springframework.data.couchbase.repository.query.StringN1qlBasedQuery" level="trace"/>
|
||||
|
||||
Reference in New Issue
Block a user