DATACOUCH-596 - fix threadsafe parameters test
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
package org.springframework.data.couchbase;
|
||||
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.runners.model.InitializationError;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* This runner initializes container for the container based testing.
|
||||
*
|
||||
* @author Subhashni Balakrishnan
|
||||
*/
|
||||
public class ContainerResourceRunner extends SpringJUnit4ClassRunner {
|
||||
|
||||
@ClassRule
|
||||
public static final TestContainerResource resource = TestContainerResource.getResource();
|
||||
|
||||
public ContainerResourceRunner(Class<?> clazz) throws InitializationError {
|
||||
super(clazz);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package org.springframework.data.couchbase;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.utils.URIBuilder;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
|
||||
/**
|
||||
* Helper to check if the Couchbase http endpoints are up.
|
||||
*/
|
||||
public class CouchbaseHttpPortListeningCheck implements Callable<Boolean> {
|
||||
|
||||
private final int port;
|
||||
private final String path;
|
||||
|
||||
public CouchbaseHttpPortListeningCheck(int port, String path) {
|
||||
this.port = port;
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
private Boolean executeRequest(URIBuilder builder) throws Exception {
|
||||
try {
|
||||
HttpGet request = new HttpGet(builder.build());
|
||||
HttpClient client = HttpClientBuilder.create().build();
|
||||
HttpResponse response = client.execute(request);
|
||||
int status = response.getStatusLine().getStatusCode();
|
||||
if (status < 200 || status >= 300) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} catch (Exception ex) {
|
||||
Thread.sleep(1000);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean call() throws Exception {
|
||||
URIBuilder builder = new URIBuilder();
|
||||
builder.setScheme("http").setHost("localhost").setPort(this.port).setPath(this.path);
|
||||
return executeRequest(builder);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package org.springframework.data.couchbase;
|
||||
|
||||
import static java.time.temporal.ChronoUnit.SECONDS;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import com.couchbase.client.java.util.features.Version;
|
||||
import org.rnorth.ducttape.ratelimits.RateLimiterBuilder;
|
||||
import org.rnorth.ducttape.unreliables.Unreliables;
|
||||
import org.testcontainers.containers.Container;
|
||||
import org.testcontainers.containers.GenericContainer;
|
||||
import org.testcontainers.containers.wait.WaitStrategy;
|
||||
|
||||
/**
|
||||
* WaitStrategy for Couchbase containers which makes the Server node is initialized, RBAC user and default bucket is
|
||||
* created.
|
||||
*/
|
||||
public class CouchbaseWaitStrategy implements WaitStrategy {
|
||||
|
||||
private Duration startupTimeout = Duration.of(60, SECONDS);
|
||||
private final Boolean rbacEnabled;
|
||||
|
||||
public CouchbaseWaitStrategy(String serverVersion) {
|
||||
Version version = Version.parseVersion(serverVersion);
|
||||
rbacEnabled = version.major() >= 5;
|
||||
}
|
||||
|
||||
private void checkResult(Container.ExecResult result, String command) throws Exception {
|
||||
if (!result.getStdout().contains("SUCCESS")) {
|
||||
throw new Exception(command + " command failed");
|
||||
}
|
||||
}
|
||||
|
||||
private void checkService(int port, String path) {
|
||||
Callable<Boolean> externalCheck = new CouchbaseHttpPortListeningCheck(port, path);
|
||||
Unreliables.retryUntilSuccess((int) startupTimeout.getSeconds(), TimeUnit.SECONDS, () -> externalCheck.call());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void waitUntilReady(GenericContainer container) {
|
||||
try {
|
||||
checkService(8091, "/pools");
|
||||
Container.ExecResult result;
|
||||
|
||||
if (rbacEnabled) {
|
||||
result = container.execInContainer("/opt/couchbase/bin/couchbase-cli", "cluster-init",
|
||||
"--cluster=127.0.0.1:8091", "--services=data,index,query", "--cluster-name=localcontainer",
|
||||
"--cluster-username=Administrator", "--cluster-password=password", "--cluster-ramsize=512",
|
||||
"--cluster-index-ramsize=512", "--index-storage-setting=default");
|
||||
checkResult(result, "Cluster init");
|
||||
result = container.execInContainer("/opt/couchbase/bin/couchbase-cli", "user-manage",
|
||||
"--cluster=127.0.0.1:8091", "--username=Administrator", "--password=password", "--set",
|
||||
"--rbac-username=protected", "--rbac-password=password", "--rbac-name=default", "--roles=admin",
|
||||
"--auth-domain=local");
|
||||
checkResult(result, "User manage");
|
||||
result = container.execInContainer("/opt/couchbase/bin/couchbase-cli", "bucket-create",
|
||||
"--cluster=127.0.0.1:8091", "--username=Administrator", "--password=password", "--bucket=protected",
|
||||
"--bucket-type=couchbase", "--bucket-ramsize=200", "--enable-flush=1", "--wait");
|
||||
} else {
|
||||
result = container.execInContainer("/opt/couchbase/bin/couchbase-cli", "cluster-init",
|
||||
"--cluster=127.0.0.1:8091", "--services=data,index,query", "-u", "Administrator", "-p", "password",
|
||||
"--cluster-ramsize=512", "--cluster-index-ramsize=512", "--index-storage-setting=default");
|
||||
checkResult(result, "Cluster init");
|
||||
result = container.execInContainer("/opt/couchbase/bin/couchbase-cli", "bucket-create",
|
||||
"--cluster=127.0.0.1:8091", "-u", "Administrator", "-p", "password", "--bucket=protected",
|
||||
"--bucket-password=password", "--bucket-type=couchbase", "--bucket-ramsize=200", "--enable-flush=1",
|
||||
"--wait");
|
||||
}
|
||||
|
||||
checkResult(result, "Bucket create");
|
||||
checkService(8093, "/query/ping");
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public WaitStrategy withStartupTimeout(Duration startupTimeout) {
|
||||
this.startupTimeout = startupTimeout;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package org.springframework.data.couchbase;
|
||||
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import org.junit.rules.ExternalResource;
|
||||
import org.testcontainers.containers.FixedHostPortGenericContainer;
|
||||
|
||||
/**
|
||||
* Testcontainers as external resource. It is recommended to use it as ClassRule.
|
||||
* It also does the internal reference counting, in case if the getResource is called again.
|
||||
*
|
||||
*/
|
||||
public class TestContainerResource extends ExternalResource {
|
||||
|
||||
private static FixedHostPortGenericContainer couchbaseContainer = null;
|
||||
private static final AtomicInteger referenceCount = new AtomicInteger();
|
||||
private static TestContainerResource currentInstance;
|
||||
private static String serverVersion;
|
||||
|
||||
|
||||
public static TestContainerResource getResource() {
|
||||
if (currentInstance == null) {
|
||||
currentInstance = new TestContainerResource();
|
||||
try {
|
||||
Properties properties = new Properties();
|
||||
properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("server.properties"));
|
||||
serverVersion = properties.getProperty("server.version");
|
||||
if(!properties.getProperty("server.resource").contentEquals("container")) {
|
||||
return null;
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
serverVersion = "5.0.1";
|
||||
}
|
||||
couchbaseContainer = new FixedHostPortGenericContainer("couchbase:" + serverVersion)
|
||||
.withFixedExposedPort(8091, 8091)
|
||||
.withFixedExposedPort(18091, 18091)
|
||||
.withFixedExposedPort(8092, 8092)
|
||||
.withFixedExposedPort(18092, 18092)
|
||||
.withFixedExposedPort(8093, 8093)
|
||||
.withFixedExposedPort(18093, 18093)
|
||||
.withFixedExposedPort(8094, 8094)
|
||||
.withFixedExposedPort(18094, 18094)
|
||||
.withFixedExposedPort(11210, 11210)
|
||||
.withFixedExposedPort(11211, 11211)
|
||||
.withFixedExposedPort(11207, 11207);
|
||||
couchbaseContainer.waitingFor(new CouchbaseWaitStrategy(serverVersion));
|
||||
couchbaseContainer.start();
|
||||
}
|
||||
|
||||
return currentInstance;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void before() {
|
||||
referenceCount.incrementAndGet();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void after() {
|
||||
if (referenceCount.decrementAndGet() == 0 && couchbaseContainer != null) {
|
||||
if(couchbaseContainer.isRunning()) {
|
||||
couchbaseContainer.close();
|
||||
}
|
||||
currentInstance = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package org.springframework.data.couchbase.repo;
|
||||
|
||||
import org.springframework.data.couchbase.repository.CouchbasePagingAndSortingRepository;
|
||||
import org.springframework.data.couchbase.repository.Party;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface PartyPagingRepository extends CouchbasePagingAndSortingRepository<Party, String> {
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
/*
|
||||
* Copyright 2017-2020 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.repo;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.couchbase.core.query.*;
|
||||
import org.springframework.data.couchbase.repository.CouchbaseRepository;
|
||||
import org.springframework.data.couchbase.repository.Party;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
/**
|
||||
* @author Simon Baslé
|
||||
* @author Subhashni Balakrishnan
|
||||
*/
|
||||
@Repository
|
||||
@ViewIndexed(designDoc = "party", viewName = "all")
|
||||
@N1qlPrimaryIndexed
|
||||
@N1qlSecondaryIndexed(indexName = "party")
|
||||
public interface PartyRepository extends CouchbaseRepository<Party, String> {
|
||||
|
||||
List<Party> findByAttendeesGreaterThanEqual(int minAttendees);
|
||||
|
||||
List<Party> findByName(String name);
|
||||
|
||||
List<Party> findByEventDateIs(Date targetDate);
|
||||
|
||||
@View(designDocument = "party", viewName = "byDate")
|
||||
List<Party> findFirst3ByEventDateGreaterThanEqual(Date targetDate);
|
||||
|
||||
List<Object> findAllByDescriptionNotNull();
|
||||
|
||||
long countAllByDescriptionNotNull();
|
||||
|
||||
@Query("SELECT MAX(attendees) FROM #{#n1ql.bucket} WHERE #{#n1ql.filter}")
|
||||
long findMaxAttendees();
|
||||
|
||||
@Query("SELECT `desc` FROM #{#n1ql.bucket} WHERE #{#n1ql.filter}")
|
||||
String findSomeString();
|
||||
|
||||
@Query("SELECT count(*) + 5 FROM #{#n1ql.bucket} WHERE #{#n1ql.filter}")
|
||||
long countCustomPlusFive();
|
||||
|
||||
@Query("#{#n1ql.selectEntity} WHERE #{#n1ql.filter}")
|
||||
long countCustom();
|
||||
|
||||
@Query("SELECT 1 = 1")
|
||||
boolean justABoolean();
|
||||
|
||||
@Query("#{#n1ql.selectEntity} WHERE #{#n1ql.filter} AND `attendees` >= $1")
|
||||
Page<Party> findPartiesWithAttendee(int count, Pageable pageable);
|
||||
|
||||
@Query("#{#n1ql.selectEntity}")
|
||||
List<Party> findParties(Sort sort);
|
||||
|
||||
@Query("#{#n1ql.selectEntity} WHERE #{#n1ql.filter} AND `desc` LIKE '%' || $included || '%' AND attendees >= $min" +
|
||||
" AND `desc` NOT LIKE '%' || $excluded || '%'")
|
||||
List<Party> findAllWithNamedParams(@Param("excluded") String ex, @Param("included") String inc,
|
||||
@Param("min") long minimumAttendees);
|
||||
|
||||
@Query("#{#n1ql.selectEntity} WHERE #{#n1ql.filter} AND `desc` LIKE '%' || $2 || '%' AND attendees >= $3" +
|
||||
" AND `desc` NOT LIKE '%' || $1 || '%'")
|
||||
List<Party> findAllWithPositionalParams(String ex, String inc, long minimumAttendees);
|
||||
|
||||
@Query("#{#n1ql.delete} WHERE #{#n1ql.filter} AND `desc` LIKE '%' || $2 || '%' AND attendees < $3" +
|
||||
" AND `desc` NOT LIKE '%' || $1 || '%' #{#n1ql.returning}")
|
||||
List<Party> removeWithPositionalParams(String ex, String inc, long minimumAttendees);
|
||||
|
||||
@Query("#{#n1ql.selectEntity} WHERE #{#n1ql.filter} AND `desc` LIKE '%' || $2 || '%' AND attendees >= $3" +
|
||||
" AND `desc` NOT LIKE '%' || $1 || '%' AND `desc` != \"this is \\\"$excluded\\\"\"")
|
||||
List<Party> findAllWithPositionalParamsAndQuotedNamedParams(@Param("excluded") String ex,
|
||||
@Param("included") String inc, @Param("min") long min);
|
||||
|
||||
List<Party> findByDescriptionOrName(String description, String name);
|
||||
|
||||
List<Party> removeByDescriptionOrName(String description, String name);
|
||||
|
||||
@Query("#{#n1ql.selectEntity} where #{#n1ql.filter} and eventDate = $1")
|
||||
List<Party> getByEventDate(Date eventDate);
|
||||
|
||||
List<Party> findByDescriptionStartingWith(String description);
|
||||
}
|
||||
@@ -1,13 +1,10 @@
|
||||
package org.springframework.data.couchbase.repo;
|
||||
package org.springframework.data.couchbase.repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.couchbase.core.query.N1qlPrimaryIndexed;
|
||||
import org.springframework.data.couchbase.repository.Item;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
@N1qlPrimaryIndexed
|
||||
public interface ItemRepository extends CrudRepository<Item, String> {
|
||||
|
||||
@@ -25,67 +25,57 @@ import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.DataRetrievalFailureException;
|
||||
//import org.springframework.data.couchbase.ContainerResourceRunner;
|
||||
|
||||
import org.springframework.data.couchbase.ContainerResourceRunner;
|
||||
import org.springframework.data.couchbase.IntegrationTestApplicationConfig;
|
||||
import org.springframework.data.couchbase.repository.config.EnableCouchbaseRepositories;
|
||||
// must not be in same package as CouchbaseRepository, otherwise AutoWired will fail on couchbaseRepository
|
||||
import org.springframework.data.couchbase.repo.ItemRepository;
|
||||
import org.springframework.data.couchbase.repo.PartyRepository;
|
||||
import org.springframework.data.couchbase.repo.PartyPagingRepository;
|
||||
import org.springframework.data.couchbase.repository.config.RepositoryOperationsMapping;
|
||||
import org.springframework.data.couchbase.repository.support.CouchbaseRepositoryFactory;
|
||||
import org.springframework.data.couchbase.repository.support.IndexManager;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.mapping.model.MappingInstantiationException;
|
||||
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.TestExecutionListeners;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.*;
|
||||
|
||||
/**
|
||||
* This has been copied from 3.2.x for testing backport of fix in DATACOUCH-484
|
||||
* This and dependent class have been copied from src/integration to src/test
|
||||
* and the repository classes have been moved from org.springframework.data.couchbase.repository
|
||||
* to org.springframework.data.couchbase.repo so that
|
||||
* org.springframework.data.couchbase.repository.CouchbaseRepository is not instantiated by
|
||||
* @Autowired
|
||||
*
|
||||
* This tests PaginAndSortingRepository features in the Couchbase connector.
|
||||
*
|
||||
* @author Simon Baslé
|
||||
* @author Subhashni Balakrishnan
|
||||
* @author Michael Reiche
|
||||
*/
|
||||
// @RunWith(ContainerResourceRunner.class)
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@RunWith(ContainerResourceRunner.class)
|
||||
@ContextConfiguration(classes = IntegrationTestApplicationConfig.class)
|
||||
@SpringJUnitConfig(IntegrationTestApplicationConfig.class)
|
||||
@TestExecutionListeners(PartyPopulatorListener.class)
|
||||
@EnableCouchbaseRepositories
|
||||
public class N1qlCouchbaseRepositoryIntegrationTests {
|
||||
public class N1qlCouchbaseRepositoryTests {
|
||||
|
||||
@Autowired private PartyPagingRepository repository;
|
||||
@Autowired private RepositoryOperationsMapping operationsMapping;
|
||||
|
||||
@Autowired private PartyRepository partyRepository;
|
||||
@Autowired private IndexManager indexManager;
|
||||
|
||||
@Autowired private ItemRepository itemRepository;
|
||||
private PartyPagingRepository repository;
|
||||
|
||||
private PartyRepository partyRepository;
|
||||
|
||||
private ItemRepository itemRepository;
|
||||
|
||||
private final String KEY_PARTY = "Party1";
|
||||
private final String KEY_ITEM = "Item1";
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
RepositoryFactorySupport factory = new CouchbaseRepositoryFactory(operationsMapping, indexManager);
|
||||
repository = factory.getRepository(PartyPagingRepository.class);
|
||||
partyRepository = factory.getRepository(PartyRepository.class);
|
||||
itemRepository = factory.getRepository(ItemRepository.class);
|
||||
partyRepository.save(new Party(KEY_PARTY, "partyName", "MatchingDescription", null, 1, null));
|
||||
itemRepository.save(new Item(KEY_ITEM, "MatchingDescription"));
|
||||
}
|
||||
@@ -144,7 +134,7 @@ public class N1qlCouchbaseRepositoryIntegrationTests {
|
||||
|
||||
@Test
|
||||
public void shouldFindAllWithSort() {
|
||||
Iterable<Party> allByAttendanceDesc = repository.findAll(Sort.by(Sort.Direction.DESC, "attendees"));
|
||||
Iterable<Party> allByAttendanceDesc = repository.findAll(new Sort(Sort.Direction.DESC, "attendees"));
|
||||
long previousAttendance = Long.MAX_VALUE;
|
||||
for (Party party : allByAttendanceDesc) {
|
||||
assertTrue(party.getAttendees() <= previousAttendance);
|
||||
@@ -155,7 +145,7 @@ public class N1qlCouchbaseRepositoryIntegrationTests {
|
||||
|
||||
@Test
|
||||
public void shouldSortOnRenamedFieldIfJsonNameIsProvidedInSort() {
|
||||
Iterable<Party> parties = repository.findAll(Sort.by(Sort.Direction.DESC, "desc"));
|
||||
Iterable<Party> parties = repository.findAll(new Sort(Sort.Direction.DESC, "desc"));
|
||||
String previousDesc = null;
|
||||
for (Party party : parties) {
|
||||
if (previousDesc != null) {
|
||||
@@ -168,7 +158,7 @@ public class N1qlCouchbaseRepositoryIntegrationTests {
|
||||
|
||||
@Test
|
||||
public void shouldSortWithoutCaseSensitivity() {
|
||||
Iterable<Party> parties = repository.findAll(Sort.by(new Sort.Order(Sort.Direction.DESC, "desc").ignoreCase()));
|
||||
Iterable<Party> parties = repository.findAll(new Sort(new Sort.Order(Sort.Direction.DESC, "desc").ignoreCase()));
|
||||
String previousDesc = null;
|
||||
for (Party party : parties) {
|
||||
if (previousDesc != null) {
|
||||
@@ -181,7 +171,7 @@ public class N1qlCouchbaseRepositoryIntegrationTests {
|
||||
|
||||
@Test
|
||||
public void shouldPageThroughEntities() {
|
||||
Pageable pageable = PageRequest.of(0, 8);
|
||||
Pageable pageable = new PageRequest(0, 8);
|
||||
|
||||
Page<Party> page1 = repository.findAll(pageable);
|
||||
assertTrue("Query for parties should be atleast 12", page1.getTotalElements() >= 12);
|
||||
@@ -190,7 +180,7 @@ public class N1qlCouchbaseRepositoryIntegrationTests {
|
||||
|
||||
@Test
|
||||
public void shouldPageThroughSortedEntities() {
|
||||
Pageable pageable = PageRequest.of(0, 8, Sort.Direction.DESC, "attendees");
|
||||
Pageable pageable = new PageRequest(0, 8, Sort.Direction.DESC, "attendees");
|
||||
|
||||
Page<Party> page1 = repository.findAll(pageable);
|
||||
assertTrue("Query for parties should be atleast 12", page1.getTotalElements() >= 12);
|
||||
@@ -214,7 +204,7 @@ public class N1qlCouchbaseRepositoryIntegrationTests {
|
||||
|
||||
@Test
|
||||
public void shouldPageWithStringBasedQuery() {
|
||||
Pageable pageable = PageRequest.of(0, 8, Sort.Direction.DESC, "attendees");
|
||||
Pageable pageable = new PageRequest(0, 8, Sort.Direction.DESC, "attendees");
|
||||
Page<Party> page1 = partyRepository.findPartiesWithAttendee(1, pageable);
|
||||
assertTrue("Query for parties with attendees should be atleast 12", page1.getTotalElements() >= 12);
|
||||
assertEquals(8, page1.getNumberOfElements());
|
||||
@@ -241,7 +231,7 @@ public class N1qlCouchbaseRepositoryIntegrationTests {
|
||||
// Fails on deserialization as a different entity item is also present
|
||||
@Test(expected = MappingInstantiationException.class)
|
||||
public void shouldFailWithMissingFilterStringBasedQuery() {
|
||||
Sort sort = Sort.by(Sort.Direction.DESC, "attendees");
|
||||
Sort sort = new Sort(Sort.Direction.DESC, "attendees");
|
||||
partyRepository.findParties(sort);
|
||||
}
|
||||
|
||||
@@ -273,5 +263,4 @@ public class N1qlCouchbaseRepositoryIntegrationTests {
|
||||
List<Party> partyList = partyRepository.findByDescriptionStartingWith(description);
|
||||
assertTrue(partyList.size() == 0);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package org.springframework.data.couchbase.repository;
|
||||
|
||||
public interface PartyPagingRepository extends CouchbasePagingAndSortingRepository<Party, String> {
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright 2017-2020 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.repository;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.couchbase.core.query.N1qlPrimaryIndexed;
|
||||
import org.springframework.data.couchbase.core.query.N1qlSecondaryIndexed;
|
||||
import org.springframework.data.couchbase.core.query.Query;
|
||||
import org.springframework.data.couchbase.core.query.View;
|
||||
import org.springframework.data.couchbase.core.query.ViewIndexed;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
|
||||
/**
|
||||
* @author Simon Baslé
|
||||
* @author Subhashni Balakrishnan
|
||||
*/
|
||||
@ViewIndexed(designDoc = "party", viewName = "all")
|
||||
@N1qlPrimaryIndexed
|
||||
@N1qlSecondaryIndexed(indexName = "party")
|
||||
public interface PartyRepository extends CouchbaseRepository<Party, String> {
|
||||
|
||||
List<Party> findByAttendeesGreaterThanEqual(int minAttendees);
|
||||
|
||||
List<Party> findByEventDateIs(Date targetDate);
|
||||
|
||||
List<Party> findByName(String name);
|
||||
|
||||
@View(designDocument = "party", viewName = "byDate")
|
||||
List<Party> findFirst3ByEventDateGreaterThanEqual(Date targetDate);
|
||||
|
||||
List<Object> findAllByDescriptionNotNull();
|
||||
|
||||
long countAllByDescriptionNotNull();
|
||||
|
||||
@Query("SELECT MAX(attendees) FROM #{#n1ql.bucket} WHERE #{#n1ql.filter}")
|
||||
long findMaxAttendees();
|
||||
|
||||
@Query("SELECT `desc` FROM #{#n1ql.bucket} WHERE #{#n1ql.filter}")
|
||||
String findSomeString();
|
||||
|
||||
@Query("SELECT count(*) + 5 FROM #{#n1ql.bucket} WHERE #{#n1ql.filter}")
|
||||
long countCustomPlusFive();
|
||||
|
||||
@Query("#{#n1ql.selectEntity} WHERE #{#n1ql.filter}")
|
||||
long countCustom();
|
||||
|
||||
@Query("SELECT 1 = 1")
|
||||
boolean justABoolean();
|
||||
|
||||
@Query("#{#n1ql.selectEntity} WHERE #{#n1ql.filter} AND `attendees` >= $1")
|
||||
Page<Party> findPartiesWithAttendee(int count, Pageable pageable);
|
||||
|
||||
@Query("#{#n1ql.selectEntity}")
|
||||
List<Party> findParties(Sort sort);
|
||||
|
||||
@Query("#{#n1ql.selectEntity} WHERE #{#n1ql.filter} AND `desc` LIKE '%' || $included || '%' AND attendees >= $min"
|
||||
+ " AND `desc` NOT LIKE '%' || $excluded || '%'")
|
||||
List<Party> findAllWithNamedParams(@Param("excluded") String ex, @Param("included") String inc,
|
||||
@Param("min") long minimumAttendees);
|
||||
|
||||
@Query("#{#n1ql.selectEntity} WHERE #{#n1ql.filter} AND `desc` LIKE '%' || $2 || '%' AND attendees >= $3"
|
||||
+ " AND `desc` NOT LIKE '%' || $1 || '%'")
|
||||
List<Party> findAllWithPositionalParams(String ex, String inc, long minimumAttendees);
|
||||
|
||||
@Query("#{#n1ql.delete} WHERE #{#n1ql.filter} AND `desc` LIKE '%' || $2 || '%' AND attendees < $3"
|
||||
+ " AND `desc` NOT LIKE '%' || $1 || '%' #{#n1ql.returning}")
|
||||
List<Party> removeWithPositionalParams(String ex, String inc, long minimumAttendees);
|
||||
|
||||
@Query("#{#n1ql.selectEntity} WHERE #{#n1ql.filter} AND `desc` LIKE '%' || $2 || '%' AND attendees >= $3"
|
||||
+ " AND `desc` NOT LIKE '%' || $1 || '%' AND `desc` != \"this is \\\"$excluded\\\"\"")
|
||||
List<Party> findAllWithPositionalParamsAndQuotedNamedParams(@Param("excluded") String ex,
|
||||
@Param("included") String inc, @Param("min") long min);
|
||||
|
||||
List<Party> findByDescriptionOrName(String description, String name);
|
||||
|
||||
List<Party> removeByDescriptionOrName(String description, String name);
|
||||
|
||||
@Query("#{#n1ql.selectEntity} where #{#n1ql.filter} and eventDate = $1")
|
||||
List<Party> getByEventDate(Date eventDate);
|
||||
|
||||
List<Party> findByDescriptionStartingWith(String description);
|
||||
}
|
||||
Reference in New Issue
Block a user