DATACOUCH-1041 - Add withCas() method to RemoveById. (#1051)
Add withCas() method to RemoveById. Co-authored-by: mikereiche <michael.reiche@couchbase.com>
This commit is contained in:
@@ -50,6 +50,11 @@ public interface ExecutableRemoveByIdOperation {
|
||||
|
||||
}
|
||||
|
||||
interface ExecutableRemoveById extends RemoveByIdWithDurability {}
|
||||
interface RemoveByIdWithCas extends RemoveByIdWithDurability {
|
||||
|
||||
RemoveByIdWithDurability withCas(Long cas);
|
||||
}
|
||||
|
||||
interface ExecutableRemoveById extends RemoveByIdWithCas {}
|
||||
|
||||
}
|
||||
|
||||
@@ -35,7 +35,8 @@ public class ExecutableRemoveByIdOperationSupport implements ExecutableRemoveByI
|
||||
|
||||
@Override
|
||||
public ExecutableRemoveById removeById() {
|
||||
return new ExecutableRemoveByIdSupport(template, null, PersistTo.NONE, ReplicateTo.NONE, DurabilityLevel.NONE);
|
||||
return new ExecutableRemoveByIdSupport(template, null, PersistTo.NONE, ReplicateTo.NONE, DurabilityLevel.NONE,
|
||||
null);
|
||||
}
|
||||
|
||||
static class ExecutableRemoveByIdSupport implements ExecutableRemoveById {
|
||||
@@ -45,17 +46,19 @@ public class ExecutableRemoveByIdOperationSupport implements ExecutableRemoveByI
|
||||
private final PersistTo persistTo;
|
||||
private final ReplicateTo replicateTo;
|
||||
private final DurabilityLevel durabilityLevel;
|
||||
private final Long cas;
|
||||
private final ReactiveRemoveByIdSupport reactiveRemoveByIdSupport;
|
||||
|
||||
ExecutableRemoveByIdSupport(final CouchbaseTemplate template, final String collection, final PersistTo persistTo,
|
||||
final ReplicateTo replicateTo, final DurabilityLevel durabilityLevel) {
|
||||
final ReplicateTo replicateTo, final DurabilityLevel durabilityLevel, Long cas) {
|
||||
this.template = template;
|
||||
this.collection = collection;
|
||||
this.persistTo = persistTo;
|
||||
this.replicateTo = replicateTo;
|
||||
this.durabilityLevel = durabilityLevel;
|
||||
this.cas = cas;
|
||||
this.reactiveRemoveByIdSupport = new ReactiveRemoveByIdSupport(template.reactive(), collection, persistTo,
|
||||
replicateTo, durabilityLevel);
|
||||
replicateTo, durabilityLevel, cas);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -71,20 +74,26 @@ public class ExecutableRemoveByIdOperationSupport implements ExecutableRemoveByI
|
||||
@Override
|
||||
public TerminatingRemoveById inCollection(final String collection) {
|
||||
Assert.hasText(collection, "Collection must not be null nor empty.");
|
||||
return new ExecutableRemoveByIdSupport(template, collection, persistTo, replicateTo, durabilityLevel);
|
||||
return new ExecutableRemoveByIdSupport(template, collection, persistTo, replicateTo, durabilityLevel, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RemoveByIdWithCollection withDurability(final DurabilityLevel durabilityLevel) {
|
||||
Assert.notNull(durabilityLevel, "Durability Level must not be null.");
|
||||
return new ExecutableRemoveByIdSupport(template, collection, persistTo, replicateTo, durabilityLevel);
|
||||
return new ExecutableRemoveByIdSupport(template, collection, persistTo, replicateTo, durabilityLevel, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RemoveByIdWithCollection withDurability(final PersistTo persistTo, final ReplicateTo replicateTo) {
|
||||
Assert.notNull(persistTo, "PersistTo must not be null.");
|
||||
Assert.notNull(replicateTo, "ReplicateTo must not be null.");
|
||||
return new ExecutableRemoveByIdSupport(template, collection, persistTo, replicateTo, durabilityLevel);
|
||||
return new ExecutableRemoveByIdSupport(template, collection, persistTo, replicateTo, durabilityLevel, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RemoveByIdWithCas withCas(final Long cas) {
|
||||
Assert.notNull(cas, "CAS must not be null.");
|
||||
return new ExecutableRemoveByIdSupport(template, collection, persistTo, replicateTo, durabilityLevel, cas);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ public interface ReactiveRemoveByIdOperation {
|
||||
interface RemoveByIdWithCollection extends TerminatingRemoveById, WithCollection<RemoveResult> {
|
||||
|
||||
TerminatingRemoveById inCollection(String collection);
|
||||
|
||||
}
|
||||
|
||||
interface RemoveByIdWithDurability extends RemoveByIdWithCollection, WithDurability<RemoveResult> {
|
||||
@@ -52,6 +53,12 @@ public interface ReactiveRemoveByIdOperation {
|
||||
|
||||
}
|
||||
|
||||
interface ReactiveRemoveById extends RemoveByIdWithDurability {}
|
||||
interface RemoveByIdWithCas extends RemoveByIdWithDurability {
|
||||
|
||||
RemoveByIdWithDurability withCas(Long cas);
|
||||
|
||||
}
|
||||
|
||||
interface ReactiveRemoveById extends RemoveByIdWithCas {}
|
||||
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ public class ReactiveRemoveByIdOperationSupport implements ReactiveRemoveByIdOpe
|
||||
|
||||
@Override
|
||||
public ReactiveRemoveById removeById() {
|
||||
return new ReactiveRemoveByIdSupport(template, null, PersistTo.NONE, ReplicateTo.NONE, DurabilityLevel.NONE);
|
||||
return new ReactiveRemoveByIdSupport(template, null, PersistTo.NONE, ReplicateTo.NONE, DurabilityLevel.NONE, null);
|
||||
}
|
||||
|
||||
static class ReactiveRemoveByIdSupport implements ReactiveRemoveById {
|
||||
@@ -47,14 +47,16 @@ public class ReactiveRemoveByIdOperationSupport implements ReactiveRemoveByIdOpe
|
||||
private final PersistTo persistTo;
|
||||
private final ReplicateTo replicateTo;
|
||||
private final DurabilityLevel durabilityLevel;
|
||||
private final Long cas;
|
||||
|
||||
ReactiveRemoveByIdSupport(final ReactiveCouchbaseTemplate template, final String collection,
|
||||
final PersistTo persistTo, final ReplicateTo replicateTo, final DurabilityLevel durabilityLevel) {
|
||||
final PersistTo persistTo, final ReplicateTo replicateTo, final DurabilityLevel durabilityLevel, Long cas) {
|
||||
this.template = template;
|
||||
this.collection = collection;
|
||||
this.persistTo = persistTo;
|
||||
this.replicateTo = replicateTo;
|
||||
this.durabilityLevel = durabilityLevel;
|
||||
this.cas = cas;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -81,28 +83,36 @@ public class ReactiveRemoveByIdOperationSupport implements ReactiveRemoveByIdOpe
|
||||
} else if (durabilityLevel != DurabilityLevel.NONE) {
|
||||
options.durability(durabilityLevel);
|
||||
}
|
||||
if (cas != null) {
|
||||
options.cas(cas);
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RemoveByIdWithDurability inCollection(final String collection) {
|
||||
Assert.hasText(collection, "Collection must not be null nor empty.");
|
||||
return new ReactiveRemoveByIdSupport(template, collection, persistTo, replicateTo, durabilityLevel, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RemoveByIdWithCollection withDurability(final DurabilityLevel durabilityLevel) {
|
||||
Assert.notNull(durabilityLevel, "Durability Level must not be null.");
|
||||
return new ReactiveRemoveByIdSupport(template, collection, persistTo, replicateTo, durabilityLevel);
|
||||
return new ReactiveRemoveByIdSupport(template, collection, persistTo, replicateTo, durabilityLevel, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RemoveByIdWithCollection withDurability(final PersistTo persistTo, final ReplicateTo replicateTo) {
|
||||
Assert.notNull(persistTo, "PersistTo must not be null.");
|
||||
Assert.notNull(replicateTo, "ReplicateTo must not be null.");
|
||||
return new ReactiveRemoveByIdSupport(template, collection, persistTo, replicateTo, durabilityLevel);
|
||||
return new ReactiveRemoveByIdSupport(template, collection, persistTo, replicateTo, durabilityLevel, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RemoveByIdWithDurability inCollection(final String collection) {
|
||||
Assert.hasText(collection, "Collection must not be null nor empty.");
|
||||
return new ReactiveRemoveByIdSupport(template, collection, persistTo, replicateTo, durabilityLevel);
|
||||
public RemoveByIdWithDurability withCas(final Long cas) {
|
||||
Assert.notNull(cas, "CAS must not be null.");
|
||||
return new ReactiveRemoveByIdSupport(template, collection, persistTo, replicateTo, durabilityLevel, cas);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -45,10 +45,10 @@ import org.springframework.data.couchbase.domain.UserAnnotated2;
|
||||
import org.springframework.data.couchbase.domain.UserAnnotated3;
|
||||
import org.springframework.data.couchbase.util.ClusterType;
|
||||
import org.springframework.data.couchbase.util.IgnoreWhen;
|
||||
import org.springframework.data.couchbase.util.JavaIntegrationTests;
|
||||
|
||||
import com.couchbase.client.java.kv.PersistTo;
|
||||
import com.couchbase.client.java.kv.ReplicateTo;
|
||||
import org.springframework.data.couchbase.util.JavaIntegrationTests;
|
||||
|
||||
;
|
||||
|
||||
@@ -103,7 +103,8 @@ class CouchbaseTemplateKeyValueIntegrationTests extends JavaIntegrationTests {
|
||||
"firstname", "lastname");
|
||||
|
||||
if (clazz.equals(User.class)) { // User.java doesn't have an durability annotation
|
||||
operator = (OneAndAllEntity) ((WithDurability<User>) operator).withDurability(PersistTo.ACTIVE, ReplicateTo.NONE);
|
||||
operator = (OneAndAllEntity) ((WithDurability<User>) operator).withDurability(PersistTo.ACTIVE,
|
||||
ReplicateTo.NONE);
|
||||
}
|
||||
|
||||
// if replace, we need to insert a document to replace
|
||||
@@ -194,16 +195,34 @@ class CouchbaseTemplateKeyValueIntegrationTests extends JavaIntegrationTests {
|
||||
|
||||
@Test
|
||||
void upsertAndRemoveById() {
|
||||
User user = new User(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
User modified = couchbaseTemplate.upsertById(User.class).one(user);
|
||||
assertEquals(user, modified);
|
||||
{
|
||||
User user = new User(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
User modified = couchbaseTemplate.upsertById(User.class).one(user);
|
||||
assertEquals(user, modified);
|
||||
|
||||
RemoveResult removeResult = couchbaseTemplate.removeById().one(user.getId());
|
||||
assertEquals(user.getId(), removeResult.getId());
|
||||
assertTrue(removeResult.getCas() != 0);
|
||||
assertTrue(removeResult.getMutationToken().isPresent());
|
||||
RemoveResult removeResult = couchbaseTemplate.removeById().one(user.getId());
|
||||
assertEquals(user.getId(), removeResult.getId());
|
||||
assertTrue(removeResult.getCas() != 0);
|
||||
assertTrue(removeResult.getMutationToken().isPresent());
|
||||
|
||||
assertNull(couchbaseTemplate.findById(User.class).one(user.getId()));
|
||||
assertNull(couchbaseTemplate.findById(User.class).one(user.getId()));
|
||||
}
|
||||
{
|
||||
User user = new User(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
User modified = couchbaseTemplate.upsertById(User.class).one(user);
|
||||
System.out.println(reactiveCouchbaseTemplate.support().getCas(user));
|
||||
System.out.println(reactiveCouchbaseTemplate.support().getCas(modified));
|
||||
assertEquals(user, modified);
|
||||
|
||||
// careful now - user and modified are the same object. The object has the new cas (@Version version)
|
||||
Long savedCas = modified.getVersion();
|
||||
modified.setVersion(123);
|
||||
assertThrows(DataIntegrityViolationException.class, () -> couchbaseTemplate.removeById()
|
||||
.withCas(reactiveCouchbaseTemplate.support().getCas(modified)).one(modified.getId()));
|
||||
modified.setVersion(savedCas);
|
||||
couchbaseTemplate.removeById().withCas(reactiveCouchbaseTemplate.support().getCas(modified))
|
||||
.one(modified.getId());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user