Merge branch 'DATACASS-33'
This commit is contained in:
@@ -18,16 +18,17 @@ package org.springframework.cassandra.core;
|
||||
import com.datastax.driver.core.ResultSetFuture;
|
||||
|
||||
/**
|
||||
* @author David Webb
|
||||
* Interface used to give an implementation access to a {@link ResultSetFuture} after the query has completed.
|
||||
*
|
||||
* @author David Webb
|
||||
*/
|
||||
public interface AsynchronousQueryListener {
|
||||
|
||||
/**
|
||||
* Called upon Query Completion.
|
||||
*
|
||||
* @param rsf The given ResultSetFuture's get methods should return immediately.
|
||||
* @param rsf The {@link ResultSetFuture}. Since this isn't called until the asynchronous query completes, it can be
|
||||
* immediately interrogated.
|
||||
*/
|
||||
public void onQueryComplete(ResultSetFuture rsf);
|
||||
|
||||
}
|
||||
|
||||
@@ -21,8 +21,17 @@ import java.util.Map;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.springframework.cassandra.core.keyspace.AlterKeyspaceSpecification;
|
||||
import org.springframework.cassandra.core.keyspace.AlterTableSpecification;
|
||||
import org.springframework.cassandra.core.keyspace.CreateIndexSpecification;
|
||||
import org.springframework.cassandra.core.keyspace.CreateKeyspaceSpecification;
|
||||
import org.springframework.cassandra.core.keyspace.CreateTableSpecification;
|
||||
import org.springframework.cassandra.core.keyspace.DropIndexSpecification;
|
||||
import org.springframework.cassandra.core.keyspace.DropKeyspaceSpecification;
|
||||
import org.springframework.cassandra.core.keyspace.DropTableSpecification;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
|
||||
import com.datastax.driver.core.Query;
|
||||
import com.datastax.driver.core.ResultSet;
|
||||
import com.datastax.driver.core.ResultSetFuture;
|
||||
import com.datastax.driver.core.Session;
|
||||
@@ -52,12 +61,26 @@ public interface CqlOperations {
|
||||
void execute(String cql) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Executes the supplied CQL Query Asynchronously and returns nothing.
|
||||
* Executes the supplied Query and returns nothing.
|
||||
*
|
||||
* @param cql The CQL Statement to execute
|
||||
* @param query The {@link Query} to execute
|
||||
*/
|
||||
void execute(Query query) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Executes the supplied Query Asynchronously and returns nothing.
|
||||
*
|
||||
* @param cql The {@link Query} to execute
|
||||
*/
|
||||
void executeAsynchronously(String cql) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Executes the supplied CQL Query Asynchronously and returns nothing.
|
||||
*
|
||||
* @param query The {@link Query} to execute
|
||||
*/
|
||||
void executeAsynchronously(Query query) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Executes the provided CQL Query, and extracts the results with the ResultSetExtractor. This uses default Query
|
||||
* Options when extracting the ResultSet.
|
||||
@@ -100,10 +123,10 @@ public interface CqlOperations {
|
||||
ResultSetFuture queryAsynchronously(String cql, QueryOptions options);
|
||||
|
||||
/**
|
||||
* Executes the provided CQL Query with the provided Runnable implementations.
|
||||
* Executes the provided CQL Query with the provided {@link Runnable} implementation.
|
||||
*
|
||||
* @param cql The Query
|
||||
* @param listener Runnable Listener for handling the query in a separate thread
|
||||
* @param listener {@link Runnable} listener for handling the query in a separate thread
|
||||
*/
|
||||
void queryAsynchronously(String cql, Runnable listener);
|
||||
|
||||
@@ -113,7 +136,8 @@ public interface CqlOperations {
|
||||
* query is completed for optimal flexibility.
|
||||
*
|
||||
* @param cql The Query
|
||||
* @param listener Runnable Listener for handling the query in a separate thread
|
||||
* @param listener {@link AsynchronousQueryListener} Listener for handling the query's {@link ResultSetFuture} in a
|
||||
* separate thread
|
||||
*/
|
||||
void queryAsynchronously(String cql, AsynchronousQueryListener listener);
|
||||
|
||||
@@ -181,6 +205,23 @@ public interface CqlOperations {
|
||||
*/
|
||||
void queryAsynchronously(String cql, AsynchronousQueryListener listener, QueryOptions options, Executor executor);
|
||||
|
||||
/**
|
||||
* Executes the provided CQL query and returns the {@link ResultSet}.
|
||||
*
|
||||
* @param cql The query
|
||||
* @return The {@link ResultSet}
|
||||
*/
|
||||
ResultSet query(String cql);
|
||||
|
||||
/**
|
||||
* Executes the provided CQL query with the given {@link QueryOptions} and returns the {@link ResultSet}.
|
||||
*
|
||||
* @param cql The query
|
||||
* @param options The {@link QueryOptions}; may be null.
|
||||
* @return The {@link ResultSet}
|
||||
*/
|
||||
ResultSet query(String cql, QueryOptions options);
|
||||
|
||||
/**
|
||||
* Executes the provided CQL Query, and extracts the results with the ResultSetExtractor.
|
||||
*
|
||||
@@ -754,4 +795,67 @@ public interface CqlOperations {
|
||||
*/
|
||||
void truncate(String tableName);
|
||||
|
||||
/**
|
||||
* Counts all rows for given table
|
||||
*
|
||||
* @param tableName
|
||||
* @return
|
||||
*/
|
||||
long count(String tableName);
|
||||
|
||||
/**
|
||||
* Convenience method to convert the given specification to CQL and execute it.
|
||||
*
|
||||
* @param specification The specification to execute; must not be null.
|
||||
*/
|
||||
ResultSet execute(DropTableSpecification specification);
|
||||
|
||||
/**
|
||||
* Convenience method to convert the given specification to CQL and execute it.
|
||||
*
|
||||
* @param specification The specification to execute; must not be null.
|
||||
*/
|
||||
ResultSet execute(CreateTableSpecification specification);
|
||||
|
||||
/**
|
||||
* Convenience method to convert the given specification to CQL and execute it.
|
||||
*
|
||||
* @param specification The specification to execute; must not be null.
|
||||
*/
|
||||
ResultSet execute(AlterTableSpecification specification);
|
||||
|
||||
/**
|
||||
* Convenience method to convert the given specification to CQL and execute it.
|
||||
*
|
||||
* @param specification The specification to execute; must not be null.
|
||||
*/
|
||||
ResultSet execute(DropKeyspaceSpecification specification);
|
||||
|
||||
/**
|
||||
* Convenience method to convert the given specification to CQL and execute it.
|
||||
*
|
||||
* @param specification The specification to execute; must not be null.
|
||||
*/
|
||||
ResultSet execute(CreateKeyspaceSpecification specification);
|
||||
|
||||
/**
|
||||
* Convenience method to convert the given specification to CQL and execute it.
|
||||
*
|
||||
* @param specification The specification to execute; must not be null.
|
||||
*/
|
||||
ResultSet execute(AlterKeyspaceSpecification specification);
|
||||
|
||||
/**
|
||||
* Convenience method to convert the given specification to CQL and execute it.
|
||||
*
|
||||
* @param specification The specification to execute; must not be null.
|
||||
*/
|
||||
ResultSet execute(DropIndexSpecification specification);
|
||||
|
||||
/**
|
||||
* Convenience method to convert the given specification to CQL and execute it.
|
||||
*
|
||||
* @param specification The specification to execute; must not be null.
|
||||
*/
|
||||
ResultSet execute(CreateIndexSpecification specification);
|
||||
}
|
||||
|
||||
@@ -27,8 +27,25 @@ import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.springframework.cassandra.core.cql.generator.AlterKeyspaceCqlGenerator;
|
||||
import org.springframework.cassandra.core.cql.generator.AlterTableCqlGenerator;
|
||||
import org.springframework.cassandra.core.cql.generator.CreateIndexCqlGenerator;
|
||||
import org.springframework.cassandra.core.cql.generator.CreateKeyspaceCqlGenerator;
|
||||
import org.springframework.cassandra.core.cql.generator.CreateTableCqlGenerator;
|
||||
import org.springframework.cassandra.core.cql.generator.DropIndexCqlGenerator;
|
||||
import org.springframework.cassandra.core.cql.generator.DropKeyspaceCqlGenerator;
|
||||
import org.springframework.cassandra.core.cql.generator.DropTableCqlGenerator;
|
||||
import org.springframework.cassandra.core.keyspace.AlterKeyspaceSpecification;
|
||||
import org.springframework.cassandra.core.keyspace.AlterTableSpecification;
|
||||
import org.springframework.cassandra.core.keyspace.CreateIndexSpecification;
|
||||
import org.springframework.cassandra.core.keyspace.CreateKeyspaceSpecification;
|
||||
import org.springframework.cassandra.core.keyspace.CreateTableSpecification;
|
||||
import org.springframework.cassandra.core.keyspace.DropIndexSpecification;
|
||||
import org.springframework.cassandra.core.keyspace.DropKeyspaceSpecification;
|
||||
import org.springframework.cassandra.core.keyspace.DropTableSpecification;
|
||||
import org.springframework.cassandra.support.CassandraAccessor;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.dao.QueryTimeoutException;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -87,6 +104,11 @@ public class CqlTemplate extends CassandraAccessor implements CqlOperations {
|
||||
return doExecute(sessionCallback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Query query) throws DataAccessException {
|
||||
doExecute(query, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(final String cql) throws DataAccessException {
|
||||
doExecute(cql, null);
|
||||
@@ -278,6 +300,7 @@ public class CqlTemplate extends CassandraAccessor implements CqlOperations {
|
||||
process(doExecute(cql, options), rch);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void query(String cql, RowCallbackHandler rch) throws DataAccessException {
|
||||
query(cql, rch, null);
|
||||
}
|
||||
@@ -287,26 +310,49 @@ public class CqlTemplate extends CassandraAccessor implements CqlOperations {
|
||||
return process(doExecute(cql, options), rowMapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet query(String cql) {
|
||||
return query(cql, (QueryOptions) null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet query(String cql, QueryOptions options) {
|
||||
|
||||
return query(cql, new ResultSetExtractor<ResultSet>() {
|
||||
|
||||
@Override
|
||||
public ResultSet extractData(ResultSet rs) throws DriverException, DataAccessException {
|
||||
return rs;
|
||||
}
|
||||
}, options);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> List<T> query(String cql, RowMapper<T> rowMapper) throws DataAccessException {
|
||||
return query(cql, rowMapper, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Map<String, Object>> queryForListOfMap(String cql) throws DataAccessException {
|
||||
return processListOfMap(doExecute(cql, null));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> List<T> queryForList(String cql, Class<T> elementType) throws DataAccessException {
|
||||
return processList(doExecute(cql, null), elementType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> queryForMap(String cql) throws DataAccessException {
|
||||
return processMap(doExecute(cql, null));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T queryForObject(String cql, Class<T> requiredType) throws DataAccessException {
|
||||
return processOne(doExecute(cql, null), requiredType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T queryForObject(String cql, RowMapper<T> rowMapper) throws DataAccessException {
|
||||
return processOne(doExecute(cql, null), rowMapper);
|
||||
}
|
||||
@@ -357,14 +403,14 @@ public class CqlTemplate extends CassandraAccessor implements CqlOperations {
|
||||
* @param callback
|
||||
* @return
|
||||
*/
|
||||
protected ResultSet doExecute(final BoundStatement bs, final QueryOptions options) {
|
||||
protected ResultSet doExecute(final Query q, final QueryOptions options) {
|
||||
|
||||
return doExecute(new SessionCallback<ResultSet>() {
|
||||
|
||||
@Override
|
||||
public ResultSet doInSession(Session s) throws DataAccessException {
|
||||
addQueryOptions(bs, options);
|
||||
return s.execute(bs);
|
||||
addQueryOptions(q, options);
|
||||
return s.execute(q);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -411,7 +457,7 @@ public class CqlTemplate extends CassandraAccessor implements CqlOperations {
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private Set<Host> getHosts() {
|
||||
protected Set<Host> getHosts() {
|
||||
|
||||
/*
|
||||
* Get the cluster metadata for this session
|
||||
@@ -450,6 +496,16 @@ public class CqlTemplate extends CassandraAccessor implements CqlOperations {
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeAsynchronously(final Query query) throws DataAccessException {
|
||||
execute(new SessionCallback<Object>() {
|
||||
@Override
|
||||
public Object doInSession(Session s) throws DataAccessException {
|
||||
return s.executeAsync(query);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void process(ResultSet resultSet, RowCallbackHandler rch) throws DataAccessException {
|
||||
try {
|
||||
@@ -766,6 +822,7 @@ public class CqlTemplate extends CassandraAccessor implements CqlOperations {
|
||||
logger.debug("Executing prepared CQL query");
|
||||
|
||||
return execute(psc, new PreparedStatementCallback<T>() {
|
||||
@Override
|
||||
public T doInPreparedStatement(PreparedStatement ps) throws DriverException {
|
||||
ResultSet rs = null;
|
||||
BoundStatement bs = null;
|
||||
@@ -794,6 +851,7 @@ public class CqlTemplate extends CassandraAccessor implements CqlOperations {
|
||||
logger.debug("Executing prepared CQL query");
|
||||
|
||||
execute(psc, new PreparedStatementCallback<Object>() {
|
||||
@Override
|
||||
public Object doInPreparedStatement(PreparedStatement ps) throws DriverException {
|
||||
ResultSet rs = null;
|
||||
BoundStatement bs = null;
|
||||
@@ -822,6 +880,7 @@ public class CqlTemplate extends CassandraAccessor implements CqlOperations {
|
||||
logger.debug("Executing prepared CQL query");
|
||||
|
||||
return execute(psc, new PreparedStatementCallback<List<T>>() {
|
||||
@Override
|
||||
public List<T> doInPreparedStatement(PreparedStatement ps) throws DriverException {
|
||||
ResultSet rs = null;
|
||||
BoundStatement bs = null;
|
||||
@@ -843,4 +902,121 @@ public class CqlTemplate extends CassandraAccessor implements CqlOperations {
|
||||
return query(psc, psb, rowMapper, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet execute(final DropTableSpecification specification) {
|
||||
|
||||
return execute(new SessionCallback<ResultSet>() {
|
||||
|
||||
@Override
|
||||
public ResultSet doInSession(Session s) throws DataAccessException {
|
||||
return s.execute(DropTableCqlGenerator.toCql(specification));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet execute(final CreateTableSpecification specification) {
|
||||
|
||||
return execute(new SessionCallback<ResultSet>() {
|
||||
|
||||
@Override
|
||||
public ResultSet doInSession(Session s) throws DataAccessException {
|
||||
return s.execute(CreateTableCqlGenerator.toCql(specification));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet execute(final AlterTableSpecification specification) {
|
||||
|
||||
return execute(new SessionCallback<ResultSet>() {
|
||||
|
||||
@Override
|
||||
public ResultSet doInSession(Session s) throws DataAccessException {
|
||||
return s.execute(AlterTableCqlGenerator.toCql(specification));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet execute(final DropKeyspaceSpecification specification) {
|
||||
|
||||
return execute(new SessionCallback<ResultSet>() {
|
||||
|
||||
@Override
|
||||
public ResultSet doInSession(Session s) throws DataAccessException {
|
||||
return s.execute(DropKeyspaceCqlGenerator.toCql(specification));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet execute(final CreateKeyspaceSpecification specification) {
|
||||
|
||||
return execute(new SessionCallback<ResultSet>() {
|
||||
|
||||
@Override
|
||||
public ResultSet doInSession(Session s) throws DataAccessException {
|
||||
return s.execute(CreateKeyspaceCqlGenerator.toCql(specification));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet execute(final AlterKeyspaceSpecification specification) {
|
||||
|
||||
return execute(new SessionCallback<ResultSet>() {
|
||||
|
||||
@Override
|
||||
public ResultSet doInSession(Session s) throws DataAccessException {
|
||||
return s.execute(AlterKeyspaceCqlGenerator.toCql(specification));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet execute(final DropIndexSpecification specification) {
|
||||
|
||||
return execute(new SessionCallback<ResultSet>() {
|
||||
|
||||
@Override
|
||||
public ResultSet doInSession(Session s) throws DataAccessException {
|
||||
return s.execute(DropIndexCqlGenerator.toCql(specification));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet execute(final CreateIndexSpecification specification) {
|
||||
|
||||
return execute(new SessionCallback<ResultSet>() {
|
||||
|
||||
@Override
|
||||
public ResultSet doInSession(Session s) throws DataAccessException {
|
||||
return s.execute(CreateIndexCqlGenerator.toCql(specification));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public long count(String tableName) {
|
||||
return selectCount(QueryBuilder.select().countAll().from(tableName).getQueryString());
|
||||
}
|
||||
|
||||
protected long selectCount(String countQuery) {
|
||||
|
||||
return query(countQuery, new ResultSetExtractor<Long>() {
|
||||
|
||||
@Override
|
||||
public Long extractData(ResultSet rs) throws DriverException, DataAccessException {
|
||||
|
||||
Row row = rs.one();
|
||||
if (row == null) {
|
||||
throw new InvalidDataAccessApiUsageException(String.format("count query did not return any results"));
|
||||
}
|
||||
|
||||
return row.getLong(0);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,8 @@ package org.springframework.cassandra.core.cql;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.datastax.driver.core.DataType;
|
||||
|
||||
public class CqlStringUtils {
|
||||
|
||||
protected static final String SINGLE_QUOTE = "\'";
|
||||
@@ -24,6 +26,8 @@ public class CqlStringUtils {
|
||||
protected static final String DOUBLE_QUOTE = "\"";
|
||||
protected static final String DOUBLE_DOUBLE_QUOTE = "\"\"";
|
||||
protected static final String EMPTY_STRING = "";
|
||||
protected static final String TYPE_PARAMETER_PREFIX = "<";
|
||||
protected static final String TYPE_PARAMETER_SUFFIX = ">";
|
||||
|
||||
public static StringBuilder noNull(StringBuilder sb) {
|
||||
return sb == null ? new StringBuilder() : sb;
|
||||
@@ -137,4 +141,34 @@ public class CqlStringUtils {
|
||||
public static String removeSingleQuotes(Object thing) {
|
||||
return thing == null ? (String) null : ((String) thing).replaceAll(SINGLE_QUOTE, EMPTY_STRING);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the given {@link DataType} as a CQL string.
|
||||
*
|
||||
* @param dataType The {@link DataType} to render; must not be null.
|
||||
*/
|
||||
public static String toCql(DataType dataType) {
|
||||
|
||||
if (dataType.getTypeArguments().isEmpty()) {
|
||||
return dataType.getName().name();
|
||||
}
|
||||
|
||||
StringBuilder s = new StringBuilder();
|
||||
s.append(dataType.getName().name()).append(TYPE_PARAMETER_PREFIX);
|
||||
|
||||
boolean first = true;
|
||||
|
||||
for (DataType argDataType : dataType.getTypeArguments()) {
|
||||
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
s.append(',');
|
||||
}
|
||||
|
||||
s.append(argDataType.getName().name());
|
||||
}
|
||||
|
||||
return s.append(TYPE_PARAMETER_SUFFIX).toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,10 +29,15 @@ import org.springframework.cassandra.core.keyspace.Option;
|
||||
*/
|
||||
public class AlterKeyspaceCqlGenerator extends KeyspaceOptionsCqlGenerator<AlterKeyspaceSpecification> {
|
||||
|
||||
public static String toCql(AlterKeyspaceSpecification specification) {
|
||||
return new AlterKeyspaceCqlGenerator(specification).toCql();
|
||||
}
|
||||
|
||||
public AlterKeyspaceCqlGenerator(AlterKeyspaceSpecification specification) {
|
||||
super(specification);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StringBuilder toCql(StringBuilder cql) {
|
||||
cql = noNull(cql);
|
||||
|
||||
|
||||
@@ -34,10 +34,15 @@ import org.springframework.cassandra.core.keyspace.TableOption;
|
||||
*/
|
||||
public class AlterTableCqlGenerator extends TableOptionsCqlGenerator<AlterTableSpecification> {
|
||||
|
||||
public static String toCql(AlterTableSpecification specification) {
|
||||
return new AlterTableCqlGenerator(specification).toCql();
|
||||
}
|
||||
|
||||
public AlterTableCqlGenerator(AlterTableSpecification specification) {
|
||||
super(specification);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StringBuilder toCql(StringBuilder cql) {
|
||||
cql = noNull(cql);
|
||||
|
||||
|
||||
@@ -28,10 +28,15 @@ import org.springframework.util.StringUtils;
|
||||
*/
|
||||
public class CreateIndexCqlGenerator extends IndexNameCqlGenerator<CreateIndexSpecification> {
|
||||
|
||||
public static String toCql(CreateIndexSpecification specification) {
|
||||
return new CreateIndexCqlGenerator(specification).toCql();
|
||||
}
|
||||
|
||||
public CreateIndexCqlGenerator(CreateIndexSpecification specification) {
|
||||
super(specification);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StringBuilder toCql(StringBuilder cql) {
|
||||
|
||||
cql = noNull(cql);
|
||||
|
||||
@@ -32,10 +32,15 @@ import org.springframework.cassandra.core.keyspace.Option;
|
||||
*/
|
||||
public class CreateKeyspaceCqlGenerator extends KeyspaceCqlGenerator<CreateKeyspaceSpecification> {
|
||||
|
||||
public static String toCql(CreateKeyspaceSpecification specification) {
|
||||
return new CreateKeyspaceCqlGenerator(specification).toCql();
|
||||
}
|
||||
|
||||
public CreateKeyspaceCqlGenerator(CreateKeyspaceSpecification specification) {
|
||||
super(specification);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StringBuilder toCql(StringBuilder cql) {
|
||||
|
||||
cql = noNull(cql);
|
||||
|
||||
@@ -35,10 +35,15 @@ import org.springframework.cassandra.core.keyspace.Option;
|
||||
*/
|
||||
public class CreateTableCqlGenerator extends TableCqlGenerator<CreateTableSpecification> {
|
||||
|
||||
public static String toCql(CreateTableSpecification specification) {
|
||||
return new CreateTableCqlGenerator(specification).toCql();
|
||||
}
|
||||
|
||||
public CreateTableCqlGenerator(CreateTableSpecification specification) {
|
||||
super(specification);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StringBuilder toCql(StringBuilder cql) {
|
||||
|
||||
cql = noNull(cql);
|
||||
|
||||
@@ -27,10 +27,15 @@ import org.springframework.cassandra.core.keyspace.DropIndexSpecification;
|
||||
*/
|
||||
public class DropIndexCqlGenerator extends IndexNameCqlGenerator<DropIndexSpecification> {
|
||||
|
||||
public static String toCql(DropIndexSpecification specification) {
|
||||
return new DropIndexCqlGenerator(specification).toCql();
|
||||
}
|
||||
|
||||
public DropIndexCqlGenerator(DropIndexSpecification specification) {
|
||||
super(specification);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StringBuilder toCql(StringBuilder cql) {
|
||||
return noNull(cql).append("DROP INDEX ")
|
||||
// .append(spec().getIfExists() ? "IF EXISTS " : "")
|
||||
|
||||
@@ -26,10 +26,15 @@ import org.springframework.cassandra.core.keyspace.DropKeyspaceSpecification;
|
||||
*/
|
||||
public class DropKeyspaceCqlGenerator extends KeyspaceNameCqlGenerator<DropKeyspaceSpecification> {
|
||||
|
||||
public static String toCql(DropKeyspaceSpecification specification) {
|
||||
return new DropKeyspaceCqlGenerator(specification).toCql();
|
||||
}
|
||||
|
||||
public DropKeyspaceCqlGenerator(DropKeyspaceSpecification specification) {
|
||||
super(specification);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StringBuilder toCql(StringBuilder cql) {
|
||||
return noNull(cql).append("DROP KEYSPACE ").append(spec().getIfExists() ? "IF EXISTS " : "")
|
||||
.append(spec().getNameAsIdentifier()).append(";");
|
||||
|
||||
@@ -26,10 +26,15 @@ import org.springframework.cassandra.core.keyspace.DropTableSpecification;
|
||||
*/
|
||||
public class DropTableCqlGenerator extends TableNameCqlGenerator<DropTableSpecification> {
|
||||
|
||||
public static String toCql(DropTableSpecification specification) {
|
||||
return new DropTableCqlGenerator(specification).toCql();
|
||||
}
|
||||
|
||||
public DropTableCqlGenerator(DropTableSpecification specification) {
|
||||
super(specification);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StringBuilder toCql(StringBuilder cql) {
|
||||
return noNull(cql).append("DROP TABLE ")
|
||||
// .append(spec().getIfExists() ? "IF EXISTS " : "")
|
||||
|
||||
@@ -47,6 +47,11 @@ public class CreateTableSpecification extends TableSpecification<CreateTableSpec
|
||||
return ifNotExists;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CreateTableSpecification name(String name) {
|
||||
return (CreateTableSpecification) super.name(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Entry point into the {@link CreateTableSpecification}'s fluent API to create a table. Convenient if imported
|
||||
* statically.
|
||||
|
||||
@@ -46,4 +46,15 @@ public class DropTableSpecification extends TableNameSpecification<DropTableSpec
|
||||
public static DropTableSpecification dropTable() {
|
||||
return new DropTableSpecification();
|
||||
}
|
||||
|
||||
/**
|
||||
* Entry point into the {@link DropTableSpecification}'s fluent API to drop a table. Convenient if imported
|
||||
* statically. This static method is shorter than the no-arg form, which would be
|
||||
* <code>dropTable().name(tableName)</code>.
|
||||
*
|
||||
* @param tableName The name of the table to drop.
|
||||
*/
|
||||
public static DropTableSpecification dropTable(String tableName) {
|
||||
return new DropTableSpecification().name(tableName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
package org.springframework.cassandra.core.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class CollectionUtils {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T[] toArray(Iterable<T> i) {
|
||||
return (T[]) toList(i).toArray();
|
||||
}
|
||||
|
||||
public static <T> List<T> toList(Iterable<T> i) {
|
||||
|
||||
List<T> list = null;
|
||||
if (i instanceof List) {
|
||||
list = (List<T>) i;
|
||||
} else {
|
||||
list = new ArrayList<T>();
|
||||
for (T t : i) {
|
||||
list.add(t);
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,6 @@ import com.datastax.driver.core.Session;
|
||||
|
||||
/**
|
||||
* @author David Webb
|
||||
*
|
||||
*/
|
||||
public class CassandraAccessor implements InitializingBean {
|
||||
|
||||
@@ -56,9 +55,7 @@ public class CassandraAccessor implements InitializingBean {
|
||||
*/
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
if (getSession() == null) {
|
||||
throw new IllegalArgumentException("Property 'session' is required");
|
||||
}
|
||||
Assert.notNull(session);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -127,6 +127,12 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>2.4</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -7,6 +7,8 @@ import org.springframework.data.cassandra.convert.CassandraConverter;
|
||||
import org.springframework.data.cassandra.core.CassandraAdminTemplate;
|
||||
import org.springframework.data.cassandra.mapping.CassandraMappingContext;
|
||||
import org.springframework.data.cassandra.mapping.CassandraPersistentEntity;
|
||||
import org.springframework.data.cassandra.mapping.EntityMapping;
|
||||
import org.springframework.data.cassandra.mapping.Mapping;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.springframework.data.cassandra.config.java;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -27,7 +28,6 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.type.filter.AnnotationTypeFilter;
|
||||
import org.springframework.data.annotation.Persistent;
|
||||
import org.springframework.data.cassandra.config.CassandraDataSessionFactoryBean;
|
||||
import org.springframework.data.cassandra.config.Mapping;
|
||||
import org.springframework.data.cassandra.config.SchemaAction;
|
||||
import org.springframework.data.cassandra.convert.CassandraConverter;
|
||||
import org.springframework.data.cassandra.convert.MappingCassandraConverter;
|
||||
@@ -35,6 +35,8 @@ import org.springframework.data.cassandra.core.CassandraAdminOperations;
|
||||
import org.springframework.data.cassandra.core.CassandraAdminTemplate;
|
||||
import org.springframework.data.cassandra.mapping.CassandraMappingContext;
|
||||
import org.springframework.data.cassandra.mapping.DefaultCassandraMappingContext;
|
||||
import org.springframework.data.cassandra.mapping.Mapping;
|
||||
import org.springframework.data.cassandra.mapping.PrimaryKeyClass;
|
||||
import org.springframework.data.cassandra.mapping.Table;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.util.ClassUtils;
|
||||
@@ -66,7 +68,7 @@ public abstract class AbstractSpringDataCassandraConfiguration extends AbstractC
|
||||
* The base package to scan for entities annotated with {@link Table} annotations. By default, returns the package
|
||||
* name of {@literal this} (<code>this.getClass().getPackage().getName()</code>).
|
||||
*/
|
||||
public String getMappingBasePackage() {
|
||||
public String getEntityBasePackage() {
|
||||
return getClass().getPackage().getName();
|
||||
}
|
||||
|
||||
@@ -125,13 +127,13 @@ public abstract class AbstractSpringDataCassandraConfiguration extends AbstractC
|
||||
/**
|
||||
* Scans the mapping base package for entity classes annotated with {@link Table} or {@link Persistent}.
|
||||
*
|
||||
* @see #getMappingBasePackage()
|
||||
* @see #getEntityBasePackage()
|
||||
* @return <code>Set<Class<?>></code> representing the annotated entity classes found.
|
||||
* @throws ClassNotFoundException
|
||||
*/
|
||||
protected Set<Class<?>> getInitialEntitySet() throws ClassNotFoundException {
|
||||
|
||||
String basePackage = getMappingBasePackage();
|
||||
String basePackage = getEntityBasePackage();
|
||||
Set<Class<?>> initialEntitySet = new HashSet<Class<?>>();
|
||||
|
||||
if (StringUtils.hasText(basePackage)) {
|
||||
@@ -139,6 +141,7 @@ public abstract class AbstractSpringDataCassandraConfiguration extends AbstractC
|
||||
false);
|
||||
componentProvider.addIncludeFilter(new AnnotationTypeFilter(Table.class));
|
||||
componentProvider.addIncludeFilter(new AnnotationTypeFilter(Persistent.class));
|
||||
componentProvider.addIncludeFilter(new AnnotationTypeFilter(PrimaryKeyClass.class));
|
||||
|
||||
for (BeanDefinition candidate : componentProvider.findCandidateComponents(basePackage)) {
|
||||
|
||||
|
||||
@@ -10,9 +10,9 @@ import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.cassandra.config.xml.CassandraSessionParser;
|
||||
import org.springframework.data.cassandra.config.DefaultDataBeanNames;
|
||||
import org.springframework.data.cassandra.config.CassandraDataSessionFactoryBean;
|
||||
import org.springframework.data.cassandra.config.EntityMapping;
|
||||
import org.springframework.data.cassandra.config.Mapping;
|
||||
import org.springframework.data.cassandra.config.SchemaAction;
|
||||
import org.springframework.data.cassandra.mapping.EntityMapping;
|
||||
import org.springframework.data.cassandra.mapping.Mapping;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.util.xml.DomUtils;
|
||||
import org.w3c.dom.Attr;
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package org.springframework.data.cassandra.convert;
|
||||
|
||||
import org.springframework.data.cassandra.mapping.CassandraPersistentProperty;
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.data.mapping.model.PersistentEntityParameterValueProvider;
|
||||
import org.springframework.data.mapping.model.PropertyValueProvider;
|
||||
|
||||
public class CassandraPersistentEntityParameterValueProvider extends
|
||||
PersistentEntityParameterValueProvider<CassandraPersistentProperty> {
|
||||
|
||||
public CassandraPersistentEntityParameterValueProvider(PersistentEntity<?, CassandraPersistentProperty> entity,
|
||||
PropertyValueProvider<CassandraPersistentProperty> provider, Object parent) {
|
||||
super(entity, provider, parent);
|
||||
}
|
||||
}
|
||||
@@ -31,11 +31,10 @@ import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mapping.model.BeanWrapper;
|
||||
import org.springframework.data.mapping.model.DefaultSpELExpressionEvaluator;
|
||||
import org.springframework.data.mapping.model.MappingException;
|
||||
import org.springframework.data.mapping.model.PersistentEntityParameterValueProvider;
|
||||
import org.springframework.data.mapping.model.PropertyValueProvider;
|
||||
import org.springframework.data.mapping.model.SpELContext;
|
||||
import org.springframework.data.util.ClassTypeInformation;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
import com.datastax.driver.core.Row;
|
||||
@@ -54,14 +53,14 @@ import com.datastax.driver.core.querybuilder.Update;
|
||||
public class MappingCassandraConverter extends AbstractCassandraConverter implements CassandraConverter,
|
||||
ApplicationContextAware, BeanClassLoaderAware {
|
||||
|
||||
protected static final Logger log = LoggerFactory.getLogger(MappingCassandraConverter.class);
|
||||
protected final Logger log = LoggerFactory.getLogger(getClass());
|
||||
|
||||
protected final CassandraMappingContext mappingContext;
|
||||
protected ApplicationContext applicationContext;
|
||||
private SpELContext spELContext;
|
||||
private boolean useFieldAccessOnly = true;
|
||||
protected SpELContext spELContext;
|
||||
protected boolean useFieldAccessOnly = true;
|
||||
|
||||
private ClassLoader beanClassLoader;
|
||||
protected ClassLoader beanClassLoader;
|
||||
|
||||
/**
|
||||
* Creates a new {@link MappingCassandraConverter} with the given {@link CassandraMappingContext}.
|
||||
@@ -69,7 +68,11 @@ public class MappingCassandraConverter extends AbstractCassandraConverter implem
|
||||
* @param mappingContext must not be {@literal null}.
|
||||
*/
|
||||
public MappingCassandraConverter(CassandraMappingContext mappingContext) {
|
||||
|
||||
super(new DefaultConversionService());
|
||||
|
||||
Assert.notNull(mappingContext);
|
||||
|
||||
this.mappingContext = mappingContext;
|
||||
this.spELContext = new SpELContext(RowReaderPropertyAccessor.INSTANCE);
|
||||
}
|
||||
@@ -111,45 +114,48 @@ public class MappingCassandraConverter extends AbstractCassandraConverter implem
|
||||
|
||||
final DefaultSpELExpressionEvaluator evaluator = new DefaultSpELExpressionEvaluator(row, spELContext);
|
||||
|
||||
final PropertyValueProvider<CassandraPersistentProperty> propertyProvider = new CassandraPropertyValueProvider(row,
|
||||
evaluator);
|
||||
final CassandraPropertyValueProvider propertyProvider = new CassandraPropertyValueProvider(row, evaluator);
|
||||
|
||||
PersistentEntityParameterValueProvider<CassandraPersistentProperty> parameterProvider = new PersistentEntityParameterValueProvider<CassandraPersistentProperty>(
|
||||
CassandraPersistentEntityParameterValueProvider parameterProvider = new CassandraPersistentEntityParameterValueProvider(
|
||||
entity, propertyProvider, null);
|
||||
|
||||
EntityInstantiator instantiator = instantiators.getInstantiatorFor(entity);
|
||||
S instance = instantiator.createInstance(entity, parameterProvider);
|
||||
|
||||
final BeanWrapper<CassandraPersistentEntity<S>, S> wrapper = BeanWrapper.create(instance, conversionService);
|
||||
S result = wrapper.getBean();
|
||||
|
||||
readPropertiesFromRow(entity, row, propertyProvider, wrapper);
|
||||
|
||||
return wrapper.getBean();
|
||||
}
|
||||
|
||||
protected void readPropertiesFromRow(final CassandraPersistentEntity<?> entity, final Row row,
|
||||
final CassandraPropertyValueProvider propertyProvider, final BeanWrapper<?, ?> wrapper) {
|
||||
|
||||
entity.doWithProperties(new PropertyHandler<CassandraPersistentProperty>() {
|
||||
|
||||
@Override
|
||||
public void doWithPersistentProperty(CassandraPersistentProperty prop) {
|
||||
|
||||
MappingCassandraConverter.this.handlePersistentPropertyRead(row, entity, prop, propertyProvider, wrapper);
|
||||
MappingCassandraConverter.this.readPropertyFromRow(row, entity, prop, propertyProvider, wrapper);
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
protected void handlePersistentPropertyRead(final Row row, final CassandraPersistentEntity<?> entity,
|
||||
final CassandraPersistentProperty prop,
|
||||
final PropertyValueProvider<CassandraPersistentProperty> propertyProvider, final BeanWrapper<?, ?> wrapper) {
|
||||
protected void readPropertyFromRow(final Row row, final CassandraPersistentEntity<?> entity,
|
||||
final CassandraPersistentProperty prop, final CassandraPropertyValueProvider propertyProvider,
|
||||
final BeanWrapper<?, ?> wrapper) {
|
||||
|
||||
if (entity.isConstructorArgument(prop)) { // skip 'cause prop was set in ctor
|
||||
return;
|
||||
}
|
||||
|
||||
if (prop.isCompositePrimaryKey()) {
|
||||
// handle composite primary key properties via recursion into this method
|
||||
throw new UnsupportedOperationException("composite primary keys are TODO");
|
||||
readPropertiesFromRow(prop.getCompositePrimaryKeyEntity(), row, propertyProvider, wrapper);
|
||||
return;
|
||||
}
|
||||
|
||||
boolean hasValueForProperty = row.getColumnDefinitions().contains(prop.getColumnName());
|
||||
if (!hasValueForProperty) {
|
||||
if (!row.getColumnDefinitions().contains(prop.getColumnName())) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -174,103 +180,121 @@ public class MappingCassandraConverter extends AbstractCassandraConverter implem
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(Object obj, Object builtStatement) {
|
||||
public void write(Object source, Object sink) {
|
||||
|
||||
if (obj == null) {
|
||||
if (source == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Class<?> beanClassLoaderClass = transformClassToBeanClassLoaderClass(obj.getClass());
|
||||
Class<?> beanClassLoaderClass = transformClassToBeanClassLoaderClass(source.getClass());
|
||||
CassandraPersistentEntity<?> entity = mappingContext.getPersistentEntity(beanClassLoaderClass);
|
||||
|
||||
if (entity == null) {
|
||||
throw new MappingException("No mapping metadata found for " + obj.getClass());
|
||||
throw new MappingException("No mapping metadata found for " + source.getClass());
|
||||
}
|
||||
|
||||
if (builtStatement instanceof Insert) {
|
||||
writeInsertInternal(obj, (Insert) builtStatement, entity);
|
||||
} else if (builtStatement instanceof Update) {
|
||||
writeUpdateInternal(obj, (Update) builtStatement, entity);
|
||||
} else if (builtStatement instanceof Where) {
|
||||
writeDeleteWhereInternal(obj, (Where) builtStatement, entity);
|
||||
if (sink instanceof Insert) {
|
||||
writeInsertFromObject(source, (Insert) sink, entity);
|
||||
} else if (sink instanceof Update) {
|
||||
writeUpdateFromObject(source, (Update) sink, entity);
|
||||
} else if (sink instanceof Where) {
|
||||
writeDeleteWhereFromObject(source, (Where) sink, entity);
|
||||
} else {
|
||||
throw new MappingException("Unknown buildStatement " + builtStatement.getClass().getName());
|
||||
throw new MappingException("Unknown buildStatement " + sink.getClass().getName());
|
||||
}
|
||||
}
|
||||
|
||||
private void writeInsertInternal(final Object objectToSave, final Insert insert, CassandraPersistentEntity<?> entity) {
|
||||
|
||||
final BeanWrapper<CassandraPersistentEntity<Object>, Object> wrapper = BeanWrapper.create(objectToSave,
|
||||
conversionService);
|
||||
|
||||
// Write the properties
|
||||
entity.doWithProperties(new PropertyHandler<CassandraPersistentProperty>() {
|
||||
@Override
|
||||
public void doWithPersistentProperty(CassandraPersistentProperty prop) {
|
||||
|
||||
Object propertyObj = wrapper.getProperty(prop, prop.getType(), useFieldAccessOnly);
|
||||
|
||||
if (propertyObj != null) {
|
||||
insert.value(prop.getColumnName(), propertyObj);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
protected void writeInsertFromObject(final Object object, final Insert insert, CassandraPersistentEntity<?> entity) {
|
||||
writeInsertFromWrapper(BeanWrapper.<CassandraPersistentEntity<Object>, Object> create(object, conversionService),
|
||||
insert, entity);
|
||||
}
|
||||
|
||||
private void writeUpdateInternal(final Object objectToSave, final Update update, CassandraPersistentEntity<?> entity) {
|
||||
protected void writeInsertFromWrapper(final BeanWrapper<CassandraPersistentEntity<Object>, Object> wrapper,
|
||||
final Insert insert, CassandraPersistentEntity<?> entity) {
|
||||
|
||||
final BeanWrapper<CassandraPersistentEntity<Object>, Object> wrapper = BeanWrapper.create(objectToSave,
|
||||
conversionService);
|
||||
|
||||
// Write the properties
|
||||
entity.doWithProperties(new PropertyHandler<CassandraPersistentProperty>() {
|
||||
|
||||
@Override
|
||||
public void doWithPersistentProperty(CassandraPersistentProperty prop) {
|
||||
|
||||
Object propertyObj = wrapper.getProperty(prop, prop.getType(), useFieldAccessOnly);
|
||||
Object value = wrapper.getProperty(prop, prop.getType(), useFieldAccessOnly);
|
||||
|
||||
if (propertyObj != null) {
|
||||
if (prop.isIdProperty()) {
|
||||
update.where(QueryBuilder.eq(prop.getColumnName(), propertyObj));
|
||||
if (prop.isCompositePrimaryKey()) {
|
||||
writeInsertFromWrapper(
|
||||
BeanWrapper.<CassandraPersistentEntity<Object>, Object> create(value, conversionService), insert,
|
||||
prop.getCompositePrimaryKeyEntity());
|
||||
return;
|
||||
}
|
||||
|
||||
if (value != null) {
|
||||
insert.value(prop.getColumnName(), value);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void writeUpdateFromObject(final Object object, final Update update, CassandraPersistentEntity<?> entity) {
|
||||
writeUpdateFromWrapper(BeanWrapper.<CassandraPersistentEntity<Object>, Object> create(object, conversionService),
|
||||
update, entity);
|
||||
}
|
||||
|
||||
protected void writeUpdateFromWrapper(final BeanWrapper<CassandraPersistentEntity<Object>, Object> wrapper,
|
||||
final Update update, final CassandraPersistentEntity<?> entity) {
|
||||
|
||||
entity.doWithProperties(new PropertyHandler<CassandraPersistentProperty>() {
|
||||
|
||||
@Override
|
||||
public void doWithPersistentProperty(CassandraPersistentProperty prop) {
|
||||
|
||||
Object value = wrapper.getProperty(prop, prop.getType(), useFieldAccessOnly);
|
||||
|
||||
if (prop.isCompositePrimaryKey()) {
|
||||
writeUpdateFromWrapper(
|
||||
BeanWrapper.<CassandraPersistentEntity<Object>, Object> create(value, conversionService), update,
|
||||
prop.getCompositePrimaryKeyEntity());
|
||||
return;
|
||||
}
|
||||
|
||||
if (value != null) {
|
||||
if (prop.isIdProperty() || entity.isCompositePrimaryKey()) {
|
||||
update.where(QueryBuilder.eq(prop.getColumnName(), value));
|
||||
} else {
|
||||
update.with(QueryBuilder.set(prop.getColumnName(), propertyObj));
|
||||
update.with(QueryBuilder.set(prop.getColumnName(), value));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void writeDeleteWhereInternal(final Object objectToSave, final Where whereId,
|
||||
CassandraPersistentEntity<?> entity) {
|
||||
protected void writeDeleteWhereFromObject(final Object object, final Where where, CassandraPersistentEntity<?> entity) {
|
||||
writeDeleteWhereFromWrapper(
|
||||
BeanWrapper.<CassandraPersistentEntity<Object>, Object> create(object, conversionService), where, entity);
|
||||
}
|
||||
|
||||
final BeanWrapper<CassandraPersistentEntity<Object>, Object> wrapper = BeanWrapper.create(objectToSave,
|
||||
conversionService);
|
||||
protected void writeDeleteWhereFromWrapper(final BeanWrapper<CassandraPersistentEntity<Object>, Object> wrapper,
|
||||
final Where where, CassandraPersistentEntity<?> entity) {
|
||||
|
||||
// Write the properties
|
||||
entity.doWithProperties(new PropertyHandler<CassandraPersistentProperty>() {
|
||||
@Override
|
||||
public void doWithPersistentProperty(CassandraPersistentProperty prop) {
|
||||
CassandraPersistentProperty idProperty = entity.getIdProperty();
|
||||
Object idValue = wrapper.getProperty(idProperty, idProperty.getType(), useFieldAccessOnly);
|
||||
|
||||
if (prop.isIdProperty()) {
|
||||
if (idValue == null) {
|
||||
String msg = String.format("no id value found in object {}", wrapper.getBean());
|
||||
log.error(msg);
|
||||
throw new IllegalArgumentException(msg);
|
||||
}
|
||||
|
||||
Object propertyObj = wrapper.getProperty(prop, prop.getType(), useFieldAccessOnly);
|
||||
|
||||
if (propertyObj != null) {
|
||||
whereId.and(QueryBuilder.eq(prop.getColumnName(), propertyObj));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
if (idProperty.isCompositePrimaryKey()) {
|
||||
writeDeleteWhereFromWrapper(
|
||||
BeanWrapper.<CassandraPersistentEntity<Object>, Object> create(idValue, conversionService), where,
|
||||
idProperty.getCompositePrimaryKeyEntity());
|
||||
return;
|
||||
}
|
||||
|
||||
where.and(QueryBuilder.eq(idProperty.getColumnName(), idValue));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> Class<T> transformClassToBeanClassLoaderClass(Class<T> entity) {
|
||||
protected <T> Class<T> transformClassToBeanClassLoaderClass(Class<T> entity) {
|
||||
try {
|
||||
return (Class<T>) ClassUtils.forName(entity.getName(), beanClassLoader);
|
||||
} catch (ClassNotFoundException e) {
|
||||
|
||||
@@ -6,7 +6,12 @@ import java.util.Map;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.cassandra.core.SessionCallback;
|
||||
import org.springframework.cassandra.core.cql.generator.AlterTableCqlGenerator;
|
||||
import org.springframework.cassandra.core.cql.generator.CreateTableCqlGenerator;
|
||||
import org.springframework.cassandra.core.cql.generator.DropTableCqlGenerator;
|
||||
import org.springframework.cassandra.core.keyspace.AlterTableSpecification;
|
||||
import org.springframework.cassandra.core.keyspace.CreateTableSpecification;
|
||||
import org.springframework.cassandra.core.keyspace.DropTableSpecification;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.data.cassandra.convert.CassandraConverter;
|
||||
@@ -60,7 +65,9 @@ public class CassandraAdminTemplate extends CassandraTemplate implements Cassand
|
||||
|
||||
@Override
|
||||
public void replaceTable(String tableName, Class<?> entityClass, Map<String, Object> optionsByName) {
|
||||
throw new UnsupportedOperationException("not yet implemented");
|
||||
|
||||
dropTable(tableName);
|
||||
createTable(false, tableName, entityClass, optionsByName);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -102,15 +109,7 @@ public class CassandraAdminTemplate extends CassandraTemplate implements Cassand
|
||||
|
||||
log.info("Dropping table => " + tableName);
|
||||
|
||||
final String q = CqlUtils.dropTable(tableName);
|
||||
log.info(q);
|
||||
|
||||
execute(new SessionCallback<ResultSet>() {
|
||||
@Override
|
||||
public ResultSet doInSession(Session s) {
|
||||
return s.execute(q);
|
||||
}
|
||||
});
|
||||
execute(DropTableSpecification.dropTable(tableName));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -125,24 +124,4 @@ public class CassandraAdminTemplate extends CassandraTemplate implements Cassand
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param entityClass
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String determineTableName(Class<?> entityClass) {
|
||||
|
||||
if (entityClass == null) {
|
||||
throw new InvalidDataAccessApiUsageException(
|
||||
"No class parameter provided, entity table name can't be determined!");
|
||||
}
|
||||
|
||||
CassandraPersistentEntity<?> entity = getCassandraMappingContext().getPersistentEntity(entityClass);
|
||||
if (entity == null) {
|
||||
throw new InvalidDataAccessApiUsageException("No Persitent Entity information found for the class "
|
||||
+ entityClass.getName());
|
||||
}
|
||||
return entity.getTableName();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,32 +16,34 @@
|
||||
package org.springframework.data.cassandra.core;
|
||||
|
||||
import org.springframework.cassandra.core.RowCallback;
|
||||
import org.springframework.data.convert.EntityReader;
|
||||
import org.springframework.data.cassandra.convert.CassandraConverter;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.datastax.driver.core.Row;
|
||||
|
||||
/**
|
||||
* Simple {@link RowCallback} that will transform {@link Row} into the given target type using the given
|
||||
* {@link EntityReader}.
|
||||
* Simple {@link RowCallback} that will transform a {@link Row} into the given target type using the given
|
||||
* {@link CassandraConverter}.
|
||||
*
|
||||
* @author Alex Shvid
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class ReadRowCallback<T> implements RowCallback<T> {
|
||||
public class CassandraConverterRowCallback<T> implements RowCallback<T> {
|
||||
|
||||
private final EntityReader<? super T, Object> reader;
|
||||
private final CassandraConverter reader;
|
||||
private final Class<T> type;
|
||||
|
||||
public ReadRowCallback(EntityReader<? super T, Object> reader, Class<T> type) {
|
||||
public CassandraConverterRowCallback(CassandraConverter reader, Class<T> type) {
|
||||
|
||||
Assert.notNull(reader);
|
||||
Assert.notNull(type);
|
||||
|
||||
this.reader = reader;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T doWith(Row row) {
|
||||
T source = reader.read(type, row);
|
||||
return source;
|
||||
return reader.read(type, row);
|
||||
}
|
||||
}
|
||||
@@ -21,8 +21,6 @@ import org.springframework.cassandra.core.CqlOperations;
|
||||
import org.springframework.cassandra.core.QueryOptions;
|
||||
import org.springframework.data.cassandra.convert.CassandraConverter;
|
||||
|
||||
import com.datastax.driver.core.querybuilder.Select;
|
||||
|
||||
/**
|
||||
* Operations for interacting with Cassandra. These operations are used by the Repository implementation, but can also
|
||||
* be used directly when that is desired by the developer.
|
||||
@@ -30,7 +28,6 @@ import com.datastax.driver.core.querybuilder.Select;
|
||||
* @author Alex Shvid
|
||||
* @author David Webb
|
||||
* @author Matthew Adams
|
||||
*
|
||||
*/
|
||||
public interface CassandraOperations extends CqlOperations {
|
||||
|
||||
@@ -46,49 +43,25 @@ public interface CassandraOperations extends CqlOperations {
|
||||
* Execute query and convert ResultSet to the list of entities
|
||||
*
|
||||
* @param query must not be {@literal null}.
|
||||
* @param selectClass must not be {@literal null}, mapped entity type.
|
||||
* @param type must not be {@literal null}, mapped entity type.
|
||||
* @return
|
||||
*/
|
||||
<T> List<T> select(String cql, Class<T> selectClass);
|
||||
<T> List<T> select(String cql, Class<T> type);
|
||||
|
||||
/**
|
||||
* Execute query and convert ResultSet to the list of entities
|
||||
*
|
||||
* @param selectQuery must not be {@literal null}.
|
||||
* @param selectClass must not be {@literal null}, mapped entity type.
|
||||
* @return
|
||||
*/
|
||||
|
||||
<T> List<T> select(Select selectQuery, Class<T> selectClass);
|
||||
<T> T selectOneById(Class<T> type, Object id);
|
||||
|
||||
/**
|
||||
* Execute query and convert ResultSet to the entity
|
||||
*
|
||||
* @param query must not be {@literal null}.
|
||||
* @param selectClass must not be {@literal null}, mapped entity type.
|
||||
* @param type must not be {@literal null}, mapped entity type.
|
||||
* @return
|
||||
*/
|
||||
<T> T selectOne(String cql, Class<T> selectClass);
|
||||
<T> T selectOne(String cql, Class<T> type);
|
||||
|
||||
<T> T selectOne(Select selectQuery, Class<T> selectClass);
|
||||
boolean exists(Class<?> type, Object id);
|
||||
|
||||
/**
|
||||
* Counts rows for given query
|
||||
*
|
||||
* @param selectQuery
|
||||
* @return
|
||||
*/
|
||||
|
||||
Long count(Select selectQuery);
|
||||
|
||||
/**
|
||||
* Counts all rows for given table
|
||||
*
|
||||
* @param tableName
|
||||
* @return
|
||||
*/
|
||||
|
||||
Long count(String tableName);
|
||||
long count(Class<?> type);
|
||||
|
||||
/**
|
||||
* Insert the given object to the table by id.
|
||||
@@ -97,23 +70,6 @@ public interface CassandraOperations extends CqlOperations {
|
||||
*/
|
||||
<T> T insert(T entity);
|
||||
|
||||
/**
|
||||
* Insert the given object to the table by id.
|
||||
*
|
||||
* @param entity
|
||||
* @param tableName
|
||||
* @return
|
||||
*/
|
||||
<T> T insert(T entity, String tableName);
|
||||
|
||||
/**
|
||||
* @param entity
|
||||
* @param tableName
|
||||
* @param options
|
||||
* @return
|
||||
*/
|
||||
<T> T insert(T entity, String tableName, QueryOptions options);
|
||||
|
||||
/**
|
||||
* @param entity
|
||||
* @param tableName
|
||||
@@ -130,15 +86,6 @@ public interface CassandraOperations extends CqlOperations {
|
||||
*/
|
||||
<T> List<T> insert(List<T> entities);
|
||||
|
||||
/**
|
||||
* Insert the given list of objects to the table by name.
|
||||
*
|
||||
* @param entities
|
||||
* @param tableName
|
||||
* @return
|
||||
*/
|
||||
<T> List<T> insert(List<T> entities, String tableName);
|
||||
|
||||
/**
|
||||
* @param entities
|
||||
* @param tableName
|
||||
@@ -147,14 +94,6 @@ public interface CassandraOperations extends CqlOperations {
|
||||
*/
|
||||
<T> List<T> insert(List<T> entities, QueryOptions options);
|
||||
|
||||
/**
|
||||
* @param entities
|
||||
* @param tableName
|
||||
* @param options
|
||||
* @return
|
||||
*/
|
||||
<T> List<T> insert(List<T> entities, String tableName, QueryOptions options);
|
||||
|
||||
/**
|
||||
* Insert the given object to the table by id.
|
||||
*
|
||||
@@ -162,13 +101,6 @@ public interface CassandraOperations extends CqlOperations {
|
||||
*/
|
||||
<T> T insertAsynchronously(T entity);
|
||||
|
||||
/**
|
||||
* Insert the given object to the table by id.
|
||||
*
|
||||
* @param object
|
||||
*/
|
||||
<T> T insertAsynchronously(T entity, String tableName);
|
||||
|
||||
/**
|
||||
* @param entity
|
||||
* @param tableName
|
||||
@@ -177,14 +109,6 @@ public interface CassandraOperations extends CqlOperations {
|
||||
*/
|
||||
<T> T insertAsynchronously(T entity, QueryOptions options);
|
||||
|
||||
/**
|
||||
* @param entity
|
||||
* @param tableName
|
||||
* @param options
|
||||
* @return
|
||||
*/
|
||||
<T> T insertAsynchronously(T entity, String tableName, QueryOptions options);
|
||||
|
||||
/**
|
||||
* Insert the given object to the table by id.
|
||||
*
|
||||
@@ -192,13 +116,6 @@ public interface CassandraOperations extends CqlOperations {
|
||||
*/
|
||||
<T> List<T> insertAsynchronously(List<T> entities);
|
||||
|
||||
/**
|
||||
* Insert the given object to the table by id.
|
||||
*
|
||||
* @param object
|
||||
*/
|
||||
<T> List<T> insertAsynchronously(List<T> entities, String tableName);
|
||||
|
||||
/**
|
||||
* @param entities
|
||||
* @param tableName
|
||||
@@ -207,14 +124,6 @@ public interface CassandraOperations extends CqlOperations {
|
||||
*/
|
||||
<T> List<T> insertAsynchronously(List<T> entities, QueryOptions options);
|
||||
|
||||
/**
|
||||
* @param entities
|
||||
* @param tableName
|
||||
* @param options
|
||||
* @return
|
||||
*/
|
||||
<T> List<T> insertAsynchronously(List<T> entities, String tableName, QueryOptions options);
|
||||
|
||||
/**
|
||||
* Insert the given object to the table by id.
|
||||
*
|
||||
@@ -222,13 +131,6 @@ public interface CassandraOperations extends CqlOperations {
|
||||
*/
|
||||
<T> T update(T entity);
|
||||
|
||||
/**
|
||||
* Insert the given object to the table by id.
|
||||
*
|
||||
* @param object
|
||||
*/
|
||||
<T> T update(T entity, String tableName);
|
||||
|
||||
/**
|
||||
* @param entity
|
||||
* @param tableName
|
||||
@@ -237,14 +139,6 @@ public interface CassandraOperations extends CqlOperations {
|
||||
*/
|
||||
<T> T update(T entity, QueryOptions options);
|
||||
|
||||
/**
|
||||
* @param entity
|
||||
* @param tableName
|
||||
* @param options
|
||||
* @return
|
||||
*/
|
||||
<T> T update(T entity, String tableName, QueryOptions options);
|
||||
|
||||
/**
|
||||
* Insert the given object to the table by id.
|
||||
*
|
||||
@@ -252,13 +146,6 @@ public interface CassandraOperations extends CqlOperations {
|
||||
*/
|
||||
<T> List<T> update(List<T> entities);
|
||||
|
||||
/**
|
||||
* Insert the given object to the table by id.
|
||||
*
|
||||
* @param object
|
||||
*/
|
||||
<T> List<T> update(List<T> entities, String tableName);
|
||||
|
||||
/**
|
||||
* @param entities
|
||||
* @param tableName
|
||||
@@ -267,14 +154,6 @@ public interface CassandraOperations extends CqlOperations {
|
||||
*/
|
||||
<T> List<T> update(List<T> entities, QueryOptions options);
|
||||
|
||||
/**
|
||||
* @param entities
|
||||
* @param tableName
|
||||
* @param options
|
||||
* @return
|
||||
*/
|
||||
<T> List<T> update(List<T> entities, String tableName, QueryOptions options);
|
||||
|
||||
/**
|
||||
* Insert the given object to the table by id.
|
||||
*
|
||||
@@ -282,13 +161,6 @@ public interface CassandraOperations extends CqlOperations {
|
||||
*/
|
||||
<T> T updateAsynchronously(T entity);
|
||||
|
||||
/**
|
||||
* Insert the given object to the table by id.
|
||||
*
|
||||
* @param object
|
||||
*/
|
||||
<T> T updateAsynchronously(T entity, String tableName);
|
||||
|
||||
/**
|
||||
* @param entity
|
||||
* @param tableName
|
||||
@@ -297,14 +169,6 @@ public interface CassandraOperations extends CqlOperations {
|
||||
*/
|
||||
<T> T updateAsynchronously(T entity, QueryOptions options);
|
||||
|
||||
/**
|
||||
* @param entity
|
||||
* @param tableName
|
||||
* @param options
|
||||
* @return
|
||||
*/
|
||||
<T> T updateAsynchronously(T entity, String tableName, QueryOptions options);
|
||||
|
||||
/**
|
||||
* Insert the given object to the table by id.
|
||||
*
|
||||
@@ -312,13 +176,6 @@ public interface CassandraOperations extends CqlOperations {
|
||||
*/
|
||||
<T> List<T> updateAsynchronously(List<T> entities);
|
||||
|
||||
/**
|
||||
* Insert the given object to the table by id.
|
||||
*
|
||||
* @param object
|
||||
*/
|
||||
<T> List<T> updateAsynchronously(List<T> entities, String tableName);
|
||||
|
||||
/**
|
||||
* @param entities
|
||||
* @param tableName
|
||||
@@ -327,14 +184,6 @@ public interface CassandraOperations extends CqlOperations {
|
||||
*/
|
||||
<T> List<T> updateAsynchronously(List<T> entities, QueryOptions options);
|
||||
|
||||
/**
|
||||
* @param entities
|
||||
* @param tableName
|
||||
* @param options
|
||||
* @return
|
||||
*/
|
||||
<T> List<T> updateAsynchronously(List<T> entities, String tableName, QueryOptions options);
|
||||
|
||||
/**
|
||||
* Remove the given object from the table by id.
|
||||
*
|
||||
@@ -342,14 +191,6 @@ public interface CassandraOperations extends CqlOperations {
|
||||
*/
|
||||
<T> void delete(T entity);
|
||||
|
||||
/**
|
||||
* Removes the given object from the given table.
|
||||
*
|
||||
* @param object
|
||||
* @param table must not be {@literal null} or empty.
|
||||
*/
|
||||
<T> void delete(T entity, String tableName);
|
||||
|
||||
/**
|
||||
* @param entity
|
||||
* @param tableName
|
||||
@@ -357,13 +198,6 @@ public interface CassandraOperations extends CqlOperations {
|
||||
*/
|
||||
<T> void delete(T entity, QueryOptions options);
|
||||
|
||||
/**
|
||||
* @param entity
|
||||
* @param tableName
|
||||
* @param options
|
||||
*/
|
||||
<T> void delete(T entity, String tableName, QueryOptions options);
|
||||
|
||||
/**
|
||||
* Remove the given object from the table by id.
|
||||
*
|
||||
@@ -371,14 +205,6 @@ public interface CassandraOperations extends CqlOperations {
|
||||
*/
|
||||
<T> void delete(List<T> entities);
|
||||
|
||||
/**
|
||||
* Removes the given object from the given table.
|
||||
*
|
||||
* @param object
|
||||
* @param table must not be {@literal null} or empty.
|
||||
*/
|
||||
<T> void delete(List<T> entities, String tableName);
|
||||
|
||||
/**
|
||||
* @param entities
|
||||
* @param tableName
|
||||
@@ -386,13 +212,6 @@ public interface CassandraOperations extends CqlOperations {
|
||||
*/
|
||||
<T> void delete(List<T> entities, QueryOptions options);
|
||||
|
||||
/**
|
||||
* @param entities
|
||||
* @param tableName
|
||||
* @param options
|
||||
*/
|
||||
<T> void delete(List<T> entities, String tableName, QueryOptions options);
|
||||
|
||||
/**
|
||||
* Remove the given object from the table by id.
|
||||
*
|
||||
@@ -407,21 +226,6 @@ public interface CassandraOperations extends CqlOperations {
|
||||
*/
|
||||
<T> void deleteAsynchronously(T entity, QueryOptions options);
|
||||
|
||||
/**
|
||||
* @param entity
|
||||
* @param tableName
|
||||
* @param options
|
||||
*/
|
||||
<T> void deleteAsynchronously(T entity, String tableName, QueryOptions options);
|
||||
|
||||
/**
|
||||
* Removes the given object from the given table.
|
||||
*
|
||||
* @param object
|
||||
* @param table must not be {@literal null} or empty.
|
||||
*/
|
||||
<T> void deleteAsynchronously(T entity, String tableName);
|
||||
|
||||
/**
|
||||
* Remove the given object from the table by id.
|
||||
*
|
||||
@@ -429,14 +233,6 @@ public interface CassandraOperations extends CqlOperations {
|
||||
*/
|
||||
<T> void deleteAsynchronously(List<T> entities);
|
||||
|
||||
/**
|
||||
* Removes the given object from the given table.
|
||||
*
|
||||
* @param object
|
||||
* @param table must not be {@literal null} or empty.
|
||||
*/
|
||||
<T> void deleteAsynchronously(List<T> entities, String tableName);
|
||||
|
||||
/**
|
||||
* @param entities
|
||||
* @param tableName
|
||||
@@ -444,17 +240,16 @@ public interface CassandraOperations extends CqlOperations {
|
||||
*/
|
||||
<T> void deleteAsynchronously(List<T> entities, QueryOptions options);
|
||||
|
||||
/**
|
||||
* @param entities
|
||||
* @param tableName
|
||||
* @param options
|
||||
*/
|
||||
<T> void deleteAsynchronously(List<T> entities, String tableName, QueryOptions options);
|
||||
|
||||
/**
|
||||
* Returns the underlying {@link CassandraConverter}.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
CassandraConverter getConverter();
|
||||
|
||||
void deleteById(Class<?> type, Object id);
|
||||
|
||||
<T> List<T> selectBySimpleIds(Class<T> type, Iterable<?> ids);
|
||||
|
||||
<T> List<T> selectAll(Class<T> type);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.cassandra.exception;
|
||||
|
||||
/**
|
||||
* Exception to handle failing to write a PersistedEntity to a CQL String or Query object
|
||||
*
|
||||
* @author David Webb
|
||||
*
|
||||
*/
|
||||
public class EntityWriterException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = -3068204776019978031L;
|
||||
|
||||
/**
|
||||
* @param message
|
||||
*/
|
||||
public EntityWriterException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param cause
|
||||
*/
|
||||
public EntityWriterException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param message
|
||||
* @param cause
|
||||
*/
|
||||
public EntityWriterException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,6 +15,9 @@
|
||||
*/
|
||||
package org.springframework.data.cassandra.mapping;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.cassandra.support.exception.UnsupportedCassandraOperationException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
@@ -24,6 +27,7 @@ import org.springframework.context.expression.BeanFactoryResolver;
|
||||
import org.springframework.data.cassandra.util.CassandraNamingUtils;
|
||||
import org.springframework.data.mapping.Association;
|
||||
import org.springframework.data.mapping.AssociationHandler;
|
||||
import org.springframework.data.mapping.PropertyHandler;
|
||||
import org.springframework.data.mapping.model.BasicPersistentEntity;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.expression.Expression;
|
||||
@@ -34,8 +38,7 @@ import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Cassandra specific {@link BasicPersistentEntity} implementation that adds Cassandra specific metadata such as the
|
||||
* table name.
|
||||
* Cassandra specific {@link BasicPersistentEntity} implementation that adds Cassandra specific metadata.
|
||||
*
|
||||
* @author Alex Shvid
|
||||
* @author Matthew T. Adams
|
||||
@@ -43,10 +46,14 @@ import org.springframework.util.StringUtils;
|
||||
public class BasicCassandraPersistentEntity<T> extends BasicPersistentEntity<T, CassandraPersistentProperty> implements
|
||||
CassandraPersistentEntity<T>, ApplicationContextAware {
|
||||
|
||||
private String tableName;
|
||||
private final SpelExpressionParser spelParser;
|
||||
private final StandardEvaluationContext spelContext;
|
||||
private final Class<T> type;
|
||||
protected String tableName;
|
||||
protected CassandraMappingContext mappingContext;
|
||||
protected final SpelExpressionParser spelParser;
|
||||
protected final StandardEvaluationContext spelContext;
|
||||
|
||||
public BasicCassandraPersistentEntity(TypeInformation<T> typeInformation) {
|
||||
this(typeInformation, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link BasicCassandraPersistentEntity} with the given {@link TypeInformation}. Will default the table
|
||||
@@ -54,23 +61,22 @@ public class BasicCassandraPersistentEntity<T> extends BasicPersistentEntity<T,
|
||||
*
|
||||
* @param typeInformation
|
||||
*/
|
||||
public BasicCassandraPersistentEntity(TypeInformation<T> typeInformation) {
|
||||
public BasicCassandraPersistentEntity(TypeInformation<T> typeInformation, CassandraMappingContext mappingContext) {
|
||||
|
||||
super(typeInformation, DefaultCassandraPersistentPropertyColumnComparator.IT);
|
||||
super(typeInformation, CassandraPersistentPropertyComparator.IT);
|
||||
|
||||
this.spelParser = new SpelExpressionParser();
|
||||
this.spelContext = new StandardEvaluationContext();
|
||||
|
||||
this.type = typeInformation.getType();
|
||||
this.mappingContext = mappingContext;
|
||||
|
||||
determineTableName();
|
||||
}
|
||||
|
||||
protected void determineTableName() {
|
||||
Table anno = type.getAnnotation(Table.class);
|
||||
Table anno = getType().getAnnotation(Table.class);
|
||||
|
||||
this.tableName = anno != null && StringUtils.hasText(anno.value()) ? anno.value() : CassandraNamingUtils
|
||||
.getPreferredTableName(type);
|
||||
.getPreferredTableName(getType());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -102,4 +108,46 @@ public class BasicCassandraPersistentEntity<T> extends BasicPersistentEntity<T,
|
||||
Assert.hasText(tableName);
|
||||
this.tableName = tableName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CassandraMappingContext getMappingContext() {
|
||||
return mappingContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCompositePrimaryKey() {
|
||||
return getType().isAnnotationPresent(PrimaryKeyClass.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CassandraPersistentProperty> getCompositePrimaryKeyProperties() {
|
||||
|
||||
final List<CassandraPersistentProperty> properties = new ArrayList<CassandraPersistentProperty>();
|
||||
|
||||
if (!isCompositePrimaryKey()) {
|
||||
throw new IllegalStateException(String.format("[%s] does not represent a composite primary key class", this
|
||||
.getType().getName()));
|
||||
}
|
||||
|
||||
addCompositePrimaryKeyProperties(this, properties);
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
protected void addCompositePrimaryKeyProperties(CassandraPersistentEntity<?> compositePrimaryKeyEntity,
|
||||
final List<CassandraPersistentProperty> properties) {
|
||||
|
||||
compositePrimaryKeyEntity.doWithProperties(new PropertyHandler<CassandraPersistentProperty>() {
|
||||
|
||||
@Override
|
||||
public void doWithPersistentProperty(CassandraPersistentProperty p) {
|
||||
|
||||
if (p.isCompositePrimaryKey()) {
|
||||
addCompositePrimaryKeyProperties(p.getCompositePrimaryKeyEntity(), properties);
|
||||
} else {
|
||||
properties.add(p);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ package org.springframework.data.cassandra.mapping;
|
||||
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -24,6 +25,7 @@ import org.springframework.cassandra.core.Ordering;
|
||||
import org.springframework.cassandra.core.PrimaryKeyType;
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.data.mapping.Association;
|
||||
import org.springframework.data.mapping.PropertyHandler;
|
||||
import org.springframework.data.mapping.model.AnnotationBasedPersistentProperty;
|
||||
import org.springframework.data.util.ClassTypeInformation;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
@@ -49,15 +51,20 @@ public class BasicCassandraPersistentProperty extends AnnotationBasedPersistentP
|
||||
*/
|
||||
public BasicCassandraPersistentProperty(Field field, PropertyDescriptor propertyDescriptor,
|
||||
CassandraPersistentEntity<?> owner, CassandraSimpleTypeHolder simpleTypeHolder) {
|
||||
|
||||
super(field, propertyDescriptor, owner, simpleTypeHolder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CassandraPersistentEntity<?> getOwner() {
|
||||
return (CassandraPersistentEntity<?>) super.getOwner();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCompositePrimaryKey() {
|
||||
return getField().getType().isAnnotationPresent(PrimaryKeyClass.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getCompositePrimaryKeyType() {
|
||||
if (!isCompositePrimaryKey()) {
|
||||
return null;
|
||||
@@ -67,31 +74,23 @@ public class BasicCassandraPersistentProperty extends AnnotationBasedPersistentP
|
||||
}
|
||||
|
||||
@Override
|
||||
public CassandraPersistentEntity<?> getCompositePrimaryKeyEntity() {
|
||||
public TypeInformation<?> getCompositePrimaryKeyTypeInformation() {
|
||||
if (!isCompositePrimaryKey()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (CassandraPersistentEntity<?>) ClassTypeInformation.from(getCompositePrimaryKeyType());
|
||||
return ClassTypeInformation.from(getCompositePrimaryKeyType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getColumnName() {
|
||||
|
||||
// first check @Column annotation
|
||||
Column column = findAnnotation(Column.class);
|
||||
if (column != null && StringUtils.hasText(column.value())) {
|
||||
return column.value();
|
||||
List<String> columnNames = getColumnNames();
|
||||
if (columnNames.size() != 1) {
|
||||
throw new IllegalStateException("property does not have a single column mapping");
|
||||
}
|
||||
|
||||
// else check @PrimaryKeyColumn annotation
|
||||
PrimaryKeyColumn pk = findAnnotation(PrimaryKeyColumn.class);
|
||||
if (pk != null && StringUtils.hasText(pk.name())) {
|
||||
return pk.name();
|
||||
}
|
||||
|
||||
// else default
|
||||
return field.getName().toLowerCase(); // TODO: replace with naming strategy class
|
||||
return columnNames.get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -199,11 +198,6 @@ public class BasicCassandraPersistentProperty extends AnnotationBasedPersistentP
|
||||
return isAnnotationPresent(PrimaryKeyColumn.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Association<CassandraPersistentProperty> createAssociation() {
|
||||
return new Association<CassandraPersistentProperty>(this, null);
|
||||
}
|
||||
|
||||
protected DataType getDataTypeFor(DataType.Name typeName) {
|
||||
DataType dataType = CassandraSimpleTypeHolder.getDataTypeFor(typeName);
|
||||
if (dataType == null) {
|
||||
@@ -230,4 +224,79 @@ public class BasicCassandraPersistentProperty extends AnnotationBasedPersistentP
|
||||
+ this.getName() + "' type is '" + this.getType() + "' in the entity " + this.getOwner().getName());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getColumnNames() {
|
||||
|
||||
final List<String> columnNames = new ArrayList<String>();
|
||||
|
||||
if (isCompositePrimaryKey()) {
|
||||
addCompositePrimaryKeyColumnNames(getCompositePrimaryKeyEntity(), columnNames);
|
||||
return columnNames;
|
||||
}
|
||||
|
||||
// else not a composite primary key property -- first check @Column annotation
|
||||
Column column = findAnnotation(Column.class);
|
||||
if (column != null && StringUtils.hasText(column.value())) {
|
||||
columnNames.add(column.value());
|
||||
return columnNames;
|
||||
}
|
||||
|
||||
// else check @PrimaryKeyColumn annotation
|
||||
PrimaryKeyColumn pk = findAnnotation(PrimaryKeyColumn.class);
|
||||
if (pk != null && StringUtils.hasText(pk.name())) {
|
||||
columnNames.add(pk.name());
|
||||
return columnNames;
|
||||
}
|
||||
|
||||
// else default
|
||||
columnNames.add(field.getName().toLowerCase()); // TODO: replace with naming strategy class
|
||||
return columnNames;
|
||||
}
|
||||
|
||||
protected void addCompositePrimaryKeyColumnNames(CassandraPersistentEntity<?> compositePrimaryKeyEntity,
|
||||
final List<String> columnNames) {
|
||||
|
||||
compositePrimaryKeyEntity.doWithProperties(new PropertyHandler<CassandraPersistentProperty>() {
|
||||
|
||||
@Override
|
||||
public void doWithPersistentProperty(CassandraPersistentProperty p) {
|
||||
if (p.isCompositePrimaryKey()) {
|
||||
addCompositePrimaryKeyColumnNames(p.getCompositePrimaryKeyEntity(), columnNames);
|
||||
} else {
|
||||
columnNames.add(p.getColumnName());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CassandraPersistentProperty> getCompositePrimaryKeyProperties() {
|
||||
|
||||
if (!isCompositePrimaryKey()) {
|
||||
throw new IllegalStateException(String.format("[%s] does not represent a composite primary key property",
|
||||
getField()));
|
||||
}
|
||||
|
||||
return getCompositePrimaryKeyEntity().getCompositePrimaryKeyProperties();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CassandraPersistentEntity<?> getCompositePrimaryKeyEntity() {
|
||||
CassandraMappingContext mappingContext = getOwner().getMappingContext();
|
||||
if (mappingContext == null) {
|
||||
throw new IllegalStateException("need CassandraMappingContext");
|
||||
}
|
||||
return mappingContext.getPersistentEntity(getCompositePrimaryKeyTypeInformation());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Association<CassandraPersistentProperty> getAssociation() {
|
||||
throw new UnsupportedOperationException("Cassandra does not support associations");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Association<CassandraPersistentProperty> createAssociation() {
|
||||
return new Association<CassandraPersistentProperty>(this, null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
package org.springframework.data.cassandra.mapping;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
|
||||
public class CachingCassandraPersistentEntity<T> extends BasicCassandraPersistentEntity<T> {
|
||||
|
||||
protected String tableName;
|
||||
protected String name;
|
||||
protected Boolean isCompositePrimaryKey;
|
||||
protected List<CassandraPersistentProperty> compositePrimaryKeyProperties;
|
||||
protected Map<String, CassandraPersistentProperty> properties = new HashMap<String, CassandraPersistentProperty>();
|
||||
|
||||
public CachingCassandraPersistentEntity(TypeInformation<T> typeInformation) {
|
||||
super(typeInformation);
|
||||
}
|
||||
|
||||
public CachingCassandraPersistentEntity(TypeInformation<T> typeInformation, CassandraMappingContext mappingContext) {
|
||||
super(typeInformation, mappingContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTableName() {
|
||||
if (tableName == null) {
|
||||
tableName = super.getTableName();
|
||||
}
|
||||
return tableName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
if (name == null) {
|
||||
name = super.getName();
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCompositePrimaryKey() {
|
||||
if (isCompositePrimaryKey == null) {
|
||||
isCompositePrimaryKey = super.isCompositePrimaryKey();
|
||||
}
|
||||
return isCompositePrimaryKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CassandraPersistentProperty> getCompositePrimaryKeyProperties() {
|
||||
if (compositePrimaryKeyProperties == null) {
|
||||
compositePrimaryKeyProperties = super.getCompositePrimaryKeyProperties();
|
||||
}
|
||||
return compositePrimaryKeyProperties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CassandraPersistentProperty getPersistentProperty(String name) {
|
||||
if (properties.get(name) == null) {
|
||||
properties.put(name, super.getPersistentProperty(name));
|
||||
}
|
||||
return properties.get(name);
|
||||
}
|
||||
}
|
||||
@@ -17,8 +17,10 @@ package org.springframework.data.cassandra.mapping;
|
||||
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.cassandra.core.Ordering;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
|
||||
import com.datastax.driver.core.DataType;
|
||||
|
||||
@@ -37,11 +39,12 @@ public class CachingCassandraPersistentProperty extends BasicCassandraPersistent
|
||||
private Boolean isClusterKeyColumn;
|
||||
private Boolean isPrimaryKeyColumn;
|
||||
private String columnName;
|
||||
private List<String> columnNames;
|
||||
private Ordering ordering;
|
||||
private boolean orderingCached = false;
|
||||
private DataType dataType;
|
||||
private Class<?> compositePrimaryKeyType;
|
||||
private CassandraPersistentEntity<?> compositePrimaryKeyEntity;
|
||||
private TypeInformation<?> compositePrimaryKeyTypeInformation;
|
||||
|
||||
/**
|
||||
* Creates a new {@link CachingCassandraPersistentProperty}.
|
||||
@@ -52,12 +55,12 @@ public class CachingCassandraPersistentProperty extends BasicCassandraPersistent
|
||||
}
|
||||
|
||||
@Override
|
||||
public CassandraPersistentEntity<?> getCompositePrimaryKeyEntity() {
|
||||
public TypeInformation<?> getCompositePrimaryKeyTypeInformation() {
|
||||
|
||||
if (compositePrimaryKeyEntity == null) {
|
||||
compositePrimaryKeyEntity = super.getCompositePrimaryKeyEntity();
|
||||
if (compositePrimaryKeyTypeInformation == null) {
|
||||
compositePrimaryKeyTypeInformation = super.getCompositePrimaryKeyTypeInformation();
|
||||
}
|
||||
return compositePrimaryKeyEntity;
|
||||
return compositePrimaryKeyTypeInformation;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -150,4 +153,12 @@ public class CachingCassandraPersistentProperty extends BasicCassandraPersistent
|
||||
}
|
||||
return isPartitionKeyColumn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getColumnNames() {
|
||||
if (columnNames == null) {
|
||||
columnNames = super.getColumnNames();
|
||||
}
|
||||
return columnNames;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package org.springframework.data.cassandra.mapping;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
/**
|
||||
* {@link Comparator} implementation that uses {@link Column#value()}.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public enum CassandraColumnAnnotationComparator implements Comparator<Column> {
|
||||
|
||||
/**
|
||||
* The sole instance of this class.
|
||||
*/
|
||||
IT;
|
||||
|
||||
@Override
|
||||
public int compare(Column left, Column right) {
|
||||
return left.value().compareTo(right.value());
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package org.springframework.data.cassandra.mapping;
|
||||
|
||||
import org.springframework.cassandra.core.keyspace.CreateTableSpecification;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
|
||||
import com.datastax.driver.core.TableMetadata;
|
||||
|
||||
@@ -26,4 +27,24 @@ public interface CassandraMappingContext extends
|
||||
* @param table May not be null.
|
||||
*/
|
||||
boolean usesTable(TableMetadata table);
|
||||
|
||||
/**
|
||||
* Returns the {@link CassandraPersistentEntity} for the given type. If it doesn't exist, this method throws
|
||||
* {@link IllegalArgumentException}.
|
||||
*
|
||||
* @param type The Java type of the persistent entity.
|
||||
* @return The {@link CassandraPersistentEntity} describing the persistent Java type.
|
||||
* @throws IllegalArgumentException if the persistent entity is unknown
|
||||
*/
|
||||
public CassandraPersistentEntity<?> getRequiredPersistentEntity(Class<?> type);
|
||||
|
||||
/**
|
||||
* Returns the {@link CassandraPersistentEntity} for the given type. If it doesn't exist, this method throws
|
||||
* {@link IllegalArgumentException}.
|
||||
*
|
||||
* @param type The {@link TypeInformation} of the persistent entity.
|
||||
* @return The {@link CassandraPersistentEntity} describing the persistent Java type.
|
||||
* @throws IllegalArgumentException if the persistent entity is unknown
|
||||
*/
|
||||
public CassandraPersistentEntity<?> getRequiredPersistentEntity(TypeInformation<?> type);
|
||||
}
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
*/
|
||||
package org.springframework.data.cassandra.mapping;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.data.mapping.model.MutablePersistentEntity;
|
||||
|
||||
@@ -24,7 +27,15 @@ import org.springframework.data.mapping.model.MutablePersistentEntity;
|
||||
* @author Alex Shvid
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public interface CassandraPersistentEntity<T> extends MutablePersistentEntity<T, CassandraPersistentProperty> {
|
||||
public interface CassandraPersistentEntity<T> extends MutablePersistentEntity<T, CassandraPersistentProperty>,
|
||||
ApplicationContextAware {
|
||||
|
||||
/**
|
||||
* Returns whether this entity represents a composite primary key.
|
||||
*/
|
||||
boolean isCompositePrimaryKey();
|
||||
|
||||
List<CassandraPersistentProperty> getCompositePrimaryKeyProperties();
|
||||
|
||||
/**
|
||||
* Returns the table name to which the entity shall be persisted.
|
||||
@@ -37,4 +48,6 @@ public interface CassandraPersistentEntity<T> extends MutablePersistentEntity<T,
|
||||
* @param tableName The table name; must contain a valid Cassandra table name.
|
||||
*/
|
||||
void setTableName(String tableName);
|
||||
|
||||
CassandraMappingContext getMappingContext();
|
||||
}
|
||||
|
||||
@@ -15,8 +15,11 @@
|
||||
*/
|
||||
package org.springframework.data.cassandra.mapping;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.cassandra.core.Ordering;
|
||||
import org.springframework.data.mapping.PersistentProperty;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
|
||||
import com.datastax.driver.core.DataType;
|
||||
|
||||
@@ -33,12 +36,6 @@ public interface CassandraPersistentProperty extends PersistentProperty<Cassandr
|
||||
*/
|
||||
boolean isCompositePrimaryKey();
|
||||
|
||||
/**
|
||||
* Returns the type of the composite primary key class of this entity, or null if this class does not use a composite
|
||||
* primary key.
|
||||
*/
|
||||
Class<?> getCompositePrimaryKeyType();
|
||||
|
||||
/**
|
||||
* Returns a {@link CassandraPersistentEntity} representing the composite primary key class of this entity, or null if
|
||||
* this class does not use a composite primary key.
|
||||
@@ -46,22 +43,42 @@ public interface CassandraPersistentProperty extends PersistentProperty<Cassandr
|
||||
CassandraPersistentEntity<?> getCompositePrimaryKeyEntity();
|
||||
|
||||
/**
|
||||
* The name of the column to which a property is persisted.
|
||||
* Returns a {@link TypeInformation} representing the type of the composite primary key class of this entity, or null
|
||||
* if this class does not use a composite primary key.
|
||||
*/
|
||||
TypeInformation<?> getCompositePrimaryKeyTypeInformation();
|
||||
|
||||
/**
|
||||
* Gets the list of composite primary key properties that this composite primary key field is a placeholder for.
|
||||
*/
|
||||
List<CassandraPersistentProperty> getCompositePrimaryKeyProperties();
|
||||
|
||||
/**
|
||||
* The name of the single column to which the property is persisted. This is a convenience method when the caller
|
||||
* knows that the property is mapped to a single column. Throws {@link IllegalStateException} if this property is
|
||||
* mapped to multiple columns.
|
||||
*/
|
||||
String getColumnName();
|
||||
|
||||
/**
|
||||
* The ordering for the column. Valid only for clustered columns.
|
||||
* The names of the columns to which the property is persisted if this is a composite primary key property. Never
|
||||
* returns null.
|
||||
*/
|
||||
List<String> getColumnNames();
|
||||
|
||||
/**
|
||||
* The ordering (ascending or descending) for the column. Valid only for primary key columns; returns null for
|
||||
* non-primary key columns.
|
||||
*/
|
||||
Ordering getPrimaryKeyOrdering();
|
||||
|
||||
/**
|
||||
* The column's data type.
|
||||
* The column's data type. Not valid for a composite primary key, in which case this method returns null.
|
||||
*/
|
||||
DataType getDataType();
|
||||
|
||||
/**
|
||||
* Whether the property has secondary index on this column.
|
||||
* Whether the property has a secondary index on this column.
|
||||
*/
|
||||
boolean isIndexed();
|
||||
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
package org.springframework.data.cassandra.mapping;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Comparator;
|
||||
|
||||
/**
|
||||
* {@link Comparator} implementation that orders {@link CassandraPersistentProperty} instances.
|
||||
* <p/>
|
||||
* Composite primary key properties and primary key properties sort before non-primary key properties.
|
||||
*
|
||||
* @author Alex Shvid
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public enum CassandraPersistentPropertyComparator implements Comparator<CassandraPersistentProperty> {
|
||||
|
||||
/**
|
||||
* The sole instance of this class.
|
||||
*/
|
||||
IT;
|
||||
|
||||
@Override
|
||||
public int compare(CassandraPersistentProperty left, CassandraPersistentProperty right) {
|
||||
|
||||
if (left != null && right == null) {
|
||||
return -1;
|
||||
}
|
||||
if (left == null && right != null) {
|
||||
return 1;
|
||||
}
|
||||
if (left == null && right == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (left.equals(right)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
boolean leftIsCompositePrimaryKey = left.isCompositePrimaryKey();
|
||||
boolean rightIsCompositePrimaryKey = right.isCompositePrimaryKey();
|
||||
|
||||
if (leftIsCompositePrimaryKey && rightIsCompositePrimaryKey) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
boolean leftIsPrimaryKey = left.isPrimaryKeyColumn();
|
||||
boolean rightIsPrimaryKey = right.isPrimaryKeyColumn();
|
||||
|
||||
Field leftField = left.getField();
|
||||
Field rightField = right.getField();
|
||||
|
||||
if (leftIsPrimaryKey && rightIsPrimaryKey) {
|
||||
return CassandraPrimaryKeyColumnAnnotationComparator.IT.compare(leftField.getAnnotation(PrimaryKeyColumn.class),
|
||||
rightField.getAnnotation(PrimaryKeyColumn.class));
|
||||
}
|
||||
|
||||
boolean leftIsKey = leftIsCompositePrimaryKey || leftIsPrimaryKey;
|
||||
boolean rightIsKey = rightIsCompositePrimaryKey || rightIsPrimaryKey;
|
||||
|
||||
if (leftIsKey && !rightIsKey) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!leftIsKey && rightIsKey) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// else, neither property is a composite primary key nor a primary key; compare @Column annotations
|
||||
|
||||
Column leftColumn = leftField.getAnnotation(Column.class);
|
||||
Column rightColumn = rightField.getAnnotation(Column.class);
|
||||
|
||||
if (leftColumn == null && rightColumn == null) {
|
||||
return leftField.getName().compareTo(rightField.getName());
|
||||
}
|
||||
|
||||
if (leftColumn != null && rightColumn != null) {
|
||||
return CassandraColumnAnnotationComparator.IT.compare(leftColumn, rightColumn);
|
||||
}
|
||||
|
||||
if (leftColumn != null && rightColumn == null) {
|
||||
return leftColumn.value().compareTo(rightField.getName());
|
||||
}
|
||||
|
||||
// else leftColumn == null && rightColumn != null)
|
||||
return leftField.getName().compareTo(rightColumn.value());
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,7 @@ import org.springframework.cassandra.core.PrimaryKeyType;
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public enum DefaultCassandraPrimaryKeyColumnComparator implements Comparator<PrimaryKeyColumn> {
|
||||
public enum CassandraPrimaryKeyColumnAnnotationComparator implements Comparator<PrimaryKeyColumn> {
|
||||
|
||||
/**
|
||||
* The sole instance of this class.
|
||||
@@ -27,23 +27,23 @@ public enum DefaultCassandraPrimaryKeyColumnComparator implements Comparator<Pri
|
||||
IT;
|
||||
|
||||
@Override
|
||||
public int compare(PrimaryKeyColumn o1, PrimaryKeyColumn o2) {
|
||||
public int compare(PrimaryKeyColumn left, PrimaryKeyColumn right) {
|
||||
|
||||
int comparison = o1.type().compareTo(o2.type());
|
||||
int comparison = left.type().compareTo(right.type());
|
||||
if (comparison != 0) {
|
||||
return comparison;
|
||||
}
|
||||
|
||||
comparison = new Integer(o1.ordinal()).compareTo(o2.ordinal());
|
||||
comparison = new Integer(left.ordinal()).compareTo(right.ordinal());
|
||||
if (comparison != 0) {
|
||||
return comparison;
|
||||
}
|
||||
|
||||
comparison = o1.name().compareTo(o2.name());
|
||||
comparison = left.name().compareTo(right.name());
|
||||
if (comparison != 0) {
|
||||
return comparison;
|
||||
}
|
||||
|
||||
return o1.ordering().compareTo(o2.ordering());
|
||||
return left.ordering().compareTo(right.ordering());
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package org.springframework.data.cassandra.mapping;
|
||||
|
||||
import static org.springframework.cassandra.core.keyspace.CreateTableSpecification.createTable;
|
||||
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.HashMap;
|
||||
@@ -73,7 +75,7 @@ public class DefaultCassandraMappingContext extends
|
||||
@Override
|
||||
protected <T> CassandraPersistentEntity<T> createPersistentEntity(TypeInformation<T> typeInformation) {
|
||||
|
||||
BasicCassandraPersistentEntity<T> entity = new BasicCassandraPersistentEntity<T>(typeInformation);
|
||||
CassandraPersistentEntity<T> entity = new CachingCassandraPersistentEntity<T>(typeInformation, this);
|
||||
|
||||
if (context != null) {
|
||||
entity.setApplicationContext(context);
|
||||
@@ -104,9 +106,7 @@ public class DefaultCassandraMappingContext extends
|
||||
|
||||
Assert.notNull(entity);
|
||||
|
||||
final CreateTableSpecification spec = new CreateTableSpecification();
|
||||
|
||||
spec.name(entity.getTableName());
|
||||
final CreateTableSpecification spec = createTable().name(entity.getTableName());
|
||||
|
||||
entity.doWithProperties(new PropertyHandler<CassandraPersistentProperty>() {
|
||||
|
||||
@@ -124,7 +124,7 @@ public class DefaultCassandraMappingContext extends
|
||||
|
||||
if (pkProp.isPartitionKeyColumn()) {
|
||||
spec.partitionKeyColumn(pkProp.getColumnName(), pkProp.getDataType());
|
||||
} else {
|
||||
} else { // it's a cluster column
|
||||
spec.clusteredKeyColumn(pkProp.getColumnName(), pkProp.getDataType(), pkProp.getPrimaryKeyOrdering());
|
||||
}
|
||||
}
|
||||
@@ -148,4 +148,29 @@ public class DefaultCassandraMappingContext extends
|
||||
|
||||
return spec;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CassandraPersistentEntity<?> getRequiredPersistentEntity(Class<?> type) {
|
||||
|
||||
CassandraPersistentEntity<?> entity = getPersistentEntity(type);
|
||||
|
||||
if (entity == null) {
|
||||
throw new IllegalArgumentException(String.format("no persistence metadata found for type [%s]", type.getName()));
|
||||
}
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CassandraPersistentEntity<?> getRequiredPersistentEntity(TypeInformation<?> type) {
|
||||
|
||||
CassandraPersistentEntity<?> entity = getPersistentEntity(type);
|
||||
|
||||
if (entity == null) {
|
||||
throw new IllegalArgumentException(String.format("no persistence metadata found for type [%s]",
|
||||
type.getActualType()));
|
||||
}
|
||||
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
package org.springframework.data.cassandra.mapping;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
/**
|
||||
* {@link Comparator} implementation that uses the {@link CassandraPersistentProperty}'s column name for ordering.
|
||||
*
|
||||
* @author Alex Shvid
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public enum DefaultCassandraPersistentPropertyColumnComparator implements Comparator<CassandraPersistentProperty> {
|
||||
|
||||
/**
|
||||
* The sole instance of this class.
|
||||
*/
|
||||
IT;
|
||||
|
||||
@Override
|
||||
public int compare(CassandraPersistentProperty o1, CassandraPersistentProperty o2) {
|
||||
return o1.getColumnName().compareTo(o2.getColumnName());
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,7 @@
|
||||
package org.springframework.data.cassandra.config;
|
||||
package org.springframework.data.cassandra.mapping;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Mapping information for an individual entity class.
|
||||
@@ -7,9 +10,21 @@ package org.springframework.data.cassandra.config;
|
||||
*/
|
||||
public class EntityMapping {
|
||||
|
||||
/**
|
||||
* The name of the entity's class.
|
||||
*/
|
||||
protected String entityClassName;
|
||||
|
||||
/**
|
||||
* The name of the table to which the entity is mapped.
|
||||
*/
|
||||
protected String tableName;
|
||||
|
||||
/**
|
||||
* The {@link PropertyMapping}s for each persistent property, keyed on property name.
|
||||
*/
|
||||
protected Map<String, PropertyMapping> propertyMappings = new HashMap<String, PropertyMapping>();
|
||||
|
||||
public EntityMapping(String entityClassName, String tableName) {
|
||||
setEntityClassName(entityClassName);
|
||||
setTableName(tableName);
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.cassandra.config;
|
||||
package org.springframework.data.cassandra.mapping;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
@@ -21,6 +21,8 @@ import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.data.annotation.Persistent;
|
||||
|
||||
/**
|
||||
* Annotates a type that represents the identity type of another class whose instances are stored in a table.
|
||||
* <p/>
|
||||
@@ -33,5 +35,6 @@ import java.lang.annotation.Target;
|
||||
@Inherited
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.TYPE })
|
||||
@Persistent
|
||||
public @interface PrimaryKeyClass {
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
package org.springframework.data.cassandra.mapping;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Mapping between a persistent entity's property and its column.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class PropertyMapping {
|
||||
|
||||
protected String propertyName;
|
||||
protected String columnName;
|
||||
|
||||
public PropertyMapping(String propertyName, String columnName) {
|
||||
|
||||
setPropertyName(propertyName);
|
||||
setColumnName(columnName);
|
||||
}
|
||||
|
||||
public String getPropertyName() {
|
||||
return propertyName;
|
||||
}
|
||||
|
||||
protected void setPropertyName(String propertyName) {
|
||||
Assert.notNull(propertyName);
|
||||
this.propertyName = propertyName;
|
||||
}
|
||||
|
||||
public String getColumnName() {
|
||||
return columnName;
|
||||
}
|
||||
|
||||
protected void setColumnName(String columnName) {
|
||||
Assert.notNull(columnName);
|
||||
this.columnName = columnName;
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,6 @@
|
||||
package org.springframework.data.cassandra.repository;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
|
||||
@@ -24,9 +23,7 @@ import org.springframework.data.repository.CrudRepository;
|
||||
* Cassandra-specific extension of the {@link CrudRepository} interface.
|
||||
*
|
||||
* @author Alex Shvid
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public interface CassandraRepository<T, ID extends Serializable> extends CrudRepository<T, ID> {
|
||||
|
||||
List<T> findByPartitionKey(ID id);
|
||||
|
||||
}
|
||||
|
||||
@@ -33,12 +33,4 @@ public interface CassandraEntityInformation<T, ID extends Serializable> extends
|
||||
* @return
|
||||
*/
|
||||
String getTableName();
|
||||
|
||||
/**
|
||||
* Returns the column that the id will be persisted to.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getIdColumn();
|
||||
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.springframework.data.cassandra.mapping.CassandraPersistentProperty;
|
||||
import org.springframework.data.cassandra.repository.query.CassandraEntityInformation;
|
||||
import org.springframework.data.mapping.model.BeanWrapper;
|
||||
import org.springframework.data.repository.core.support.AbstractEntityInformation;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* {@link CassandraEntityInformation} implementation using a {@link CassandraPersistentEntity} instance to lookup the
|
||||
@@ -59,49 +60,28 @@ public class MappingCassandraEntityInformation<T, ID extends Serializable> exten
|
||||
this.customTableName = customTableName;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.support.EntityInformation#getId(java.lang.Object)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public ID getId(T entity) {
|
||||
|
||||
CassandraPersistentProperty idProperty = entityMetadata.getIdProperty();
|
||||
Assert.notNull(entity);
|
||||
|
||||
CassandraPersistentProperty idProperty = entityMetadata.getIdProperty();
|
||||
if (idProperty == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return (ID) BeanWrapper.create(entity, null).getProperty(idProperty);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return (ID) BeanWrapper.create(entity, null).getProperty(idProperty);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.support.EntityInformation#getIdType()
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Class<ID> getIdType() {
|
||||
return (Class<ID>) entityMetadata.getIdProperty().getType();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.repository.CassandraEntityInformation#getTableName()
|
||||
*/
|
||||
@Override
|
||||
public String getTableName() {
|
||||
return customTableName == null ? entityMetadata.getTableName() : customTableName;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.repository.CassandraEntityInformation#getIdColumn()
|
||||
*/
|
||||
public String getIdColumn() {
|
||||
return entityMetadata.getIdProperty().getName();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,33 +16,27 @@
|
||||
package org.springframework.data.cassandra.repository.support;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.cassandra.core.CqlOperations;
|
||||
import org.springframework.cassandra.core.util.CollectionUtils;
|
||||
import org.springframework.data.cassandra.core.CassandraOperations;
|
||||
import org.springframework.data.cassandra.core.CassandraTemplate;
|
||||
import org.springframework.data.cassandra.repository.CassandraRepository;
|
||||
import org.springframework.data.cassandra.repository.query.CassandraEntityInformation;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.datastax.driver.core.querybuilder.Clause;
|
||||
import com.datastax.driver.core.querybuilder.Delete;
|
||||
import com.datastax.driver.core.querybuilder.QueryBuilder;
|
||||
import com.datastax.driver.core.querybuilder.Select;
|
||||
|
||||
/**
|
||||
* Repository base implementation for Cassandra.
|
||||
*
|
||||
* @author Alex Shvid
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
|
||||
public class SimpleCassandraRepository<T, ID extends Serializable> implements CassandraRepository<T, ID> {
|
||||
|
||||
private final CassandraTemplate cassandraTemplate;
|
||||
private final CassandraEntityInformation<T, ID> entityInformation;
|
||||
protected CassandraOperations template;
|
||||
protected CassandraEntityInformation<T, ID> entityInformation;
|
||||
|
||||
/**
|
||||
* Creates a new {@link SimpleCassandraRepository} for the given {@link CassandraEntityInformation} and
|
||||
@@ -51,201 +45,71 @@ public class SimpleCassandraRepository<T, ID extends Serializable> implements Ca
|
||||
* @param metadata must not be {@literal null}.
|
||||
* @param template must not be {@literal null}.
|
||||
*/
|
||||
public SimpleCassandraRepository(CassandraEntityInformation<T, ID> metadata,
|
||||
CassandraTemplate cassandraTemplate) {
|
||||
public SimpleCassandraRepository(CassandraEntityInformation<T, ID> metadata, CassandraTemplate template) {
|
||||
|
||||
Assert.notNull(cassandraTemplate);
|
||||
Assert.notNull(template);
|
||||
Assert.notNull(metadata);
|
||||
|
||||
this.entityInformation = metadata;
|
||||
this.cassandraTemplate = cassandraTemplate;
|
||||
this.template = template;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.CrudRepository#save(java.lang.Object)
|
||||
*/
|
||||
public <S extends T> S save(S entity) {
|
||||
|
||||
Assert.notNull(entity, "Entity must not be null!");
|
||||
cassandraTemplate.insert(entity, entityInformation.getTableName());
|
||||
return entity;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.CrudRepository#save(java.lang.Iterable)
|
||||
*/
|
||||
public <S extends T> List<S> save(Iterable<S> entities) {
|
||||
|
||||
Assert.notNull(entities, "The given Iterable of entities not be null!");
|
||||
|
||||
List<S> result = new ArrayList<S>();
|
||||
|
||||
for (S entity : entities) {
|
||||
save(entity);
|
||||
result.add(entity);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private Clause getIdClause(ID id) {
|
||||
Clause clause = QueryBuilder.eq(entityInformation.getIdColumn(), id);
|
||||
return clause;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.CrudRepository#findOne(java.io.Serializable)
|
||||
*/
|
||||
public T findOne(ID id) {
|
||||
Assert.notNull(id, "The given id must not be null!");
|
||||
|
||||
Select select = QueryBuilder.select().all().from(entityInformation.getTableName());
|
||||
select.where(getIdClause(id));
|
||||
|
||||
return cassandraTemplate.selectOne(select, entityInformation.getJavaType());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.cassandra.repository.CassandraRepository#findByPartitionKey(java.io.Serializable)
|
||||
*/
|
||||
@Override
|
||||
public List<T> findByPartitionKey(ID id) {
|
||||
Assert.notNull(id, "The given id must not be null!");
|
||||
|
||||
Select select = QueryBuilder.select().all().from(entityInformation.getTableName());
|
||||
select.where(getIdClause(id));
|
||||
|
||||
return cassandraTemplate.select(select, entityInformation.getJavaType());
|
||||
public <S extends T> S save(S entity) {
|
||||
return template.insert(entity);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.CrudRepository#exists(java.io.Serializable)
|
||||
*/
|
||||
@Override
|
||||
public <S extends T> List<S> save(Iterable<S> entities) {
|
||||
return template.insert(CollectionUtils.toList(entities));
|
||||
}
|
||||
|
||||
@Override
|
||||
public T findOne(ID id) {
|
||||
return template.selectOneById(entityInformation.getJavaType(), id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean exists(ID id) {
|
||||
|
||||
Assert.notNull(id, "The given id must not be null!");
|
||||
|
||||
Select select = QueryBuilder.select().countAll().from(entityInformation.getTableName());
|
||||
select.where(getIdClause(id));
|
||||
|
||||
Long num = cassandraTemplate.count(select);
|
||||
return num != null && num.longValue() > 0;
|
||||
return template.exists(entityInformation.getJavaType(), id);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.CrudRepository#count()
|
||||
*/
|
||||
@Override
|
||||
public long count() {
|
||||
return cassandraTemplate.count(entityInformation.getTableName());
|
||||
return template.count(entityInformation.getTableName());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.CrudRepository#delete(java.io.Serializable)
|
||||
*/
|
||||
@Override
|
||||
public void delete(ID id) {
|
||||
Assert.notNull(id, "The given id must not be null!");
|
||||
|
||||
Delete delete = QueryBuilder.delete().all().from(entityInformation.getTableName());
|
||||
delete.where(getIdClause(id));
|
||||
|
||||
cassandraTemplate.execute(delete.getQueryString());
|
||||
template.deleteById(entityInformation.getJavaType(), id);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.CrudRepository#delete(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public void delete(T entity) {
|
||||
Assert.notNull(entity, "The given entity must not be null!");
|
||||
delete(entityInformation.getId(entity));
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.CrudRepository#delete(java.lang.Iterable)
|
||||
*/
|
||||
@Override
|
||||
public void delete(Iterable<? extends T> entities) {
|
||||
|
||||
Assert.notNull(entities, "The given Iterable of entities not be null!");
|
||||
|
||||
for (T entity : entities) {
|
||||
delete(entity);
|
||||
}
|
||||
template.delete(CollectionUtils.toList(entities));
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.CrudRepository#deleteAll()
|
||||
*/
|
||||
@Override
|
||||
public void deleteAll() {
|
||||
cassandraTemplate.truncate(entityInformation.getTableName());
|
||||
template.truncate(entityInformation.getTableName());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.CrudRepository#findAll()
|
||||
*/
|
||||
@Override
|
||||
public List<T> findAll() {
|
||||
Select select = QueryBuilder.select().all().from(entityInformation.getTableName());
|
||||
return findAll(select);
|
||||
return template.selectAll(entityInformation.getJavaType());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.CrudRepository#findAll(java.lang.Iterable)
|
||||
*/
|
||||
@Override
|
||||
public Iterable<T> findAll(Iterable<ID> ids) {
|
||||
|
||||
List<ID> parameters = new ArrayList<ID>();
|
||||
for (ID id : ids) {
|
||||
parameters.add(id);
|
||||
}
|
||||
Clause clause = QueryBuilder.in(entityInformation.getIdColumn(), parameters.toArray());
|
||||
Select select = QueryBuilder.select().all().from(entityInformation.getTableName());
|
||||
select.where(clause);
|
||||
|
||||
return findAll(select);
|
||||
return template.selectBySimpleIds(entityInformation.getJavaType(), ids);
|
||||
}
|
||||
|
||||
private List<T> findAll(Select query) {
|
||||
|
||||
if (query == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return cassandraTemplate.select(query, entityInformation.getJavaType());
|
||||
protected List<T> findAll(Select query) {
|
||||
return template.select(query.getQueryString(), entityInformation.getJavaType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the underlying {@link CqlOperations} instance.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected CqlOperations getCassandraOperations() {
|
||||
return this.cassandraTemplate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the underlying {@link CassandraOperations} instance.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected CassandraOperations getCassandraDataOperations() {
|
||||
return this.cassandraTemplate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the entityInformation
|
||||
*/
|
||||
protected CassandraEntityInformation<T, ID> getEntityInformation() {
|
||||
return entityInformation;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,25 +3,14 @@ package org.springframework.data.cassandra.util;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.cassandra.core.CqlTemplate;
|
||||
import org.springframework.cassandra.core.QueryOptions;
|
||||
import org.springframework.data.cassandra.exception.EntityWriterException;
|
||||
import org.springframework.cassandra.core.cql.CqlStringUtils;
|
||||
import org.springframework.data.cassandra.mapping.CassandraPersistentEntity;
|
||||
import org.springframework.data.cassandra.mapping.CassandraPersistentProperty;
|
||||
import org.springframework.data.convert.EntityWriter;
|
||||
import org.springframework.data.mapping.PropertyHandler;
|
||||
|
||||
import com.datastax.driver.core.ColumnMetadata;
|
||||
import com.datastax.driver.core.DataType;
|
||||
import com.datastax.driver.core.Query;
|
||||
import com.datastax.driver.core.Statement;
|
||||
import com.datastax.driver.core.TableMetadata;
|
||||
import com.datastax.driver.core.querybuilder.Batch;
|
||||
import com.datastax.driver.core.querybuilder.Delete;
|
||||
import com.datastax.driver.core.querybuilder.Delete.Where;
|
||||
import com.datastax.driver.core.querybuilder.Insert;
|
||||
import com.datastax.driver.core.querybuilder.QueryBuilder;
|
||||
import com.datastax.driver.core.querybuilder.Update;
|
||||
|
||||
/**
|
||||
* Utilities to convert Cassandra Annotated objects to Queries and CQL.
|
||||
@@ -33,39 +22,7 @@ import com.datastax.driver.core.querybuilder.Update;
|
||||
public abstract class CqlUtils {
|
||||
|
||||
/**
|
||||
* Create the List of CQL for the indexes required for Cassandra mapped Table.
|
||||
*
|
||||
* @param tableName
|
||||
* @param entity
|
||||
* @return The list of CQL statements to run with session.execute()
|
||||
*/
|
||||
public static List<String> createIndexes(final String tableName, final CassandraPersistentEntity<?> entity) {
|
||||
final List<String> result = new ArrayList<String>();
|
||||
|
||||
entity.doWithProperties(new PropertyHandler<CassandraPersistentProperty>() {
|
||||
@Override
|
||||
public void doWithPersistentProperty(CassandraPersistentProperty prop) {
|
||||
|
||||
if (prop.isIndexed()) {
|
||||
|
||||
final StringBuilder str = new StringBuilder();
|
||||
str.append("CREATE INDEX ON ");
|
||||
str.append(tableName);
|
||||
str.append(" (");
|
||||
str.append(prop.getColumnName());
|
||||
str.append(");");
|
||||
|
||||
result.add(str.toString());
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alter the table to refelct the entity annotations
|
||||
* Alter the table to reflect the entity annotations
|
||||
*
|
||||
* @param tableName
|
||||
* @param entity
|
||||
@@ -104,7 +61,7 @@ public abstract class CqlUtils {
|
||||
str.append("TYPE ");
|
||||
}
|
||||
|
||||
str.append(toCQL(columnDataType));
|
||||
str.append(CqlStringUtils.toCql(columnDataType));
|
||||
|
||||
str.append(';');
|
||||
result.add(str.toString());
|
||||
@@ -114,243 +71,4 @@ public abstract class CqlUtils {
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a Query Object for an insert
|
||||
*
|
||||
* @param tableName
|
||||
* @param objectToSave
|
||||
* @param entity
|
||||
* @param optionsByName
|
||||
*
|
||||
* @return The Query object to run with session.execute();
|
||||
* @throws EntityWriterException
|
||||
*/
|
||||
public static Query toInsertQuery(String tableName, final Object objectToSave, QueryOptions options,
|
||||
EntityWriter<Object, Object> entityWriter) throws EntityWriterException {
|
||||
|
||||
final Insert q = QueryBuilder.insertInto(tableName);
|
||||
|
||||
/*
|
||||
* Write properties
|
||||
*/
|
||||
entityWriter.write(objectToSave, q);
|
||||
|
||||
/*
|
||||
* Add Query Options
|
||||
*/
|
||||
CqlTemplate.addQueryOptions(q, options);
|
||||
|
||||
/*
|
||||
* Add TTL to Insert object
|
||||
*/
|
||||
if (options != null && options.getTtl() != null) {
|
||||
q.using(QueryBuilder.ttl(options.getTtl()));
|
||||
}
|
||||
|
||||
return q;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a Query Object for an Update
|
||||
*
|
||||
* @param tableName
|
||||
* @param objectToSave
|
||||
* @param entity
|
||||
* @param optionsByName
|
||||
*
|
||||
* @return The Query object to run with session.execute();
|
||||
* @throws EntityWriterException
|
||||
*/
|
||||
public static Query toUpdateQuery(String tableName, final Object objectToSave, QueryOptions options,
|
||||
EntityWriter<Object, Object> entityWriter) throws EntityWriterException {
|
||||
|
||||
final Update q = QueryBuilder.update(tableName);
|
||||
|
||||
/*
|
||||
* Write properties
|
||||
*/
|
||||
entityWriter.write(objectToSave, q);
|
||||
|
||||
/*
|
||||
* Add Query Options
|
||||
*/
|
||||
CqlTemplate.addQueryOptions(q, options);
|
||||
|
||||
/*
|
||||
* Add TTL to Insert object
|
||||
*/
|
||||
if (options != null && options.getTtl() != null) {
|
||||
q.using(QueryBuilder.ttl(options.getTtl()));
|
||||
}
|
||||
|
||||
return q;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a Batch Object for multiple Updates
|
||||
*
|
||||
* @param tableName
|
||||
* @param objectsToSave
|
||||
* @param entity
|
||||
* @param optionsByName
|
||||
*
|
||||
* @return The Query object to run with session.execute();
|
||||
* @throws EntityWriterException
|
||||
*/
|
||||
public static <T> Batch toUpdateBatchQuery(final String tableName, final List<T> objectsToSave, QueryOptions options,
|
||||
EntityWriter<Object, Object> entityWriter) throws EntityWriterException {
|
||||
|
||||
/*
|
||||
* Return variable is a Batch statement
|
||||
*/
|
||||
final Batch b = QueryBuilder.batch();
|
||||
|
||||
for (final T objectToSave : objectsToSave) {
|
||||
|
||||
b.add((Statement) toUpdateQuery(tableName, objectToSave, options, entityWriter));
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Add Query Options
|
||||
*/
|
||||
CqlTemplate.addQueryOptions(b, options);
|
||||
|
||||
return b;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a Batch Object for multiple inserts
|
||||
*
|
||||
* @param tableName
|
||||
* @param objectsToSave
|
||||
* @param entity
|
||||
* @param optionsByName
|
||||
*
|
||||
* @return The Query object to run with session.execute();
|
||||
* @throws EntityWriterException
|
||||
*/
|
||||
public static <T> Batch toInsertBatchQuery(final String tableName, final List<T> objectsToSave, QueryOptions options,
|
||||
EntityWriter<Object, Object> entityWriter) throws EntityWriterException {
|
||||
|
||||
/*
|
||||
* Return variable is a Batch statement
|
||||
*/
|
||||
final Batch b = QueryBuilder.batch();
|
||||
|
||||
for (final T objectToSave : objectsToSave) {
|
||||
|
||||
b.add((Statement) toInsertQuery(tableName, objectToSave, options, entityWriter));
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Add Query Options
|
||||
*/
|
||||
CqlTemplate.addQueryOptions(b, options);
|
||||
|
||||
return b;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Delete Query Object from an annotated POJO
|
||||
*
|
||||
* @param tableName
|
||||
* @param objectToRemove
|
||||
* @param entity
|
||||
* @param optionsByName
|
||||
* @return
|
||||
* @throws EntityWriterException
|
||||
*/
|
||||
public static Query toDeleteQuery(String tableName, final Object objectToRemove, QueryOptions options,
|
||||
EntityWriter<Object, Object> entityWriter) throws EntityWriterException {
|
||||
|
||||
final Delete.Selection ds = QueryBuilder.delete();
|
||||
final Delete q = ds.from(tableName);
|
||||
final Where w = q.where();
|
||||
|
||||
/*
|
||||
* Write where condition to find by Id
|
||||
*/
|
||||
entityWriter.write(objectToRemove, w);
|
||||
|
||||
CqlTemplate.addQueryOptions(q, options);
|
||||
|
||||
return q;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param dataType
|
||||
* @return
|
||||
*/
|
||||
public static String toCQL(DataType dataType) {
|
||||
if (dataType.getTypeArguments().isEmpty()) {
|
||||
return dataType.getName().name();
|
||||
} else {
|
||||
StringBuilder str = new StringBuilder();
|
||||
str.append(dataType.getName().name());
|
||||
str.append('<');
|
||||
for (DataType argDataType : dataType.getTypeArguments()) {
|
||||
if (str.charAt(str.length() - 1) != '<') {
|
||||
str.append(',');
|
||||
}
|
||||
str.append(argDataType.getName().name());
|
||||
}
|
||||
str.append('>');
|
||||
return str.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param tableName
|
||||
* @return
|
||||
*/
|
||||
public static String dropTable(String tableName) {
|
||||
|
||||
if (tableName == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
StringBuilder str = new StringBuilder();
|
||||
str.append("DROP TABLE " + tableName + ";");
|
||||
return str.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Batch Query object for multiple deletes.
|
||||
*
|
||||
* @param tableName
|
||||
* @param entities
|
||||
* @param entity
|
||||
* @param optionsByName
|
||||
*
|
||||
* @return
|
||||
* @throws EntityWriterException
|
||||
*/
|
||||
public static <T> Batch toDeleteBatchQuery(String tableName, List<T> entities, QueryOptions options,
|
||||
EntityWriter<Object, Object> entityWriter) throws EntityWriterException {
|
||||
|
||||
/*
|
||||
* Return variable is a Batch statement
|
||||
*/
|
||||
final Batch b = QueryBuilder.batch();
|
||||
|
||||
for (final T objectToSave : entities) {
|
||||
|
||||
b.add((Statement) toDeleteQuery(tableName, objectToSave, options, entityWriter));
|
||||
|
||||
}
|
||||
|
||||
CqlTemplate.addQueryOptions(b, options);
|
||||
|
||||
return b;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,14 +1,84 @@
|
||||
package org.springframework.data.cassandra.test.integration;
|
||||
|
||||
import static org.springframework.cassandra.core.keyspace.DropTableSpecification.dropTable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cassandra.test.integration.AbstractEmbeddedCassandraIntegrationTest;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.data.cassandra.core.CassandraOperations;
|
||||
import org.springframework.data.cassandra.test.integration.support.SpringDataBuildProperties;
|
||||
import org.springframework.data.cassandra.test.integration.template.CassandraDataOperationsTest.Config;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.datastax.driver.core.TableMetadata;
|
||||
|
||||
public class AbstractSpringDataEmbeddedCassandraIntegrationTest extends AbstractEmbeddedCassandraIntegrationTest {
|
||||
|
||||
static {
|
||||
// override necessary superclass statics
|
||||
public static List<String> SCRIPT;
|
||||
public static List<TableMetadata> TABLES;
|
||||
|
||||
static {
|
||||
SpringDataBuildProperties props = new SpringDataBuildProperties();
|
||||
CASSANDRA_NATIVE_PORT = props.getCassandraPort();
|
||||
}
|
||||
|
||||
public Logger log = LoggerFactory.getLogger(getClass());
|
||||
|
||||
@Autowired
|
||||
public CassandraOperations template;
|
||||
|
||||
/**
|
||||
* Saves all table metadata, then drops & creates all tables.
|
||||
*/
|
||||
public void recreateAllTables() {
|
||||
|
||||
saveAllTableMetadata();
|
||||
|
||||
for (TableMetadata table : TABLES) {
|
||||
template.execute(dropTable(table.getName()));
|
||||
template.execute(table.asCQLQuery());
|
||||
}
|
||||
}
|
||||
|
||||
public void saveAllTableMetadata() {
|
||||
saveAllTableMetadata(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves all table metadata statically.
|
||||
*/
|
||||
public void saveAllTableMetadata(boolean force) {
|
||||
|
||||
if (TABLES != null && !force) {
|
||||
return;
|
||||
}
|
||||
|
||||
TABLES = new ArrayList<TableMetadata>(template.getSession().getCluster().getMetadata()
|
||||
.getKeyspace(Config.KEYSPACE_NAME).getTables());
|
||||
}
|
||||
|
||||
public List<String> readScriptLines(String resourceName) {
|
||||
return readScriptLines(resourceName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the lines from the script referenced by {@link #RESOURCE}.
|
||||
*/
|
||||
public List<String> readScriptLines(String resourceName, boolean force) throws IOException {
|
||||
|
||||
if (SCRIPT != null && !force) {
|
||||
return SCRIPT;
|
||||
}
|
||||
|
||||
Assert.hasText(resourceName);
|
||||
|
||||
return SCRIPT = FileUtils.readLines(new ClassPathResource(resourceName).getFile());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.cassandra.test.integration.table;
|
||||
package org.springframework.data.cassandra.test.integration.composites;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Set;
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.cassandra.test.integration.table;
|
||||
package org.springframework.data.cassandra.test.integration.composites;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.cassandra.test.integration.table;
|
||||
package org.springframework.data.cassandra.test.integration.composites;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.cassandra.test.integration.table;
|
||||
package org.springframework.data.cassandra.test.integration.composites;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.cassandra.test.integration.table;
|
||||
package org.springframework.data.cassandra.test.integration.composites;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.cassandra.test.integration.table;
|
||||
package org.springframework.data.cassandra.test.integration.composites;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.cassandra.test.integration.table;
|
||||
package org.springframework.data.cassandra.test.integration.composites;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.cassandra.test.integration.table;
|
||||
package org.springframework.data.cassandra.test.integration.composites;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@@ -1,38 +1,21 @@
|
||||
package org.springframework.data.cassandra.test.integration.config;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.cassandra.exceptions.ConfigurationException;
|
||||
import org.apache.thrift.transport.TTransportException;
|
||||
import org.cassandraunit.utils.EmbeddedCassandraServerHelper;
|
||||
import org.junit.After;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.data.cassandra.test.integration.AbstractSpringDataEmbeddedCassandraIntegrationTest;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration
|
||||
public class CassandraNamespaceTests {
|
||||
public class CassandraNamespaceTests extends AbstractSpringDataEmbeddedCassandraIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext ctx;
|
||||
|
||||
@BeforeClass
|
||||
public static void startCassandra() throws IOException, TTransportException, ConfigurationException,
|
||||
InterruptedException {
|
||||
EmbeddedCassandraServerHelper.startEmbeddedCassandra("spring-cassandra.yaml");
|
||||
}
|
||||
|
||||
@After
|
||||
public void clearCassandra() {
|
||||
EmbeddedCassandraServerHelper.cleanEmbeddedCassandra();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
Assert.notNull(ctx);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.springframework.data.cassandra.test.integration.config;
|
||||
|
||||
import org.springframework.cassandra.test.unit.support.Utils;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.cassandra.config.java.AbstractSpringDataCassandraConfiguration;
|
||||
@@ -23,7 +24,7 @@ public class TestConfig extends AbstractSpringDataCassandraConfiguration {
|
||||
public static final int PORT = PROPS.getCassandraPort();
|
||||
public static final int RPC_PORT = PROPS.getCassandraRpcPort();
|
||||
|
||||
public static final String KEYSPACE_NAME = "test";
|
||||
public static final String KEYSPACE_NAME = Utils.randomKeyspaceName();
|
||||
|
||||
@Override
|
||||
protected String getKeyspaceName() {
|
||||
|
||||
@@ -19,13 +19,8 @@ import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.cassandra.exceptions.ConfigurationException;
|
||||
import org.apache.thrift.transport.TTransportException;
|
||||
import org.cassandraunit.utils.EmbeddedCassandraServerHelper;
|
||||
import org.junit.After;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
@@ -33,6 +28,7 @@ import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.data.cassandra.mapping.BasicCassandraPersistentEntity;
|
||||
import org.springframework.data.cassandra.mapping.Table;
|
||||
import org.springframework.data.cassandra.test.integration.AbstractSpringDataEmbeddedCassandraIntegrationTest;
|
||||
import org.springframework.data.util.ClassTypeInformation;
|
||||
|
||||
/**
|
||||
@@ -41,17 +37,11 @@ import org.springframework.data.util.ClassTypeInformation;
|
||||
* @author Alex Shvid
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class BasicCassandraPersistentEntityIntegrationTests {
|
||||
public class BasicCassandraPersistentEntityIntegrationTests extends AbstractSpringDataEmbeddedCassandraIntegrationTest {
|
||||
|
||||
@Mock
|
||||
ApplicationContext context;
|
||||
|
||||
@BeforeClass
|
||||
public static void startCassandra() throws IOException, TTransportException, ConfigurationException,
|
||||
InterruptedException {
|
||||
EmbeddedCassandraServerHelper.startEmbeddedCassandra("spring-cassandra.yaml");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void subclassInheritsAtDocumentAnnotation() {
|
||||
|
||||
@@ -84,11 +74,6 @@ public class BasicCassandraPersistentEntityIntegrationTests {
|
||||
assertThat(entity.getTableName(), is(bean.tableName));
|
||||
}
|
||||
|
||||
@After
|
||||
public void clearCassandra() {
|
||||
EmbeddedCassandraServerHelper.cleanEmbeddedCassandra();
|
||||
}
|
||||
|
||||
@Table("messages")
|
||||
static class Message {
|
||||
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright (c) 2011 by the original author(s).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.cassandra.test.integration.mapping;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.cassandra.core.PrimaryKeyType;
|
||||
import org.springframework.cassandra.core.keyspace.ColumnSpecification;
|
||||
import org.springframework.cassandra.core.keyspace.CreateTableSpecification;
|
||||
import org.springframework.data.cassandra.mapping.BasicCassandraPersistentProperty;
|
||||
import org.springframework.data.cassandra.mapping.CachingCassandraPersistentProperty;
|
||||
import org.springframework.data.cassandra.mapping.CassandraMappingContext;
|
||||
import org.springframework.data.cassandra.mapping.CassandraPersistentEntity;
|
||||
import org.springframework.data.cassandra.mapping.CassandraPersistentProperty;
|
||||
import org.springframework.data.cassandra.mapping.CassandraSimpleTypeHolder;
|
||||
import org.springframework.data.cassandra.mapping.Column;
|
||||
import org.springframework.data.cassandra.mapping.DefaultCassandraMappingContext;
|
||||
import org.springframework.data.cassandra.mapping.PrimaryKey;
|
||||
import org.springframework.data.cassandra.mapping.PrimaryKeyClass;
|
||||
import org.springframework.data.cassandra.mapping.PrimaryKeyColumn;
|
||||
import org.springframework.data.cassandra.mapping.Table;
|
||||
import org.springframework.data.util.ClassTypeInformation;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import com.datastax.driver.core.DataType;
|
||||
|
||||
/**
|
||||
* Integration test for {@link BasicCassandraPersistentProperty} with a composite primary key class.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class CassandraCompositePrimaryKeyIntegrationTests {
|
||||
|
||||
private static final CassandraSimpleTypeHolder SIMPLE_TYPE_HOLDER = new CassandraSimpleTypeHolder();
|
||||
|
||||
@PrimaryKeyClass
|
||||
static class Key {
|
||||
|
||||
@PrimaryKeyColumn(ordinal = 0, type = PrimaryKeyType.PARTITIONED)
|
||||
String z;
|
||||
|
||||
@PrimaryKeyColumn(ordinal = 1, type = PrimaryKeyType.CLUSTERED)
|
||||
String a;
|
||||
}
|
||||
|
||||
@Table
|
||||
static class Thing {
|
||||
|
||||
@PrimaryKey
|
||||
Key id;
|
||||
|
||||
Date time;
|
||||
|
||||
@Column("message")
|
||||
String text;
|
||||
}
|
||||
|
||||
CassandraMappingContext context;
|
||||
CassandraPersistentEntity<?> thing;
|
||||
CassandraPersistentEntity<?> key;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
context = new DefaultCassandraMappingContext();
|
||||
thing = context.getPersistentEntity(ClassTypeInformation.from(Thing.class));
|
||||
key = context.getPersistentEntity(ClassTypeInformation.from(Key.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateMappingInfo() {
|
||||
|
||||
Field field = ReflectionUtils.findField(Thing.class, "id");
|
||||
CassandraPersistentProperty property = new CachingCassandraPersistentProperty(field, null, thing,
|
||||
SIMPLE_TYPE_HOLDER);
|
||||
assertTrue(property.isIdProperty());
|
||||
assertTrue(property.isCompositePrimaryKey());
|
||||
|
||||
List<String> expectedColumnNames = Arrays.asList(new String[] { "z", "a" });
|
||||
assertTrue(expectedColumnNames.equals(property.getColumnNames()));
|
||||
|
||||
List<String> actualColumnNames = new ArrayList<String>();
|
||||
List<CassandraPersistentProperty> properties = property.getCompositePrimaryKeyProperties();
|
||||
for (CassandraPersistentProperty p : properties) {
|
||||
actualColumnNames.addAll(p.getColumnNames());
|
||||
}
|
||||
assertTrue(expectedColumnNames.equals(actualColumnNames));
|
||||
|
||||
CreateTableSpecification spec = context.getCreateTableSpecificationFor(thing);
|
||||
|
||||
List<ColumnSpecification> partitionKeyColumns = spec.getPartitionKeyColumns();
|
||||
assertEquals(1, partitionKeyColumns.size());
|
||||
ColumnSpecification partitionKeyColumn = partitionKeyColumns.get(0);
|
||||
assertEquals("z", partitionKeyColumn.getName());
|
||||
assertEquals(PrimaryKeyType.PARTITIONED, partitionKeyColumn.getKeyType());
|
||||
assertEquals(DataType.text(), partitionKeyColumn.getType());
|
||||
|
||||
List<ColumnSpecification> clusteredKeyColumns = spec.getClusteredKeyColumns();
|
||||
assertEquals(1, clusteredKeyColumns.size());
|
||||
ColumnSpecification clusteredKeyColumn = clusteredKeyColumns.get(0);
|
||||
assertEquals("a", clusteredKeyColumn.getName());
|
||||
assertEquals(PrimaryKeyType.CLUSTERED, clusteredKeyColumn.getKeyType());
|
||||
assertEquals(DataType.text(), partitionKeyColumn.getType());
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,7 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.cassandra.mapping.BasicCassandraPersistentEntity;
|
||||
import org.springframework.data.cassandra.mapping.BasicCassandraPersistentProperty;
|
||||
import org.springframework.data.cassandra.mapping.CachingCassandraPersistentProperty;
|
||||
import org.springframework.data.cassandra.mapping.CassandraPersistentEntity;
|
||||
import org.springframework.data.cassandra.mapping.CassandraPersistentProperty;
|
||||
import org.springframework.data.cassandra.mapping.CassandraSimpleTypeHolder;
|
||||
@@ -76,6 +77,6 @@ public class CompoundPrimaryKeyIntegrationTests {
|
||||
}
|
||||
|
||||
private CassandraPersistentProperty getPropertyFor(Field field) {
|
||||
return new BasicCassandraPersistentProperty(field, null, entity, new CassandraSimpleTypeHolder());
|
||||
return new CachingCassandraPersistentProperty(field, null, entity, new CassandraSimpleTypeHolder());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ public class UserRepositoryJavaConfigIntegrationTests extends AbstractSpringData
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMappingBasePackage() {
|
||||
public String getEntityBasePackage() {
|
||||
return User.class.getPackage().getName();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.cassandra.test.integration.table;
|
||||
package org.springframework.data.cassandra.test.integration.simpletons;
|
||||
|
||||
import org.springframework.data.cassandra.mapping.PrimaryKey;
|
||||
import org.springframework.data.cassandra.mapping.Table;
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.cassandra.test.integration.table;
|
||||
package org.springframework.data.cassandra.test.integration.simpletons;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package org.springframework.data.cassandra.test.integration.support;
|
||||
|
||||
import org.cassandraunit.dataset.commons.AbstractCommonsParserDataSet;
|
||||
import org.cassandraunit.dataset.commons.ParsedKeyspace;
|
||||
|
||||
public class ManualDataSet extends AbstractCommonsParserDataSet {
|
||||
|
||||
private String keyspaceName;
|
||||
private ParsedKeyspace pks;
|
||||
|
||||
public ManualDataSet(String keyspaceName) {
|
||||
this.keyspaceName = keyspaceName;
|
||||
|
||||
pks = new ParsedKeyspace();
|
||||
pks.setName(this.keyspaceName);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ParsedKeyspace getParsedKeyspace() {
|
||||
return pks;
|
||||
}
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.cassandra.test.integration.template;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.cassandra.exceptions.ConfigurationException;
|
||||
import org.apache.thrift.transport.TTransportException;
|
||||
import org.cassandraunit.DataLoader;
|
||||
import org.cassandraunit.dataset.yaml.ClassPathYamlDataSet;
|
||||
import org.cassandraunit.utils.EmbeddedCassandraServerHelper;
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cassandra.core.CqlOperations;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.data.cassandra.test.integration.config.TestConfig;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.support.AnnotationConfigContextLoader;
|
||||
|
||||
/**
|
||||
* @author David Webb
|
||||
*
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = { TestConfig.class }, loader = AnnotationConfigContextLoader.class)
|
||||
public class CassandraAdminTest {
|
||||
|
||||
@Autowired
|
||||
private CqlOperations cassandraTemplate;
|
||||
|
||||
@Mock
|
||||
ApplicationContext context;
|
||||
|
||||
@BeforeClass
|
||||
public static void startCassandra() throws IOException, TTransportException, ConfigurationException,
|
||||
InterruptedException {
|
||||
EmbeddedCassandraServerHelper.startEmbeddedCassandra("spring-cassandra.yaml");
|
||||
|
||||
/*
|
||||
* Load data file to creat the test keyspace before we init the template
|
||||
*/
|
||||
DataLoader dataLoader = new DataLoader("Test Cluster", "localhost:" + TestConfig.RPC_PORT);
|
||||
dataLoader.load(new ClassPathYamlDataSet("cassandra-keyspace.yaml"));
|
||||
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setupKeyspace() {
|
||||
|
||||
/*
|
||||
* Load data file to creat the test keyspace before we init the template
|
||||
*/
|
||||
DataLoader dataLoader = new DataLoader("Test Cluster", "localhost:" + TestConfig.RPC_PORT);
|
||||
dataLoader.load(new ClassPathYamlDataSet("cassandra-keyspace.yaml"));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void alterTableTest() {
|
||||
|
||||
// cassandraTemplate.alterTable(UserAlter.class);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dropTableTest() {
|
||||
|
||||
// cassandraTemplate.dropTable(User.class);
|
||||
// cassandraTemplate.dropTable("comments");
|
||||
|
||||
}
|
||||
|
||||
@After
|
||||
public void clearCassandra() {
|
||||
EmbeddedCassandraServerHelper.cleanEmbeddedCassandra();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void stopCassandra() {
|
||||
EmbeddedCassandraServerHelper.cleanEmbeddedCassandra();
|
||||
}
|
||||
}
|
||||
@@ -15,22 +15,18 @@
|
||||
*/
|
||||
package org.springframework.data.cassandra.test.integration.template;
|
||||
|
||||
import static org.springframework.cassandra.core.keyspace.CreateKeyspaceSpecification.createKeyspace;
|
||||
import static org.springframework.cassandra.core.keyspace.DropTableSpecification.dropTable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.apache.cassandra.exceptions.ConfigurationException;
|
||||
import org.apache.thrift.transport.TTransportException;
|
||||
import org.cassandraunit.CassandraCQLUnit;
|
||||
import org.cassandraunit.DataLoader;
|
||||
import org.cassandraunit.dataset.cql.ClassPathCQLDataSet;
|
||||
import org.cassandraunit.dataset.yaml.ClassPathYamlDataSet;
|
||||
import org.cassandraunit.utils.EmbeddedCassandraServerHelper;
|
||||
import org.junit.After;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.slf4j.Logger;
|
||||
@@ -39,14 +35,19 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cassandra.core.ConsistencyLevel;
|
||||
import org.springframework.cassandra.core.QueryOptions;
|
||||
import org.springframework.cassandra.core.RetryPolicy;
|
||||
import org.springframework.cassandra.core.keyspace.CreateKeyspaceSpecification;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.data.cassandra.config.SchemaAction;
|
||||
import org.springframework.data.cassandra.core.CassandraOperations;
|
||||
import org.springframework.data.cassandra.test.integration.AbstractSpringDataEmbeddedCassandraIntegrationTest;
|
||||
import org.springframework.data.cassandra.test.integration.config.TestConfig;
|
||||
import org.springframework.data.cassandra.test.integration.support.SpringDataBuildProperties;
|
||||
import org.springframework.data.cassandra.test.integration.table.Book;
|
||||
import org.springframework.data.cassandra.test.integration.simpletons.Book;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.support.AnnotationConfigContextLoader;
|
||||
|
||||
import com.datastax.driver.core.TableMetadata;
|
||||
import com.datastax.driver.core.querybuilder.QueryBuilder;
|
||||
import com.datastax.driver.core.querybuilder.Select;
|
||||
|
||||
@@ -57,51 +58,43 @@ import com.datastax.driver.core.querybuilder.Select;
|
||||
*
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = { TestConfig.class }, loader = AnnotationConfigContextLoader.class)
|
||||
public class CassandraDataOperationsTest {
|
||||
@ContextConfiguration
|
||||
public class CassandraDataOperationsTest extends AbstractSpringDataEmbeddedCassandraIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private CassandraOperations cassandraTemplate;
|
||||
@Configuration
|
||||
public static class Config extends TestConfig {
|
||||
|
||||
private static Logger log = LoggerFactory.getLogger(CassandraDataOperationsTest.class);
|
||||
@Override
|
||||
public SchemaAction getSchemaAction() {
|
||||
return SchemaAction.RECREATE;
|
||||
}
|
||||
|
||||
public static final SpringDataBuildProperties PROPS = new SpringDataBuildProperties();
|
||||
private final static String CASSANDRA_CONFIG = "spring-cassandra.yaml";
|
||||
private final static String KEYSPACE_NAME = "test";
|
||||
private final static String CASSANDRA_HOST = "localhost";
|
||||
private final static int CASSANDRA_NATIVE_PORT = PROPS.getCassandraPort();
|
||||
private final static int CASSANDRA_THRIFT_PORT = PROPS.getCassandraRpcPort();
|
||||
@Override
|
||||
protected List<CreateKeyspaceSpecification> getKeyspaceCreations() {
|
||||
return Arrays.asList(createKeyspace().name(getKeyspaceName()).withSimpleReplication());
|
||||
}
|
||||
|
||||
@Rule
|
||||
public CassandraCQLUnit cassandraCQLUnit = new CassandraCQLUnit(new ClassPathCQLDataSet("cql-dataload.cql",
|
||||
KEYSPACE_NAME), CASSANDRA_CONFIG, CASSANDRA_HOST, CASSANDRA_NATIVE_PORT);
|
||||
@Override
|
||||
public String getEntityBasePackage() {
|
||||
return Book.class.getPackage().getName();
|
||||
}
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void startCassandra() throws IOException, TTransportException, ConfigurationException,
|
||||
InterruptedException {
|
||||
|
||||
EmbeddedCassandraServerHelper.startEmbeddedCassandra(CASSANDRA_CONFIG);
|
||||
|
||||
/*
|
||||
* Load data file to creat the test keyspace before we init the template
|
||||
*/
|
||||
DataLoader dataLoader = new DataLoader("Test Cluster", CASSANDRA_HOST + ":" + CASSANDRA_THRIFT_PORT);
|
||||
dataLoader.load(new ClassPathYamlDataSet("cassandra-keyspace.yaml"));
|
||||
@Before
|
||||
public void before() throws IOException {
|
||||
recreateAllTables();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void insertTest() {
|
||||
|
||||
/*
|
||||
* Test Single Insert with entity
|
||||
*/
|
||||
Book b1 = new Book();
|
||||
b1.setIsbn("123456-1");
|
||||
b1.setTitle("Spring Data Cassandra Guide");
|
||||
b1.setAuthor("Cassandra Guru");
|
||||
b1.setPages(521);
|
||||
|
||||
cassandraTemplate.insert(b1);
|
||||
template.insert(b1);
|
||||
|
||||
Book b2 = new Book();
|
||||
b2.setIsbn("123456-2");
|
||||
@@ -109,11 +102,8 @@ public class CassandraDataOperationsTest {
|
||||
b2.setAuthor("Cassandra Guru");
|
||||
b2.setPages(521);
|
||||
|
||||
cassandraTemplate.insert(b2, "book_alt");
|
||||
template.insert(b2);
|
||||
|
||||
/*
|
||||
* Test Single Insert with entity
|
||||
*/
|
||||
Book b3 = new Book();
|
||||
b3.setIsbn("123456-3");
|
||||
b3.setTitle("Spring Data Cassandra Guide");
|
||||
@@ -124,34 +114,27 @@ public class CassandraDataOperationsTest {
|
||||
options.setConsistencyLevel(ConsistencyLevel.ONE);
|
||||
options.setRetryPolicy(RetryPolicy.DOWNGRADING_CONSISTENCY);
|
||||
|
||||
cassandraTemplate.insert(b3, "book", options);
|
||||
template.insert(b3, options);
|
||||
|
||||
/*
|
||||
* Test Single Insert with entity
|
||||
*/
|
||||
Book b5 = new Book();
|
||||
b5.setIsbn("123456-5");
|
||||
b5.setTitle("Spring Data Cassandra Guide");
|
||||
b5.setAuthor("Cassandra Guru");
|
||||
b5.setPages(265);
|
||||
|
||||
cassandraTemplate.insert(b5, options);
|
||||
|
||||
template.insert(b5, options);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void insertAsynchronouslyTest() {
|
||||
|
||||
/*
|
||||
* Test Single Insert with entity
|
||||
*/
|
||||
Book b1 = new Book();
|
||||
b1.setIsbn("123456-1");
|
||||
b1.setTitle("Spring Data Cassandra Guide");
|
||||
b1.setAuthor("Cassandra Guru");
|
||||
b1.setPages(521);
|
||||
|
||||
cassandraTemplate.insertAsynchronously(b1);
|
||||
template.insertAsynchronously(b1);
|
||||
|
||||
Book b2 = new Book();
|
||||
b2.setIsbn("123456-2");
|
||||
@@ -159,7 +142,7 @@ public class CassandraDataOperationsTest {
|
||||
b2.setAuthor("Cassandra Guru");
|
||||
b2.setPages(521);
|
||||
|
||||
cassandraTemplate.insertAsynchronously(b2, "book_alt");
|
||||
template.insertAsynchronously(b2);
|
||||
|
||||
/*
|
||||
* Test Single Insert with entity
|
||||
@@ -174,7 +157,7 @@ public class CassandraDataOperationsTest {
|
||||
options.setConsistencyLevel(ConsistencyLevel.ONE);
|
||||
options.setRetryPolicy(RetryPolicy.DOWNGRADING_CONSISTENCY);
|
||||
|
||||
cassandraTemplate.insertAsynchronously(b3, "book", options);
|
||||
template.insertAsynchronously(b3, options);
|
||||
|
||||
/*
|
||||
* Test Single Insert with entity
|
||||
@@ -194,7 +177,7 @@ public class CassandraDataOperationsTest {
|
||||
b5.setAuthor("Cassandra Guru");
|
||||
b5.setPages(265);
|
||||
|
||||
cassandraTemplate.insertAsynchronously(b5, options);
|
||||
template.insertAsynchronously(b5, options);
|
||||
|
||||
}
|
||||
|
||||
@@ -209,19 +192,19 @@ public class CassandraDataOperationsTest {
|
||||
|
||||
books = getBookList(20);
|
||||
|
||||
cassandraTemplate.insert(books);
|
||||
template.insert(books);
|
||||
|
||||
books = getBookList(20);
|
||||
|
||||
cassandraTemplate.insert(books, "book_alt");
|
||||
template.insert(books);
|
||||
|
||||
books = getBookList(20);
|
||||
|
||||
cassandraTemplate.insert(books, "book", options);
|
||||
template.insert(books, options);
|
||||
|
||||
books = getBookList(20);
|
||||
|
||||
cassandraTemplate.insert(books, options);
|
||||
template.insert(books, options);
|
||||
|
||||
}
|
||||
|
||||
@@ -236,19 +219,19 @@ public class CassandraDataOperationsTest {
|
||||
|
||||
books = getBookList(20);
|
||||
|
||||
cassandraTemplate.insertAsynchronously(books);
|
||||
template.insertAsynchronously(books);
|
||||
|
||||
books = getBookList(20);
|
||||
|
||||
cassandraTemplate.insertAsynchronously(books, "book_alt");
|
||||
template.insertAsynchronously(books);
|
||||
|
||||
books = getBookList(20);
|
||||
|
||||
cassandraTemplate.insertAsynchronously(books, "book", options);
|
||||
template.insertAsynchronously(books, options);
|
||||
|
||||
books = getBookList(20);
|
||||
|
||||
cassandraTemplate.insertAsynchronously(books, options);
|
||||
template.insertAsynchronously(books, options);
|
||||
|
||||
}
|
||||
|
||||
@@ -290,7 +273,7 @@ public class CassandraDataOperationsTest {
|
||||
b1.setAuthor("Cassandra Guru");
|
||||
b1.setPages(521);
|
||||
|
||||
cassandraTemplate.update(b1);
|
||||
template.update(b1);
|
||||
|
||||
Book b2 = new Book();
|
||||
b2.setIsbn("123456-2");
|
||||
@@ -298,7 +281,7 @@ public class CassandraDataOperationsTest {
|
||||
b2.setAuthor("Cassandra Guru");
|
||||
b2.setPages(521);
|
||||
|
||||
cassandraTemplate.update(b2, "book_alt");
|
||||
template.update(b2);
|
||||
|
||||
/*
|
||||
* Test Single Insert with entity
|
||||
@@ -309,7 +292,7 @@ public class CassandraDataOperationsTest {
|
||||
b3.setAuthor("Cassandra Guru");
|
||||
b3.setPages(265);
|
||||
|
||||
cassandraTemplate.update(b3, "book", options);
|
||||
template.update(b3, options);
|
||||
|
||||
/*
|
||||
* Test Single Insert with entity
|
||||
@@ -320,7 +303,7 @@ public class CassandraDataOperationsTest {
|
||||
b5.setAuthor("Cassandra Guru");
|
||||
b5.setPages(265);
|
||||
|
||||
cassandraTemplate.update(b5, options);
|
||||
template.update(b5, options);
|
||||
|
||||
}
|
||||
|
||||
@@ -342,7 +325,7 @@ public class CassandraDataOperationsTest {
|
||||
b1.setAuthor("Cassandra Guru");
|
||||
b1.setPages(521);
|
||||
|
||||
cassandraTemplate.updateAsynchronously(b1);
|
||||
template.updateAsynchronously(b1);
|
||||
|
||||
Book b2 = new Book();
|
||||
b2.setIsbn("123456-2");
|
||||
@@ -350,7 +333,7 @@ public class CassandraDataOperationsTest {
|
||||
b2.setAuthor("Cassandra Guru");
|
||||
b2.setPages(521);
|
||||
|
||||
cassandraTemplate.updateAsynchronously(b2, "book_alt");
|
||||
template.updateAsynchronously(b2);
|
||||
|
||||
/*
|
||||
* Test Single Insert with entity
|
||||
@@ -361,7 +344,7 @@ public class CassandraDataOperationsTest {
|
||||
b3.setAuthor("Cassandra Guru");
|
||||
b3.setPages(265);
|
||||
|
||||
cassandraTemplate.updateAsynchronously(b3, "book", options);
|
||||
template.updateAsynchronously(b3, options);
|
||||
|
||||
/*
|
||||
* Test Single Insert with entity
|
||||
@@ -372,7 +355,7 @@ public class CassandraDataOperationsTest {
|
||||
b5.setAuthor("Cassandra Guru");
|
||||
b5.setPages(265);
|
||||
|
||||
cassandraTemplate.updateAsynchronously(b5, options);
|
||||
template.updateAsynchronously(b5, options);
|
||||
|
||||
}
|
||||
|
||||
@@ -387,35 +370,35 @@ public class CassandraDataOperationsTest {
|
||||
|
||||
books = getBookList(20);
|
||||
|
||||
cassandraTemplate.insert(books);
|
||||
template.insert(books);
|
||||
|
||||
alterBooks(books);
|
||||
|
||||
cassandraTemplate.update(books);
|
||||
template.update(books);
|
||||
|
||||
books = getBookList(20);
|
||||
|
||||
cassandraTemplate.insert(books, "book_alt");
|
||||
template.insert(books);
|
||||
|
||||
alterBooks(books);
|
||||
|
||||
cassandraTemplate.update(books, "book_alt");
|
||||
template.update(books);
|
||||
|
||||
books = getBookList(20);
|
||||
|
||||
cassandraTemplate.insert(books, "book", options);
|
||||
template.insert(books, options);
|
||||
|
||||
alterBooks(books);
|
||||
|
||||
cassandraTemplate.update(books, "book", options);
|
||||
template.update(books, options);
|
||||
|
||||
books = getBookList(20);
|
||||
|
||||
cassandraTemplate.insert(books, options);
|
||||
template.insert(books, options);
|
||||
|
||||
alterBooks(books);
|
||||
|
||||
cassandraTemplate.update(books, options);
|
||||
template.update(books, options);
|
||||
|
||||
}
|
||||
|
||||
@@ -430,35 +413,35 @@ public class CassandraDataOperationsTest {
|
||||
|
||||
books = getBookList(20);
|
||||
|
||||
cassandraTemplate.insert(books);
|
||||
template.insert(books);
|
||||
|
||||
alterBooks(books);
|
||||
|
||||
cassandraTemplate.updateAsynchronously(books);
|
||||
template.updateAsynchronously(books);
|
||||
|
||||
books = getBookList(20);
|
||||
|
||||
cassandraTemplate.insert(books, "book_alt");
|
||||
template.insert(books);
|
||||
|
||||
alterBooks(books);
|
||||
|
||||
cassandraTemplate.updateAsynchronously(books, "book_alt");
|
||||
template.updateAsynchronously(books);
|
||||
|
||||
books = getBookList(20);
|
||||
|
||||
cassandraTemplate.insert(books, "book", options);
|
||||
template.insert(books, options);
|
||||
|
||||
alterBooks(books);
|
||||
|
||||
cassandraTemplate.updateAsynchronously(books, "book", options);
|
||||
template.updateAsynchronously(books, options);
|
||||
|
||||
books = getBookList(20);
|
||||
|
||||
cassandraTemplate.insert(books, options);
|
||||
template.insert(books, options);
|
||||
|
||||
alterBooks(books);
|
||||
|
||||
cassandraTemplate.updateAsynchronously(books, options);
|
||||
template.updateAsynchronously(books, options);
|
||||
|
||||
}
|
||||
|
||||
@@ -489,12 +472,12 @@ public class CassandraDataOperationsTest {
|
||||
Book b1 = new Book();
|
||||
b1.setIsbn("123456-1");
|
||||
|
||||
cassandraTemplate.delete(b1);
|
||||
template.delete(b1);
|
||||
|
||||
Book b2 = new Book();
|
||||
b2.setIsbn("123456-2");
|
||||
|
||||
cassandraTemplate.delete(b2, "book_alt");
|
||||
template.delete(b2);
|
||||
|
||||
/*
|
||||
* Test Single Insert with entity
|
||||
@@ -502,7 +485,7 @@ public class CassandraDataOperationsTest {
|
||||
Book b3 = new Book();
|
||||
b3.setIsbn("123456-3");
|
||||
|
||||
cassandraTemplate.delete(b3, "book", options);
|
||||
template.delete(b3, options);
|
||||
|
||||
/*
|
||||
* Test Single Insert with entity
|
||||
@@ -510,7 +493,7 @@ public class CassandraDataOperationsTest {
|
||||
Book b5 = new Book();
|
||||
b5.setIsbn("123456-5");
|
||||
|
||||
cassandraTemplate.delete(b5, options);
|
||||
template.delete(b5, options);
|
||||
|
||||
}
|
||||
|
||||
@@ -529,12 +512,12 @@ public class CassandraDataOperationsTest {
|
||||
Book b1 = new Book();
|
||||
b1.setIsbn("123456-1");
|
||||
|
||||
cassandraTemplate.deleteAsynchronously(b1);
|
||||
template.deleteAsynchronously(b1);
|
||||
|
||||
Book b2 = new Book();
|
||||
b2.setIsbn("123456-2");
|
||||
|
||||
cassandraTemplate.deleteAsynchronously(b2, "book_alt");
|
||||
template.deleteAsynchronously(b2);
|
||||
|
||||
/*
|
||||
* Test Single Insert with entity
|
||||
@@ -542,7 +525,7 @@ public class CassandraDataOperationsTest {
|
||||
Book b3 = new Book();
|
||||
b3.setIsbn("123456-3");
|
||||
|
||||
cassandraTemplate.deleteAsynchronously(b3, "book", options);
|
||||
template.deleteAsynchronously(b3, options);
|
||||
|
||||
/*
|
||||
* Test Single Insert with entity
|
||||
@@ -550,7 +533,7 @@ public class CassandraDataOperationsTest {
|
||||
Book b5 = new Book();
|
||||
b5.setIsbn("123456-5");
|
||||
|
||||
cassandraTemplate.deleteAsynchronously(b5, options);
|
||||
template.deleteAsynchronously(b5, options);
|
||||
|
||||
}
|
||||
|
||||
@@ -565,27 +548,27 @@ public class CassandraDataOperationsTest {
|
||||
|
||||
books = getBookList(20);
|
||||
|
||||
cassandraTemplate.insert(books);
|
||||
template.insert(books);
|
||||
|
||||
cassandraTemplate.delete(books);
|
||||
template.delete(books);
|
||||
|
||||
books = getBookList(20);
|
||||
|
||||
cassandraTemplate.insert(books, "book_alt");
|
||||
template.insert(books);
|
||||
|
||||
cassandraTemplate.delete(books, "book_alt");
|
||||
template.delete(books);
|
||||
|
||||
books = getBookList(20);
|
||||
|
||||
cassandraTemplate.insert(books, "book", options);
|
||||
template.insert(books, options);
|
||||
|
||||
cassandraTemplate.delete(books, "book", options);
|
||||
template.delete(books, options);
|
||||
|
||||
books = getBookList(20);
|
||||
|
||||
cassandraTemplate.insert(books, options);
|
||||
template.insert(books, options);
|
||||
|
||||
cassandraTemplate.delete(books, options);
|
||||
template.delete(books, options);
|
||||
|
||||
}
|
||||
|
||||
@@ -600,27 +583,27 @@ public class CassandraDataOperationsTest {
|
||||
|
||||
books = getBookList(20);
|
||||
|
||||
cassandraTemplate.insert(books);
|
||||
template.insert(books);
|
||||
|
||||
cassandraTemplate.deleteAsynchronously(books);
|
||||
template.deleteAsynchronously(books);
|
||||
|
||||
books = getBookList(20);
|
||||
|
||||
cassandraTemplate.insert(books, "book_alt");
|
||||
template.insert(books);
|
||||
|
||||
cassandraTemplate.deleteAsynchronously(books, "book_alt");
|
||||
template.deleteAsynchronously(books);
|
||||
|
||||
books = getBookList(20);
|
||||
|
||||
cassandraTemplate.insert(books, "book", options);
|
||||
template.insert(books, options);
|
||||
|
||||
cassandraTemplate.deleteAsynchronously(books, "book", options);
|
||||
template.deleteAsynchronously(books, options);
|
||||
|
||||
books = getBookList(20);
|
||||
|
||||
cassandraTemplate.insert(books, options);
|
||||
template.insert(books, options);
|
||||
|
||||
cassandraTemplate.deleteAsynchronously(books, options);
|
||||
template.deleteAsynchronously(books, options);
|
||||
|
||||
}
|
||||
|
||||
@@ -636,12 +619,12 @@ public class CassandraDataOperationsTest {
|
||||
b1.setAuthor("Cassandra Guru");
|
||||
b1.setPages(521);
|
||||
|
||||
cassandraTemplate.insert(b1);
|
||||
template.insert(b1);
|
||||
|
||||
Select select = QueryBuilder.select().all().from("book");
|
||||
select.where(QueryBuilder.eq("isbn", "123456-1"));
|
||||
|
||||
Book b = cassandraTemplate.selectOne(select, Book.class);
|
||||
Book b = template.selectOne(select.getQueryString(), Book.class);
|
||||
|
||||
log.info("SingleSelect Book Title -> " + b.getTitle());
|
||||
log.info("SingleSelect Book Author -> " + b.getAuthor());
|
||||
@@ -656,11 +639,11 @@ public class CassandraDataOperationsTest {
|
||||
|
||||
List<Book> books = getBookList(20);
|
||||
|
||||
cassandraTemplate.insert(books);
|
||||
template.insert(books);
|
||||
|
||||
Select select = QueryBuilder.select().all().from("book");
|
||||
|
||||
List<Book> b = cassandraTemplate.select(select, Book.class);
|
||||
List<Book> b = template.select(select.getQueryString(), Book.class);
|
||||
|
||||
log.info("Book Count -> " + b.size());
|
||||
|
||||
@@ -671,23 +654,11 @@ public class CassandraDataOperationsTest {
|
||||
@Test
|
||||
public void selectCountTest() {
|
||||
|
||||
List<Book> books = getBookList(20);
|
||||
int count = 20;
|
||||
List<Book> books = getBookList(count);
|
||||
|
||||
cassandraTemplate.insert(books);
|
||||
|
||||
Select select = QueryBuilder.select().countAll().from("book");
|
||||
|
||||
Long count = cassandraTemplate.count(select);
|
||||
|
||||
log.info("Book Count -> " + count);
|
||||
|
||||
Assert.assertEquals(count, new Long(20));
|
||||
|
||||
}
|
||||
|
||||
@After
|
||||
public void clearCassandra() {
|
||||
EmbeddedCassandraServerHelper.cleanEmbeddedCassandra();
|
||||
template.insert(books);
|
||||
|
||||
Assert.assertEquals(count, template.count(Book.class));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
name: test
|
||||
name: ks9487fb2da1a541e39a05e5545d64411a
|
||||
replicationFactor: 1
|
||||
strategy: org.apache.cassandra.locator.SimpleStrategy
|
||||
Reference in New Issue
Block a user