|
|
|
|
@@ -16,6 +16,8 @@
|
|
|
|
|
|
|
|
|
|
package org.springframework.data.couchbase.repository;
|
|
|
|
|
|
|
|
|
|
import static com.couchbase.client.java.query.QueryScanConsistency.NOT_BOUNDED;
|
|
|
|
|
import static com.couchbase.client.java.query.QueryScanConsistency.REQUEST_PLUS;
|
|
|
|
|
import static java.util.Arrays.asList;
|
|
|
|
|
import static org.assertj.core.api.Assertions.assertThat;
|
|
|
|
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
|
|
|
@@ -25,6 +27,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
|
|
|
|
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
|
|
|
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
|
|
|
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
|
|
|
import static org.springframework.data.couchbase.config.BeanNames.COUCHBASE_TEMPLATE;
|
|
|
|
|
|
|
|
|
|
import junit.framework.AssertionFailedError;
|
|
|
|
|
|
|
|
|
|
@@ -46,6 +49,8 @@ import javax.validation.ConstraintViolationException;
|
|
|
|
|
|
|
|
|
|
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.Bean;
|
|
|
|
|
import org.springframework.context.annotation.Configuration;
|
|
|
|
|
import org.springframework.dao.DataIntegrityViolationException;
|
|
|
|
|
@@ -63,6 +68,7 @@ import org.springframework.data.couchbase.domain.Address;
|
|
|
|
|
import org.springframework.data.couchbase.domain.Airport;
|
|
|
|
|
import org.springframework.data.couchbase.domain.AirportMini;
|
|
|
|
|
import org.springframework.data.couchbase.domain.AirportRepository;
|
|
|
|
|
import org.springframework.data.couchbase.domain.AirportRepositoryScanConsistencyTest;
|
|
|
|
|
import org.springframework.data.couchbase.domain.NaiveAuditorAware;
|
|
|
|
|
import org.springframework.data.couchbase.domain.Person;
|
|
|
|
|
import org.springframework.data.couchbase.domain.PersonRepository;
|
|
|
|
|
@@ -267,6 +273,80 @@ public class CouchbaseRepositoryQueryIntegrationTests extends ClusterAwareIntegr
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void saveNotBoundedRequestPlus() {
|
|
|
|
|
ApplicationContext ac = new AnnotationConfigApplicationContext(ConfigRequestPlus.class);
|
|
|
|
|
// the Config class has been modified, these need to be loaded again
|
|
|
|
|
CouchbaseTemplate couchbaseTemplateRP = (CouchbaseTemplate) ac.getBean(COUCHBASE_TEMPLATE);
|
|
|
|
|
AirportRepository airportRepositoryRP = (AirportRepository) ac.getBean("airportRepository");
|
|
|
|
|
|
|
|
|
|
// save() followed by query with NOT_BOUNDED will result in not finding the document
|
|
|
|
|
Airport vie = new Airport("airports::vie", "vie", "low9");
|
|
|
|
|
Airport airport2 = null;
|
|
|
|
|
for (int i = 1; i <= 100; i++) {
|
|
|
|
|
// set version == 0 so save() will be an upsert, not a replace
|
|
|
|
|
Airport saved = airportRepositoryRP.save(vie.clearVersion());
|
|
|
|
|
try {
|
|
|
|
|
airport2 = airportRepositoryRP.iata(saved.getIata());
|
|
|
|
|
if (airport2 == null) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
} catch (DataRetrievalFailureException drfe) {
|
|
|
|
|
airport2 = null; //
|
|
|
|
|
} finally {
|
|
|
|
|
// airportRepository.delete(vie);
|
|
|
|
|
// instead of delete, use removeResult to test QueryOptions.consistentWith()
|
|
|
|
|
RemoveResult removeResult = couchbaseTemplateRP.removeById().one(vie.getId());
|
|
|
|
|
assertEquals(vie.getId(), removeResult.getId());
|
|
|
|
|
assertTrue(removeResult.getCas() != 0);
|
|
|
|
|
assertTrue(removeResult.getMutationToken().isPresent());
|
|
|
|
|
Airport airport3 = airportRepositoryRP.iata(vie.getIata());
|
|
|
|
|
assertNull(airport3, "should have been removed");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
assertNotNull(airport2, "airport2 should have never been null");
|
|
|
|
|
Airport saved = airportRepositoryRP.save(vie.clearVersion());
|
|
|
|
|
List<Airport> airports = couchbaseTemplateRP.findByQuery(Airport.class).withConsistency(NOT_BOUNDED).all();
|
|
|
|
|
RemoveResult removeResult = couchbaseTemplateRP.removeById().one(saved.getId());
|
|
|
|
|
assertFalse(!airports.isEmpty(), "airports should have been empty");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void saveNotBoundedWithDefaultRepository() {
|
|
|
|
|
|
|
|
|
|
ApplicationContext ac = new AnnotationConfigApplicationContext(Config.class);
|
|
|
|
|
// the Config class has been modified, these need to be loaded again
|
|
|
|
|
CouchbaseTemplate couchbaseTemplateRP = (CouchbaseTemplate) ac.getBean(COUCHBASE_TEMPLATE);
|
|
|
|
|
AirportRepositoryScanConsistencyTest airportRepositoryRP = (AirportRepositoryScanConsistencyTest) ac.getBean("airportRepositoryScanConsistencyTest");
|
|
|
|
|
|
|
|
|
|
List<Airport> sizeBeforeTest = airportRepositoryRP.findAll();
|
|
|
|
|
assertEquals(0, sizeBeforeTest.size());
|
|
|
|
|
|
|
|
|
|
Airport vie = new Airport("airports::vie", "vie" , "low9");
|
|
|
|
|
Airport saved = airportRepositoryRP.save(vie);
|
|
|
|
|
List<Airport> allSaved = airportRepositoryRP.findAll();
|
|
|
|
|
couchbaseTemplate.removeById(Airport.class).one(saved.getId());
|
|
|
|
|
assertNotEquals( 1, allSaved.size(),"should not have found 1 airport");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void saveRequestPlusWithDefaultRepository() {
|
|
|
|
|
|
|
|
|
|
ApplicationContext ac = new AnnotationConfigApplicationContext(ConfigRequestPlus.class);
|
|
|
|
|
// the Config class has been modified, these need to be loaded again
|
|
|
|
|
AirportRepositoryScanConsistencyTest airportRepositoryRP = (AirportRepositoryScanConsistencyTest) ac.getBean("airportRepositoryScanConsistencyTest");
|
|
|
|
|
|
|
|
|
|
List<Airport> sizeBeforeTest = airportRepositoryRP.findAll();
|
|
|
|
|
assertEquals(0, sizeBeforeTest.size());
|
|
|
|
|
|
|
|
|
|
Airport vie = new Airport("airports::vie", "vie" , "low9");
|
|
|
|
|
Airport saved = airportRepositoryRP.save(vie);
|
|
|
|
|
List<Airport> allSaved = airportRepositoryRP.findAll();
|
|
|
|
|
couchbaseTemplate.removeById(Airport.class).one(saved.getId());
|
|
|
|
|
assertEquals( 1, allSaved.size(),"should have found 1 airport");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
void findByTypeAlias() {
|
|
|
|
|
Airport vie = null;
|
|
|
|
|
@@ -386,9 +466,7 @@ public class CouchbaseRepositoryQueryIntegrationTests extends ClusterAwareIntegr
|
|
|
|
|
// set version == 0 so save() will be an upsert, not a replace
|
|
|
|
|
Airport saved = airportRepository.save(vie.clearVersion());
|
|
|
|
|
try {
|
|
|
|
|
airport2 = airportRepository
|
|
|
|
|
.withOptions(QueryOptions.queryOptions().scanConsistency(QueryScanConsistency.NOT_BOUNDED))
|
|
|
|
|
.iata(saved.getIata());
|
|
|
|
|
airport2 = airportRepository.iata(saved.getIata());
|
|
|
|
|
if (airport2 == null) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
@@ -401,14 +479,16 @@ public class CouchbaseRepositoryQueryIntegrationTests extends ClusterAwareIntegr
|
|
|
|
|
assertEquals(vie.getId(), removeResult.getId());
|
|
|
|
|
assertTrue(removeResult.getCas() != 0);
|
|
|
|
|
assertTrue(removeResult.getMutationToken().isPresent());
|
|
|
|
|
Airport airport3 = airportRepository
|
|
|
|
|
.withOptions(QueryOptions.queryOptions().scanConsistency(QueryScanConsistency.REQUEST_PLUS)
|
|
|
|
|
.consistentWith(MutationState.from(removeResult.getMutationToken().get())))
|
|
|
|
|
.iata(vie.getIata());
|
|
|
|
|
Airport airport3 = airportRepository.iata(vie.getIata());
|
|
|
|
|
assertNull(airport3, "should have been removed");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
assertNull(airport2, "airport2 should have likely been null at least once");
|
|
|
|
|
Airport saved = airportRepository.save(vie.clearVersion());
|
|
|
|
|
couchbaseTemplate.findByQuery(Airport.class).withConsistency(REQUEST_PLUS).all();
|
|
|
|
|
airport2 = airportRepository.iata(vie.getIata());
|
|
|
|
|
RemoveResult removeResult = couchbaseTemplate.removeById().one(saved.getId());
|
|
|
|
|
assertNotNull(airport2, "airport2 should have been found");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
@@ -474,7 +554,7 @@ public class CouchbaseRepositoryQueryIntegrationTests extends ClusterAwareIntegr
|
|
|
|
|
airportRepository.saveAll(
|
|
|
|
|
Arrays.stream(iatas).map((iata) -> new Airport("airports::" + iata, iata, iata.toLowerCase(Locale.ROOT)))
|
|
|
|
|
.collect(Collectors.toSet()));
|
|
|
|
|
couchbaseTemplate.findByQuery(Airport.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
|
|
|
|
|
couchbaseTemplate.findByQuery(Airport.class).withConsistency(REQUEST_PLUS).all();
|
|
|
|
|
Long count = airportRepository.countFancyExpression(asList("JFK"), asList("jfk"), false);
|
|
|
|
|
assertEquals(1, count);
|
|
|
|
|
|
|
|
|
|
@@ -677,7 +757,7 @@ public class CouchbaseRepositoryQueryIntegrationTests extends ClusterAwareIntegr
|
|
|
|
|
void couchbaseRepositoryQuery() throws Exception {
|
|
|
|
|
User user = new User("1", "Dave", "Wilson");
|
|
|
|
|
userRepository.save(user);
|
|
|
|
|
couchbaseTemplate.findByQuery(User.class).withConsistency(QueryScanConsistency.REQUEST_PLUS)
|
|
|
|
|
couchbaseTemplate.findByQuery(User.class).withConsistency(REQUEST_PLUS)
|
|
|
|
|
.matching(QueryCriteria.where("firstname").is("Dave").and("`1`").is("`1`")).all();
|
|
|
|
|
String input = "findByFirstname";
|
|
|
|
|
Method method = UserRepository.class.getMethod(input, String.class);
|
|
|
|
|
@@ -809,4 +889,45 @@ public class CouchbaseRepositoryQueryIntegrationTests extends ClusterAwareIntegr
|
|
|
|
|
return new ValidatingCouchbaseEventListener(validator());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Configuration
|
|
|
|
|
@EnableCouchbaseRepositories("org.springframework.data.couchbase")
|
|
|
|
|
@EnableCouchbaseAuditing(auditorAwareRef = "auditorAwareRef", dateTimeProviderRef = "dateTimeProviderRef")
|
|
|
|
|
static class ConfigRequestPlus extends AbstractCouchbaseConfiguration {
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public String getConnectionString() {
|
|
|
|
|
return connectionString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public String getUserName() {
|
|
|
|
|
return config().adminUsername();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public String getPassword() {
|
|
|
|
|
return config().adminPassword();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public String getBucketName() {
|
|
|
|
|
return bucketName();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Bean(name = "auditorAwareRef")
|
|
|
|
|
public NaiveAuditorAware testAuditorAware() {
|
|
|
|
|
return new NaiveAuditorAware();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Bean(name = "dateTimeProviderRef")
|
|
|
|
|
public DateTimeProvider testDateTimeProvider() {
|
|
|
|
|
return new AuditingDateTimeProvider();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public QueryScanConsistency getDefaultConsistency() {
|
|
|
|
|
return REQUEST_PLUS;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|