Skip to content

DATACOUCH-615 Use query in removeByQuery #264

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Oct 5, 2020
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ public Mono<Boolean> exists() {
}

private String assembleEntityQuery(final boolean count) {
return query.toN1qlString(template, this.domainType, count);
return query.toN1qlSelectString(template, this.domainType, count);
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,7 @@ static class ReactiveRemoveByQuerySupport<T> implements ReactiveRemoveByQuery<T>
@Override
public Flux<RemoveResult> all() {
return Flux.defer(() -> {
String bucket = "`" + template.getBucketName() + "`";

String typeKey = template.getConverter().getTypeKey();
String typeValue = template.support().getJavaNameForEntity(domainType);
String where = " WHERE `" + typeKey + "` = \"" + typeValue + "\"";

String returning = " RETURNING meta().*";
String statement = "DELETE FROM " + bucket + " " + where + returning;
String statement = assembleDeleteQuery();

return template.getCouchbaseClientFactory().getCluster().reactive().query(statement, buildQueryOptions())
.onErrorMap(throwable -> {
Expand All @@ -75,7 +68,7 @@ public Flux<RemoveResult> all() {
return throwable;
}
}).flatMapMany(ReactiveQueryResult::rowsAsObject)
.map(row -> new RemoveResult(row.getString("id"), row.getLong("cas"), Optional.empty()));
.map(row -> new RemoveResult(row.getString("__id"), row.getLong("__cas"), Optional.empty()));
});
}

Expand All @@ -97,6 +90,10 @@ public RemoveByQueryWithQuery<T> consistentWith(final QueryScanConsistency scanC
return new ReactiveRemoveByQuerySupport<>(template, domainType, query, scanConsistency);
}

private String assembleDeleteQuery() {
return query.toN1qlRemoveString(template, this.domainType);
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ public String export() {
return sb.toString();
}

public String toN1qlString(ReactiveCouchbaseTemplate template, Class domainClass, boolean isCount) {
public String toN1qlSelectString(ReactiveCouchbaseTemplate template, Class domainClass, boolean isCount) {
StringBasedN1qlQueryParser.N1qlSpelValues n1ql = getN1qlSpelValues(template, domainClass, isCount);
final StringBuilder statement = new StringBuilder();
appendString(statement, n1ql.selectEntity); // select ...
Expand All @@ -254,6 +254,16 @@ public String toN1qlString(ReactiveCouchbaseTemplate template, Class domainClass
return statement.toString();
}

public String toN1qlRemoveString(ReactiveCouchbaseTemplate template, Class domainClass) {
StringBasedN1qlQueryParser.N1qlSpelValues n1ql = getN1qlSpelValues(template, domainClass, false);
final StringBuilder statement = new StringBuilder();
appendString(statement, n1ql.delete); // delete ...
appendWhereString(statement, n1ql.filter); // typeKey = typeValue
appendWhere(statement, null); // criteria on this Query
appendString(statement, n1ql.returning);
return statement.toString();
}

StringBasedN1qlQueryParser.N1qlSpelValues getN1qlSpelValues(ReactiveCouchbaseTemplate template, Class domainClass,
boolean isCount) {
String typeKey = template.getConverter().getTypeKey();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ private void appendInlineN1qlStatement(final StringBuilder sb) {
}

@Override
public String toN1qlString(ReactiveCouchbaseTemplate template, Class domainClass, boolean isCount) {
public String toN1qlSelectString(ReactiveCouchbaseTemplate template, Class domainClass, boolean isCount) {
final StringBuilder statement = new StringBuilder();
appendInlineN1qlStatement(statement); // apply the string statement
// To use generated parameters for literals
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,10 @@
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.dao.DataRetrievalFailureException;
import org.springframework.data.couchbase.CouchbaseClientFactory;
import org.springframework.data.couchbase.SimpleCouchbaseClientFactory;
import org.springframework.data.couchbase.core.query.Query;
import org.springframework.data.couchbase.core.query.QueryCriteria;
import org.springframework.data.couchbase.domain.Config;
import org.springframework.data.couchbase.domain.NaiveAuditorAware;
import org.springframework.data.couchbase.domain.User;
Expand All @@ -46,13 +47,13 @@

import com.couchbase.client.core.error.IndexExistsException;
import com.couchbase.client.java.query.QueryScanConsistency;
import reactor.core.publisher.Mono;

/**
* Query tests Theses tests rely on a cb server running
*
* @author Michael Nitschinger
* @author Michael Reiche
* @author Haris Alesevic
*/
@IgnoreWhen(missesCapabilities = Capabilities.QUERY, clusterTypes = ClusterType.MOCKED)
class CouchbaseTemplateQueryIntegrationTests extends ClusterAwareIntegrationTests {
Expand Down Expand Up @@ -82,6 +83,8 @@ void beforeEach() {
ApplicationContext ac = new AnnotationConfigApplicationContext(Config.class);
couchbaseTemplate = (CouchbaseTemplate) ac.getBean(COUCHBASE_TEMPLATE);
reactiveCouchbaseTemplate = (ReactiveCouchbaseTemplate) ac.getBean(REACTIVE_COUCHBASE_TEMPLATE);
// ensure each test starts with clean state
couchbaseTemplate.removeByQuery(User.class).all();
}

@Test
Expand Down Expand Up @@ -128,7 +131,7 @@ void findByQuery() {
}

@Test
void removeByQuery() {
void removeByQueryAll() {
User user1 = new User(UUID.randomUUID().toString(), "user1", "user1");
User user2 = new User(UUID.randomUUID().toString(), "user2", "user2");

Expand All @@ -144,4 +147,28 @@ void removeByQuery() {

}

@Test
void removeByMatchingQuery() {
User user1 = new User(UUID.randomUUID().toString(), "user1", "user1");
User user2 = new User(UUID.randomUUID().toString(), "user2", "user2");
User specialUser = new User(UUID.randomUUID().toString(), "special", "special");

couchbaseTemplate.upsertById(User.class).all(Arrays.asList(user1, user2, specialUser));

assertTrue(couchbaseTemplate.existsById().one(user1.getId()));
assertTrue(couchbaseTemplate.existsById().one(user2.getId()));
assertTrue(couchbaseTemplate.existsById().one(specialUser.getId()));

Query nonSpecialUsers = new Query(QueryCriteria.where("firstname").notLike("special"));

couchbaseTemplate.removeByQuery(User.class).consistentWith(QueryScanConsistency.REQUEST_PLUS)
.matching(nonSpecialUsers)
.all();

assertNull(couchbaseTemplate.findById(User.class).one(user1.getId()));
assertNull(couchbaseTemplate.findById(User.class).one(user2.getId()));
assertNotNull(couchbaseTemplate.findById(User.class).one(specialUser.getId()));

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,16 @@
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;
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;
import org.springframework.data.couchbase.domain.Airline;
import org.springframework.data.couchbase.domain.AirlineRepository;
import org.springframework.data.couchbase.domain.User;
import org.springframework.data.couchbase.domain.UserRepository;
import org.springframework.data.couchbase.repository.config.EnableCouchbaseRepositories;
import org.springframework.data.couchbase.util.Capabilities;
import org.springframework.data.couchbase.util.ClusterAwareIntegrationTests;
import org.springframework.data.couchbase.util.ClusterType;
import org.springframework.data.couchbase.util.IgnoreWhen;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.projection.SpelAwareProxyProjectionFactory;
import org.springframework.data.repository.core.NamedQueries;
Expand All @@ -46,9 +40,7 @@
import org.springframework.data.repository.query.*;

import java.lang.reflect.Method;
import java.util.Optional;
import java.util.Properties;
import java.util.UUID;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
Expand Down Expand Up @@ -88,7 +80,7 @@ void createsQueryCorrectly() throws Exception {
Query query = creator.createQuery();
assertEquals(
"SELECT META(`travel-sample`).id AS __id, META(`travel-sample`).cas AS __cas, `travel-sample`.* FROM `travel-sample` where `_class` = \"org.springframework.data.couchbase.domain.User\" and firstname = $1 and lastname = $2",
query.toN1qlString(couchbaseTemplate.reactive(), User.class, false));
query.toN1qlSelectString(couchbaseTemplate.reactive(), User.class, false));
}

@Test
Expand All @@ -106,7 +98,7 @@ void createsQueryCorrectly2() throws Exception {
Query query = creator.createQuery();
assertEquals(
"SELECT META(`travel-sample`).id AS __id, META(`travel-sample`).cas AS __cas, `travel-sample`.* FROM `travel-sample` where `_class` = \"org.springframework.data.couchbase.domain.User\" and (firstname = $first or lastname = $last)",
query.toN1qlString(couchbaseTemplate.reactive(), User.class, false));
query.toN1qlSelectString(couchbaseTemplate.reactive(), User.class, false));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@

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.context.annotation.Configuration;
Expand Down Expand Up @@ -91,7 +90,7 @@ void findUsingStringNq1l() throws Exception {
queryMethod, converter, config().bucketname(), QueryMethodEvaluationContextProvider.DEFAULT, namedQueries);

Query query = creator.createQuery();
System.out.println(query.toN1qlString(couchbaseTemplate.reactive(), Airline.class, false));
System.out.println(query.toN1qlSelectString(couchbaseTemplate.reactive(), Airline.class, false));

try {
Thread.sleep(3000);
Expand Down