DATACOUCH-504 - Apply eclipse formatting rules.
This commit is contained in:
@@ -16,20 +16,20 @@
|
||||
|
||||
package org.springframework.data.couchbase;
|
||||
|
||||
import com.couchbase.client.core.env.OwnedSupplier;
|
||||
import com.couchbase.client.java.env.ClusterEnvironment;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.springframework.dao.support.PersistenceExceptionTranslator;
|
||||
import org.springframework.data.couchbase.core.CouchbaseExceptionTranslator;
|
||||
|
||||
import com.couchbase.client.core.env.Authenticator;
|
||||
import com.couchbase.client.core.env.OwnedSupplier;
|
||||
import com.couchbase.client.core.io.CollectionIdentifier;
|
||||
import com.couchbase.client.java.Bucket;
|
||||
import com.couchbase.client.java.Cluster;
|
||||
import com.couchbase.client.java.ClusterOptions;
|
||||
import com.couchbase.client.java.Collection;
|
||||
import com.couchbase.client.java.Scope;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
import com.couchbase.client.java.env.ClusterEnvironment;
|
||||
|
||||
public class SimpleCouchbaseClientFactory implements CouchbaseClientFactory {
|
||||
|
||||
@@ -45,19 +45,24 @@ public class SimpleCouchbaseClientFactory implements CouchbaseClientFactory {
|
||||
|
||||
public SimpleCouchbaseClientFactory(final String connectionString, final Authenticator authenticator,
|
||||
final String bucketName, final String scopeName) {
|
||||
this(new OwnedSupplier<>(Cluster.connect(connectionString, ClusterOptions.clusterOptions(authenticator))), bucketName, scopeName);
|
||||
this(new OwnedSupplier<>(Cluster.connect(connectionString, ClusterOptions.clusterOptions(authenticator))),
|
||||
bucketName, scopeName);
|
||||
}
|
||||
|
||||
public SimpleCouchbaseClientFactory(final String connectionString, final Authenticator authenticator,
|
||||
final String bucketName, final String scopeName, final ClusterEnvironment environment) {
|
||||
this(new OwnedSupplier<>(Cluster.connect(connectionString, ClusterOptions.clusterOptions(authenticator).environment(environment))), bucketName, scopeName);
|
||||
final String bucketName, final String scopeName, final ClusterEnvironment environment) {
|
||||
this(
|
||||
new OwnedSupplier<>(
|
||||
Cluster.connect(connectionString, ClusterOptions.clusterOptions(authenticator).environment(environment))),
|
||||
bucketName, scopeName);
|
||||
}
|
||||
|
||||
public SimpleCouchbaseClientFactory(final Cluster cluster, final String bucketName, final String scopeName) {
|
||||
this(() -> cluster, bucketName, scopeName);
|
||||
}
|
||||
|
||||
private SimpleCouchbaseClientFactory(final Supplier<Cluster> cluster, final String bucketName, final String scopeName) {
|
||||
private SimpleCouchbaseClientFactory(final Supplier<Cluster> cluster, final String bucketName,
|
||||
final String scopeName) {
|
||||
this.cluster = cluster;
|
||||
this.bucket = cluster.get().bucket(bucketName);
|
||||
this.scope = scopeName == null ? bucket.defaultScope() : bucket.scope(scopeName);
|
||||
|
||||
@@ -48,9 +48,9 @@ public class CouchbaseCacheManager extends AbstractTransactionSupportingCacheMan
|
||||
* @param allowInFlightCacheCreation allow create unconfigured caches.
|
||||
*/
|
||||
private CouchbaseCacheManager(final CouchbaseCacheWriter cacheWriter,
|
||||
final CouchbaseCacheConfiguration defaultCacheConfiguration,
|
||||
final Map<String, CouchbaseCacheConfiguration> initialCacheConfiguration,
|
||||
final boolean allowInFlightCacheCreation) {
|
||||
final CouchbaseCacheConfiguration defaultCacheConfiguration,
|
||||
final Map<String, CouchbaseCacheConfiguration> initialCacheConfiguration,
|
||||
final boolean allowInFlightCacheCreation) {
|
||||
|
||||
Assert.notNull(cacheWriter, "CacheWriter must not be null!");
|
||||
Assert.notNull(defaultCacheConfiguration, "DefaultCacheConfiguration must not be null!");
|
||||
@@ -70,7 +70,7 @@ public class CouchbaseCacheManager extends AbstractTransactionSupportingCacheMan
|
||||
public static CouchbaseCacheManager create(CouchbaseClientFactory clientFactory) {
|
||||
Assert.notNull(clientFactory, "ConnectionFactory must not be null!");
|
||||
return new CouchbaseCacheManager(new DefaultCouchbaseCacheWriter(clientFactory),
|
||||
CouchbaseCacheConfiguration.defaultCacheConfig(), new LinkedHashMap<>(), true);
|
||||
CouchbaseCacheConfiguration.defaultCacheConfig(), new LinkedHashMap<>(), true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -126,10 +126,10 @@ public class CouchbaseCacheManager extends AbstractTransactionSupportingCacheMan
|
||||
public static class CouchbaseCacheManagerBuilder {
|
||||
|
||||
private final CouchbaseCacheWriter cacheWriter;
|
||||
private CouchbaseCacheConfiguration defaultCacheConfiguration = CouchbaseCacheConfiguration.defaultCacheConfig();
|
||||
private final Map<String, CouchbaseCacheConfiguration> initialCaches = new LinkedHashMap<>();
|
||||
private boolean enableTransactions;
|
||||
boolean allowInFlightCacheCreation = true;
|
||||
private CouchbaseCacheConfiguration defaultCacheConfiguration = CouchbaseCacheConfiguration.defaultCacheConfig();
|
||||
private boolean enableTransactions;
|
||||
|
||||
private CouchbaseCacheManagerBuilder(CouchbaseCacheWriter cacheWriter) {
|
||||
this.cacheWriter = cacheWriter;
|
||||
@@ -170,7 +170,8 @@ public class CouchbaseCacheManager extends AbstractTransactionSupportingCacheMan
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable {@link CouchbaseCache}s to synchronize cache put/evict operations with ongoing Spring-managed transactions.
|
||||
* Enable {@link CouchbaseCache}s to synchronize cache put/evict operations with ongoing Spring-managed
|
||||
* transactions.
|
||||
*
|
||||
* @return this {@link CouchbaseCacheManagerBuilder}.
|
||||
*/
|
||||
@@ -200,11 +201,11 @@ public class CouchbaseCacheManager extends AbstractTransactionSupportingCacheMan
|
||||
* @return this {@link CouchbaseCacheManagerBuilder}.
|
||||
*/
|
||||
public CouchbaseCacheManagerBuilder withInitialCacheConfigurations(
|
||||
Map<String, CouchbaseCacheConfiguration> cacheConfigurations) {
|
||||
Map<String, CouchbaseCacheConfiguration> cacheConfigurations) {
|
||||
|
||||
Assert.notNull(cacheConfigurations, "CacheConfigurations must not be null!");
|
||||
cacheConfigurations.forEach((cacheName, configuration) -> Assert.notNull(configuration,
|
||||
String.format("CouchbaseCacheConfiguration for cache %s must not be null!", cacheName)));
|
||||
String.format("CouchbaseCacheConfiguration for cache %s must not be null!", cacheName)));
|
||||
|
||||
this.initialCaches.putAll(cacheConfigurations);
|
||||
return this;
|
||||
@@ -216,7 +217,7 @@ public class CouchbaseCacheManager extends AbstractTransactionSupportingCacheMan
|
||||
* @return this {@link CouchbaseCacheManagerBuilder}.
|
||||
*/
|
||||
public CouchbaseCacheManagerBuilder withCacheConfiguration(String cacheName,
|
||||
CouchbaseCacheConfiguration cacheConfiguration) {
|
||||
CouchbaseCacheConfiguration cacheConfiguration) {
|
||||
|
||||
Assert.notNull(cacheName, "CacheName must not be null!");
|
||||
Assert.notNull(cacheConfiguration, "CacheConfiguration must not be null!");
|
||||
@@ -267,7 +268,7 @@ public class CouchbaseCacheManager extends AbstractTransactionSupportingCacheMan
|
||||
*/
|
||||
public CouchbaseCacheManager build() {
|
||||
CouchbaseCacheManager cm = new CouchbaseCacheManager(cacheWriter, defaultCacheConfiguration, initialCaches,
|
||||
allowInFlightCacheCreation);
|
||||
allowInFlightCacheCreation);
|
||||
cm.setTransactionAware(enableTransactions);
|
||||
return cm;
|
||||
}
|
||||
|
||||
@@ -16,11 +16,12 @@
|
||||
|
||||
package org.springframework.data.couchbase.config;
|
||||
|
||||
import static com.couchbase.client.java.ClusterOptions.*;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import com.couchbase.client.java.Cluster;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
|
||||
@@ -49,11 +50,10 @@ import org.springframework.util.StringUtils;
|
||||
import com.couchbase.client.core.deps.com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.couchbase.client.core.env.Authenticator;
|
||||
import com.couchbase.client.core.env.PasswordAuthenticator;
|
||||
import com.couchbase.client.java.Cluster;
|
||||
import com.couchbase.client.java.env.ClusterEnvironment;
|
||||
import com.couchbase.client.java.json.JacksonTransformers;
|
||||
|
||||
import static com.couchbase.client.java.ClusterOptions.*;
|
||||
|
||||
/**
|
||||
* Base class for Spring Data Couchbase configuration using JavaConfig.
|
||||
*
|
||||
@@ -88,10 +88,8 @@ public abstract class AbstractCouchbaseConfiguration {
|
||||
|
||||
@Bean(destroyMethod = "disconnect")
|
||||
public Cluster couchbaseCluster(ClusterEnvironment couchbaseClusterEnvironment) {
|
||||
return Cluster.connect(
|
||||
getConnectionString(),
|
||||
clusterOptions(authenticator()).environment(couchbaseClusterEnvironment)
|
||||
);
|
||||
return Cluster.connect(getConnectionString(),
|
||||
clusterOptions(authenticator()).environment(couchbaseClusterEnvironment));
|
||||
}
|
||||
|
||||
@Bean(destroyMethod = "shutdown")
|
||||
@@ -107,13 +105,13 @@ public abstract class AbstractCouchbaseConfiguration {
|
||||
|
||||
@Bean(name = BeanNames.COUCHBASE_TEMPLATE)
|
||||
public CouchbaseTemplate couchbaseTemplate(CouchbaseClientFactory couchbaseClientFactory,
|
||||
MappingCouchbaseConverter mappingCouchbaseConverter) {
|
||||
MappingCouchbaseConverter mappingCouchbaseConverter) {
|
||||
return new CouchbaseTemplate(couchbaseClientFactory, mappingCouchbaseConverter);
|
||||
}
|
||||
|
||||
@Bean(name = BeanNames.REACTIVE_COUCHBASE_TEMPLATE)
|
||||
public ReactiveCouchbaseTemplate reactiveCouchbaseTemplate(CouchbaseClientFactory couchbaseClientFactory,
|
||||
MappingCouchbaseConverter mappingCouchbaseConverter) {
|
||||
MappingCouchbaseConverter mappingCouchbaseConverter) {
|
||||
return new ReactiveCouchbaseTemplate(couchbaseClientFactory, mappingCouchbaseConverter);
|
||||
}
|
||||
|
||||
@@ -137,9 +135,11 @@ public abstract class AbstractCouchbaseConfiguration {
|
||||
}
|
||||
|
||||
@Bean(name = BeanNames.REACTIVE_COUCHBASE_OPERATIONS_MAPPING)
|
||||
public ReactiveRepositoryOperationsMapping reactiveCouchbaseRepositoryOperationsMapping(ReactiveCouchbaseTemplate reactiveCouchbaseTemplate) {
|
||||
public ReactiveRepositoryOperationsMapping reactiveCouchbaseRepositoryOperationsMapping(
|
||||
ReactiveCouchbaseTemplate reactiveCouchbaseTemplate) {
|
||||
// create a base mapping that associates all repositories to the default template
|
||||
ReactiveRepositoryOperationsMapping baseMapping = new ReactiveRepositoryOperationsMapping(reactiveCouchbaseTemplate);
|
||||
ReactiveRepositoryOperationsMapping baseMapping = new ReactiveRepositoryOperationsMapping(
|
||||
reactiveCouchbaseTemplate);
|
||||
// let the user tune it
|
||||
configureReactiveRepositoryOperationsMapping(baseMapping);
|
||||
return baseMapping;
|
||||
@@ -179,8 +179,8 @@ public abstract class AbstractCouchbaseConfiguration {
|
||||
|
||||
/**
|
||||
* Determines the name of the field that will store the type information for complex types when using the
|
||||
* {@link #mappingCouchbaseConverter(CouchbaseMappingContext, CouchbaseCustomConversions)}. Defaults
|
||||
* to {@value MappingCouchbaseConverter#TYPEKEY_DEFAULT}.
|
||||
* {@link #mappingCouchbaseConverter(CouchbaseMappingContext, CouchbaseCustomConversions)}. Defaults to
|
||||
* {@value MappingCouchbaseConverter#TYPEKEY_DEFAULT}.
|
||||
*
|
||||
* @see MappingCouchbaseConverter#TYPEKEY_DEFAULT
|
||||
* @see MappingCouchbaseConverter#TYPEKEY_SYNCGATEWAY_COMPATIBLE
|
||||
@@ -196,7 +196,7 @@ public abstract class AbstractCouchbaseConfiguration {
|
||||
*/
|
||||
@Bean
|
||||
public MappingCouchbaseConverter mappingCouchbaseConverter(CouchbaseMappingContext couchbaseMappingContext,
|
||||
CouchbaseCustomConversions couchbaseCustomConversions) {
|
||||
CouchbaseCustomConversions couchbaseCustomConversions) {
|
||||
MappingCouchbaseConverter converter = new MappingCouchbaseConverter(couchbaseMappingContext, typeKey());
|
||||
converter.setCustomConversions(couchbaseCustomConversions);
|
||||
return converter;
|
||||
@@ -234,8 +234,7 @@ public abstract class AbstractCouchbaseConfiguration {
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure whether to automatically create indices for domain types by deriving the
|
||||
* from the entity or not.
|
||||
* Configure whether to automatically create indices for domain types by deriving the from the entity or not.
|
||||
*/
|
||||
protected boolean autoIndexCreation() {
|
||||
return false;
|
||||
|
||||
@@ -16,12 +16,6 @@
|
||||
|
||||
package org.springframework.data.couchbase.config;
|
||||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.data.couchbase.CouchbaseClientFactory;
|
||||
import org.springframework.data.couchbase.core.CouchbaseOperations;
|
||||
import org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter;
|
||||
import org.springframework.data.couchbase.core.convert.translation.TranslationService;
|
||||
|
||||
/**
|
||||
* Contains default bean names for Couchbase beans. These are the names of the beans used by Spring Data Couchbase,
|
||||
* unless an explicit id is given to the bean either in the xml configuration or the
|
||||
|
||||
@@ -24,8 +24,6 @@ import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.support.PersistenceExceptionTranslator;
|
||||
import org.springframework.data.couchbase.CouchbaseClientFactory;
|
||||
import org.springframework.data.couchbase.core.convert.CouchbaseConverter;
|
||||
|
||||
import com.couchbase.client.java.Collection;
|
||||
import org.springframework.data.couchbase.core.index.CouchbasePersistentEntityIndexCreator;
|
||||
import org.springframework.data.couchbase.core.mapping.CouchbaseMappingContext;
|
||||
import org.springframework.data.couchbase.core.mapping.CouchbasePersistentEntity;
|
||||
@@ -33,6 +31,8 @@ import org.springframework.data.couchbase.core.mapping.CouchbasePersistentProper
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
import com.couchbase.client.java.Collection;
|
||||
|
||||
public class CouchbaseTemplate implements CouchbaseOperations, ApplicationContextAware {
|
||||
|
||||
private final CouchbaseClientFactory clientFactory;
|
||||
@@ -43,7 +43,6 @@ public class CouchbaseTemplate implements CouchbaseOperations, ApplicationContex
|
||||
private final ReactiveCouchbaseTemplate reactiveCouchbaseTemplate;
|
||||
private @Nullable CouchbasePersistentEntityIndexCreator indexCreator;
|
||||
|
||||
|
||||
public CouchbaseTemplate(final CouchbaseClientFactory clientFactory, final CouchbaseConverter converter) {
|
||||
this.clientFactory = clientFactory;
|
||||
this.converter = converter;
|
||||
@@ -168,7 +167,8 @@ public class CouchbaseTemplate implements CouchbaseOperations, ApplicationContex
|
||||
String[] indexCreators = context.getBeanNamesForType(CouchbasePersistentEntityIndexCreator.class);
|
||||
|
||||
for (String creator : indexCreators) {
|
||||
CouchbasePersistentEntityIndexCreator creatorBean = context.getBean(creator, CouchbasePersistentEntityIndexCreator.class);
|
||||
CouchbasePersistentEntityIndexCreator creatorBean = context.getBean(creator,
|
||||
CouchbasePersistentEntityIndexCreator.class);
|
||||
if (creatorBean.isIndexCreatorFor(mappingContext)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
*/
|
||||
package org.springframework.data.couchbase.core;
|
||||
|
||||
import org.springframework.data.couchbase.core.query.QueryCriteria;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.data.couchbase.core.query.Query;
|
||||
import org.springframework.data.couchbase.core.query.QueryCriteria;
|
||||
|
||||
import com.couchbase.client.java.query.QueryOptions;
|
||||
import com.couchbase.client.java.query.QueryScanConsistency;
|
||||
|
||||
@@ -15,26 +15,24 @@
|
||||
*/
|
||||
package org.springframework.data.couchbase.core.index;
|
||||
|
||||
import com.couchbase.client.core.error.IndexExistsException;
|
||||
import com.couchbase.client.java.Cluster;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.data.couchbase.core.CouchbaseOperations;
|
||||
import org.springframework.data.couchbase.core.index.CouchbasePersistentEntityIndexResolver.IndexDefinitionHolder;
|
||||
import org.springframework.data.couchbase.core.mapping.CouchbaseMappingContext;
|
||||
import org.springframework.data.couchbase.core.mapping.CouchbasePersistentEntity;
|
||||
import org.springframework.data.couchbase.core.mapping.Document;
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mapping.context.MappingContextEvent;
|
||||
import org.springframework.data.couchbase.core.index.CouchbasePersistentEntityIndexResolver.IndexDefinitionHolder;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Collectors;
|
||||
import com.couchbase.client.core.error.IndexExistsException;
|
||||
import com.couchbase.client.java.Cluster;
|
||||
|
||||
public class CouchbasePersistentEntityIndexCreator implements ApplicationListener<MappingContextEvent<?, ?>> {
|
||||
|
||||
@@ -46,7 +44,7 @@ public class CouchbasePersistentEntityIndexCreator implements ApplicationListene
|
||||
private final CouchbaseOperations couchbaseOperations;
|
||||
|
||||
public CouchbasePersistentEntityIndexCreator(final CouchbaseMappingContext mappingContext,
|
||||
final CouchbaseOperations operations) {
|
||||
final CouchbaseOperations operations) {
|
||||
this.mappingContext = mappingContext;
|
||||
this.couchbaseOperations = operations;
|
||||
this.indexResolver = QueryIndexResolver.create(mappingContext, operations);
|
||||
@@ -85,8 +83,9 @@ public class CouchbasePersistentEntityIndexCreator implements ApplicationListene
|
||||
|
||||
for (IndexDefinition indexDefinition : indexResolver.resolveIndexFor(entity.getTypeInformation())) {
|
||||
IndexDefinitionHolder indexToCreate = indexDefinition instanceof IndexDefinitionHolder
|
||||
? (IndexDefinitionHolder) indexDefinition
|
||||
: new IndexDefinitionHolder(indexDefinition.getIndexFields(), indexDefinition.getIndexName(), indexDefinition.getIndexPredicate());
|
||||
? (IndexDefinitionHolder) indexDefinition
|
||||
: new IndexDefinitionHolder(indexDefinition.getIndexFields(), indexDefinition.getIndexName(),
|
||||
indexDefinition.getIndexPredicate());
|
||||
|
||||
createIndex(indexToCreate);
|
||||
}
|
||||
@@ -96,13 +95,9 @@ public class CouchbasePersistentEntityIndexCreator implements ApplicationListene
|
||||
private void createIndex(final IndexDefinitionHolder indexToCreate) {
|
||||
Cluster cluster = couchbaseOperations.getCouchbaseClientFactory().getCluster();
|
||||
|
||||
StringBuilder statement = new StringBuilder("CREATE INDEX ")
|
||||
.append(indexToCreate.getIndexName())
|
||||
.append(" ON `")
|
||||
.append(couchbaseOperations.getBucketName())
|
||||
.append("` (")
|
||||
.append(String.join(",", indexToCreate.getIndexFields()))
|
||||
.append(")");
|
||||
StringBuilder statement = new StringBuilder("CREATE INDEX ").append(indexToCreate.getIndexName()).append(" ON `")
|
||||
.append(couchbaseOperations.getBucketName()).append("` (")
|
||||
.append(String.join(",", indexToCreate.getIndexFields())).append(")");
|
||||
|
||||
if (indexToCreate.getIndexPredicate() != null && !indexToCreate.getIndexPredicate().isEmpty()) {
|
||||
statement.append(" WHERE ").append(indexToCreate.getIndexPredicate());
|
||||
@@ -114,8 +109,8 @@ public class CouchbasePersistentEntityIndexCreator implements ApplicationListene
|
||||
// ignored on purpose, rest is propagated
|
||||
LOGGER.debug("Index \"" + indexToCreate.getIndexName() + "\" already exists, ignoring.");
|
||||
} catch (Exception ex) {
|
||||
throw new DataIntegrityViolationException("Could not auto-create index with statement: "
|
||||
+ statement.toString(), ex);
|
||||
throw new DataIntegrityViolationException("Could not auto-create index with statement: " + statement.toString(),
|
||||
ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,11 @@
|
||||
*/
|
||||
package org.springframework.data.couchbase.core.index;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.data.couchbase.core.CouchbaseOperations;
|
||||
import org.springframework.data.couchbase.core.mapping.CouchbasePersistentEntity;
|
||||
import org.springframework.data.couchbase.core.mapping.CouchbasePersistentProperty;
|
||||
@@ -27,21 +32,14 @@ import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class CouchbasePersistentEntityIndexResolver implements QueryIndexResolver {
|
||||
|
||||
private final MappingContext<? extends CouchbasePersistentEntity<?>, CouchbasePersistentProperty> mappingContext;
|
||||
private final CouchbaseOperations operations;
|
||||
|
||||
public CouchbasePersistentEntityIndexResolver(
|
||||
final MappingContext<? extends CouchbasePersistentEntity<?>, CouchbasePersistentProperty> mappingContext,
|
||||
CouchbaseOperations operations) {
|
||||
final MappingContext<? extends CouchbasePersistentEntity<?>, CouchbasePersistentProperty> mappingContext,
|
||||
CouchbaseOperations operations) {
|
||||
this.mappingContext = mappingContext;
|
||||
this.operations = operations;
|
||||
}
|
||||
@@ -55,29 +53,27 @@ public class CouchbasePersistentEntityIndexResolver implements QueryIndexResolve
|
||||
Assert.notNull(root, "CouchbasePersistentEntity must not be null!");
|
||||
Document document = root.findAnnotation(Document.class);
|
||||
Assert.notNull(document, () -> String
|
||||
.format("Entity %s is not a collection root. Make sure to annotate it with @Document!", root.getName()));
|
||||
.format("Entity %s is not a collection root. Make sure to annotate it with @Document!", root.getName()));
|
||||
|
||||
List<IndexDefinitionHolder> indexInformation = new ArrayList<>();
|
||||
|
||||
root.doWithProperties((PropertyHandler<CouchbasePersistentProperty>) property -> this
|
||||
.potentiallyAddIndexForProperty(root, property, indexInformation));
|
||||
.potentiallyAddIndexForProperty(root, property, indexInformation));
|
||||
|
||||
return indexInformation;
|
||||
}
|
||||
|
||||
private void potentiallyAddIndexForProperty(final CouchbasePersistentEntity<?> root,
|
||||
final CouchbasePersistentProperty persistentProperty,
|
||||
final List<IndexDefinitionHolder> indexes) {
|
||||
final CouchbasePersistentProperty persistentProperty, final List<IndexDefinitionHolder> indexes) {
|
||||
List<IndexDefinitionHolder> indexDefinitions = createIndexDefinitionHolderForProperty(
|
||||
persistentProperty.getFieldName(), root, persistentProperty);
|
||||
persistentProperty.getFieldName(), root, persistentProperty);
|
||||
if (!indexDefinitions.isEmpty()) {
|
||||
indexes.addAll(indexDefinitions);
|
||||
}
|
||||
}
|
||||
|
||||
private List<IndexDefinitionHolder> createIndexDefinitionHolderForProperty(final String dotPath,
|
||||
final CouchbasePersistentEntity<?> persistentEntity,
|
||||
final CouchbasePersistentProperty persistentProperty) {
|
||||
final CouchbasePersistentEntity<?> persistentEntity, final CouchbasePersistentProperty persistentProperty) {
|
||||
|
||||
List<IndexDefinitionHolder> indices = new ArrayList<>();
|
||||
|
||||
@@ -86,7 +82,7 @@ public class CouchbasePersistentEntityIndexResolver implements QueryIndexResolve
|
||||
}
|
||||
|
||||
if (persistentEntity.isAnnotationPresent(CompositeQueryIndex.class)
|
||||
|| persistentEntity.isAnnotationPresent(CompositeQueryIndexes.class)) {
|
||||
|| persistentEntity.isAnnotationPresent(CompositeQueryIndexes.class)) {
|
||||
indices.addAll(createCompositeQueryIndexDefinitions(persistentEntity, persistentProperty));
|
||||
}
|
||||
|
||||
@@ -95,7 +91,7 @@ public class CouchbasePersistentEntityIndexResolver implements QueryIndexResolve
|
||||
|
||||
@Nullable
|
||||
protected IndexDefinitionHolder createFieldQueryIndexDefinition(final CouchbasePersistentEntity<?> entity,
|
||||
final CouchbasePersistentProperty property) {
|
||||
final CouchbasePersistentProperty property) {
|
||||
QueryIndexed index = property.findAnnotation(QueryIndexed.class);
|
||||
if (index == null) {
|
||||
return null;
|
||||
@@ -113,7 +109,7 @@ public class CouchbasePersistentEntityIndexResolver implements QueryIndexResolve
|
||||
}
|
||||
|
||||
protected List<IndexDefinitionHolder> createCompositeQueryIndexDefinitions(final CouchbasePersistentEntity<?> entity,
|
||||
final CouchbasePersistentProperty property) {
|
||||
final CouchbasePersistentProperty property) {
|
||||
|
||||
List<CompositeQueryIndex> indexAnnotations = new ArrayList<>();
|
||||
|
||||
@@ -128,34 +124,22 @@ public class CouchbasePersistentEntityIndexResolver implements QueryIndexResolve
|
||||
|
||||
String predicate = getPredicate(entityInfo);
|
||||
|
||||
|
||||
return indexAnnotations
|
||||
.stream()
|
||||
.map(ann -> {
|
||||
List<String> fields = Arrays.asList(ann.fields());
|
||||
String fieldsIndexName = String
|
||||
.join("_", fields)
|
||||
.toLowerCase()
|
||||
.replace(" ", "")
|
||||
.replace("asc", "")
|
||||
return indexAnnotations.stream().map(ann -> {
|
||||
List<String> fields = Arrays.asList(ann.fields());
|
||||
String fieldsIndexName = String.join("_", fields).toLowerCase().replace(" ", "").replace("asc", "")
|
||||
.replace("desc", "");
|
||||
|
||||
String indexName = "idx_"
|
||||
+ StringUtils.uncapitalize(entity.getType().getSimpleName())
|
||||
+ "_"
|
||||
+ fieldsIndexName;
|
||||
return new IndexDefinitionHolder(fields, indexName, predicate);
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
String indexName = "idx_" + StringUtils.uncapitalize(entity.getType().getSimpleName()) + "_" + fieldsIndexName;
|
||||
return new IndexDefinitionHolder(fields, indexName, predicate);
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private String getPredicate(final MappingCouchbaseEntityInformation<?, Object> entityInfo) {
|
||||
String typeKey = operations.getConverter().getTypeKey();
|
||||
String typeValue = entityInfo.getJavaType().getName();
|
||||
return "`" + typeKey + "` = \"" + typeValue + "\"";
|
||||
return "`" + typeKey + "` = \"" + typeValue + "\"";
|
||||
}
|
||||
|
||||
|
||||
public static class IndexDefinitionHolder implements IndexDefinition {
|
||||
|
||||
private final List<String> fields;
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
package org.springframework.data.couchbase.core.index;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
|
||||
@@ -42,8 +42,8 @@ public interface QueryIndexResolver {
|
||||
* @since 2.2
|
||||
*/
|
||||
static QueryIndexResolver create(
|
||||
MappingContext<? extends CouchbasePersistentEntity<?>, CouchbasePersistentProperty> mappingContext,
|
||||
CouchbaseOperations operations) {
|
||||
MappingContext<? extends CouchbasePersistentEntity<?>, CouchbasePersistentProperty> mappingContext,
|
||||
CouchbaseOperations operations) {
|
||||
Assert.notNull(mappingContext, "CouchbaseMappingContext must not be null!");
|
||||
return new CouchbasePersistentEntityIndexResolver(mappingContext, operations);
|
||||
}
|
||||
|
||||
@@ -24,23 +24,23 @@ import java.lang.annotation.Target;
|
||||
import org.springframework.data.couchbase.repository.CouchbaseRepository;
|
||||
|
||||
/**
|
||||
* This annotation is targeted at {@link CouchbaseRepository Repository} interfaces, indicating that
|
||||
* the framework should ensure a N1QL Secondary Index is present when the repository is instantiated.
|
||||
* This annotation is targeted at {@link CouchbaseRepository Repository} interfaces, indicating that the framework
|
||||
* should ensure a N1QL Secondary Index is present when the repository is instantiated.
|
||||
* <p/>
|
||||
* Said index will relate to the "type" field (the one bearing type information) and restrict on documents
|
||||
* that match the repository's entity class.
|
||||
* Said index will relate to the "type" field (the one bearing type information) and restrict on documents that match
|
||||
* the repository's entity class.
|
||||
* <p/>
|
||||
* Be sure to also use {@link N1qlPrimaryIndexed} to make sure the PRIMARY INDEX is there as well.
|
||||
*
|
||||
* @author Simon Baslé
|
||||
*/
|
||||
@Target({ElementType.TYPE})
|
||||
@Target({ ElementType.TYPE })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface N1qlSecondaryIndexed {
|
||||
|
||||
/**
|
||||
* the name of the index to be created, in the repository's associated bucket namespace.
|
||||
*/
|
||||
String indexName();
|
||||
/**
|
||||
* the name of the index to be created, in the repository's associated bucket namespace.
|
||||
*/
|
||||
String indexName();
|
||||
|
||||
}
|
||||
|
||||
@@ -1,20 +1,18 @@
|
||||
package org.springframework.data.couchbase.core.query;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class Query {
|
||||
|
||||
private final List<QueryCriteria> criteria = new ArrayList<>();
|
||||
private long skip;
|
||||
private int limit;
|
||||
private Sort sort = Sort.unsorted();
|
||||
private final List<QueryCriteria> criteria = new ArrayList<>();
|
||||
|
||||
public Query() {}
|
||||
|
||||
@@ -27,12 +25,12 @@ public class Query {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set number of documents to skip before returning results.
|
||||
*
|
||||
* @param skip
|
||||
* @return
|
||||
*/
|
||||
/**
|
||||
* Set number of documents to skip before returning results.
|
||||
*
|
||||
* @param skip
|
||||
* @return
|
||||
*/
|
||||
public Query skip(long skip) {
|
||||
this.skip = skip;
|
||||
return this;
|
||||
@@ -126,5 +124,4 @@ public class Query {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,25 +1,23 @@
|
||||
package org.springframework.data.couchbase.core.query;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Formatter;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
public class QueryCriteria implements QueryCriteriaDefinition {
|
||||
|
||||
private final String key;
|
||||
/**
|
||||
* Holds the chain itself, the current operator being always the last one.
|
||||
*/
|
||||
private List<QueryCriteria> criteriaChain;
|
||||
|
||||
/**
|
||||
* Represents how the chain is hung together, null only for the first element.
|
||||
*/
|
||||
private ChainOperator chainOperator;
|
||||
|
||||
private final String key;
|
||||
private String operator;
|
||||
private Object[] value;
|
||||
private String format;
|
||||
@@ -29,10 +27,11 @@ public class QueryCriteria implements QueryCriteriaDefinition {
|
||||
}
|
||||
|
||||
QueryCriteria(List<QueryCriteria> chain, String key, Object value, ChainOperator chainOperator) {
|
||||
this(chain, key, new Object[]{value}, chainOperator, null, null);
|
||||
this(chain, key, new Object[] { value }, chainOperator, null, null);
|
||||
}
|
||||
|
||||
QueryCriteria(List<QueryCriteria> chain, String key, Object[] value, ChainOperator chainOperator, String operator, String format) {
|
||||
QueryCriteria(List<QueryCriteria> chain, String key, Object[] value, ChainOperator chainOperator, String operator,
|
||||
String format) {
|
||||
this.criteriaChain = chain;
|
||||
criteriaChain.add(this);
|
||||
this.key = key;
|
||||
@@ -49,6 +48,12 @@ public class QueryCriteria implements QueryCriteriaDefinition {
|
||||
return new QueryCriteria(new ArrayList<>(), key, null, null);
|
||||
}
|
||||
|
||||
private static QueryCriteria wrap(QueryCriteria criteria) {
|
||||
QueryCriteria qc = new QueryCriteria(new LinkedList<QueryCriteria>(), criteria.key, criteria.value, null,
|
||||
criteria.operator, criteria.format);
|
||||
return qc;
|
||||
}
|
||||
|
||||
public QueryCriteria and(String key) {
|
||||
return new QueryCriteria(this.criteriaChain, key, null, ChainOperator.AND);
|
||||
}
|
||||
@@ -65,54 +70,43 @@ public class QueryCriteria implements QueryCriteriaDefinition {
|
||||
return new QueryCriteria(this.criteriaChain, key, null, ChainOperator.OR);
|
||||
}
|
||||
|
||||
private static QueryCriteria wrap(QueryCriteria criteria) {
|
||||
QueryCriteria qc = new QueryCriteria(
|
||||
new LinkedList<QueryCriteria>(),
|
||||
criteria.key,
|
||||
criteria.value,
|
||||
null,
|
||||
criteria.operator,
|
||||
criteria.format);
|
||||
return qc;
|
||||
}
|
||||
|
||||
public QueryCriteria eq(@Nullable Object o) {
|
||||
return is(o);
|
||||
}
|
||||
|
||||
public QueryCriteria is(@Nullable Object o) {
|
||||
operator = "=";
|
||||
value = new Object[]{o};
|
||||
value = new Object[] { o };
|
||||
return this;
|
||||
}
|
||||
|
||||
public QueryCriteria ne(@Nullable Object o) {
|
||||
operator = "!=";
|
||||
value = new Object[]{o};
|
||||
value = new Object[] { o };
|
||||
return this;
|
||||
}
|
||||
|
||||
public QueryCriteria lt(@Nullable Object o) {
|
||||
operator = "<";
|
||||
value = new Object[]{o};
|
||||
value = new Object[] { o };
|
||||
return this;
|
||||
}
|
||||
|
||||
public QueryCriteria lte(@Nullable Object o) {
|
||||
operator = "<=";
|
||||
value = new Object[]{o};
|
||||
value = new Object[] { o };
|
||||
return this;
|
||||
}
|
||||
|
||||
public QueryCriteria gt(@Nullable Object o) {
|
||||
operator = ">";
|
||||
value = new Object[]{o};
|
||||
value = new Object[] { o };
|
||||
return this;
|
||||
}
|
||||
|
||||
public QueryCriteria gte(@Nullable Object o) {
|
||||
operator = ">=";
|
||||
value = new Object[]{o};
|
||||
value = new Object[] { o };
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -128,7 +122,7 @@ public class QueryCriteria implements QueryCriteriaDefinition {
|
||||
|
||||
public QueryCriteria plus(@Nullable Object o) {
|
||||
operator = "PLUS";
|
||||
value = new Object[]{o};
|
||||
value = new Object[] { o };
|
||||
format = "(%1$s + %3$s)";
|
||||
return this;
|
||||
}
|
||||
@@ -145,20 +139,20 @@ public class QueryCriteria implements QueryCriteriaDefinition {
|
||||
|
||||
public QueryCriteria regex(@Nullable Object o) {
|
||||
operator = "REGEXP_LIKE";
|
||||
value = new Object[]{o};
|
||||
value = new Object[] { o };
|
||||
format = "regexp_like(%1$s, %3$s)";
|
||||
return this;
|
||||
}
|
||||
|
||||
public QueryCriteria containing(@Nullable Object o) {
|
||||
operator = "CONTAINS";
|
||||
value = new Object[]{o};
|
||||
value = new Object[] { o };
|
||||
format = "contains(%1$s, %3$s)";
|
||||
return this;
|
||||
}
|
||||
|
||||
public QueryCriteria notContaining(@Nullable Object o) {
|
||||
value = new QueryCriteria[]{wrap(containing(o))};
|
||||
value = new QueryCriteria[] { wrap(containing(o)) };
|
||||
operator = "NOT";
|
||||
format = format = "not( %3$s )";
|
||||
return this;
|
||||
@@ -166,13 +160,13 @@ public class QueryCriteria implements QueryCriteriaDefinition {
|
||||
|
||||
public QueryCriteria like(@Nullable Object o) {
|
||||
operator = "LIKE";
|
||||
value = new Object[]{o};
|
||||
value = new Object[] { o };
|
||||
format = "%1$s like %3$s";
|
||||
return this;
|
||||
}
|
||||
|
||||
public QueryCriteria notLike(@Nullable Object o) {
|
||||
value = new QueryCriteria[]{wrap(like(o))};
|
||||
value = new QueryCriteria[] { wrap(like(o)) };
|
||||
operator = "NOT";
|
||||
format = format = "not( %3$s )";
|
||||
return (QueryCriteria) this;
|
||||
@@ -222,14 +216,14 @@ public class QueryCriteria implements QueryCriteriaDefinition {
|
||||
|
||||
public QueryCriteria within(@Nullable Object o) {
|
||||
operator = "WITHIN";
|
||||
value = new Object[]{o};
|
||||
value = new Object[] { o };
|
||||
format = "%1$s within $3$s";
|
||||
return (QueryCriteria) this;
|
||||
}
|
||||
|
||||
public QueryCriteria between(@Nullable Object o1, @Nullable Object o2) {
|
||||
operator = "BETWEEN";
|
||||
value = new Object[]{o1, o2};
|
||||
value = new Object[] { o1, o2 };
|
||||
format = "%1$s between %3$s and %4$s";
|
||||
return (QueryCriteria) this;
|
||||
}
|
||||
@@ -239,15 +233,16 @@ public class QueryCriteria implements QueryCriteriaDefinition {
|
||||
value = o;
|
||||
StringBuilder sb = new StringBuilder("%1$s in ( [ ");
|
||||
for (int i = 1; i <= value.length; i++) { // format indices start at 1
|
||||
if (i > 1) sb.append(", ");
|
||||
sb.append("%" + (i + 2) + "$s"); // the first is fieldName, second is operator, args start at 3
|
||||
if (i > 1)
|
||||
sb.append(", ");
|
||||
sb.append("%" + (i + 2) + "$s"); // the first is fieldName, second is operator, args start at 3
|
||||
}
|
||||
format = sb.append(" ] )").toString();
|
||||
return (QueryCriteria) this;
|
||||
}
|
||||
|
||||
public QueryCriteria notIn(@Nullable Object... o) {
|
||||
value = new QueryCriteria[]{wrap(in(o))};
|
||||
value = new QueryCriteria[] { wrap(in(o)) };
|
||||
operator = "NOT";
|
||||
format = format = "not( %3$s )"; // field = 1$, operator = 2$, value=$3, $4, ...
|
||||
return (QueryCriteria) this;
|
||||
@@ -261,7 +256,7 @@ public class QueryCriteria implements QueryCriteriaDefinition {
|
||||
}
|
||||
|
||||
public QueryCriteria FALSE() {
|
||||
value = new QueryCriteria[]{wrap(TRUE())};
|
||||
value = new QueryCriteria[] { wrap(TRUE()) };
|
||||
operator = "not";
|
||||
format = format = "not( %3$s )";
|
||||
return (QueryCriteria) this;
|
||||
@@ -312,7 +307,6 @@ public class QueryCriteria implements QueryCriteriaDefinition {
|
||||
return sb;
|
||||
}
|
||||
|
||||
|
||||
private String maybeWrapValue(Object value) {
|
||||
if (value instanceof String) {
|
||||
return "\"" + value + "\"";
|
||||
@@ -332,8 +326,7 @@ public class QueryCriteria implements QueryCriteriaDefinition {
|
||||
}
|
||||
|
||||
enum ChainOperator {
|
||||
AND("and"),
|
||||
OR("or");
|
||||
AND("and"), OR("or");
|
||||
|
||||
private final String representation;
|
||||
|
||||
@@ -347,4 +340,3 @@ public class QueryCriteria implements QueryCriteriaDefinition {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
package org.springframework.data.couchbase.core.query;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* @author Oliver Gierke
|
||||
* @author Christoph Strobl
|
||||
|
||||
@@ -18,7 +18,6 @@ package org.springframework.data.couchbase.repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.couchbase.core.CouchbaseOperations;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.repository.NoRepositoryBean;
|
||||
import org.springframework.data.repository.PagingAndSortingRepository;
|
||||
|
||||
@@ -100,9 +100,9 @@ public class ReactiveRepositoryOperationsMapping {
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a repository interface and its domain type, resolves which {@link ReactiveCouchbaseOperations} it should be backed
|
||||
* with. Starts by looking for a direct mapping to the interface, then a common mapping for the domain type, then
|
||||
* falls back to the default CouchbaseOperations.
|
||||
* Given a repository interface and its domain type, resolves which {@link ReactiveCouchbaseOperations} it should be
|
||||
* backed with. Starts by looking for a direct mapping to the interface, then a common mapping for the domain type,
|
||||
* then falls back to the default CouchbaseOperations.
|
||||
*
|
||||
* @param repositoryInterface the repository's interface.
|
||||
* @param domainType the repository's domain type / entity.
|
||||
|
||||
@@ -97,7 +97,7 @@ public abstract class AbstractN1qlBasedQuery implements RepositoryQuery {
|
||||
if (queryMethod.hasConsistencyAnnotation()) {
|
||||
return queryMethod.getConsistencyAnnotation().value();
|
||||
}
|
||||
|
||||
|
||||
return getCouchbaseOperations().getDefaultConsistency().n1qlConsistency();*/
|
||||
}
|
||||
|
||||
|
||||
@@ -153,8 +153,8 @@ public class CouchbaseQueryMethod extends QueryMethod {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the query string declared in a {@link Query} annotation or {@literal null} if neither the annotation
|
||||
* found nor the attribute was specified.
|
||||
* Returns the query string declared in a {@link Query} annotation or {@literal null} if neither the annotation found
|
||||
* nor the attribute was specified.
|
||||
*
|
||||
* @return the query statement if present.
|
||||
*/
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
package org.springframework.data.couchbase.repository.query;
|
||||
|
||||
import static org.springframework.data.couchbase.core.query.QueryCriteria.*;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.springframework.data.couchbase.core.mapping.CouchbasePersistentProperty;
|
||||
import org.springframework.data.couchbase.core.query.QueryCriteria;
|
||||
import org.springframework.data.couchbase.core.query.Query;
|
||||
import org.springframework.data.couchbase.core.query.QueryCriteria;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.mapping.PersistentPropertyPath;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
@@ -11,17 +15,13 @@ import org.springframework.data.repository.query.parser.AbstractQueryCreator;
|
||||
import org.springframework.data.repository.query.parser.Part;
|
||||
import org.springframework.data.repository.query.parser.PartTree;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import static org.springframework.data.couchbase.core.query.QueryCriteria.*;
|
||||
|
||||
public class N1qlQueryCreator extends AbstractQueryCreator<Query, QueryCriteria> {
|
||||
|
||||
private final ParameterAccessor accessor;
|
||||
private final MappingContext<?, CouchbasePersistentProperty> context;
|
||||
|
||||
public N1qlQueryCreator(final PartTree tree, final ParameterAccessor accessor,
|
||||
final MappingContext<?, CouchbasePersistentProperty> context) {
|
||||
final MappingContext<?, CouchbasePersistentProperty> context) {
|
||||
super(tree, accessor);
|
||||
this.accessor = accessor;
|
||||
this.context = context;
|
||||
@@ -57,13 +57,13 @@ public class N1qlQueryCreator extends AbstractQueryCreator<Query, QueryCriteria>
|
||||
}
|
||||
|
||||
private QueryCriteria from(final Part part, final CouchbasePersistentProperty property, final QueryCriteria criteria,
|
||||
final Iterator<Object> parameters) {
|
||||
final Iterator<Object> parameters) {
|
||||
|
||||
final Part.Type type = part.getType();
|
||||
/*
|
||||
NEAR(new String[]{"IsNear", "Near"}),
|
||||
WITHIN(new String[]{"IsWithin", "Within"}),
|
||||
*/
|
||||
/*
|
||||
NEAR(new String[]{"IsNear", "Near"}),
|
||||
WITHIN(new String[]{"IsWithin", "Within"}),
|
||||
*/
|
||||
switch (type) {
|
||||
case GREATER_THAN:
|
||||
case AFTER:
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package org.springframework.data.couchbase.repository.query;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.couchbase.core.CouchbaseOperations;
|
||||
import org.springframework.data.couchbase.core.query.Query;
|
||||
import org.springframework.data.repository.query.ParameterAccessor;
|
||||
@@ -7,8 +9,6 @@ import org.springframework.data.repository.query.ParametersParameterAccessor;
|
||||
import org.springframework.data.repository.query.QueryMethod;
|
||||
import org.springframework.data.repository.query.parser.PartTree;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class N1qlRepositoryQueryExecutor {
|
||||
|
||||
private final CouchbaseOperations operations;
|
||||
|
||||
@@ -91,7 +91,7 @@ public class OldN1qlQueryCreator extends AbstractQueryCreator<N1QLExpression, N1
|
||||
private final AtomicInteger position;
|
||||
|
||||
public OldN1qlQueryCreator(PartTree tree, ParameterAccessor parameters, N1QLExpression selectFrom,
|
||||
CouchbaseConverter converter, CouchbaseQueryMethod queryMethod) {
|
||||
CouchbaseConverter converter, CouchbaseQueryMethod queryMethod) {
|
||||
super(tree, parameters);
|
||||
this.selectFrom = selectFrom;
|
||||
this.converter = converter;
|
||||
|
||||
@@ -15,12 +15,11 @@
|
||||
*/
|
||||
package org.springframework.data.couchbase.repository.query;
|
||||
|
||||
import org.springframework.data.couchbase.core.ReactiveCouchbaseOperations;
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.data.couchbase.core.CouchbaseOperations;
|
||||
import org.springframework.data.couchbase.core.ReactiveCouchbaseOperations;
|
||||
import org.springframework.data.couchbase.core.query.N1QLExpression;
|
||||
import org.springframework.data.couchbase.core.query.N1QLQuery;
|
||||
import org.springframework.data.couchbase.repository.query.support.N1qlUtils;
|
||||
|
||||
@@ -1,22 +1,21 @@
|
||||
package org.springframework.data.couchbase.repository.query;
|
||||
|
||||
import java.util.List;
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
import org.springframework.data.couchbase.core.CouchbaseOperations;
|
||||
import org.springframework.data.couchbase.core.ReactiveCouchbaseOperations;
|
||||
import org.springframework.data.couchbase.core.query.Query;
|
||||
import org.springframework.data.repository.query.ParameterAccessor;
|
||||
import org.springframework.data.repository.query.ParametersParameterAccessor;
|
||||
import org.springframework.data.repository.query.QueryMethod;
|
||||
import org.springframework.data.repository.query.parser.PartTree;
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
public class ReactiveN1qlRepositoryQueryExecutor {
|
||||
|
||||
private final ReactiveCouchbaseOperations operations;
|
||||
private final QueryMethod queryMethod;
|
||||
|
||||
public ReactiveN1qlRepositoryQueryExecutor(final ReactiveCouchbaseOperations operations, final QueryMethod queryMethod) {
|
||||
public ReactiveN1qlRepositoryQueryExecutor(final ReactiveCouchbaseOperations operations,
|
||||
final QueryMethod queryMethod) {
|
||||
this.operations = operations;
|
||||
this.queryMethod = queryMethod;
|
||||
}
|
||||
|
||||
@@ -47,8 +47,8 @@ public class ReactiveStringN1qlBasedQuery extends ReactiveAbstractN1qlBasedQuery
|
||||
private final QueryMethodEvaluationContextProvider evaluationContextProvider;
|
||||
|
||||
public ReactiveStringN1qlBasedQuery(String statement, CouchbaseQueryMethod queryMethod,
|
||||
ReactiveCouchbaseOperations couchbaseOperations, SpelExpressionParser spelParser,
|
||||
QueryMethodEvaluationContextProvider evaluationContextProvider) {
|
||||
ReactiveCouchbaseOperations couchbaseOperations, SpelExpressionParser spelParser,
|
||||
QueryMethodEvaluationContextProvider evaluationContextProvider) {
|
||||
super(queryMethod, couchbaseOperations);
|
||||
|
||||
this.queryParser = new StringBasedN1qlQueryParser(statement, queryMethod, getCouchbaseOperations().getBucketName(),
|
||||
|
||||
@@ -65,8 +65,8 @@ public class StringBasedN1qlQueryParser {
|
||||
*/
|
||||
public static final String SPEL_ENTITY = "#" + SPEL_PREFIX + ".fields";
|
||||
/**
|
||||
* Use this variable in a SpEL expression in a {@link Query @Query} annotation's inline statement WHERE clause.
|
||||
* This will be replaced by the expression allowing to only select documents matching the entity's class. Eg.
|
||||
* Use this variable in a SpEL expression in a {@link Query @Query} annotation's inline statement WHERE clause. This
|
||||
* will be replaced by the expression allowing to only select documents matching the entity's class. Eg.
|
||||
* <code>"SELECT * FROM test WHERE test = true AND #{{@value SPEL_FILTER}}"</code>.
|
||||
*/
|
||||
public static final String SPEL_FILTER = "#" + SPEL_PREFIX + ".filter";
|
||||
@@ -97,6 +97,7 @@ public class StringBasedN1qlQueryParser {
|
||||
private final N1qlSpelValues statementContext;
|
||||
private final N1qlSpelValues countContext;
|
||||
private final CouchbaseConverter couchbaseConverter;
|
||||
|
||||
public StringBasedN1qlQueryParser(String statement, QueryMethod queryMethod, String bucketName,
|
||||
CouchbaseConverter couchbaseConverter, String typeField, Class<?> typeValue) {
|
||||
this.statement = statement;
|
||||
|
||||
@@ -25,10 +25,7 @@ import org.springframework.data.couchbase.core.mapping.CouchbasePersistentEntity
|
||||
import org.springframework.data.couchbase.core.mapping.CouchbasePersistentProperty;
|
||||
import org.springframework.data.couchbase.repository.config.RepositoryOperationsMapping;
|
||||
import org.springframework.data.couchbase.repository.query.CouchbaseEntityInformation;
|
||||
import org.springframework.data.couchbase.repository.query.CouchbaseQueryMethod;
|
||||
import org.springframework.data.couchbase.repository.query.CouchbaseRepositoryQuery;
|
||||
import org.springframework.data.couchbase.repository.query.PartTreeN1qlBasedQuery;
|
||||
import org.springframework.data.couchbase.repository.query.StringN1qlBasedQuery;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.projection.ProjectionFactory;
|
||||
import org.springframework.data.repository.core.NamedQueries;
|
||||
@@ -161,9 +158,9 @@ public class CouchbaseRepositoryFactory extends RepositoryFactorySupport {
|
||||
|
||||
/*CouchbaseQueryMethod queryMethod = new CouchbaseQueryMethod(method, metadata, factory, mappingContext);
|
||||
String namedQueryName = queryMethod.getNamedQueryName();
|
||||
|
||||
|
||||
if (queryMethod.hasN1qlAnnotation()) {
|
||||
|
||||
|
||||
if (queryMethod.hasInlineN1qlQuery()) {
|
||||
return new StringN1qlBasedQuery(queryMethod.getInlineN1qlQuery(), queryMethod, couchbaseOperations,
|
||||
SPEL_PARSER, evaluationContextProvider);
|
||||
@@ -172,9 +169,9 @@ public class CouchbaseRepositoryFactory extends RepositoryFactorySupport {
|
||||
return new StringN1qlBasedQuery(namedQuery, queryMethod, couchbaseOperations, SPEL_PARSER,
|
||||
evaluationContextProvider);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
return new PartTreeN1qlBasedQuery(queryMethod, couchbaseOperations);*/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,17 +19,12 @@ import java.io.Serializable;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.data.couchbase.core.CouchbaseOperations;
|
||||
import org.springframework.data.couchbase.core.ReactiveCouchbaseOperations;
|
||||
import org.springframework.data.couchbase.core.mapping.CouchbasePersistentEntity;
|
||||
import org.springframework.data.couchbase.core.mapping.CouchbasePersistentProperty;
|
||||
import org.springframework.data.couchbase.repository.config.ReactiveRepositoryOperationsMapping;
|
||||
import org.springframework.data.couchbase.repository.query.CouchbaseEntityInformation;
|
||||
import org.springframework.data.couchbase.repository.query.CouchbaseQueryMethod;
|
||||
import org.springframework.data.couchbase.repository.query.CouchbaseRepositoryQuery;
|
||||
import org.springframework.data.couchbase.repository.query.ReactiveCouchbaseRepositoryQuery;
|
||||
import org.springframework.data.couchbase.repository.query.ReactivePartTreeN1qlBasedQuery;
|
||||
import org.springframework.data.couchbase.repository.query.ReactiveStringN1qlBasedQuery;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.projection.ProjectionFactory;
|
||||
import org.springframework.data.repository.core.NamedQueries;
|
||||
@@ -95,7 +90,7 @@ public class ReactiveCouchbaseRepositoryFactory extends ReactiveRepositoryFactor
|
||||
@Override
|
||||
public <T, ID> CouchbaseEntityInformation<T, ID> getEntityInformation(Class<T> domainClass) {
|
||||
CouchbasePersistentEntity<T> entity = (CouchbasePersistentEntity<T>) mappingContext
|
||||
.getRequiredPersistentEntity(domainClass);
|
||||
.getRequiredPersistentEntity(domainClass);
|
||||
return new MappingCouchbaseEntityInformation<>(entity);
|
||||
}
|
||||
|
||||
@@ -110,11 +105,11 @@ public class ReactiveCouchbaseRepositoryFactory extends ReactiveRepositoryFactor
|
||||
*/
|
||||
@Override
|
||||
protected final Object getTargetRepository(final RepositoryInformation metadata) {
|
||||
ReactiveCouchbaseOperations couchbaseOperations = couchbaseOperationsMapping.resolve(metadata.getRepositoryInterface(),
|
||||
metadata.getDomainType());
|
||||
ReactiveCouchbaseOperations couchbaseOperations = couchbaseOperationsMapping
|
||||
.resolve(metadata.getRepositoryInterface(), metadata.getDomainType());
|
||||
CouchbaseEntityInformation<?, Serializable> entityInformation = getEntityInformation(metadata.getDomainType());
|
||||
SimpleReactiveCouchbaseRepository repository = getTargetRepositoryViaReflection(metadata, entityInformation,
|
||||
couchbaseOperations);
|
||||
couchbaseOperations);
|
||||
repository.setRepositoryMethodMetadata(crudMethodMetadataPostProcessor.getCrudMethodMetadata());
|
||||
return repository;
|
||||
}
|
||||
@@ -154,7 +149,7 @@ public class ReactiveCouchbaseRepositoryFactory extends ReactiveRepositoryFactor
|
||||
public RepositoryQuery resolveQuery(Method method, RepositoryMetadata metadata, ProjectionFactory factory,
|
||||
NamedQueries namedQueries) {
|
||||
final ReactiveCouchbaseOperations couchbaseOperations = couchbaseOperationsMapping
|
||||
.resolve(metadata.getRepositoryInterface(), metadata.getDomainType());
|
||||
.resolve(metadata.getRepositoryInterface(), metadata.getDomainType());
|
||||
|
||||
return new ReactiveCouchbaseRepositoryQuery(couchbaseOperations, new QueryMethod(method, metadata, factory));
|
||||
}
|
||||
|
||||
@@ -54,7 +54,8 @@ public class ReactiveCouchbaseRepositoryFactoryBean<T extends Repository<S, ID>,
|
||||
setReactiveCouchbaseOperationsMapping(new ReactiveRepositoryOperationsMapping(reactiveCouchbaseOperations));
|
||||
}
|
||||
|
||||
public void setReactiveCouchbaseOperationsMapping(final ReactiveRepositoryOperationsMapping couchbaseOperationsMapping) {
|
||||
public void setReactiveCouchbaseOperationsMapping(
|
||||
final ReactiveRepositoryOperationsMapping couchbaseOperationsMapping) {
|
||||
this.couchbaseOperationsMapping = couchbaseOperationsMapping;
|
||||
setMappingContext(couchbaseOperationsMapping.getMappingContext());
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.springframework.data.couchbase.repository.support;
|
||||
|
||||
import com.couchbase.client.java.query.QueryScanConsistency;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
@@ -34,6 +33,8 @@ import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.util.Streamable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.couchbase.client.java.query.QueryScanConsistency;
|
||||
|
||||
/**
|
||||
* Reactive repository base implementation for Couchbase.
|
||||
*
|
||||
@@ -199,7 +200,8 @@ public class SimpleReactiveCouchbaseRepository<T, ID> implements ReactiveCouchba
|
||||
}
|
||||
|
||||
private Flux<T> findAll(final Query query) {
|
||||
return operations.findByQuery(entityInformation.getJavaType()).consistentWith(buildQueryScanConsistency()).matching(query).all();
|
||||
return operations.findByQuery(entityInformation.getJavaType()).consistentWith(buildQueryScanConsistency())
|
||||
.matching(query).all();
|
||||
}
|
||||
|
||||
private QueryScanConsistency buildQueryScanConsistency() {
|
||||
|
||||
@@ -24,11 +24,11 @@ import org.springframework.data.couchbase.core.query.View;
|
||||
*/
|
||||
public interface ViewMetadataProvider {
|
||||
|
||||
/**
|
||||
* Returns the {@link View} to be used.
|
||||
*
|
||||
* @return the View, or null if the method hasn't been annotated with @View.
|
||||
*/
|
||||
View getView();
|
||||
/**
|
||||
* Returns the {@link View} to be used.
|
||||
*
|
||||
* @return the View, or null if the method hasn't been annotated with @View.
|
||||
*/
|
||||
View getView();
|
||||
|
||||
}
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
|
||||
package org.springframework.data.couchbase.repository.support;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
@@ -26,91 +30,87 @@ import org.springframework.data.couchbase.core.query.View;
|
||||
import org.springframework.data.repository.core.RepositoryInformation;
|
||||
import org.springframework.data.repository.core.support.RepositoryProxyPostProcessor;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* {@link RepositoryProxyPostProcessor} that sets up an interceptor to read {@link View} information from the
|
||||
* invoked method. This is necessary to allow redeclaration of CRUD methods in repository interfaces and configure
|
||||
* view information on them.
|
||||
* {@link RepositoryProxyPostProcessor} that sets up an interceptor to read {@link View} information from the invoked
|
||||
* method. This is necessary to allow redeclaration of CRUD methods in repository interfaces and configure view
|
||||
* information on them.
|
||||
*
|
||||
* @author David Harrigan
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public enum ViewPostProcessor implements RepositoryProxyPostProcessor {
|
||||
|
||||
INSTANCE;
|
||||
INSTANCE;
|
||||
|
||||
private static final ThreadLocal<Map<Object, Object>> VIEW_METADATA = new NamedThreadLocal<Map<Object, Object>>("View Metadata");
|
||||
private static final ThreadLocal<Map<Object, Object>> VIEW_METADATA = new NamedThreadLocal<Map<Object, Object>>(
|
||||
"View Metadata");
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.core.support.RepositoryProxyPostProcessor#postProcess(org.springframework.aop.framework.ProxyFactory, org.springframework.data.repository.core.RepositoryInformation)
|
||||
*/
|
||||
@Override
|
||||
public void postProcess(ProxyFactory factory, RepositoryInformation repositoryInformation) {
|
||||
|
||||
factory.addAdvice(ExposeInvocationInterceptor.INSTANCE);
|
||||
factory.addAdvice(ViewInterceptor.INSTANCE);
|
||||
}
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.core.support.RepositoryProxyPostProcessor#postProcess(org.springframework.aop.framework.ProxyFactory, org.springframework.data.repository.core.RepositoryInformation)
|
||||
*/
|
||||
@Override
|
||||
public void postProcess(ProxyFactory factory, RepositoryInformation repositoryInformation) {
|
||||
|
||||
public ViewMetadataProvider getViewMetadataProvider() {
|
||||
return ThreadBoundViewMetadata.INSTANCE;
|
||||
}
|
||||
factory.addAdvice(ExposeInvocationInterceptor.INSTANCE);
|
||||
factory.addAdvice(ViewInterceptor.INSTANCE);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link MethodInterceptor} to inspect the currently invoked {@link Method} for a {@link View} annotation.
|
||||
* <p/>
|
||||
* If a View annotation is found, it will bind it to a locally held ThreadLocal for later lookup in the
|
||||
* SimpleCouchbaseRepository class.
|
||||
*
|
||||
* @author David Harrigan.
|
||||
*/
|
||||
static enum ViewInterceptor implements MethodInterceptor {
|
||||
public ViewMetadataProvider getViewMetadataProvider() {
|
||||
return ThreadBoundViewMetadata.INSTANCE;
|
||||
}
|
||||
|
||||
INSTANCE;
|
||||
/**
|
||||
* {@link MethodInterceptor} to inspect the currently invoked {@link Method} for a {@link View} annotation.
|
||||
* <p/>
|
||||
* If a View annotation is found, it will bind it to a locally held ThreadLocal for later lookup in the
|
||||
* SimpleCouchbaseRepository class.
|
||||
*
|
||||
* @author David Harrigan.
|
||||
*/
|
||||
static enum ViewInterceptor implements MethodInterceptor {
|
||||
|
||||
@Override
|
||||
public Object invoke(final MethodInvocation invocation) throws Throwable {
|
||||
INSTANCE;
|
||||
|
||||
final View view = AnnotationUtils.getAnnotation(invocation.getMethod(), View.class);
|
||||
if (view != null) {
|
||||
Map<Object, Object> map = VIEW_METADATA.get();
|
||||
if (map == null) {
|
||||
map = new HashMap<Object, Object>();
|
||||
VIEW_METADATA.set(map);
|
||||
}
|
||||
map.put(invocation.getMethod(), view);
|
||||
}
|
||||
try {
|
||||
return invocation.proceed();
|
||||
} finally {
|
||||
VIEW_METADATA.remove();
|
||||
}
|
||||
@Override
|
||||
public Object invoke(final MethodInvocation invocation) throws Throwable {
|
||||
|
||||
}
|
||||
final View view = AnnotationUtils.getAnnotation(invocation.getMethod(), View.class);
|
||||
if (view != null) {
|
||||
Map<Object, Object> map = VIEW_METADATA.get();
|
||||
if (map == null) {
|
||||
map = new HashMap<Object, Object>();
|
||||
VIEW_METADATA.set(map);
|
||||
}
|
||||
map.put(invocation.getMethod(), view);
|
||||
}
|
||||
try {
|
||||
return invocation.proceed();
|
||||
} finally {
|
||||
VIEW_METADATA.remove();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link ViewMetadataProvider} that looks up a bound View from a locally held ThreadLocal, using
|
||||
* the current method invocationas as the key. If not bound View is found, a null is returned.
|
||||
*
|
||||
* @author David Harrigan.
|
||||
*/
|
||||
private static enum ThreadBoundViewMetadata implements ViewMetadataProvider {
|
||||
}
|
||||
|
||||
INSTANCE;
|
||||
/**
|
||||
* {@link ViewMetadataProvider} that looks up a bound View from a locally held ThreadLocal, using the current method
|
||||
* invocationas as the key. If not bound View is found, a null is returned.
|
||||
*
|
||||
* @author David Harrigan.
|
||||
*/
|
||||
private static enum ThreadBoundViewMetadata implements ViewMetadataProvider {
|
||||
|
||||
@Override
|
||||
public View getView() {
|
||||
final MethodInvocation invocation = ExposeInvocationInterceptor.currentInvocation();
|
||||
final Map<Object, Object> map = VIEW_METADATA.get();
|
||||
return (map == null) ? null : (View) map.get(invocation.getMethod());
|
||||
}
|
||||
INSTANCE;
|
||||
|
||||
}
|
||||
@Override
|
||||
public View getView() {
|
||||
final MethodInvocation invocation = ExposeInvocationInterceptor.currentInvocation();
|
||||
final Map<Object, Object> map = VIEW_METADATA.get();
|
||||
return (map == null) ? null : (View) map.get(invocation.getMethod());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user