Completed more of the CQL generators.
This commit is contained in:
@@ -428,6 +428,7 @@ public class CassandraTemplate extends CassandraAccessor implements CassandraOpe
|
||||
* @see org.springframework.cassandra.core.CassandraOperations#processList(com.datastax.driver.core.ResultSet, java.lang.Class)
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings( "unchecked" )
|
||||
public <T> List<T> processList(ResultSet resultSet, Class<T> elementType) throws DataAccessException {
|
||||
List<Row> rows = resultSet.all();
|
||||
List<T> list = new ArrayList<T>(rows.size());
|
||||
|
||||
@@ -19,11 +19,7 @@ import static org.springframework.cassandra.core.cql.CqlStringUtils.noNull;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.cassandra.core.keyspace.AddColumnSpecification;
|
||||
import org.springframework.cassandra.core.keyspace.AlterColumnSpecification;
|
||||
import org.springframework.cassandra.core.keyspace.AlterKeyspaceSpecification;
|
||||
import org.springframework.cassandra.core.keyspace.ColumnChangeSpecification;
|
||||
import org.springframework.cassandra.core.keyspace.DropColumnSpecification;
|
||||
import org.springframework.cassandra.core.keyspace.Option;
|
||||
|
||||
/**
|
||||
@@ -41,8 +37,7 @@ public class AlterKeyspaceCqlGenerator extends KeyspaceOptionsCqlGenerator<Alter
|
||||
cql = noNull(cql);
|
||||
|
||||
preambleCql(cql);
|
||||
// changesCql(cql);
|
||||
// optionsCql(cql);
|
||||
optionsCql(cql);
|
||||
|
||||
cql.append(";");
|
||||
|
||||
@@ -53,69 +48,51 @@ public class AlterKeyspaceCqlGenerator extends KeyspaceOptionsCqlGenerator<Alter
|
||||
return noNull(cql).append("ALTER KEYSPACE ").append(spec().getNameAsIdentifier()).append(" ");
|
||||
}
|
||||
|
||||
// protected StringBuilder changesCql(StringBuilder cql) {
|
||||
// cql = noNull(cql);
|
||||
//
|
||||
// boolean first = true;
|
||||
// for (ColumnChangeSpecification change : spec().getChanges()) {
|
||||
// if (first) {
|
||||
// first = false;
|
||||
// } else {
|
||||
// cql.append(" ");
|
||||
// }
|
||||
// getCqlGeneratorFor(change).toCql(cql);
|
||||
// }
|
||||
//
|
||||
// return cql;
|
||||
// }
|
||||
//
|
||||
// protected ColumnChangeCqlGenerator<?> getCqlGeneratorFor(ColumnChangeSpecification change) {
|
||||
// if (change instanceof AddColumnSpecification) {
|
||||
// return new AddColumnCqlGenerator((AddColumnSpecification) change);
|
||||
// }
|
||||
// if (change instanceof DropColumnSpecification) {
|
||||
// return new DropColumnCqlGenerator((DropColumnSpecification) change);
|
||||
// }
|
||||
// if (change instanceof AlterColumnSpecification) {
|
||||
// return new AlterColumnCqlGenerator((AlterColumnSpecification) change);
|
||||
// }
|
||||
// throw new IllegalArgumentException("unknown ColumnChangeSpecification type: " + change.getClass().getName());
|
||||
// }
|
||||
//
|
||||
// @SuppressWarnings("unchecked")
|
||||
// protected StringBuilder optionsCql(StringBuilder cql) {
|
||||
// cql = noNull(cql);
|
||||
//
|
||||
// Map<String, Object> options = spec().getOptions();
|
||||
// if (options == null || options.isEmpty()) {
|
||||
// return cql;
|
||||
// }
|
||||
//
|
||||
// cql.append(" WITH ");
|
||||
// boolean first = true;
|
||||
// for (String key : options.keySet()) {
|
||||
// if (first) {
|
||||
// first = false;
|
||||
// } else {
|
||||
// cql.append(" AND ");
|
||||
// }
|
||||
//
|
||||
// cql.append(key);
|
||||
//
|
||||
// Object value = options.get(key);
|
||||
// if (value == null) {
|
||||
// continue;
|
||||
// }
|
||||
// cql.append(" = ");
|
||||
//
|
||||
// if (value instanceof Map) {
|
||||
// optionValueMap((Map<Option, Object>) value, cql);
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// // else just use value as string
|
||||
// cql.append(value.toString());
|
||||
// }
|
||||
// return cql;
|
||||
// }
|
||||
@SuppressWarnings( "unchecked" )
|
||||
protected StringBuilder optionsCql(StringBuilder cql) {
|
||||
cql = noNull(cql);
|
||||
|
||||
// begin options clause
|
||||
Map<String, Object> options = spec().getOptions();
|
||||
|
||||
if (!options.isEmpty()) {
|
||||
|
||||
// option preamble
|
||||
boolean first = true;
|
||||
cql.append(" WITH ");
|
||||
// end option preamble
|
||||
|
||||
if (!options.isEmpty()) {
|
||||
for (String name : options.keySet()) {
|
||||
// append AND if we're not on first option
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
cql.append(" AND ");
|
||||
}
|
||||
|
||||
// append <name> = <value>
|
||||
cql.append(name);
|
||||
|
||||
Object value = options.get(name);
|
||||
if (value == null) { // then assume string-only, valueless option like "COMPACT STORAGE"
|
||||
continue;
|
||||
}
|
||||
|
||||
cql.append(" = ");
|
||||
|
||||
if (value instanceof Map) {
|
||||
optionValueMap((Map<Option, Object>) value, cql);
|
||||
continue; // end non-empty value map
|
||||
}
|
||||
|
||||
// else just use value as string
|
||||
cql.append(value.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
// end options
|
||||
|
||||
return cql;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,15 +15,10 @@
|
||||
*/
|
||||
package org.springframework.cassandra.core.cql.generator;
|
||||
|
||||
import static org.springframework.cassandra.core.PrimaryKeyType.CLUSTERED;
|
||||
import static org.springframework.cassandra.core.PrimaryKeyType.PARTITIONED;
|
||||
import static org.springframework.cassandra.core.cql.CqlStringUtils.noNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.cassandra.core.keyspace.ColumnSpecification;
|
||||
import org.springframework.cassandra.core.keyspace.CreateKeyspaceSpecification;
|
||||
import org.springframework.cassandra.core.keyspace.Option;
|
||||
|
||||
@@ -56,146 +51,53 @@ public class CreateKeyspaceCqlGenerator extends KeyspaceCqlGenerator<CreateKeysp
|
||||
.append(spec().getNameAsIdentifier());
|
||||
}
|
||||
|
||||
protected void optionsCql(StringBuilder cql) {
|
||||
@SuppressWarnings( "unchecked" )
|
||||
protected StringBuilder optionsCql(StringBuilder cql) {
|
||||
cql = noNull(cql);
|
||||
|
||||
cql.append("WITH REPLICATION =");
|
||||
cql.append( " " );
|
||||
|
||||
// begin options clause
|
||||
Map<String, Object> options = spec().getOptions();
|
||||
|
||||
if (!options.isEmpty()) {
|
||||
|
||||
// option preamble
|
||||
boolean first = true;
|
||||
cql.append(" WITH ");
|
||||
// end option preamble
|
||||
|
||||
if (!options.isEmpty()) {
|
||||
for (String name : options.keySet()) {
|
||||
// append AND if we're not on first option
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
cql.append(" AND ");
|
||||
}
|
||||
|
||||
// append <name> = <value>
|
||||
cql.append(name);
|
||||
|
||||
Object value = options.get(name);
|
||||
if (value == null) { // then assume string-only, valueless option like "COMPACT STORAGE"
|
||||
continue;
|
||||
}
|
||||
|
||||
cql.append(" = ");
|
||||
|
||||
if (value instanceof Map) {
|
||||
optionValueMap((Map<Option, Object>) value, cql);
|
||||
continue; // end non-empty value map
|
||||
}
|
||||
|
||||
// else just use value as string
|
||||
cql.append(value.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
// end options
|
||||
|
||||
return cql;
|
||||
}
|
||||
|
||||
|
||||
// @SuppressWarnings("unchecked")
|
||||
// protected StringBuilder columnsAndOptionsCql(StringBuilder cql) {
|
||||
//
|
||||
// cql = noNull(cql);
|
||||
//
|
||||
// // begin columns
|
||||
// cql.append(" (");
|
||||
//
|
||||
// List<ColumnSpecification> partitionKeys = new ArrayList<ColumnSpecification>();
|
||||
// List<ColumnSpecification> clusterKeys = new ArrayList<ColumnSpecification>();
|
||||
// for (ColumnSpecification col : spec().getColumns()) {
|
||||
// col.toCql(cql).append(", ");
|
||||
//
|
||||
// if (col.getKeyType() == PARTITIONED) {
|
||||
// partitionKeys.add(col);
|
||||
// } else if (col.getKeyType() == CLUSTERED) {
|
||||
// clusterKeys.add(col);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // begin primary key clause
|
||||
// cql.append("PRIMARY KEY (");
|
||||
//
|
||||
// if (partitionKeys.size() > 1) {
|
||||
// // begin partition key clause
|
||||
// cql.append("(");
|
||||
// }
|
||||
//
|
||||
// appendColumnNames(cql, partitionKeys);
|
||||
//
|
||||
// if (partitionKeys.size() > 1) {
|
||||
// cql.append(")");
|
||||
// // end partition key clause
|
||||
// }
|
||||
//
|
||||
// if (!clusterKeys.isEmpty()) {
|
||||
// cql.append(", ");
|
||||
// }
|
||||
//
|
||||
// appendColumnNames(cql, clusterKeys);
|
||||
//
|
||||
// cql.append(")");
|
||||
// // end primary key clause
|
||||
//
|
||||
// cql.append(")");
|
||||
// // end columns
|
||||
//
|
||||
// StringBuilder ordering = createOrderingClause(clusterKeys);
|
||||
// // begin options
|
||||
// // begin option clause
|
||||
// Map<String, Object> options = spec().getOptions();
|
||||
//
|
||||
// if (ordering != null || !options.isEmpty()) {
|
||||
//
|
||||
// // option preamble
|
||||
// boolean first = true;
|
||||
// cql.append(" WITH ");
|
||||
// // end option preamble
|
||||
//
|
||||
// if (ordering != null) {
|
||||
// cql.append(ordering);
|
||||
// first = false;
|
||||
// }
|
||||
// if (!options.isEmpty()) {
|
||||
// for (String name : options.keySet()) {
|
||||
// // append AND if we're not on first option
|
||||
// if (first) {
|
||||
// first = false;
|
||||
// } else {
|
||||
// cql.append(" AND ");
|
||||
// }
|
||||
//
|
||||
// // append <name> = <value>
|
||||
// cql.append(name);
|
||||
//
|
||||
// Object value = options.get(name);
|
||||
// if (value == null) { // then assume string-only, valueless option like "COMPACT STORAGE"
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// cql.append(" = ");
|
||||
//
|
||||
// if (value instanceof Map) {
|
||||
// optionValueMap((Map<Option, Object>) value, cql);
|
||||
// continue; // end non-empty value map
|
||||
// }
|
||||
//
|
||||
// // else just use value as string
|
||||
// cql.append(value.toString());
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// // end options
|
||||
//
|
||||
// return cql;
|
||||
// }
|
||||
|
||||
// private static StringBuilder createOrderingClause(List<ColumnSpecification> columns) {
|
||||
// StringBuilder ordering = null;
|
||||
// boolean first = true;
|
||||
// for (ColumnSpecification col : columns) {
|
||||
//
|
||||
// if (col.getOrdering() != null) { // then ordering specified
|
||||
// if (ordering == null) { // then initialize ordering clause
|
||||
// ordering = new StringBuilder().append("CLUSTERING ORDER BY (");
|
||||
// }
|
||||
// if (first) {
|
||||
// first = false;
|
||||
// } else {
|
||||
// ordering.append(", ");
|
||||
// }
|
||||
// ordering.append(col.getName()).append(" ").append(col.getOrdering().cql());
|
||||
// }
|
||||
// }
|
||||
// if (ordering != null) { // then end ordering option
|
||||
// ordering.append(")");
|
||||
// }
|
||||
// return ordering;
|
||||
// }
|
||||
//
|
||||
// private static void appendColumnNames(StringBuilder str, List<ColumnSpecification> columns) {
|
||||
//
|
||||
// boolean first = true;
|
||||
// for (ColumnSpecification col : columns) {
|
||||
// if (first) {
|
||||
// first = false;
|
||||
// } else {
|
||||
// str.append(", ");
|
||||
// }
|
||||
// str.append(col.getName());
|
||||
//
|
||||
// }
|
||||
//
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
@@ -15,14 +15,7 @@
|
||||
*/
|
||||
package org.springframework.cassandra.core.cql.generator;
|
||||
|
||||
import static org.springframework.cassandra.core.cql.CqlStringUtils.escapeSingle;
|
||||
import static org.springframework.cassandra.core.cql.CqlStringUtils.noNull;
|
||||
import static org.springframework.cassandra.core.cql.CqlStringUtils.singleQuote;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.cassandra.core.keyspace.KeyspaceSpecification;
|
||||
import org.springframework.cassandra.core.keyspace.Option;
|
||||
|
||||
/**
|
||||
* Base class that contains behavior common to CQL generation for table operations.
|
||||
@@ -41,40 +34,4 @@ public abstract class KeyspaceCqlGenerator<T extends KeyspaceSpecification<T>> e
|
||||
protected T spec() {
|
||||
return (T) getSpecification();
|
||||
}
|
||||
|
||||
protected StringBuilder optionValueMap(Map<Option, Object> valueMap, StringBuilder cql) {
|
||||
cql = noNull(cql);
|
||||
|
||||
if (valueMap == null || valueMap.isEmpty()) {
|
||||
return cql;
|
||||
}
|
||||
// else option value is a non-empty map
|
||||
|
||||
// append { 'name' : 'value', ... }
|
||||
cql.append("{ ");
|
||||
boolean mapFirst = true;
|
||||
for (Map.Entry<Option, Object> entry : valueMap.entrySet()) {
|
||||
if (mapFirst) {
|
||||
mapFirst = false;
|
||||
} else {
|
||||
cql.append(", ");
|
||||
}
|
||||
|
||||
Option option = entry.getKey();
|
||||
cql.append(singleQuote(option.getName())); // entries in map keys are always quoted
|
||||
cql.append(" : ");
|
||||
Object entryValue = entry.getValue();
|
||||
entryValue = entryValue == null ? "" : entryValue.toString();
|
||||
if (option.escapesValue()) {
|
||||
entryValue = escapeSingle(entryValue);
|
||||
}
|
||||
if (option.quotesValue()) {
|
||||
entryValue = singleQuote(entryValue);
|
||||
}
|
||||
cql.append(entryValue);
|
||||
}
|
||||
cql.append(" }");
|
||||
|
||||
return cql;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,13 +15,6 @@
|
||||
*/
|
||||
package org.springframework.cassandra.core.cql.generator;
|
||||
|
||||
import static org.springframework.cassandra.core.cql.CqlStringUtils.escapeSingle;
|
||||
import static org.springframework.cassandra.core.cql.CqlStringUtils.noNull;
|
||||
import static org.springframework.cassandra.core.cql.CqlStringUtils.singleQuote;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.cassandra.core.keyspace.Option;
|
||||
import org.springframework.cassandra.core.keyspace.TableSpecification;
|
||||
|
||||
/**
|
||||
@@ -41,40 +34,4 @@ public abstract class TableCqlGenerator<T extends TableSpecification<T>> extends
|
||||
protected T spec() {
|
||||
return (T) getSpecification();
|
||||
}
|
||||
|
||||
protected StringBuilder optionValueMap(Map<Option, Object> valueMap, StringBuilder cql) {
|
||||
cql = noNull(cql);
|
||||
|
||||
if (valueMap == null || valueMap.isEmpty()) {
|
||||
return cql;
|
||||
}
|
||||
// else option value is a non-empty map
|
||||
|
||||
// append { 'name' : 'value', ... }
|
||||
cql.append("{ ");
|
||||
boolean mapFirst = true;
|
||||
for (Map.Entry<Option, Object> entry : valueMap.entrySet()) {
|
||||
if (mapFirst) {
|
||||
mapFirst = false;
|
||||
} else {
|
||||
cql.append(", ");
|
||||
}
|
||||
|
||||
Option option = entry.getKey();
|
||||
cql.append(singleQuote(option.getName())); // entries in map keys are always quoted
|
||||
cql.append(" : ");
|
||||
Object entryValue = entry.getValue();
|
||||
entryValue = entryValue == null ? "" : entryValue.toString();
|
||||
if (option.escapesValue()) {
|
||||
entryValue = escapeSingle(entryValue);
|
||||
}
|
||||
if (option.quotesValue()) {
|
||||
entryValue = singleQuote(entryValue);
|
||||
}
|
||||
cql.append(entryValue);
|
||||
}
|
||||
cql.append(" }");
|
||||
|
||||
return cql;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,7 +88,6 @@ public class CreateIndexSpecification extends IndexNameSpecification<CreateIndex
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public CreateIndexSpecification tableName(String tableName) {
|
||||
checkIdentifier(tableName);
|
||||
this.tableName = tableName;
|
||||
|
||||
@@ -27,4 +27,12 @@ public class CreateKeyspaceSpecification extends KeyspaceSpecification<CreateKey
|
||||
return ifNotExists;
|
||||
}
|
||||
|
||||
/**
|
||||
* Entry point into the {@link CreateTableSpecification}'s fluent API to create a table. Convenient if imported
|
||||
* statically.
|
||||
*/
|
||||
public static CreateKeyspaceSpecification createKeyspace() {
|
||||
return new CreateKeyspaceSpecification();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -37,11 +37,7 @@ public interface KeyspaceDescriptor {
|
||||
/**
|
||||
* Returns the replication strategy.
|
||||
*/
|
||||
String getReplicationStrategy();
|
||||
|
||||
Long getReplicationFactor();
|
||||
|
||||
Map<String, Long> getDataCenters();
|
||||
Boolean getDurableWrites();
|
||||
|
||||
/**
|
||||
* Returns an unmodifiable {@link Map} of keyspace options.
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package org.springframework.cassandra.core.keyspace;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public enum KeyspaceOption implements Option {
|
||||
REPLICATION_STRATEGY("class", String.class, true, true, true),
|
||||
REPLICATION("replication", Map.class, true, false, false),
|
||||
|
||||
REPLICATION_FACTOR("replication_factor", Long.class, false, false, false);
|
||||
DURABLE_WRITES("durable_writes", Boolean.class, false, false, false);
|
||||
|
||||
private Option delegate;
|
||||
|
||||
|
||||
@@ -15,9 +15,6 @@
|
||||
*/
|
||||
package org.springframework.cassandra.core.keyspace;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
@@ -28,48 +25,27 @@ import java.util.Map;
|
||||
*/
|
||||
public class KeyspaceSpecification<T> extends KeyspaceOptionsSpecification<KeyspaceSpecification<T>> implements KeyspaceDescriptor {
|
||||
|
||||
private String replicationStrategy;
|
||||
|
||||
private Long replicationFactor;
|
||||
|
||||
private Map<String, Long> dataCenters = new HashMap<String, Long>();
|
||||
|
||||
@Override
|
||||
public String getReplicationStrategy() {
|
||||
return replicationStrategy;
|
||||
}
|
||||
private Boolean durableWrites;
|
||||
|
||||
/**
|
||||
* @param replicationStrategy the replicationStrategy to set
|
||||
* @param durableWrites the durableWrites to set
|
||||
*/
|
||||
public void setReplicationStrategy(String replicationStrategy) {
|
||||
this.replicationStrategy = replicationStrategy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the replicationFactor
|
||||
*/
|
||||
@Override
|
||||
public Long getReplicationFactor() {
|
||||
return replicationFactor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param replicationFactor the replicationFactor to set
|
||||
*/
|
||||
public void setReplicationFactor(Long replicationFactor) {
|
||||
this.replicationFactor = replicationFactor;
|
||||
@SuppressWarnings( "unchecked" )
|
||||
public T durableWrites(Boolean durableWrites) {
|
||||
this.durableWrites = durableWrites;
|
||||
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Long> getDataCenters() {
|
||||
return Collections.unmodifiableMap( dataCenters );
|
||||
public Boolean getDurableWrites() {
|
||||
return durableWrites;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param dataCenters the dataCenters to set
|
||||
* @param durableWrites the durableWrites to set
|
||||
*/
|
||||
public void setDataCenters(Map<String, Long> dataCenters) {
|
||||
this.dataCenters = dataCenters;
|
||||
public void setDurableWrites(Boolean durableWrites) {
|
||||
this.durableWrites = durableWrites;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,6 +140,7 @@ public class CassandraOperationsTest extends AbstractEmbeddedCassandraIntegratio
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings( "unchecked" )
|
||||
public void ingestionTestListOfList() {
|
||||
|
||||
String cql = "insert into book (isbn, title, author, pages) values (?, ?, ?, ?)";
|
||||
@@ -507,6 +508,7 @@ public class CassandraOperationsTest extends AbstractEmbeddedCassandraIntegratio
|
||||
// Insert our 3 test books.
|
||||
ingestionTestObjectArray();
|
||||
|
||||
@SuppressWarnings( "unused" )
|
||||
Book book = cassandraTemplate.queryForObject("select * from book where isbn in ('1234','2345','3456')",
|
||||
new RowMapper<Book>() {
|
||||
@Override
|
||||
@@ -561,6 +563,7 @@ public class CassandraOperationsTest extends AbstractEmbeddedCassandraIntegratio
|
||||
@Test(expected = ClassCastException.class)
|
||||
public void queryForObjectTestCqlStringRequiredTypeInvalid() {
|
||||
|
||||
@SuppressWarnings( "unused" )
|
||||
Float title = cassandraTemplate.queryForObject("select title from book where isbn in ('" + ISBN_NINES + "')",
|
||||
Float.class);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user