DATACOUCH-504 - Reintroduce query index generation

This changeset reintroduces automatic n1ql index generation but through
new annotations: QueryIndexed and CompositeQueryIndex (as well as
CompositeQueryIndexes to supply more than one). They are translated
into create index statements and executed at startup if configured
in the config.

Note that automatic index management is disabled by default but can
be overidden with a simple flag on the config override. More features
to come later.
This commit is contained in:
Michael Nitschinger
2020-03-10 15:04:40 +01:00
parent fff16bc958
commit f950e4648a
15 changed files with 737 additions and 1 deletions

View File

@@ -0,0 +1,31 @@
package org.springframework.data.couchbase.domain;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.PersistenceConstructor;
import org.springframework.data.couchbase.core.index.CompositeQueryIndex;
import org.springframework.data.couchbase.core.index.QueryIndexed;
import org.springframework.data.couchbase.core.mapping.Document;
@Document
@CompositeQueryIndex(fields = {"id", "name desc"})
public class Airline {
@Id
String id;
@QueryIndexed
String name;
@PersistenceConstructor
public Airline(String id, String name) {
this.id = id;
}
public String getId() {
return id;
}
public String getName() {
return name;
}
}

View File

@@ -0,0 +1,25 @@
/*
* Copyright 2017-2019 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.repository.PagingAndSortingRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface AirlineRepository extends PagingAndSortingRepository<Airline, String> {
}

View File

@@ -0,0 +1,103 @@
/*
* Copyright 2017-2019 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 com.couchbase.client.java.Cluster;
import com.couchbase.client.java.manager.query.QueryIndex;
import org.junit.jupiter.api.Test;
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.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.test.context.junit.jupiter.SpringJUnitConfig;
import java.util.Optional;
import static org.junit.jupiter.api.Assertions.*;
@SpringJUnitConfig(CouchbaseRepositoryAutoQueryIndexIntegrationTests.Config.class)
@IgnoreWhen(missesCapabilities = Capabilities.QUERY, clusterTypes = ClusterType.MOCKED)
public class CouchbaseRepositoryAutoQueryIndexIntegrationTests extends ClusterAwareIntegrationTests {
@Autowired
private Cluster cluster;
/**
* Since the index creation happens at startup, the only way to properly check is by querying the
* index list and making sure it is present.
*/
@Test
void createsSingleFieldIndex() {
Optional<QueryIndex> foundIndex = cluster
.queryIndexes()
.getAllIndexes(bucketName())
.stream()
.filter(i -> i.name().equals("idx_airline_name"))
.findFirst();
assertTrue(foundIndex.isPresent());
assertTrue(foundIndex.get().condition().get().contains("_class"));
}
@Test
void createsCompositeIndex() {
Optional<QueryIndex> foundIndex = cluster
.queryIndexes()
.getAllIndexes(bucketName())
.stream()
.filter(i -> i.name().equals("idx_airline_id_name"))
.findFirst();
assertTrue(foundIndex.isPresent());
assertTrue(foundIndex.get().condition().get().contains("_class"));
}
@Configuration
@EnableCouchbaseRepositories("org.springframework.data.couchbase")
static class Config 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();
}
@Override
protected boolean autoIndexCreation() {
return true;
}
}
}

View File

@@ -31,12 +31,16 @@ import org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration;
import org.springframework.data.couchbase.domain.Airport;
import org.springframework.data.couchbase.domain.AirportRepository;
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.test.context.junit.jupiter.SpringJUnitConfig;
import com.couchbase.client.core.error.IndexExistsException;
@SpringJUnitConfig(CouchbaseRepositoryQueryIntegrationTests.Config.class)
@IgnoreWhen(missesCapabilities = Capabilities.QUERY, clusterTypes = ClusterType.MOCKED)
public class CouchbaseRepositoryQueryIntegrationTests extends ClusterAwareIntegrationTests {
@Autowired CouchbaseClientFactory clientFactory;