testing coming along
This commit is contained in:
@@ -60,6 +60,7 @@ dependencies {
|
||||
testCompile("javax.annotation:jsr250-api:1.0", optional)
|
||||
testCompile("com.thoughtworks.xstream:xstream:1.3", optional)
|
||||
testCompile "org.cassandraunit:cassandra-unit:$cassandraUnitVersion"
|
||||
testCompile "org.cassandraunit:cassandra-unit-spring:$cassandraUnitVersion"
|
||||
testCompile "cglib:cglib-nodep:$cglibVersion"
|
||||
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ import org.springframework.cassandra.core.keyspace.Option;
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class AlterTableCqlGenerator extends AbstractTableOperationCqlGenerator<AlterTableSpecification> {
|
||||
public class AlterTableCqlGenerator extends TableOptionsCqlGenerator<AlterTableSpecification> {
|
||||
|
||||
public AlterTableCqlGenerator(AlterTableSpecification specification) {
|
||||
super(specification);
|
||||
|
||||
@@ -17,7 +17,7 @@ import org.springframework.cassandra.core.keyspace.Option;
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class CreateTableCqlGenerator extends AbstractTableOperationCqlGenerator<CreateTableSpecification> {
|
||||
public class CreateTableCqlGenerator extends TableCqlGenerator<CreateTableSpecification> {
|
||||
|
||||
public CreateTableCqlGenerator(CreateTableSpecification specification) {
|
||||
super(specification);
|
||||
@@ -110,7 +110,7 @@ public class CreateTableCqlGenerator extends AbstractTableOperationCqlGenerator<
|
||||
clustering.append(")");
|
||||
}
|
||||
|
||||
boolean parenthesize = partitionKeys.size() + primaryKeys.size() > 1;
|
||||
boolean parenthesize = true;// partitionKeys.size() + primaryKeys.size() > 1;
|
||||
|
||||
cql.append(parenthesize ? "(" : "");
|
||||
cql.append(partitions);
|
||||
@@ -118,6 +118,8 @@ public class CreateTableCqlGenerator extends AbstractTableOperationCqlGenerator<
|
||||
cql.append(primaries);
|
||||
cql.append(parenthesize ? ")" : "");
|
||||
// end primary key clause
|
||||
|
||||
cql.append(")");
|
||||
// end columns
|
||||
|
||||
// begin options
|
||||
|
||||
@@ -3,32 +3,20 @@ package org.springframework.cassandra.core.cql.generator;
|
||||
import static org.springframework.cassandra.core.cql.CqlStringUtils.noNull;
|
||||
|
||||
import org.springframework.cassandra.core.keyspace.DropTableSpecification;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* CQL generator for generating a <code>DROP TABLE</code> statement.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class DropTableCqlGenerator {
|
||||
|
||||
protected DropTableSpecification specification;
|
||||
public class DropTableCqlGenerator extends TableNameCqlGenerator<DropTableSpecification> {
|
||||
|
||||
public DropTableCqlGenerator(DropTableSpecification specification) {
|
||||
setSpecification(specification);
|
||||
}
|
||||
|
||||
protected void setSpecification(DropTableSpecification specification) {
|
||||
Assert.notNull(specification);
|
||||
this.specification = specification;
|
||||
super(specification);
|
||||
}
|
||||
|
||||
public StringBuilder toCql(StringBuilder cql) {
|
||||
return noNull(cql).append("DROP TABLE ").append(specification.getIfExists() ? "IF EXISTS " : "")
|
||||
.append(specification.getNameAsIdentifier());
|
||||
}
|
||||
|
||||
public String toCql() {
|
||||
return toCql(null).toString();
|
||||
return noNull(cql).append("DROP TABLE ").append(spec().getIfExists() ? "IF EXISTS " : "")
|
||||
.append(spec().getNameAsIdentifier()).append(";");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,9 +6,8 @@ import static org.springframework.cassandra.core.cql.CqlStringUtils.singleQuote;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.cassandra.core.keyspace.AbstractTableSpecification;
|
||||
import org.springframework.cassandra.core.keyspace.Option;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.cassandra.core.keyspace.TableSpecification;
|
||||
|
||||
/**
|
||||
* Base class that contains behavior common to CQL generation for table operations.
|
||||
@@ -16,31 +15,16 @@ import org.springframework.util.Assert;
|
||||
* @author Matthew T. Adams
|
||||
* @param T The subtype of this class for which this is a CQL generator.
|
||||
*/
|
||||
public abstract class AbstractTableOperationCqlGenerator<T extends AbstractTableSpecification<T>> {
|
||||
public abstract class TableCqlGenerator<T extends TableSpecification<T>> extends
|
||||
TableOptionsCqlGenerator<TableSpecification<T>> {
|
||||
|
||||
public abstract StringBuilder toCql(StringBuilder cql);
|
||||
|
||||
private AbstractTableSpecification<T> specification;
|
||||
|
||||
public AbstractTableOperationCqlGenerator(AbstractTableSpecification<T> specification) {
|
||||
setSpecification(specification);
|
||||
}
|
||||
|
||||
protected void setSpecification(AbstractTableSpecification<T> specification) {
|
||||
Assert.notNull(specification);
|
||||
this.specification = specification;
|
||||
public TableCqlGenerator(TableSpecification<T> specification) {
|
||||
super(specification);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public T getSpecification() {
|
||||
return (T) specification;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenient synonymous method of {@link #getSpecification()}.
|
||||
*/
|
||||
protected T spec() {
|
||||
return getSpecification();
|
||||
return (T) getSpecification();
|
||||
}
|
||||
|
||||
protected StringBuilder optionValueMap(Map<Option, Object> valueMap, StringBuilder cql) {
|
||||
@@ -78,8 +62,4 @@ public abstract class AbstractTableOperationCqlGenerator<T extends AbstractTable
|
||||
|
||||
return cql;
|
||||
}
|
||||
|
||||
public String toCql() {
|
||||
return toCql(null).toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package org.springframework.cassandra.core.cql.generator;
|
||||
|
||||
import org.springframework.cassandra.core.keyspace.TableNameSpecification;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
public abstract class TableNameCqlGenerator<T extends TableNameSpecification<T>> {
|
||||
|
||||
public abstract StringBuilder toCql(StringBuilder cql);
|
||||
|
||||
private TableNameSpecification<T> specification;
|
||||
|
||||
public TableNameCqlGenerator(TableNameSpecification<T> specification) {
|
||||
setSpecification(specification);
|
||||
}
|
||||
|
||||
protected void setSpecification(TableNameSpecification<T> specification) {
|
||||
Assert.notNull(specification);
|
||||
this.specification = specification;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public T getSpecification() {
|
||||
return (T) specification;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenient synonymous method of {@link #getSpecification()}.
|
||||
*/
|
||||
protected T spec() {
|
||||
return getSpecification();
|
||||
}
|
||||
|
||||
public String toCql() {
|
||||
return toCql(null).toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
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.TableOptionsSpecification;
|
||||
|
||||
/**
|
||||
* Base class that contains behavior common to CQL generation for table operations.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
* @param T The subtype of this class for which this is a CQL generator.
|
||||
*/
|
||||
public abstract class TableOptionsCqlGenerator<T extends TableOptionsSpecification<T>> extends
|
||||
TableNameCqlGenerator<TableOptionsSpecification<T>> {
|
||||
|
||||
public TableOptionsCqlGenerator(TableOptionsSpecification<T> specification) {
|
||||
super(specification);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -6,25 +6,45 @@ import java.util.List;
|
||||
|
||||
import com.datastax.driver.core.DataType;
|
||||
|
||||
public class AlterTableSpecification extends AbstractTableSpecification<AlterTableSpecification> {
|
||||
/**
|
||||
* Builder class to construct an <code>ALTER TABLE</code> specification.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class AlterTableSpecification extends TableOptionsSpecification<AlterTableSpecification> {
|
||||
|
||||
/**
|
||||
* The list of column changes.
|
||||
*/
|
||||
private List<ColumnChangeSpecification> changes = new ArrayList<ColumnChangeSpecification>();
|
||||
|
||||
/**
|
||||
* Adds a <code>DROP</code> to the list of column changes.
|
||||
*/
|
||||
public AlterTableSpecification drop(String column) {
|
||||
changes.add(new DropColumnSpecification(column));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an <code>ADD</code> to the list of column changes.
|
||||
*/
|
||||
public AlterTableSpecification add(String column, DataType type) {
|
||||
changes.add(new AddColumnSpecification(column, type));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an <code>ALTER</code> to the list of column changes.
|
||||
*/
|
||||
public AlterTableSpecification alter(String column, DataType type) {
|
||||
changes.add(new AlterColumnSpecification(column, type));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an unmodifiable list of column changes.
|
||||
*/
|
||||
public List<ColumnChangeSpecification> getChanges() {
|
||||
return Collections.unmodifiableList(changes);
|
||||
}
|
||||
|
||||
@@ -1,27 +1,13 @@
|
||||
package org.springframework.cassandra.core.keyspace;
|
||||
|
||||
import static org.springframework.data.cassandra.mapping.KeyType.PARTITION;
|
||||
import static org.springframework.data.cassandra.mapping.KeyType.PRIMARY;
|
||||
import static org.springframework.data.cassandra.mapping.Ordering.ASCENDING;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.cassandra.mapping.KeyType;
|
||||
import org.springframework.data.cassandra.mapping.Ordering;
|
||||
|
||||
import com.datastax.driver.core.DataType;
|
||||
|
||||
/**
|
||||
* Builder class to construct CQL for a <code>CREATE TABLE</code> statement. Not threadsafe.
|
||||
* Builder class to construct a <code>CREATE TABLE</code> specification.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class CreateTableSpecification extends AbstractTableSpecification<CreateTableSpecification> {
|
||||
public class CreateTableSpecification extends TableSpecification<CreateTableSpecification> {
|
||||
|
||||
private boolean ifNotExists = false;
|
||||
private List<ColumnSpecification> columns = new ArrayList<ColumnSpecification>();
|
||||
|
||||
/**
|
||||
* Causes the inclusion of an <code>IF NOT EXISTS</code> clause.
|
||||
@@ -42,36 +28,7 @@ public class CreateTableSpecification extends AbstractTableSpecification<CreateT
|
||||
return this;
|
||||
}
|
||||
|
||||
public CreateTableSpecification column(String name, DataType type) {
|
||||
return column(name, type, null, null);
|
||||
}
|
||||
|
||||
public CreateTableSpecification partitionKeyColumn(String name, DataType type) {
|
||||
return column(name, type, PARTITION, null);
|
||||
}
|
||||
|
||||
public CreateTableSpecification primaryKeyColumn(String name, DataType type) {
|
||||
return primaryKeyColumn(name, type, ASCENDING);
|
||||
}
|
||||
|
||||
public CreateTableSpecification primaryKeyColumn(String name, DataType type, Ordering order) {
|
||||
return column(name, type, PRIMARY, order);
|
||||
}
|
||||
|
||||
protected CreateTableSpecification column(String name, DataType type, KeyType keyType, Ordering ordering) {
|
||||
columns().add(new ColumnSpecification().name(name).type(type).keyType(keyType).ordering(ordering));
|
||||
return this;
|
||||
}
|
||||
|
||||
protected List<ColumnSpecification> columns() {
|
||||
return columns == null ? columns = new ArrayList<ColumnSpecification>() : columns;
|
||||
}
|
||||
|
||||
public boolean getIfNotExists() {
|
||||
return ifNotExists;
|
||||
}
|
||||
|
||||
public List<ColumnSpecification> getColumns() {
|
||||
return Collections.unmodifiableList(columns);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package org.springframework.cassandra.core.keyspace;
|
||||
|
||||
/**
|
||||
* Convenient default implementation of {@link TableDescriptor} as an extension of {@link TableSpecification} that
|
||||
* doesn't require the use of generics.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class DefaultTableDescriptor extends TableSpecification<DefaultTableDescriptor> {
|
||||
|
||||
/**
|
||||
* Factory method to produce a new {@link DefaultTableDescriptor}. Convenient if imported statically.
|
||||
*/
|
||||
public static DefaultTableDescriptor table() {
|
||||
return new DefaultTableDescriptor();
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,14 @@
|
||||
package org.springframework.cassandra.core.keyspace;
|
||||
|
||||
import static org.springframework.cassandra.core.cql.CqlStringUtils.checkIdentifier;
|
||||
import static org.springframework.cassandra.core.cql.CqlStringUtils.identifize;
|
||||
/**
|
||||
* Builder class that supports the construction of <code>DROP TABLE</code> specifications.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class DropTableSpecification extends TableNameSpecification<DropTableSpecification> {
|
||||
|
||||
public class DropTableSpecification {
|
||||
|
||||
private String name;
|
||||
private boolean ifExists;
|
||||
|
||||
public DropTableSpecification name(String name) {
|
||||
checkIdentifier(name);
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DropTableSpecification ifExists() {
|
||||
return ifExists(true);
|
||||
}
|
||||
@@ -26,8 +21,4 @@ public class DropTableSpecification {
|
||||
public boolean getIfExists() {
|
||||
return ifExists;
|
||||
}
|
||||
|
||||
public String getNameAsIdentifier() {
|
||||
return identifize(name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
package org.springframework.cassandra.core.keyspace;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Describes a table.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public interface TableDescriptor {
|
||||
|
||||
/**
|
||||
* Returns the name of the table.
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* Returns the name of the table as an identifer or quoted identifier as appropriate.
|
||||
*/
|
||||
String getNameAsIdentifier();
|
||||
|
||||
/**
|
||||
* Returns an unmodifiable {@link List} of {@link ColumnSpecification}s.
|
||||
*/
|
||||
List<ColumnSpecification> getColumns();
|
||||
|
||||
/**
|
||||
* Returns an unmodifiable list of all partition key columns.
|
||||
*/
|
||||
public List<ColumnSpecification> getPartitionKeyColumns();
|
||||
|
||||
/**
|
||||
* Returns an unmodifiable list of all primary key columns that are not also partition key columns.
|
||||
*/
|
||||
public List<ColumnSpecification> getPrimaryKeyColumns();
|
||||
|
||||
/**
|
||||
* Returns an unmodifiable list of all partition and primary key columns.
|
||||
*/
|
||||
public List<ColumnSpecification> getKeyColumns();
|
||||
|
||||
/**
|
||||
* Returns an unmodifiable list of all non-key columns.
|
||||
*/
|
||||
public List<ColumnSpecification> getNonKeyColumns();
|
||||
|
||||
/**
|
||||
* Returns an unmodifiable {@link Map} of table options.
|
||||
*/
|
||||
Map<String, Object> getOptions();
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package org.springframework.cassandra.core.keyspace;
|
||||
|
||||
import static org.springframework.cassandra.core.cql.CqlStringUtils.checkIdentifier;
|
||||
import static org.springframework.cassandra.core.cql.CqlStringUtils.identifize;
|
||||
|
||||
/**
|
||||
* Abstract builder class to support the construction of table specifications.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
* @param <T> The subtype of the {@link TableNameSpecification}
|
||||
*/
|
||||
public abstract class TableNameSpecification<T extends TableNameSpecification<T>> {
|
||||
|
||||
/**
|
||||
* The name of the table.
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* Sets the table name.
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public T name(String name) {
|
||||
checkIdentifier(name);
|
||||
this.name = name;
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getNameAsIdentifier() {
|
||||
return identifize(name);
|
||||
}
|
||||
}
|
||||
@@ -122,9 +122,13 @@ public enum TableOption implements Option {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return getValue();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package org.springframework.cassandra.core.keyspace;
|
||||
|
||||
import static org.springframework.cassandra.core.cql.CqlStringUtils.checkIdentifier;
|
||||
import static org.springframework.cassandra.core.cql.CqlStringUtils.escapeSingle;
|
||||
import static org.springframework.cassandra.core.cql.CqlStringUtils.identifize;
|
||||
import static org.springframework.cassandra.core.cql.CqlStringUtils.singleQuote;
|
||||
|
||||
import java.util.Collections;
|
||||
@@ -12,39 +10,26 @@ import java.util.Map;
|
||||
import org.springframework.cassandra.core.cql.CqlStringUtils;
|
||||
|
||||
/**
|
||||
* Base class that contains behavior common to table operations.
|
||||
* Abstract builder class to support the construction of table specifications that have table options, that is, those
|
||||
* options normally specified by <code>WITH ... AND ...</code>.
|
||||
* <p/>
|
||||
* It is important to note that although this class depends on {@link TableOption} for convenient and typesafe use, it
|
||||
* ultimately stores its options in a <code>Map<String,Object></code> for flexibility. This means that
|
||||
* {@link #with(TableOption)} and {@link #with(TableOption, Object)} delegate to
|
||||
* {@link #with(String, Object, boolean, boolean)}. This design allows the API to support new Cassandra options as they
|
||||
* are introduced without having to update the code immediately.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
* @param T The subtype of AbstractTableBuilder.
|
||||
* @param <T> The subtype of the {@link TableOptionsSpecification}.
|
||||
*/
|
||||
public abstract class AbstractTableSpecification<T extends AbstractTableSpecification<T>> {
|
||||
|
||||
private String name;
|
||||
public abstract class TableOptionsSpecification<T extends TableOptionsSpecification<T>> extends
|
||||
TableNameSpecification<TableOptionsSpecification<T>> {
|
||||
|
||||
protected Map<String, Object> options = new LinkedHashMap<String, Object>();
|
||||
|
||||
/**
|
||||
* Sets the table name.
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public T name(String name) {
|
||||
setName(name);
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
checkIdentifier(name);
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getNameAsIdentifier() {
|
||||
return identifize(name);
|
||||
return (T) super.name(name);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -0,0 +1,162 @@
|
||||
package org.springframework.cassandra.core.keyspace;
|
||||
|
||||
import static org.springframework.data.cassandra.mapping.KeyType.PARTITION;
|
||||
import static org.springframework.data.cassandra.mapping.KeyType.PRIMARY;
|
||||
import static org.springframework.data.cassandra.mapping.Ordering.ASCENDING;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.cassandra.mapping.KeyType;
|
||||
import org.springframework.data.cassandra.mapping.Ordering;
|
||||
|
||||
import com.datastax.driver.core.DataType;
|
||||
|
||||
/**
|
||||
* Builder class to support the construction of table specifications that have columns. This class can also be used as a
|
||||
* standalone {@link TableDescriptor}, independent of {@link CreateTableSpecification}.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class TableSpecification<T> extends TableOptionsSpecification<TableSpecification<T>> implements TableDescriptor {
|
||||
|
||||
/**
|
||||
* List of all columns.
|
||||
*/
|
||||
private List<ColumnSpecification> columns = new ArrayList<ColumnSpecification>();
|
||||
|
||||
/**
|
||||
* List of only those columns that comprise the partition key.
|
||||
*/
|
||||
private List<ColumnSpecification> partitionKeyColumns = new ArrayList<ColumnSpecification>();
|
||||
|
||||
/**
|
||||
* List of only those columns that comprise the primary key that are not also part of the partition key.
|
||||
*/
|
||||
private List<ColumnSpecification> primaryKeyColumns = new ArrayList<ColumnSpecification>();
|
||||
|
||||
/**
|
||||
* List of only those columns that are not partition or primary key columns.
|
||||
*/
|
||||
private List<ColumnSpecification> nonKeyColumns = new ArrayList<ColumnSpecification>();
|
||||
|
||||
/**
|
||||
* Adds the given non-key column to the table. Must be specified after all primary key columns.
|
||||
*
|
||||
* @param name The column name; must be a valid unquoted or quoted identifier without the surrounding double quotes.
|
||||
* @param type The data type of the column.
|
||||
*/
|
||||
public T column(String name, DataType type) {
|
||||
return column(name, type, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given partition key column to the table. Must be specified before any other columns.
|
||||
*
|
||||
* @param name The column name; must be a valid unquoted or quoted identifier without the surrounding double quotes.
|
||||
* @param type The data type of the column.
|
||||
* @return this
|
||||
*/
|
||||
public T partitionKeyColumn(String name, DataType type) {
|
||||
return column(name, type, PARTITION, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given primary key column to the table with ascending ordering. Must be specified after all partition key
|
||||
* columns and before any non-key columns.
|
||||
*
|
||||
* @param name The column name; must be a valid unquoted or quoted identifier without the surrounding double quotes.
|
||||
* @param type The data type of the column.
|
||||
* @return this
|
||||
*/
|
||||
public T primaryKeyColumn(String name, DataType type) {
|
||||
return primaryKeyColumn(name, type, ASCENDING);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given primary key column to the table with the given ordering (<code>null</code> meaning ascending). Must
|
||||
* be specified after all partition key columns and before any non-key columns.
|
||||
*
|
||||
* @param name The column name; must be a valid unquoted or quoted identifier without the surrounding double quotes.
|
||||
* @param type The data type of the column.
|
||||
* @return this
|
||||
*/
|
||||
public T primaryKeyColumn(String name, DataType type, Ordering ordering) {
|
||||
return column(name, type, PRIMARY, ordering);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given info as a new column to the table. Partition key columns must precede primary key columns, which
|
||||
* must precede non-key columns.
|
||||
*
|
||||
* @param name The column name; must be a valid unquoted or quoted identifier without the surrounding double quotes.
|
||||
* @param type The data type of the column.
|
||||
* @param keyType Indicates key type. Null means that the column is not a key column.
|
||||
* @param ordering If the given {@link KeyType} is {@link KeyType#PRIMARY}, then the given ordering is used, else
|
||||
* ignored.
|
||||
* @return this
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected T column(String name, DataType type, KeyType keyType, Ordering ordering) {
|
||||
|
||||
ColumnSpecification column = new ColumnSpecification().name(name).type(type).keyType(keyType)
|
||||
.ordering(keyType == PRIMARY ? ordering : null);
|
||||
|
||||
columns.add(column);
|
||||
|
||||
if (keyType == KeyType.PARTITION) {
|
||||
partitionKeyColumns.add(column);
|
||||
}
|
||||
|
||||
if (keyType == KeyType.PRIMARY) {
|
||||
primaryKeyColumns.add(column);
|
||||
}
|
||||
|
||||
if (keyType == null) {
|
||||
nonKeyColumns.add(column);
|
||||
}
|
||||
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an unmodifiable list of all columns.
|
||||
*/
|
||||
public List<ColumnSpecification> getColumns() {
|
||||
return Collections.unmodifiableList(columns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an unmodifiable list of all partition key columns.
|
||||
*/
|
||||
public List<ColumnSpecification> getPartitionKeyColumns() {
|
||||
return Collections.unmodifiableList(partitionKeyColumns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an unmodifiable list of all primary key columns that are not also partition key columns.
|
||||
*/
|
||||
public List<ColumnSpecification> getPrimaryKeyColumns() {
|
||||
return Collections.unmodifiableList(primaryKeyColumns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an unmodifiable list of all primary key columns that are not also partition key columns.
|
||||
*/
|
||||
public List<ColumnSpecification> getKeyColumns() {
|
||||
|
||||
ArrayList<ColumnSpecification> keyColumns = new ArrayList<ColumnSpecification>();
|
||||
keyColumns.addAll(partitionKeyColumns);
|
||||
keyColumns.addAll(primaryKeyColumns);
|
||||
|
||||
return Collections.unmodifiableList(keyColumns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an unmodifiable list of all non-key columns.
|
||||
*/
|
||||
public List<ColumnSpecification> getNonKeyColumns() {
|
||||
return Collections.unmodifiableList(nonKeyColumns);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.springframework.cassandra.core.keyspace;
|
||||
package org.springframework.cassandra.core.util;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
@@ -144,7 +144,7 @@ public class CassandraKeyspaceFactoryBean implements FactoryBean<Keyspace>, Init
|
||||
// drop the old keyspace if needed
|
||||
if (keyspaceExists && (keyspaceAttributes.isCreate() || keyspaceAttributes.isCreateDrop())) {
|
||||
log.info("Drop keyspace " + keyspace + " on afterPropertiesSet");
|
||||
session.execute("DROP KEYSPACE " + keyspace);
|
||||
session.execute("DROP KEYSPACE " + keyspace + ";");
|
||||
keyspaceExists = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
package org.springframework.cassandra.test.integration.core.cql.generator;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.apache.cassandra.exceptions.ConfigurationException;
|
||||
import org.apache.thrift.transport.TTransportException;
|
||||
import org.cassandraunit.utils.EmbeddedCassandraServerHelper;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
|
||||
import com.datastax.driver.core.Cluster;
|
||||
import com.datastax.driver.core.KeyspaceMetadata;
|
||||
import com.datastax.driver.core.Session;
|
||||
|
||||
public abstract class AbstractEmbeddedCassandraIntegrationTest {
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws ConfigurationException, TTransportException, IOException,
|
||||
InterruptedException {
|
||||
EmbeddedCassandraServerHelper.startEmbeddedCassandra("cassandra.yaml");
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether to clear the cluster before the next test.
|
||||
*/
|
||||
protected boolean clear = true;
|
||||
/**
|
||||
* Whether to connect to Cassandra.
|
||||
*/
|
||||
protected boolean connect = true;
|
||||
/**
|
||||
* The {@link Cluster} that's connected to Cassandra.
|
||||
*/
|
||||
protected Cluster cluster;
|
||||
/**
|
||||
* If not <code>null</code>, get a {@link Session} for the from the {@link #cluster}.
|
||||
*/
|
||||
protected String keyspace = "ks" + UUID.randomUUID().toString().replace("-", "");
|
||||
/**
|
||||
* The {@link Session} for the {@link #keyspace} from the {@link #cluster}.
|
||||
*/
|
||||
protected Session session;
|
||||
|
||||
/**
|
||||
* Returns whether we're currently connected to the cluster.
|
||||
*/
|
||||
public boolean connected() {
|
||||
return session != null;
|
||||
}
|
||||
|
||||
public Cluster cluster() {
|
||||
return Cluster.builder().addContactPoint("localhost").withPort(9042).build();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
if (connect && !connected()) {
|
||||
cluster = cluster();
|
||||
|
||||
if (keyspace == null) {
|
||||
session = cluster.connect();
|
||||
} else {
|
||||
|
||||
KeyspaceMetadata kmd = cluster.getMetadata().getKeyspace(keyspace);
|
||||
if (kmd == null) { // then create keyspace
|
||||
session = cluster.connect();
|
||||
session.execute("CREATE KEYSPACE " + keyspace
|
||||
+ " WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 1};");
|
||||
session.execute("USE " + keyspace + ";");
|
||||
} // else keyspace already exists
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() {
|
||||
if (clear && connected()) {
|
||||
EmbeddedCassandraServerHelper.cleanEmbeddedCassandra();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
package org.springframework.cassandra.test.integration.core.cql.generator;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.cassandra.core.keyspace.ColumnSpecification;
|
||||
import org.springframework.cassandra.core.keyspace.TableDescriptor;
|
||||
import org.springframework.cassandra.core.keyspace.TableOption;
|
||||
import org.springframework.cassandra.core.keyspace.TableOption.CachingOption;
|
||||
|
||||
import com.datastax.driver.core.ColumnMetadata;
|
||||
import com.datastax.driver.core.Session;
|
||||
import com.datastax.driver.core.TableMetadata;
|
||||
import com.datastax.driver.core.TableMetadata.Options;
|
||||
|
||||
public class CqlTableSpecificationAssertions {
|
||||
|
||||
public static double DELTA = 1e-6; // delta for comparisons of doubles
|
||||
|
||||
public static void assertTable(TableDescriptor expected, String keyspace, Session session) {
|
||||
TableMetadata tmd = session.getCluster().getMetadata().getKeyspace(keyspace.toLowerCase())
|
||||
.getTable(expected.getName());
|
||||
|
||||
assertEquals(expected.getName().toLowerCase(), tmd.getName().toLowerCase());
|
||||
assertPartitionKeyColumns(expected, tmd);
|
||||
assertPrimaryKeyColumns(expected, tmd);
|
||||
assertColumns(expected.getColumns(), tmd.getColumns());
|
||||
assertOptions(expected.getOptions(), tmd.getOptions());
|
||||
}
|
||||
|
||||
public static void assertPartitionKeyColumns(TableDescriptor expected, TableMetadata actual) {
|
||||
assertColumns(expected.getPartitionKeyColumns(), actual.getPartitionKey());
|
||||
}
|
||||
|
||||
public static void assertPrimaryKeyColumns(TableDescriptor expected, TableMetadata actual) {
|
||||
assertColumns(expected.getKeyColumns(), actual.getPrimaryKey());
|
||||
}
|
||||
|
||||
public static void assertOptions(Map<String, Object> expected, Options actual) {
|
||||
|
||||
for (String key : expected.keySet()) {
|
||||
|
||||
Object value = expected.get(key);
|
||||
TableOption tableOption = getTableOptionFor(key);
|
||||
|
||||
if (tableOption == null && key.equalsIgnoreCase(TableOption.COMPACT_STORAGE.getName())) {
|
||||
// TODO: figure out how to tell if COMPACT STORAGE was used
|
||||
continue;
|
||||
}
|
||||
|
||||
assertOption(tableOption, key, value, getOptionFor(tableOption, tableOption.getType(), actual));
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "incomplete-switch" })
|
||||
public static void assertOption(TableOption tableOption, String key, Object expected, Object actual) {
|
||||
|
||||
if (tableOption == null) { // then this is a string-only or unknown value
|
||||
key.equalsIgnoreCase(actual.toString()); // TODO: determine if this is the right test
|
||||
}
|
||||
|
||||
switch (tableOption) {
|
||||
|
||||
case BLOOM_FILTER_FP_CHANCE:
|
||||
case READ_REPAIR_CHANCE:
|
||||
case DCLOCAL_READ_REPAIR_CHANCE:
|
||||
assertEquals((Double) expected, (Double) actual, DELTA);
|
||||
return;
|
||||
|
||||
case CACHING:
|
||||
assertEquals(CachingOption.valueOf((String) expected).getValue(), actual);
|
||||
return;
|
||||
|
||||
case COMPACTION:
|
||||
assertCompaction((Map<String, Object>) expected, (Map<String, String>) actual);
|
||||
return;
|
||||
|
||||
case COMPRESSION:
|
||||
assertCompression((Map<String, Object>) expected, (Map<String, String>) actual);
|
||||
return;
|
||||
}
|
||||
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
public static void assertCompaction(Map<String, Object> expected, Map<String, String> actual) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
public static void assertCompression(Map<String, Object> expected, Map<String, String> actual) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
public static TableOption getTableOptionFor(String key) {
|
||||
try {
|
||||
return TableOption.valueOf(key);
|
||||
} catch (IllegalArgumentException x) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T getOptionFor(TableOption option, Class<?> type, Options options) {
|
||||
switch (option) {
|
||||
case BLOOM_FILTER_FP_CHANCE:
|
||||
return (T) (Double) options.getBloomFilterFalsePositiveChance();
|
||||
case CACHING:
|
||||
return (T) options.getCaching();
|
||||
case COMMENT:
|
||||
return (T) options.getComment();
|
||||
case COMPACTION:
|
||||
return (T) options.getCompaction();
|
||||
case COMPACT_STORAGE:
|
||||
throw new Error(); // TODO: figure out
|
||||
case COMPRESSION:
|
||||
return (T) options.getCompression();
|
||||
case DCLOCAL_READ_REPAIR_CHANCE:
|
||||
return (T) (Double) options.getReadRepairChance();
|
||||
case GC_GRACE_SECONDS:
|
||||
return (T) new Long(options.getGcGraceInSeconds());
|
||||
case READ_REPAIR_CHANCE:
|
||||
return (T) (Double) options.getReadRepairChance();
|
||||
case REPLICATE_ON_WRITE:
|
||||
return (T) (Boolean) options.getReplicateOnWrite();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void assertColumns(List<ColumnSpecification> expected, List<ColumnMetadata> actual) {
|
||||
for (int i = 0; i < expected.size(); i++) {
|
||||
ColumnSpecification expectedColumn = expected.get(i);
|
||||
ColumnMetadata actualColumn = actual.get(i);
|
||||
|
||||
assertColumn(expectedColumn, actualColumn);
|
||||
}
|
||||
}
|
||||
|
||||
public static void assertColumn(ColumnSpecification expected, ColumnMetadata actual) {
|
||||
assertEquals(expected.getName().toLowerCase(), actual.getName().toLowerCase());
|
||||
assertEquals(expected.getType(), actual.getType());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package org.springframework.cassandra.test.integration.core.cql.generator;
|
||||
|
||||
import static org.springframework.cassandra.test.integration.core.cql.generator.CqlTableSpecificationAssertions.assertTable;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.cassandra.test.unit.core.cql.generator.CreateTableCqlGeneratorTests.BasicTest;
|
||||
|
||||
public class CreateTableCqlGeneratorIntegrationTests {
|
||||
|
||||
public static class BasicIntegrationTest extends AbstractEmbeddedCassandraIntegrationTest {
|
||||
BasicTest unit = new BasicTest();
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
unit.prepare();
|
||||
|
||||
session.execute(unit.cql);
|
||||
|
||||
assertTable(unit.specification, keyspace, session);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
package org.springframework.cassandra.test.unit.core.cql.generator;
|
||||
|
||||
import static org.springframework.cassandra.core.keyspace.TableOperations.alterTable;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.cassandra.core.cql.generator.AlterTableCqlGenerator;
|
||||
import org.springframework.cassandra.core.keyspace.AlterTableSpecification;
|
||||
|
||||
import com.datastax.driver.core.DataType;
|
||||
|
||||
public class AlterTableCqlGeneratorTest {
|
||||
|
||||
@Test
|
||||
public void testAlterTableBuilder() throws Exception {
|
||||
String name = "mytable";
|
||||
DataType addedType = DataType.timeuuid();
|
||||
String addedName = "added_column";
|
||||
DataType alteredType = DataType.text();
|
||||
String alteredName = "altered_column";
|
||||
String droppedName = "dropped";
|
||||
|
||||
AlterTableSpecification alter = alterTable().name(name).add(addedName, addedType).alter(alteredName, alteredType)
|
||||
.drop(droppedName);
|
||||
AlterTableCqlGenerator generator = new AlterTableCqlGenerator(alter);
|
||||
System.out.println(generator.toCql());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package org.springframework.cassandra.test.unit.core.cql.generator;
|
||||
|
||||
import static junit.framework.Assert.assertTrue;
|
||||
import static org.springframework.cassandra.core.keyspace.TableOperations.alterTable;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.cassandra.core.cql.generator.AlterTableCqlGenerator;
|
||||
import org.springframework.cassandra.core.keyspace.AlterTableSpecification;
|
||||
|
||||
import com.datastax.driver.core.DataType;
|
||||
|
||||
public class AlterTableCqlGeneratorTests {
|
||||
|
||||
/**
|
||||
* Asserts that the preamble is first & correctly formatted in the given CQL string.
|
||||
*/
|
||||
public static void assertPreamble(String tableName, String cql) {
|
||||
assertTrue(cql.startsWith("ALTER TABLE " + tableName + " "));
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given list of columns definitions are contained in the given CQL string properly.
|
||||
*
|
||||
* @param columnSpec IE, "foo text, bar blob"
|
||||
*/
|
||||
public static void assertColumnChanges(String columnSpec, String cql) {
|
||||
assertTrue(cql.contains(""));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenient base class that other test classes can use so as not to repeat the generics declarations.
|
||||
*/
|
||||
public static abstract class AlterTableTest extends
|
||||
TableOperationCqlGeneratorTest<AlterTableSpecification, AlterTableCqlGenerator> {
|
||||
}
|
||||
|
||||
public static class BasicTest extends AlterTableTest {
|
||||
|
||||
public String name = "mytable";
|
||||
public DataType alteredType = DataType.text();
|
||||
public String altered = "altered";
|
||||
|
||||
public DataType addedType = DataType.text();
|
||||
public String added = "added";
|
||||
|
||||
public String dropped = "dropped";
|
||||
|
||||
public AlterTableSpecification specification() {
|
||||
return alterTable().name(name).alter(altered, alteredType).add(added, addedType).drop(dropped);
|
||||
}
|
||||
|
||||
public AlterTableCqlGenerator generator() {
|
||||
return new AlterTableCqlGenerator(specification);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
prepare();
|
||||
|
||||
assertPreamble(name, cql);
|
||||
assertColumnChanges(
|
||||
String.format("ALTER %s TYPE %s, ADD %s %s, DROP %s", altered, alteredType, added, addedType, dropped), cql);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
package org.springframework.cassandra.test.unit.core.cql.generator;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
import static org.springframework.cassandra.core.keyspace.MapBuilder.map;
|
||||
import static org.springframework.cassandra.core.keyspace.TableOperations.createTable;
|
||||
import static org.springframework.cassandra.core.keyspace.TableOption.BLOOM_FILTER_FP_CHANCE;
|
||||
import static org.springframework.cassandra.core.keyspace.TableOption.CACHING;
|
||||
import static org.springframework.cassandra.core.keyspace.TableOption.COMMENT;
|
||||
import static org.springframework.cassandra.core.keyspace.TableOption.COMPACTION;
|
||||
import static org.springframework.cassandra.core.keyspace.TableOption.CompactionOption.TOMBSTONE_THRESHOLD;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.cassandra.core.cql.generator.CreateTableCqlGenerator;
|
||||
import org.springframework.cassandra.core.keyspace.CreateTableSpecification;
|
||||
import org.springframework.cassandra.core.keyspace.TableOption.CachingOption;
|
||||
|
||||
import com.datastax.driver.core.DataType;
|
||||
|
||||
public class CreateTableCqlGeneratorTest {
|
||||
|
||||
@Test
|
||||
public void createTableTest() {
|
||||
String name = "my\"\"table";
|
||||
DataType type0 = DataType.text();
|
||||
String partKey0 = "partitionKey0";
|
||||
String partition1 = "partitionKey1";
|
||||
String primary0 = "primary0";
|
||||
DataType type1 = DataType.text();
|
||||
String column1 = "column1";
|
||||
DataType type2 = DataType.bigint();
|
||||
String column2 = "column2";
|
||||
Object comment = "this is a comment";
|
||||
Object bloom = "0.00075";
|
||||
Object caching = CachingOption.KEYS_ONLY;
|
||||
|
||||
CreateTableSpecification create = createTable().ifNotExists().name(name).partitionKeyColumn(partKey0, type0)
|
||||
.partitionKeyColumn(partition1, type0).primaryKeyColumn(primary0, type0).column(column1, type1)
|
||||
.column(column2, type2).with(COMMENT, comment).with(BLOOM_FILTER_FP_CHANCE, bloom)
|
||||
.with(COMPACTION, map().entry(TOMBSTONE_THRESHOLD, "0.15")).with(CACHING, caching);
|
||||
|
||||
CreateTableCqlGenerator generator = new CreateTableCqlGenerator(create);
|
||||
String cql = generator.toCql();
|
||||
assertEquals(
|
||||
"CREATE TABLE IF NOT EXISTS \"my\"\"table\" (partitionKey0 text, partitionKey1 text, primary0 text, column1 text, column2 bigint, PRIMARY KEY ((partitionKey0, partitionKey1), primary0) WITH CLUSTERING ORDER BY (primary0 ASC) AND comment = 'this is a comment' AND bloom_filter_fp_chance = 0.00075 AND compaction = { 'tombstone_threshold' : 0.15 } AND caching = keys_only;",
|
||||
cql);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package org.springframework.cassandra.test.unit.core.cql.generator;
|
||||
|
||||
import static junit.framework.Assert.assertTrue;
|
||||
import static org.springframework.cassandra.core.keyspace.TableOperations.createTable;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.cassandra.core.cql.generator.CreateTableCqlGenerator;
|
||||
import org.springframework.cassandra.core.keyspace.CreateTableSpecification;
|
||||
|
||||
import com.datastax.driver.core.DataType;
|
||||
|
||||
public class CreateTableCqlGeneratorTests {
|
||||
|
||||
/**
|
||||
* Asserts that the preamble is first & correctly formatted in the given CQL string.
|
||||
*/
|
||||
public static void assertPreamble(String tableName, String cql) {
|
||||
assertTrue(cql.startsWith("CREATE TABLE " + tableName + " "));
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given primary key definition is contained in the given CQL string properly.
|
||||
*
|
||||
* @param primaryKeyString IE, "foo", "foo, bar, baz", "(foo, bar), baz", etc
|
||||
*/
|
||||
public static void assertPrimaryKey(String primaryKeyString, String cql) {
|
||||
assertTrue(cql.contains(", PRIMARY KEY (" + primaryKeyString + "))"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given list of columns definitions are contained in the given CQL string properly.
|
||||
*
|
||||
* @param columnSpec IE, "foo text, bar blob"
|
||||
*/
|
||||
public static void assertColumns(String columnSpec, String cql) {
|
||||
assertTrue(cql.contains("(" + columnSpec + ","));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenient base class that other test classes can use so as not to repeat the generics declarations.
|
||||
*/
|
||||
public static abstract class CreateTableTest extends
|
||||
TableOperationCqlGeneratorTest<CreateTableSpecification, CreateTableCqlGenerator> {
|
||||
}
|
||||
|
||||
public static class BasicTest extends CreateTableTest {
|
||||
|
||||
public String name = "mytable";
|
||||
public DataType partitionKeyType0 = DataType.text();
|
||||
public String partitionKey0 = "partitionKey0";
|
||||
public DataType columnType1 = DataType.text();
|
||||
public String column1 = "column1";
|
||||
|
||||
public CreateTableSpecification specification() {
|
||||
return createTable().name(name).partitionKeyColumn(partitionKey0, partitionKeyType0).column(column1, columnType1);
|
||||
}
|
||||
|
||||
public CreateTableCqlGenerator generator() {
|
||||
return new CreateTableCqlGenerator(specification);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
prepare();
|
||||
|
||||
assertPreamble(name, cql);
|
||||
assertColumns(partitionKey0 + " " + partitionKeyType0 + ", " + column1 + " " + columnType1, cql);
|
||||
assertPrimaryKey(partitionKey0, cql);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
package org.springframework.cassandra.test.unit.core.cql.generator;
|
||||
|
||||
import static org.springframework.cassandra.core.keyspace.TableOperations.dropTable;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.cassandra.core.cql.generator.DropTableCqlGenerator;
|
||||
import org.springframework.cassandra.core.keyspace.DropTableSpecification;
|
||||
|
||||
public class DropTableCqlGeneratorTest {
|
||||
|
||||
@Test
|
||||
public void testDropTableBuilder() throws Exception {
|
||||
DropTableSpecification drop = dropTable().ifExists().name("mytable");
|
||||
|
||||
DropTableCqlGenerator generator = new DropTableCqlGenerator(drop);
|
||||
System.out.println(generator.toCql());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package org.springframework.cassandra.test.unit.core.cql.generator;
|
||||
|
||||
import static junit.framework.Assert.assertTrue;
|
||||
import static org.springframework.cassandra.core.keyspace.TableOperations.dropTable;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.cassandra.core.cql.generator.DropTableCqlGenerator;
|
||||
import org.springframework.cassandra.core.keyspace.DropTableSpecification;
|
||||
|
||||
public class DropTableCqlGeneratorTests {
|
||||
|
||||
/**
|
||||
* Asserts that the preamble is first & correctly formatted in the given CQL string.
|
||||
*/
|
||||
public static void assertStatement(String tableName, String cql) {
|
||||
assertTrue(cql.equals("DROP TABLE " + tableName + ";"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given list of columns definitions are contained in the given CQL string properly.
|
||||
*
|
||||
* @param columnSpec IE, "foo text, bar blob"
|
||||
*/
|
||||
public static void assertColumnChanges(String columnSpec, String cql) {
|
||||
assertTrue(cql.contains(""));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenient base class that other test classes can use so as not to repeat the generics declarations.
|
||||
*/
|
||||
public static abstract class DropTableTest extends
|
||||
TableOperationCqlGeneratorTest<DropTableSpecification, DropTableCqlGenerator> {
|
||||
}
|
||||
|
||||
public static class BasicTest extends DropTableTest {
|
||||
|
||||
public String name = "mytable";
|
||||
|
||||
public DropTableSpecification specification() {
|
||||
return dropTable().name(name);
|
||||
}
|
||||
|
||||
public DropTableCqlGenerator generator() {
|
||||
return new DropTableCqlGenerator(specification);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
prepare();
|
||||
|
||||
assertStatement(name, cql);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package org.springframework.cassandra.test.unit.core.cql.generator;
|
||||
|
||||
import org.springframework.cassandra.core.cql.generator.TableNameCqlGenerator;
|
||||
import org.springframework.cassandra.core.keyspace.TableNameSpecification;
|
||||
|
||||
/**
|
||||
* Useful test class that specifies just about as much as you can for a CQL generation test. Intended to be extended by
|
||||
* classes that contain methods annotated with {@link Test}. Everything is public because this is a test class with no
|
||||
* need for encapsulation, and it makes for easier reuse in other tests like integration tests (hint hint).
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*
|
||||
* @param <S> The type of the {@link TableNameSpecification}
|
||||
* @param <G> The type of the {@link TableNameCqlGenerator}
|
||||
*/
|
||||
public abstract class TableOperationCqlGeneratorTest<S extends TableNameSpecification<?>, G extends TableNameCqlGenerator<?>> {
|
||||
|
||||
public abstract S specification();
|
||||
|
||||
public abstract G generator();
|
||||
|
||||
public String tableName;
|
||||
public S specification;
|
||||
public G generator;
|
||||
public String cql;
|
||||
|
||||
public void prepare() {
|
||||
this.specification = specification();
|
||||
this.generator = generator();
|
||||
this.cql = generateCql();
|
||||
}
|
||||
|
||||
public String generateCql() {
|
||||
return generator.toCql();
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
|
||||
|
||||
<context:property-placeholder
|
||||
location="classpath:/org/springframework/data/cassandra/config/cassandra.properties" />
|
||||
location="classpath:/org/springframework/data/cassandra/test/integration/config/cassandra.properties" />
|
||||
|
||||
<cassandra:cluster id="cassandra-cluster"
|
||||
contactPoints="${cassandra.contactPoints}" port="${cassandra.port}"
|
||||
|
||||
Reference in New Issue
Block a user