Introduce KeyspaceProvider to StatementFactory.
StatementFactory now accepts a KeyspaceProvider to determine a specific Keyspace for a built statement. StatementFactory can be obtained through CassandraTemplate and its async/reactive variants. Closes #1275
This commit is contained in:
@@ -27,6 +27,7 @@ import java.util.stream.StreamSupport;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
@@ -39,20 +40,7 @@ import org.springframework.data.cassandra.SessionFactory;
|
||||
import org.springframework.data.cassandra.core.EntityOperations.AdaptibleEntity;
|
||||
import org.springframework.data.cassandra.core.convert.CassandraConverter;
|
||||
import org.springframework.data.cassandra.core.convert.MappingCassandraConverter;
|
||||
import org.springframework.data.cassandra.core.cql.AsyncCqlOperations;
|
||||
import org.springframework.data.cassandra.core.cql.AsyncCqlTemplate;
|
||||
import org.springframework.data.cassandra.core.cql.AsyncPreparedStatementCreator;
|
||||
import org.springframework.data.cassandra.core.cql.AsyncResultSetExtractor;
|
||||
import org.springframework.data.cassandra.core.cql.AsyncSessionCallback;
|
||||
import org.springframework.data.cassandra.core.cql.CassandraAccessor;
|
||||
import org.springframework.data.cassandra.core.cql.CqlProvider;
|
||||
import org.springframework.data.cassandra.core.cql.PreparedStatementBinder;
|
||||
import org.springframework.data.cassandra.core.cql.QueryExtractorDelegate;
|
||||
import org.springframework.data.cassandra.core.cql.QueryOptions;
|
||||
import org.springframework.data.cassandra.core.cql.RowCallbackHandler;
|
||||
import org.springframework.data.cassandra.core.cql.RowMapper;
|
||||
import org.springframework.data.cassandra.core.cql.SingleColumnRowMapper;
|
||||
import org.springframework.data.cassandra.core.cql.WriteOptions;
|
||||
import org.springframework.data.cassandra.core.cql.*;
|
||||
import org.springframework.data.cassandra.core.cql.session.DefaultSessionFactory;
|
||||
import org.springframework.data.cassandra.core.cql.util.StatementBuilder;
|
||||
import org.springframework.data.cassandra.core.mapping.CassandraPersistentEntity;
|
||||
@@ -244,6 +232,17 @@ public class AsyncCassandraTemplate
|
||||
return this.converter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link StatementFactory} used by this template to construct and run Cassandra CQL statements.
|
||||
*
|
||||
* @return the {@link StatementFactory} used by this template to construct and run Cassandra CQL statements.
|
||||
* @see StatementFactory
|
||||
* @since 2.1
|
||||
*/
|
||||
public StatementFactory getStatementFactory() {
|
||||
return this.statementFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this instance is configured to use {@link PreparedStatement prepared statements}. If enabled
|
||||
* (default), then all persistence methods (such as {@link #select}, {@link #update}, and others) will make use of
|
||||
@@ -300,17 +299,6 @@ public class AsyncCassandraTemplate
|
||||
return getEntityOperations().getRequiredPersistentEntity(entityType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link StatementFactory} used by this template to construct and run Cassandra CQL statements.
|
||||
*
|
||||
* @return the {@link StatementFactory} used by this template to construct and run Cassandra CQL statements.
|
||||
* @see StatementFactory
|
||||
* @since 2.1
|
||||
*/
|
||||
protected StatementFactory getStatementFactory() {
|
||||
return this.statementFactory;
|
||||
}
|
||||
|
||||
private CqlIdentifier getTableName(Class<?> entityClass) {
|
||||
return getEntityOperations().getTableName(entityClass);
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ import java.util.Arrays;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.springframework.data.cassandra.core.convert.CassandraConverter;
|
||||
import org.springframework.data.cassandra.core.convert.UpdateMapper;
|
||||
import org.springframework.data.cassandra.core.cql.QueryOptions;
|
||||
import org.springframework.data.cassandra.core.cql.WriteOptions;
|
||||
import org.springframework.data.cassandra.core.mapping.BasicCassandraPersistentEntity;
|
||||
@@ -66,7 +65,7 @@ class CassandraBatchTemplate implements CassandraBatchOperations {
|
||||
* @param batchType must not be {@literal null}.
|
||||
* @since 3.2.6
|
||||
*/
|
||||
CassandraBatchTemplate(CassandraOperations operations, BatchType batchType) {
|
||||
CassandraBatchTemplate(CassandraTemplate operations, BatchType batchType) {
|
||||
|
||||
Assert.notNull(operations, "CassandraOperations must not be null");
|
||||
Assert.notNull(batchType, "BatchType must not be null");
|
||||
@@ -75,7 +74,7 @@ class CassandraBatchTemplate implements CassandraBatchOperations {
|
||||
this.batch = BatchStatement.builder(batchType);
|
||||
this.converter = operations.getConverter();
|
||||
this.mappingContext = this.converter.getMappingContext();
|
||||
this.statementFactory = new StatementFactory(new UpdateMapper(converter));
|
||||
this.statementFactory = operations.getStatementFactory();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.util.stream.Stream;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
@@ -35,20 +36,7 @@ import org.springframework.data.cassandra.SessionFactory;
|
||||
import org.springframework.data.cassandra.core.EntityOperations.AdaptibleEntity;
|
||||
import org.springframework.data.cassandra.core.convert.CassandraConverter;
|
||||
import org.springframework.data.cassandra.core.convert.MappingCassandraConverter;
|
||||
import org.springframework.data.cassandra.core.convert.QueryMapper;
|
||||
import org.springframework.data.cassandra.core.convert.UpdateMapper;
|
||||
import org.springframework.data.cassandra.core.cql.CassandraAccessor;
|
||||
import org.springframework.data.cassandra.core.cql.CqlOperations;
|
||||
import org.springframework.data.cassandra.core.cql.CqlProvider;
|
||||
import org.springframework.data.cassandra.core.cql.CqlTemplate;
|
||||
import org.springframework.data.cassandra.core.cql.PreparedStatementBinder;
|
||||
import org.springframework.data.cassandra.core.cql.PreparedStatementCreator;
|
||||
import org.springframework.data.cassandra.core.cql.QueryExtractorDelegate;
|
||||
import org.springframework.data.cassandra.core.cql.QueryOptions;
|
||||
import org.springframework.data.cassandra.core.cql.RowMapper;
|
||||
import org.springframework.data.cassandra.core.cql.SessionCallback;
|
||||
import org.springframework.data.cassandra.core.cql.SingleColumnRowMapper;
|
||||
import org.springframework.data.cassandra.core.cql.WriteOptions;
|
||||
import org.springframework.data.cassandra.core.cql.*;
|
||||
import org.springframework.data.cassandra.core.cql.session.DefaultSessionFactory;
|
||||
import org.springframework.data.cassandra.core.cql.util.StatementBuilder;
|
||||
import org.springframework.data.cassandra.core.mapping.CassandraPersistentEntity;
|
||||
@@ -193,7 +181,7 @@ public class CassandraTemplate implements CassandraOperations, ApplicationEventP
|
||||
this.converter = converter;
|
||||
this.cqlOperations = cqlOperations;
|
||||
this.entityOperations = new EntityOperations(converter);
|
||||
this.statementFactory = new StatementFactory(new QueryMapper(converter), new UpdateMapper(converter));
|
||||
this.statementFactory = new StatementFactory(converter);
|
||||
this.eventDelegate = new EntityLifecycleEventDelegate();
|
||||
}
|
||||
|
||||
@@ -246,6 +234,17 @@ public class CassandraTemplate implements CassandraOperations, ApplicationEventP
|
||||
return this.converter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link StatementFactory} used by this template to construct and run Cassandra CQL statements.
|
||||
*
|
||||
* @return the {@link StatementFactory} used by this template to construct and run Cassandra CQL statements.
|
||||
* @see org.springframework.data.cassandra.core.StatementFactory
|
||||
* @since 2.1
|
||||
*/
|
||||
public StatementFactory getStatementFactory() {
|
||||
return this.statementFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this instance is configured to use {@link PreparedStatement prepared statements}. If enabled
|
||||
* (default), then all persistence methods (such as {@link #select}, {@link #update}, and others) will make use of
|
||||
@@ -301,17 +300,6 @@ public class CassandraTemplate implements CassandraOperations, ApplicationEventP
|
||||
return getEntityOperations().getRequiredPersistentEntity(entityType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link StatementFactory} used by this template to construct and run Cassandra CQL statements.
|
||||
*
|
||||
* @return the {@link StatementFactory} used by this template to construct and run Cassandra CQL statements.
|
||||
* @see org.springframework.data.cassandra.core.StatementFactory
|
||||
* @since 2.1
|
||||
*/
|
||||
protected StatementFactory getStatementFactory() {
|
||||
return this.statementFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CqlIdentifier getTableName(Class<?> entityClass) {
|
||||
return getEntityOperations().getTableName(entityClass);
|
||||
|
||||
@@ -26,7 +26,6 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.springframework.data.cassandra.core.convert.CassandraConverter;
|
||||
import org.springframework.data.cassandra.core.convert.UpdateMapper;
|
||||
import org.springframework.data.cassandra.core.cql.QueryOptions;
|
||||
import org.springframework.data.cassandra.core.cql.WriteOptions;
|
||||
import org.springframework.data.cassandra.core.mapping.BasicCassandraPersistentEntity;
|
||||
@@ -74,7 +73,7 @@ class ReactiveCassandraBatchTemplate implements ReactiveCassandraBatchOperations
|
||||
* @param batchType must not be {@literal null}.
|
||||
* @since 3.2.6
|
||||
*/
|
||||
ReactiveCassandraBatchTemplate(ReactiveCassandraOperations operations, BatchType batchType) {
|
||||
ReactiveCassandraBatchTemplate(ReactiveCassandraTemplate operations, BatchType batchType) {
|
||||
|
||||
Assert.notNull(operations, "CassandraOperations must not be null");
|
||||
Assert.notNull(batchType, "BatchType must not be null");
|
||||
@@ -83,7 +82,7 @@ class ReactiveCassandraBatchTemplate implements ReactiveCassandraBatchOperations
|
||||
this.batch = BatchStatement.builder(batchType);
|
||||
this.converter = operations.getConverter();
|
||||
this.mappingContext = this.converter.getMappingContext();
|
||||
this.statementFactory = new StatementFactory(new UpdateMapper(converter));
|
||||
this.statementFactory = operations.getStatementFactory();
|
||||
}
|
||||
|
||||
private void assertNotExecuted() {
|
||||
|
||||
@@ -27,6 +27,7 @@ import java.util.function.Supplier;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.reactivestreams.Publisher;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
@@ -41,18 +42,7 @@ import org.springframework.data.cassandra.ReactiveSessionFactory;
|
||||
import org.springframework.data.cassandra.core.EntityOperations.AdaptibleEntity;
|
||||
import org.springframework.data.cassandra.core.convert.CassandraConverter;
|
||||
import org.springframework.data.cassandra.core.convert.MappingCassandraConverter;
|
||||
import org.springframework.data.cassandra.core.cql.CassandraAccessor;
|
||||
import org.springframework.data.cassandra.core.cql.CqlProvider;
|
||||
import org.springframework.data.cassandra.core.cql.PreparedStatementBinder;
|
||||
import org.springframework.data.cassandra.core.cql.QueryExtractorDelegate;
|
||||
import org.springframework.data.cassandra.core.cql.QueryOptions;
|
||||
import org.springframework.data.cassandra.core.cql.ReactiveCqlOperations;
|
||||
import org.springframework.data.cassandra.core.cql.ReactiveCqlTemplate;
|
||||
import org.springframework.data.cassandra.core.cql.ReactivePreparedStatementCreator;
|
||||
import org.springframework.data.cassandra.core.cql.ReactiveSessionCallback;
|
||||
import org.springframework.data.cassandra.core.cql.RowMapper;
|
||||
import org.springframework.data.cassandra.core.cql.SingleColumnRowMapper;
|
||||
import org.springframework.data.cassandra.core.cql.WriteOptions;
|
||||
import org.springframework.data.cassandra.core.cql.*;
|
||||
import org.springframework.data.cassandra.core.cql.session.DefaultReactiveSessionFactory;
|
||||
import org.springframework.data.cassandra.core.cql.util.StatementBuilder;
|
||||
import org.springframework.data.cassandra.core.mapping.CassandraPersistentEntity;
|
||||
@@ -253,6 +243,17 @@ public class ReactiveCassandraTemplate
|
||||
return this.converter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link StatementFactory} used by this template to construct and run Cassandra CQL statements.
|
||||
*
|
||||
* @return the {@link StatementFactory} used by this template to construct and run Cassandra CQL statements.
|
||||
* @see org.springframework.data.cassandra.core.StatementFactory
|
||||
* @since 2.1
|
||||
*/
|
||||
public StatementFactory getStatementFactory() {
|
||||
return this.statementFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this instance is configured to use {@link PreparedStatement prepared statements}. If enabled
|
||||
* (default), then all persistence methods (such as {@link #select}, {@link #update}, and others) will make use of
|
||||
@@ -309,17 +310,6 @@ public class ReactiveCassandraTemplate
|
||||
return getEntityOperations().getRequiredPersistentEntity(entityType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link StatementFactory} used by this template to construct and run Cassandra CQL statements.
|
||||
*
|
||||
* @return the {@link StatementFactory} used by this template to construct and run Cassandra CQL statements.
|
||||
* @see org.springframework.data.cassandra.core.StatementFactory
|
||||
* @since 2.1
|
||||
*/
|
||||
protected StatementFactory getStatementFactory() {
|
||||
return this.statementFactory;
|
||||
}
|
||||
|
||||
CqlIdentifier getTableName(Class<?> entityClass) {
|
||||
return getRequiredPersistentEntity(entityClass).getTableName();
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ import org.springframework.data.cassandra.core.cql.QueryOptionsUtil.CqlStatement
|
||||
import org.springframework.data.cassandra.core.cql.WriteOptions;
|
||||
import org.springframework.data.cassandra.core.cql.util.StatementBuilder;
|
||||
import org.springframework.data.cassandra.core.cql.util.TermFactory;
|
||||
import org.springframework.data.cassandra.core.mapping.BasicCassandraPersistentEntity;
|
||||
import org.springframework.data.cassandra.core.mapping.CassandraPersistentEntity;
|
||||
import org.springframework.data.cassandra.core.mapping.CassandraPersistentProperty;
|
||||
import org.springframework.data.cassandra.core.mapping.PersistentPropertyTranslator;
|
||||
@@ -64,6 +65,7 @@ import org.springframework.data.mapping.PersistentProperty;
|
||||
import org.springframework.data.projection.EntityProjection;
|
||||
import org.springframework.data.projection.ProjectionInformation;
|
||||
import org.springframework.data.util.Predicates;
|
||||
import org.springframework.data.util.ProxyUtils;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -108,6 +110,8 @@ public class StatementFactory {
|
||||
|
||||
private final UpdateMapper updateMapper;
|
||||
|
||||
private KeyspaceProvider keyspaceProvider = KeyspaceProviders.EMPTY_KEYSPACE;
|
||||
|
||||
/**
|
||||
* Create {@link StatementFactory} given {@link CassandraConverter}.
|
||||
*
|
||||
@@ -117,6 +121,7 @@ public class StatementFactory {
|
||||
public StatementFactory(CassandraConverter converter) {
|
||||
|
||||
Assert.notNull(converter, "CassandraConverter must not be null");
|
||||
|
||||
this.cassandraConverter = converter;
|
||||
|
||||
UpdateMapper updateMapper = new UpdateMapper(converter);
|
||||
@@ -169,20 +174,34 @@ public class StatementFactory {
|
||||
return this.updateMapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link KeyspaceProvider} to determine the {@link CqlIdentifier keyspace} for a
|
||||
* {@link CassandraPersistentEntity entity}-related statement.
|
||||
*
|
||||
* @param keyspaceProvider the keyspace provider to use, must not be {@literal null}.
|
||||
* @since 4.4
|
||||
*/
|
||||
public void setKeyspaceProvider(KeyspaceProvider keyspaceProvider) {
|
||||
|
||||
Assert.notNull(keyspaceProvider, "KeyspaceProvider must not be null");
|
||||
|
||||
this.keyspaceProvider = keyspaceProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@literal COUNT} statement by mapping {@link Query} to {@link Select}.
|
||||
*
|
||||
* @param query user-defined count {@link Query} to execute; must not be {@literal null}.
|
||||
* @param persistentEntity {@link CassandraPersistentEntity entity} to count; must not be {@literal null}.
|
||||
* @param entity {@link CassandraPersistentEntity entity} to count; must not be {@literal null}.
|
||||
* @return the select builder.
|
||||
* @since 2.1
|
||||
*/
|
||||
public StatementBuilder<Select> count(Query query, CassandraPersistentEntity<?> persistentEntity) {
|
||||
public StatementBuilder<Select> count(Query query, CassandraPersistentEntity<?> entity) {
|
||||
|
||||
Assert.notNull(query, "Query must not be null");
|
||||
Assert.notNull(persistentEntity, "CassandraPersistentEntity must not be null");
|
||||
Assert.notNull(entity, "CassandraPersistentEntity must not be null");
|
||||
|
||||
return count(query, persistentEntity, persistentEntity.getTableName());
|
||||
return count(query, entity, entity.getTableName());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -208,18 +227,18 @@ public class StatementFactory {
|
||||
* {@link UpdateOptions}.
|
||||
*
|
||||
* @param id must not be {@literal null}.
|
||||
* @param persistentEntity must not be {@literal null}.
|
||||
* @param entity must not be {@literal null}.
|
||||
* @param tableName must not be {@literal null}.
|
||||
* @return the select builder.
|
||||
*/
|
||||
public StatementBuilder<Select> selectOneById(Object id, CassandraPersistentEntity<?> persistentEntity,
|
||||
public StatementBuilder<Select> selectOneById(Object id, CassandraPersistentEntity<?> entity,
|
||||
CqlIdentifier tableName) {
|
||||
|
||||
Where where = new Where();
|
||||
|
||||
cassandraConverter.write(id, where, persistentEntity);
|
||||
cassandraConverter.write(id, where, entity);
|
||||
|
||||
return StatementBuilder.of(QueryBuilder.selectFrom(tableName).all().limit(1))
|
||||
return StatementBuilder.of(QueryBuilder.selectFrom(getKeyspace(entity, tableName), tableName).all().limit(1))
|
||||
.bind((statement, factory) -> statement.where(toRelations(where, factory)));
|
||||
}
|
||||
|
||||
@@ -227,38 +246,37 @@ public class StatementFactory {
|
||||
* Create a {@literal SELECT} statement by mapping {@link Query} to {@link Select}.
|
||||
*
|
||||
* @param query must not be {@literal null}.
|
||||
* @param persistentEntity must not be {@literal null}.
|
||||
* @param entity must not be {@literal null}.
|
||||
* @return the select builder.
|
||||
*/
|
||||
public StatementBuilder<Select> select(Query query, CassandraPersistentEntity<?> persistentEntity) {
|
||||
public StatementBuilder<Select> select(Query query, CassandraPersistentEntity<?> entity) {
|
||||
|
||||
Assert.notNull(query, "Query must not be null");
|
||||
Assert.notNull(persistentEntity, "CassandraPersistentEntity must not be null");
|
||||
Assert.notNull(entity, "CassandraPersistentEntity must not be null");
|
||||
|
||||
return select(query, persistentEntity, persistentEntity.getTableName());
|
||||
return select(query, entity, entity.getTableName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@literal SELECT} statement by mapping {@link Query} to {@link Select}.
|
||||
*
|
||||
* @param query must not be {@literal null}.
|
||||
* @param persistentEntity must not be {@literal null}.
|
||||
* @param entity must not be {@literal null}.
|
||||
* @param tableName must not be {@literal null}.
|
||||
* @return the select builder.
|
||||
* @since 2.1
|
||||
*/
|
||||
public StatementBuilder<Select> select(Query query, CassandraPersistentEntity<?> persistentEntity,
|
||||
CqlIdentifier tableName) {
|
||||
public StatementBuilder<Select> select(Query query, CassandraPersistentEntity<?> entity, CqlIdentifier tableName) {
|
||||
|
||||
Assert.notNull(query, "Query must not be null");
|
||||
Assert.notNull(persistentEntity, "CassandraPersistentEntity must not be null");
|
||||
Assert.notNull(persistentEntity, "Table name must not be null");
|
||||
Assert.notNull(entity, "CassandraPersistentEntity must not be null");
|
||||
Assert.notNull(entity, "Table name must not be null");
|
||||
|
||||
Filter filter = getQueryMapper().getMappedObject(query, persistentEntity);
|
||||
Filter filter = getQueryMapper().getMappedObject(query, entity);
|
||||
|
||||
List<Selector> selectors = getQueryMapper().getMappedSelectors(query.getColumns(), persistentEntity);
|
||||
List<Selector> selectors = getQueryMapper().getMappedSelectors(query.getColumns(), entity);
|
||||
|
||||
return createSelect(query, persistentEntity, filter, selectors, tableName);
|
||||
return createSelect(query, entity, filter, selectors, tableName);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -274,9 +292,9 @@ public class StatementFactory {
|
||||
Assert.notNull(objectToInsert, "Object to builder must not be null");
|
||||
Assert.notNull(options, "WriteOptions must not be null");
|
||||
|
||||
CassandraPersistentEntity<?> persistentEntity = cassandraConverter.getMappingContext()
|
||||
CassandraPersistentEntity<?> entity = cassandraConverter.getMappingContext()
|
||||
.getRequiredPersistentEntity(objectToInsert.getClass());
|
||||
return insert(objectToInsert, options, persistentEntity, persistentEntity.getTableName());
|
||||
return insert(objectToInsert, options, entity, entity.getTableName());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -285,15 +303,15 @@ public class StatementFactory {
|
||||
* @param tableName the table name, must not be empty and not {@literal null}.
|
||||
* @param objectToInsert the object to save, must not be {@literal null}.
|
||||
* @param options optional {@link WriteOptions} to apply to the {@link Insert} statement, may be {@literal null}.
|
||||
* @param persistentEntity the {@link CassandraPersistentEntity} to write insert values.
|
||||
* @param entity the {@link CassandraPersistentEntity} to write insert values.
|
||||
* @return the select builder.
|
||||
*/
|
||||
public StatementBuilder<RegularInsert> insert(Object objectToInsert, WriteOptions options,
|
||||
CassandraPersistentEntity<?> persistentEntity, CqlIdentifier tableName) {
|
||||
CassandraPersistentEntity<?> entity, CqlIdentifier tableName) {
|
||||
|
||||
Assert.notNull(tableName, "TableName must not be null");
|
||||
Assert.notNull(objectToInsert, "Object to insert must not be null");
|
||||
Assert.notNull(persistentEntity, "CassandraPersistentEntity must not be null");
|
||||
Assert.notNull(entity, "CassandraPersistentEntity must not be null");
|
||||
|
||||
boolean insertNulls;
|
||||
|
||||
@@ -304,10 +322,11 @@ public class StatementFactory {
|
||||
}
|
||||
|
||||
Map<CqlIdentifier, Object> object = new LinkedHashMap<>();
|
||||
cassandraConverter.write(objectToInsert, object, persistentEntity);
|
||||
cassandraConverter.write(objectToInsert, object, entity);
|
||||
|
||||
StatementBuilder<RegularInsert> builder = StatementBuilder
|
||||
.of(QueryBuilder.insertInto(tableName).valuesByIds(Collections.emptyMap())).bind((statement, factory) -> {
|
||||
.of(QueryBuilder.insertInto(getKeyspace(entity, tableName), tableName).valuesByIds(Collections.emptyMap()))
|
||||
.bind((statement, factory) -> {
|
||||
|
||||
Map<CqlIdentifier, Term> values = createTerms(insertNulls, object, factory);
|
||||
CqlStatementOptionsAccessor<Insert> accessor = factory.ifBoundOrInline(
|
||||
@@ -342,17 +361,17 @@ public class StatementFactory {
|
||||
* Create an {@literal UPDATE} statement by mapping {@link Query} to {@link Update}.
|
||||
*
|
||||
* @param query must not be {@literal null}.
|
||||
* @param persistentEntity must not be {@literal null}.
|
||||
* @param entity must not be {@literal null}.
|
||||
* @return the update builder.
|
||||
*/
|
||||
public StatementBuilder<com.datastax.oss.driver.api.querybuilder.update.Update> update(Query query, Update update,
|
||||
CassandraPersistentEntity<?> persistentEntity) {
|
||||
CassandraPersistentEntity<?> entity) {
|
||||
|
||||
Assert.notNull(query, "Query must not be null");
|
||||
Assert.notNull(update, "Update must not be null");
|
||||
Assert.notNull(persistentEntity, "CassandraPersistentEntity must not be null");
|
||||
Assert.notNull(entity, "CassandraPersistentEntity must not be null");
|
||||
|
||||
return update(query, update, persistentEntity, persistentEntity.getTableName());
|
||||
return update(query, update, entity, entity.getTableName());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -360,25 +379,26 @@ public class StatementFactory {
|
||||
*
|
||||
* @param query must not be {@literal null}.
|
||||
* @param update must not be {@literal null}.
|
||||
* @param persistentEntity must not be {@literal null}.
|
||||
* @param entity must not be {@literal null}.
|
||||
* @param tableName must not be {@literal null}.
|
||||
* @return the update builder.
|
||||
* @since 2.1
|
||||
*/
|
||||
StatementBuilder<com.datastax.oss.driver.api.querybuilder.update.Update> update(Query query, Update update,
|
||||
CassandraPersistentEntity<?> persistentEntity, CqlIdentifier tableName) {
|
||||
CassandraPersistentEntity<?> entity, CqlIdentifier tableName) {
|
||||
|
||||
Assert.notNull(query, "Query must not be null");
|
||||
Assert.notNull(update, "Update must not be null");
|
||||
Assert.notNull(persistentEntity, "CassandraPersistentEntity must not be null");
|
||||
Assert.notNull(entity, "CassandraPersistentEntity must not be null");
|
||||
Assert.notNull(tableName, "Table name must not be null");
|
||||
|
||||
Filter filter = getQueryMapper().getMappedObject(query, persistentEntity);
|
||||
Filter filter = getQueryMapper().getMappedObject(query, entity);
|
||||
|
||||
Update mappedUpdate = getUpdateMapper().getMappedObject(update, persistentEntity);
|
||||
Update mappedUpdate = getUpdateMapper().getMappedObject(update, entity);
|
||||
|
||||
StatementBuilder<com.datastax.oss.driver.api.querybuilder.update.Update> builder = update(tableName, mappedUpdate,
|
||||
filter, query.getQueryOptions().filter(WriteOptions.class::isInstance).map(WriteOptions.class::cast));
|
||||
StatementBuilder<com.datastax.oss.driver.api.querybuilder.update.Update> builder = update(entity, tableName,
|
||||
mappedUpdate, filter,
|
||||
query.getQueryOptions().filter(WriteOptions.class::isInstance).map(WriteOptions.class::cast));
|
||||
|
||||
query.getQueryOptions().filter(UpdateOptions.class::isInstance).map(UpdateOptions.class::cast)
|
||||
.map(UpdateOptions::getIfCondition)
|
||||
@@ -405,10 +425,10 @@ public class StatementFactory {
|
||||
Assert.notNull(objectToUpdate, "Object to builder must not be null");
|
||||
Assert.notNull(options, "WriteOptions must not be null");
|
||||
|
||||
CassandraPersistentEntity<?> persistentEntity = cassandraConverter.getMappingContext()
|
||||
CassandraPersistentEntity<?> entity = cassandraConverter.getMappingContext()
|
||||
.getRequiredPersistentEntity(objectToUpdate.getClass());
|
||||
|
||||
return update(objectToUpdate, options, persistentEntity, persistentEntity.getTableName());
|
||||
return update(objectToUpdate, options, entity, entity.getTableName());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -437,7 +457,7 @@ public class StatementFactory {
|
||||
where.forEach((cqlIdentifier, o) -> object.remove(cqlIdentifier));
|
||||
|
||||
StatementBuilder<com.datastax.oss.driver.api.querybuilder.update.Update> builder = StatementBuilder
|
||||
.of(QueryBuilder.update(tableName).set().where()).bind((statement, factory) -> {
|
||||
.of(QueryBuilder.update(getKeyspace(entity, tableName), tableName).set().where()).bind((statement, factory) -> {
|
||||
|
||||
CqlStatementOptionsAccessor<UpdateStart> accessor = factory.ifBoundOrInline(
|
||||
bindings -> CqlStatementOptionsAccessor.ofUpdate(bindings, (UpdateStart) statement),
|
||||
@@ -462,18 +482,17 @@ public class StatementFactory {
|
||||
* {@link UpdateOptions}.
|
||||
*
|
||||
* @param id must not be {@literal null}.
|
||||
* @param persistentEntity must not be {@literal null}.
|
||||
* @param entity must not be {@literal null}.
|
||||
* @param tableName must not be {@literal null}.
|
||||
* @return the delete builder.
|
||||
*/
|
||||
public StatementBuilder<Delete> deleteById(Object id, CassandraPersistentEntity<?> persistentEntity,
|
||||
CqlIdentifier tableName) {
|
||||
public StatementBuilder<Delete> deleteById(Object id, CassandraPersistentEntity<?> entity, CqlIdentifier tableName) {
|
||||
|
||||
Where where = new Where();
|
||||
|
||||
cassandraConverter.write(id, where, persistentEntity);
|
||||
cassandraConverter.write(id, where, entity);
|
||||
|
||||
return StatementBuilder.of(QueryBuilder.deleteFrom(tableName).where())
|
||||
return StatementBuilder.of(QueryBuilder.deleteFrom(getKeyspace(entity, tableName), tableName).where())
|
||||
.bind((statement, factory) -> statement.where(toRelations(where, factory)));
|
||||
}
|
||||
|
||||
@@ -481,37 +500,36 @@ public class StatementFactory {
|
||||
* Create a {@literal DELETE} statement by mapping {@link Query} to {@link Delete}.
|
||||
*
|
||||
* @param query must not be {@literal null}.
|
||||
* @param persistentEntity must not be {@literal null}.
|
||||
* @param entity must not be {@literal null}.
|
||||
* @return the delete builder.
|
||||
*/
|
||||
public StatementBuilder<Delete> delete(Query query, CassandraPersistentEntity<?> persistentEntity) {
|
||||
public StatementBuilder<Delete> delete(Query query, CassandraPersistentEntity<?> entity) {
|
||||
|
||||
Assert.notNull(query, "Query must not be null");
|
||||
Assert.notNull(persistentEntity, "CassandraPersistentEntity must not be null");
|
||||
Assert.notNull(entity, "CassandraPersistentEntity must not be null");
|
||||
|
||||
return delete(query, persistentEntity, persistentEntity.getTableName());
|
||||
return delete(query, entity, entity.getTableName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@literal DELETE} statement by mapping {@link Query} to {@link Delete}.
|
||||
*
|
||||
* @param query must not be {@literal null}.
|
||||
* @param persistentEntity must not be {@literal null}.
|
||||
* @param entity must not be {@literal null}.
|
||||
* @param tableName must not be {@literal null}.
|
||||
* @return the delete builder.
|
||||
* @see 2.1
|
||||
*/
|
||||
public StatementBuilder<Delete> delete(Query query, CassandraPersistentEntity<?> persistentEntity,
|
||||
CqlIdentifier tableName) {
|
||||
public StatementBuilder<Delete> delete(Query query, CassandraPersistentEntity<?> entity, CqlIdentifier tableName) {
|
||||
|
||||
Assert.notNull(query, "Query must not be null");
|
||||
Assert.notNull(persistentEntity, "CassandraPersistentEntity must not be null");
|
||||
Assert.notNull(entity, "CassandraPersistentEntity must not be null");
|
||||
Assert.notNull(tableName, "Table name must not be null");
|
||||
|
||||
Filter filter = getQueryMapper().getMappedObject(query, persistentEntity);
|
||||
List<CqlIdentifier> columnNames = getQueryMapper().getMappedColumnNames(query.getColumns(), persistentEntity);
|
||||
Filter filter = getQueryMapper().getMappedObject(query, entity);
|
||||
List<CqlIdentifier> columnNames = getQueryMapper().getMappedColumnNames(query.getColumns(), entity);
|
||||
|
||||
StatementBuilder<Delete> builder = delete(columnNames, tableName, filter,
|
||||
StatementBuilder<Delete> builder = delete(columnNames, entity, tableName, filter,
|
||||
query.getQueryOptions().filter(WriteOptions.class::isInstance).map(WriteOptions.class::cast));
|
||||
|
||||
query.getQueryOptions().filter(DeleteOptions.class::isInstance).map(DeleteOptions.class::cast)
|
||||
@@ -543,8 +561,11 @@ public class StatementFactory {
|
||||
|
||||
Where where = new Where();
|
||||
entityWriter.write(entity, where);
|
||||
BasicCassandraPersistentEntity<?> persistentEntity = cassandraConverter.getMappingContext()
|
||||
.getRequiredPersistentEntity(ProxyUtils.getUserClass(entity.getClass()));
|
||||
|
||||
StatementBuilder<Delete> builder = StatementBuilder.of(QueryBuilder.deleteFrom(tableName).where())
|
||||
StatementBuilder<Delete> builder = StatementBuilder
|
||||
.of(QueryBuilder.deleteFrom(getKeyspace(persistentEntity, tableName), tableName).where())
|
||||
.bind((statement, factory) -> {
|
||||
|
||||
Delete statementToUse;
|
||||
@@ -595,9 +616,9 @@ public class StatementFactory {
|
||||
PersistentPropertyTranslator translator = PersistentPropertyTranslator.create(domainType,
|
||||
Predicates.negate(CassandraPersistentProperty::hasExplicitColumnName));
|
||||
|
||||
CassandraPersistentEntity<?> persistentEntity = getQueryMapper().getConverter().getMappingContext()
|
||||
CassandraPersistentEntity<?> entity = getQueryMapper().getConverter().getMappingContext()
|
||||
.getRequiredPersistentEntity(projection.getMappedType());
|
||||
for (CassandraPersistentProperty property : persistentEntity) {
|
||||
for (CassandraPersistentProperty property : entity) {
|
||||
columns.include(translator.translate(property).getColumnName());
|
||||
}
|
||||
}
|
||||
@@ -630,7 +651,7 @@ public class StatementFactory {
|
||||
Sort sort = Optional.of(query.getSort()).map(querySort -> getQueryMapper().getMappedSort(querySort, entity))
|
||||
.orElse(Sort.unsorted());
|
||||
|
||||
StatementBuilder<Select> select = createSelectAndOrder(selectors, tableName, filter, sort);
|
||||
StatementBuilder<Select> select = createSelectAndOrder(selectors, entity, tableName, filter, sort);
|
||||
|
||||
if (query.isAllowFiltering()) {
|
||||
select.apply(Select::allowFiltering);
|
||||
@@ -651,13 +672,18 @@ public class StatementFactory {
|
||||
return select;
|
||||
}
|
||||
|
||||
private static StatementBuilder<Select> createSelectAndOrder(List<Selector> selectors, CqlIdentifier from,
|
||||
Filter filter, Sort sort) {
|
||||
@Nullable
|
||||
private CqlIdentifier getKeyspace(CassandraPersistentEntity<?> entity, CqlIdentifier tableName) {
|
||||
return keyspaceProvider.getKeyspace(entity, tableName);
|
||||
}
|
||||
|
||||
private StatementBuilder<Select> createSelectAndOrder(List<Selector> selectors, CassandraPersistentEntity<?> entity,
|
||||
CqlIdentifier from, Filter filter, Sort sort) {
|
||||
|
||||
Select select;
|
||||
|
||||
if (selectors.isEmpty()) {
|
||||
select = QueryBuilder.selectFrom(from).all();
|
||||
select = QueryBuilder.selectFrom(getKeyspace(entity, from), from).all();
|
||||
} else {
|
||||
|
||||
List<com.datastax.oss.driver.api.querybuilder.select.Selector> mappedSelectors = new ArrayList<>(
|
||||
@@ -668,7 +694,7 @@ public class StatementFactory {
|
||||
mappedSelectors.add(orElseGet);
|
||||
}
|
||||
|
||||
select = QueryBuilder.selectFrom(from).selectors(mappedSelectors);
|
||||
select = QueryBuilder.selectFrom(getKeyspace(entity, from), from).selectors(mappedSelectors);
|
||||
}
|
||||
|
||||
StatementBuilder<Select> builder = StatementBuilder.of(select);
|
||||
@@ -726,10 +752,11 @@ public class StatementFactory {
|
||||
.column(CqlIdentifier.fromInternal(selector.getExpression()));
|
||||
}
|
||||
|
||||
private static StatementBuilder<com.datastax.oss.driver.api.querybuilder.update.Update> update(CqlIdentifier table,
|
||||
Update mappedUpdate, Filter filter, Optional<WriteOptions> optionalOptions) {
|
||||
private StatementBuilder<com.datastax.oss.driver.api.querybuilder.update.Update> update(
|
||||
CassandraPersistentEntity<?> entity, CqlIdentifier table, Update mappedUpdate, Filter filter,
|
||||
Optional<WriteOptions> optionalOptions) {
|
||||
|
||||
UpdateStart updateStart = QueryBuilder.update(table);
|
||||
UpdateStart updateStart = QueryBuilder.update(getKeyspace(entity, table), table);
|
||||
|
||||
return StatementBuilder.of((com.datastax.oss.driver.api.querybuilder.update.Update) updateStart)
|
||||
.bind((statement, factory) -> {
|
||||
@@ -882,10 +909,10 @@ public class StatementFactory {
|
||||
return Assignment.append(updateOp.toCqlIdentifier(), termFactory.create(updateOp.getValue()));
|
||||
}
|
||||
|
||||
private StatementBuilder<Delete> delete(List<CqlIdentifier> columnNames, CqlIdentifier from, Filter filter,
|
||||
Optional<WriteOptions> optionsOptional) {
|
||||
private StatementBuilder<Delete> delete(List<CqlIdentifier> columnNames, CassandraPersistentEntity<?> entity,
|
||||
CqlIdentifier from, Filter filter, Optional<WriteOptions> optionsOptional) {
|
||||
|
||||
DeleteSelection select = QueryBuilder.deleteFrom(from);
|
||||
DeleteSelection select = QueryBuilder.deleteFrom(getKeyspace(entity, from), from);
|
||||
|
||||
for (CqlIdentifier columnName : columnNames) {
|
||||
select = select.column(columnName);
|
||||
@@ -1201,4 +1228,38 @@ public class StatementFactory {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Function interface to determine a {@link CqlIdentifier keyspace} for a given {@link CassandraPersistentEntity} and
|
||||
* {@code tableName}. Classes implementing this interface can choose to return a keyspace or {@code null} to use the
|
||||
* default keyspace.
|
||||
*
|
||||
* @since 4.4
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface KeyspaceProvider {
|
||||
|
||||
/**
|
||||
* Determine a {@link CqlIdentifier keyspace} for a given {@link CassandraPersistentEntity} and {@code tableName}.
|
||||
*
|
||||
* @param entity the persistent entity for which the operation is applied.
|
||||
* @param tableName the table of the operation.
|
||||
* @return a {@link CqlIdentifier keyspace} to use a dedicated keyspace for a
|
||||
* {@link com.datastax.oss.driver.api.core.cql.Statement} or {@code null} to use the default session
|
||||
* keyspace.
|
||||
*/
|
||||
@Nullable
|
||||
CqlIdentifier getKeyspace(CassandraPersistentEntity<?> entity, CqlIdentifier tableName);
|
||||
|
||||
}
|
||||
|
||||
enum KeyspaceProviders implements KeyspaceProvider {
|
||||
EMPTY_KEYSPACE {
|
||||
@Nullable
|
||||
@Override
|
||||
public CqlIdentifier getKeyspace(CassandraPersistentEntity<?> entity, CqlIdentifier tableName) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -259,6 +259,17 @@ public class AsyncCassandraTemplate
|
||||
return this.converter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link StatementFactory} used by this template to construct and run Cassandra CQL statements.
|
||||
*
|
||||
* @return the {@link StatementFactory} used by this template to construct and run Cassandra CQL statements.
|
||||
* @see StatementFactory
|
||||
* @since 2.1
|
||||
*/
|
||||
public StatementFactory getStatementFactory() {
|
||||
return this.statementFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this instance is configured to use {@link PreparedStatement prepared statements}. If enabled
|
||||
* (default), then all persistence methods (such as {@link #select}, {@link #update}, and others) will make use of
|
||||
@@ -315,17 +326,6 @@ public class AsyncCassandraTemplate
|
||||
return getEntityOperations().getRequiredPersistentEntity(entityType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link StatementFactory} used by this template to construct and run Cassandra CQL statements.
|
||||
*
|
||||
* @return the {@link StatementFactory} used by this template to construct and run Cassandra CQL statements.
|
||||
* @see StatementFactory
|
||||
* @since 2.1
|
||||
*/
|
||||
protected StatementFactory getStatementFactory() {
|
||||
return this.statementFactory;
|
||||
}
|
||||
|
||||
private CqlIdentifier getTableName(Class<?> entityClass) {
|
||||
return getEntityOperations().getTableName(entityClass);
|
||||
}
|
||||
|
||||
@@ -56,7 +56,8 @@ public class PartTreeCassandraQuery extends AbstractCassandraQuery {
|
||||
|
||||
this.tree = new PartTree(queryMethod.getName(), queryMethod.getResultProcessor().getReturnedType().getDomainType());
|
||||
this.mappingContext = operations.getConverter().getMappingContext();
|
||||
this.statementFactory = new StatementFactory(new UpdateMapper(operations.getConverter()));
|
||||
this.statementFactory = operations instanceof CassandraTemplate ct ? ct.getStatementFactory()
|
||||
: new StatementFactory(new UpdateMapper(operations.getConverter()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.data.cassandra.repository.query;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.data.cassandra.core.ReactiveCassandraOperations;
|
||||
import org.springframework.data.cassandra.core.ReactiveCassandraTemplate;
|
||||
import org.springframework.data.cassandra.core.StatementFactory;
|
||||
import org.springframework.data.cassandra.core.convert.UpdateMapper;
|
||||
import org.springframework.data.cassandra.core.mapping.CassandraMappingContext;
|
||||
@@ -58,7 +59,8 @@ public class ReactivePartTreeCassandraQuery extends AbstractReactiveCassandraQue
|
||||
|
||||
this.tree = new PartTree(queryMethod.getName(), queryMethod.getResultProcessor().getReturnedType().getDomainType());
|
||||
this.mappingContext = operations.getConverter().getMappingContext();
|
||||
this.statementFactory = new StatementFactory(new UpdateMapper(operations.getConverter()));
|
||||
this.statementFactory = operations instanceof ReactiveCassandraTemplate rct ? rct.getStatementFactory()
|
||||
: new StatementFactory(new UpdateMapper(operations.getConverter()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package org.springframework.data.cassandra.core;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
import static org.springframework.data.cassandra.core.query.Criteria.*;
|
||||
import static org.springframework.data.domain.Sort.Direction.*;
|
||||
|
||||
import java.time.Duration;
|
||||
@@ -26,6 +27,7 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.cassandra.core.convert.CassandraConverter;
|
||||
import org.springframework.data.cassandra.core.convert.MappingCassandraConverter;
|
||||
@@ -37,7 +39,6 @@ import org.springframework.data.cassandra.core.cql.util.StatementBuilder.Paramet
|
||||
import org.springframework.data.cassandra.core.mapping.CassandraPersistentEntity;
|
||||
import org.springframework.data.cassandra.core.mapping.Column;
|
||||
import org.springframework.data.cassandra.core.query.Columns;
|
||||
import org.springframework.data.cassandra.core.query.Criteria;
|
||||
import org.springframework.data.cassandra.core.query.Query;
|
||||
import org.springframework.data.cassandra.core.query.Update;
|
||||
import org.springframework.data.cassandra.domain.Group;
|
||||
@@ -79,6 +80,17 @@ class StatementFactoryUnitTests {
|
||||
assertThat(select.build(ParameterHandling.INLINE).getQuery()).isEqualTo("SELECT * FROM group");
|
||||
}
|
||||
|
||||
@Test // GH-1275
|
||||
void shouldConsiderKeyspaceForSelect() {
|
||||
|
||||
statementFactory.setKeyspaceProvider((entity, tableName) -> CqlIdentifier.fromCql("ks_" + tableName));
|
||||
|
||||
StatementBuilder<Select> select = statementFactory.select(Query.empty(),
|
||||
converter.getMappingContext().getRequiredPersistentEntity(Group.class));
|
||||
|
||||
assertThat(select.build(ParameterHandling.INLINE).getQuery()).isEqualTo("SELECT * FROM ks_group.group");
|
||||
}
|
||||
|
||||
@Test // DATACASS-708
|
||||
void selectShouldApplyQueryOptions() {
|
||||
|
||||
@@ -98,7 +110,7 @@ class StatementFactoryUnitTests {
|
||||
@Test // DATACASS-343
|
||||
void shouldMapSelectQueryWithColumnsAndCriteria() {
|
||||
|
||||
Query query = Query.query(Criteria.where("foo").is("bar")).columns(Columns.from("age"));
|
||||
Query query = Query.query(where("foo").is("bar")).columns(Columns.from("age"));
|
||||
|
||||
StatementBuilder<Select> select = statementFactory.select(query, groupEntity);
|
||||
|
||||
@@ -108,7 +120,7 @@ class StatementFactoryUnitTests {
|
||||
@Test // DATACASS-549
|
||||
void shouldMapSelectQueryNotEquals() {
|
||||
|
||||
Query query = Query.query(Criteria.where("foo").ne("bar")).columns(Columns.from("age"));
|
||||
Query query = Query.query(where("foo").ne("bar")).columns(Columns.from("age"));
|
||||
|
||||
StatementBuilder<Select> select = statementFactory.select(query, groupEntity);
|
||||
|
||||
@@ -118,7 +130,7 @@ class StatementFactoryUnitTests {
|
||||
@Test // DATACASS-549
|
||||
void shouldMapSelectQueryIsNotNull() {
|
||||
|
||||
Query query = Query.query(Criteria.where("foo").isNotNull()).columns(Columns.from("age"));
|
||||
Query query = Query.query(where("foo").isNotNull()).columns(Columns.from("age"));
|
||||
|
||||
StatementBuilder<Select> select = statementFactory.select(query, groupEntity);
|
||||
|
||||
@@ -152,7 +164,7 @@ class StatementFactoryUnitTests {
|
||||
@Test // GH-1401
|
||||
void shouldMapSelectQueryWithLimit() {
|
||||
|
||||
Query query = Query.query(Criteria.where("email").is("e@mail")).limit(Limit.of(10));
|
||||
Query query = Query.query(where("email").is("e@mail")).limit(Limit.of(10));
|
||||
|
||||
StatementBuilder<Select> select = statementFactory.select(query,
|
||||
converter.getMappingContext().getRequiredPersistentEntity(Group.class));
|
||||
@@ -192,12 +204,12 @@ class StatementFactoryUnitTests {
|
||||
@Test // GH-1172
|
||||
void shouldMapSelectInQueryAsInlineValue() {
|
||||
|
||||
StatementBuilder<Select> select = statementFactory.select(Query.query(Criteria.where("foo").in("bar")),
|
||||
StatementBuilder<Select> select = statementFactory.select(Query.query(where("foo").in("bar")),
|
||||
groupEntity);
|
||||
|
||||
assertThat(select.build(ParameterHandling.INLINE).getQuery()).isEqualTo("SELECT * FROM group WHERE foo IN ('bar')");
|
||||
|
||||
select = statementFactory.select(Query.query(Criteria.where("foo").in("bar", "baz")), groupEntity);
|
||||
select = statementFactory.select(Query.query(where("foo").in("bar", "baz")), groupEntity);
|
||||
|
||||
assertThat(select.build(ParameterHandling.INLINE).getQuery())
|
||||
.isEqualTo("SELECT * FROM group WHERE foo IN ('bar','baz')");
|
||||
@@ -206,14 +218,14 @@ class StatementFactoryUnitTests {
|
||||
@Test // GH-1172
|
||||
void shouldMapSelectInQueryAsByIndexValue() {
|
||||
|
||||
StatementBuilder<Select> select = statementFactory.select(Query.query(Criteria.where("foo").in("bar")),
|
||||
StatementBuilder<Select> select = statementFactory.select(Query.query(where("foo").in("bar")),
|
||||
groupEntity);
|
||||
SimpleStatement statement = select.build(ParameterHandling.BY_INDEX);
|
||||
|
||||
assertThat(statement.getQuery()).isEqualTo("SELECT * FROM group WHERE foo IN ?");
|
||||
assertThat(statement.getPositionalValues()).containsOnly(Collections.singletonList("bar"));
|
||||
|
||||
select = statementFactory.select(Query.query(Criteria.where("foo").in("bar", "baz")), groupEntity);
|
||||
select = statementFactory.select(Query.query(where("foo").in("bar", "baz")), groupEntity);
|
||||
statement = select.build(ParameterHandling.BY_INDEX);
|
||||
|
||||
assertThat(statement.getQuery()).isEqualTo("SELECT * FROM group WHERE foo IN ?");
|
||||
@@ -223,7 +235,7 @@ class StatementFactoryUnitTests {
|
||||
@Test // GH-1172
|
||||
void shouldMapSelectInQueryAsByNamedValue() {
|
||||
|
||||
StatementBuilder<Select> select = statementFactory.select(Query.query(Criteria.where("foo").in("bar")),
|
||||
StatementBuilder<Select> select = statementFactory.select(Query.query(where("foo").in("bar")),
|
||||
groupEntity);
|
||||
SimpleStatement statement = select.build(ParameterHandling.BY_NAME);
|
||||
|
||||
@@ -231,7 +243,7 @@ class StatementFactoryUnitTests {
|
||||
assertThat(statement.getNamedValues()).hasSize(1).containsEntry(CqlIdentifier.fromCql("p0"),
|
||||
Collections.singletonList("bar"));
|
||||
|
||||
select = statementFactory.select(Query.query(Criteria.where("foo").in("bar", "baz")), groupEntity);
|
||||
select = statementFactory.select(Query.query(where("foo").in("bar", "baz")), groupEntity);
|
||||
statement = select.build(ParameterHandling.BY_NAME);
|
||||
|
||||
assertThat(statement.getQuery()).isEqualTo("SELECT * FROM group WHERE foo IN :p0");
|
||||
@@ -254,7 +266,7 @@ class StatementFactoryUnitTests {
|
||||
void shouldMapDeleteQueryWithTimestampColumns() {
|
||||
|
||||
DeleteOptions options = DeleteOptions.builder().timestamp(1234).build();
|
||||
Query query = Query.query(Criteria.where("foo").is("bar")).queryOptions(options);
|
||||
Query query = Query.query(where("foo").is("bar")).queryOptions(options);
|
||||
|
||||
StatementBuilder<Delete> delete = statementFactory.delete(query,
|
||||
converter.getMappingContext().getRequiredPersistentEntity(Group.class));
|
||||
@@ -267,7 +279,7 @@ class StatementFactoryUnitTests {
|
||||
void deleteByQueryWithOptionsShouldRenderBindMarkers() {
|
||||
|
||||
DeleteOptions options = DeleteOptions.builder().timestamp(1234).build();
|
||||
Query query = Query.query(Criteria.where("foo").is("bar")).queryOptions(options);
|
||||
Query query = Query.query(where("foo").is("bar")).queryOptions(options);
|
||||
|
||||
StatementBuilder<Delete> delete = statementFactory.delete(query,
|
||||
converter.getMappingContext().getRequiredPersistentEntity(Group.class));
|
||||
@@ -295,6 +307,33 @@ class StatementFactoryUnitTests {
|
||||
assertThat(statement.getPositionalValues()).containsExactly(1234L, "foo");
|
||||
}
|
||||
|
||||
@Test // GH-1275
|
||||
void shouldConsiderKeyspaceForDeleteByEntity() {
|
||||
|
||||
statementFactory.setKeyspaceProvider((entity, tableName) -> CqlIdentifier.fromCql("ks_" + tableName));
|
||||
|
||||
Person person = new Person();
|
||||
person.id = "foo";
|
||||
|
||||
StatementBuilder<Delete> delete = statementFactory.delete(person, DeleteOptions.empty(), converter,
|
||||
CqlIdentifier.fromCql("person"));
|
||||
|
||||
SimpleStatement statement = delete.build(ParameterHandling.BY_INDEX);
|
||||
|
||||
assertThat(statement.getQuery()).isEqualTo("DELETE FROM ks_person.person WHERE id=?");
|
||||
}
|
||||
|
||||
@Test // GH-1275
|
||||
void shouldConsiderKeyspaceForDelete() {
|
||||
|
||||
statementFactory.setKeyspaceProvider((entity, tableName) -> CqlIdentifier.fromCql("ks_" + tableName));
|
||||
StatementBuilder<Delete> delete = statementFactory.delete(Query.query(where("foo").is("bar")), groupEntity);
|
||||
|
||||
SimpleStatement statement = delete.build(ParameterHandling.BY_INDEX);
|
||||
|
||||
assertThat(statement.getQuery()).isEqualTo("DELETE FROM ks_group.group WHERE foo=?");
|
||||
}
|
||||
|
||||
@Test // DATACASS-708
|
||||
void deleteShouldApplyQueryOptions() {
|
||||
|
||||
@@ -325,6 +364,20 @@ class StatementFactoryUnitTests {
|
||||
assertThat(insert.build(ParameterHandling.INLINE).getQuery()).isEqualTo("INSERT INTO person (id) VALUES ('foo')");
|
||||
}
|
||||
|
||||
@Test // GH-1275
|
||||
void shouldConsiderKeyspaceForInsert() {
|
||||
|
||||
statementFactory.setKeyspaceProvider((entity, tableName) -> CqlIdentifier.fromCql("ks_" + tableName));
|
||||
|
||||
Person person = new Person();
|
||||
person.id = "foo";
|
||||
|
||||
StatementBuilder<RegularInsert> insert = statementFactory.insert(person, WriteOptions.empty());
|
||||
|
||||
assertThat(insert.build(ParameterHandling.INLINE).getQuery())
|
||||
.isEqualTo("INSERT INTO ks_person.person (id) VALUES ('foo')");
|
||||
}
|
||||
|
||||
@Test // DATACASS-708
|
||||
void insertShouldApplyQueryOptions() {
|
||||
|
||||
@@ -415,7 +468,7 @@ class StatementFactoryUnitTests {
|
||||
@Test // DATACASS-343
|
||||
void shouldCreateSetUpdate() {
|
||||
|
||||
Query query = Query.query(Criteria.where("foo").is("bar"));
|
||||
Query query = Query.query(where("foo").is("bar"));
|
||||
|
||||
StatementBuilder<com.datastax.oss.driver.api.querybuilder.update.Update> update = statementFactory.update(query,
|
||||
Update.empty().set("firstName", "baz").set("boo", "baa"), personEntity);
|
||||
@@ -424,11 +477,25 @@ class StatementFactoryUnitTests {
|
||||
.isEqualTo("UPDATE person SET first_name='baz', boo='baa' WHERE foo='bar'");
|
||||
}
|
||||
|
||||
@Test // GH-1275
|
||||
void shouldConsiderKeyspaceForCreateSetUpdate() {
|
||||
|
||||
statementFactory.setKeyspaceProvider((entity, tableName) -> CqlIdentifier.fromCql("ks_" + tableName));
|
||||
|
||||
Query query = Query.query(where("foo").is("bar"));
|
||||
|
||||
StatementBuilder<com.datastax.oss.driver.api.querybuilder.update.Update> update = statementFactory.update(query,
|
||||
Update.empty().set("firstName", "baz").set("boo", "baa"), personEntity);
|
||||
|
||||
assertThat(update.build(ParameterHandling.INLINE).getQuery())
|
||||
.isEqualTo("UPDATE ks_person.person SET first_name='baz', boo='baa' WHERE foo='bar'");
|
||||
}
|
||||
|
||||
@Test // DATACASS-656
|
||||
void shouldCreateSetUpdateWithTtl() {
|
||||
|
||||
WriteOptions options = WriteOptions.builder().ttl(Duration.ofMinutes(1)).build();
|
||||
Query query = Query.query(Criteria.where("foo").is("bar")).queryOptions(options);
|
||||
Query query = Query.query(where("foo").is("bar")).queryOptions(options);
|
||||
|
||||
StatementBuilder<com.datastax.oss.driver.api.querybuilder.update.Update> update = statementFactory.update(query,
|
||||
Update.empty().set("firstName", "baz"), personEntity);
|
||||
@@ -441,7 +508,7 @@ class StatementFactoryUnitTests {
|
||||
void shouldCreateSetUpdateWithTimestamp() {
|
||||
|
||||
WriteOptions options = WriteOptions.builder().timestamp(1234).build();
|
||||
Query query = Query.query(Criteria.where("foo").is("bar")).queryOptions(options);
|
||||
Query query = Query.query(where("foo").is("bar")).queryOptions(options);
|
||||
|
||||
StatementBuilder<com.datastax.oss.driver.api.querybuilder.update.Update> update = statementFactory.update(query,
|
||||
Update.empty().set("firstName", "baz"), personEntity);
|
||||
@@ -454,7 +521,7 @@ class StatementFactoryUnitTests {
|
||||
void updateWithOptionsShouldRenderBindMarker() {
|
||||
|
||||
WriteOptions options = WriteOptions.builder().ttl(Duration.ofMinutes(1)).timestamp(1234).build();
|
||||
Query query = Query.query(Criteria.where("foo").is("bar")).queryOptions(options);
|
||||
Query query = Query.query(where("foo").is("bar")).queryOptions(options);
|
||||
|
||||
StatementBuilder<com.datastax.oss.driver.api.querybuilder.update.Update> update = statementFactory.update(query,
|
||||
Update.empty().set("firstName", "baz"), personEntity);
|
||||
@@ -626,7 +693,7 @@ class StatementFactoryUnitTests {
|
||||
@Test // DATACASS-569
|
||||
void shouldCreateSetUpdateIfExists() {
|
||||
|
||||
Query query = Query.query(Criteria.where("foo").is("bar"))
|
||||
Query query = Query.query(where("foo").is("bar"))
|
||||
.queryOptions(UpdateOptions.builder().withIfExists().build());
|
||||
|
||||
StatementBuilder<com.datastax.oss.driver.api.querybuilder.update.Update> update = statementFactory.update(query,
|
||||
@@ -639,8 +706,8 @@ class StatementFactoryUnitTests {
|
||||
@Test // DATACASS-656
|
||||
void shouldCreateSetUpdateIfCondition() {
|
||||
|
||||
Query query = Query.query(Criteria.where("foo").is("bar"))
|
||||
.queryOptions(UpdateOptions.builder().ifCondition(Criteria.where("foo").is("baz")).build());
|
||||
Query query = Query.query(where("foo").is("bar"))
|
||||
.queryOptions(UpdateOptions.builder().ifCondition(where("foo").is("baz")).build());
|
||||
|
||||
StatementBuilder<com.datastax.oss.driver.api.querybuilder.update.Update> update = statementFactory.update(query,
|
||||
Update.empty().set("firstName", "baz"), personEntity);
|
||||
@@ -657,7 +724,7 @@ class StatementFactoryUnitTests {
|
||||
.serialConsistencyLevel(DefaultConsistencyLevel.QUORUM) //
|
||||
.build();
|
||||
|
||||
Query query = Query.query(Criteria.where("foo").is("bar")).queryOptions(queryOptions);
|
||||
Query query = Query.query(where("foo").is("bar")).queryOptions(queryOptions);
|
||||
|
||||
StatementBuilder<com.datastax.oss.driver.api.querybuilder.update.Update> update = statementFactory.update(query,
|
||||
Update.empty().set("firstName", "baz"), personEntity);
|
||||
@@ -698,7 +765,7 @@ class StatementFactoryUnitTests {
|
||||
@Test // DATACASS-656
|
||||
void shouldCreateSetUpdateFromObjectIfCondition() {
|
||||
|
||||
UpdateOptions options = UpdateOptions.builder().ifCondition(Criteria.where("foo").is("bar")).build();
|
||||
UpdateOptions options = UpdateOptions.builder().ifCondition(where("foo").is("bar")).build();
|
||||
Person person = new Person();
|
||||
person.id = "foo";
|
||||
person.firstName = "bar";
|
||||
@@ -774,7 +841,7 @@ class StatementFactoryUnitTests {
|
||||
@Test // DATACASS-512
|
||||
void shouldCreateCountQuery() {
|
||||
|
||||
Query query = Query.query(Criteria.where("foo").is("bar"));
|
||||
Query query = Query.query(where("foo").is("bar"));
|
||||
|
||||
StatementBuilder<Select> count = statementFactory.count(query,
|
||||
converter.getMappingContext().getRequiredPersistentEntity(Group.class));
|
||||
|
||||
Reference in New Issue
Block a user