diff --git a/spring-cassandra/src/main/java/org/springframework/cassandra/core/CqlIdentifier.java b/spring-cassandra/src/main/java/org/springframework/cassandra/core/CqlIdentifier.java
deleted file mode 100644
index a48697dcb..000000000
--- a/spring-cassandra/src/main/java/org/springframework/cassandra/core/CqlIdentifier.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright 2013-2014 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.cassandra.core;
-
-import java.util.regex.Pattern;
-
-import org.springframework.cassandra.core.cql.CqlStringUtils;
-
-/**
- * This encapsulates the logic for CQL identifiers.
- *
- * @author John McPeek
- *
- */
-public class CqlIdentifier {
- public static final String UNQUOTED_IDENTIFIER_REGEX = "[a-zA-Z_][a-zA-Z0-9_]*";
- public static final Pattern UNQUOTED_IDENTIFIER_PATTERN = Pattern.compile(UNQUOTED_IDENTIFIER_REGEX);
- public static final String QUOTED_IDENTIFIER_REGEX = "[a-zA-Z_]([a-zA-Z0-9_]|\"{2}+)*";
- public static final Pattern QUOTED_IDENTIFIER_PATTERN = Pattern.compile(QUOTED_IDENTIFIER_REGEX);
-
- private String name;
- private boolean quoted;
-
- public CqlIdentifier(String identifier) {
- this(identifier, false);
- }
-
- /**
- * Renders the given string as a legal Cassandra identifier.
- *
- *
If the given identifier is a legal quoted identifier or forceQuote is true, it is set encased in double quotes.
- *
- *
If the given identifier is a legal unquoted identifier, it is set unchanged.
- *
If the given identifier is illegal, an {@link IllegalArgumentException} is thrown.
- *
- */
- public CqlIdentifier(String name, boolean forceQuoting) {
- if (isUnquotedIdentifier(name) && forceQuoting == false) {
- this.name = name;
- } else if (isQuotedIdentifier(name)) {
- this.name = name;
- quoted = true;
- } else {
- throw new IllegalArgumentException("[" + name + "] is not a valid CQL quoted or unquoted identifier");
- }
- }
-
- public String toCql() {
- String id = quoted ? CqlStringUtils.doubleQuote(name) : name;
- return id;
- }
-
- public StringBuilder toCql(StringBuilder sb) {
- return sb.append(toCql());
- }
-
- @Override
- public String toString() {
- return toCql();
- }
-
- public String getName() {
- return name;
- }
-
- public boolean isQuoted() {
- return quoted;
- }
-
- public static CqlIdentifier cqlId(String identifier) {
- CqlIdentifier id = new CqlIdentifier(identifier);
- return id;
- }
-
- public static CqlIdentifier quotedCqlId(String identifier) {
- CqlIdentifier id = new CqlIdentifier(identifier, true);
- return id;
- }
-
- public static boolean isIdentifier(CharSequence chars) {
- return isUnquotedIdentifier(chars) || isQuotedIdentifier(chars);
- }
-
- public static boolean isUnquotedIdentifier(CharSequence chars) {
- return UNQUOTED_IDENTIFIER_PATTERN.matcher(chars).matches();
- }
-
- public static boolean isQuotedIdentifier(CharSequence chars) {
- return QUOTED_IDENTIFIER_PATTERN.matcher(chars).matches();
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((name == null) ? 0 : name.hashCode());
- result = prime * result + (quoted ? 1231 : 1237);
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- CqlIdentifier other = (CqlIdentifier) obj;
- if (name == null) {
- if (other.name != null)
- return false;
- } else if (!name.equals(other.name))
- return false;
- if (quoted != other.quoted)
- return false;
- return true;
- }
-}
diff --git a/spring-cassandra/src/main/java/org/springframework/cassandra/core/ReservedKeyword.java b/spring-cassandra/src/main/java/org/springframework/cassandra/core/ReservedKeyword.java
new file mode 100644
index 000000000..1b623552d
--- /dev/null
+++ b/spring-cassandra/src/main/java/org/springframework/cassandra/core/ReservedKeyword.java
@@ -0,0 +1,41 @@
+package org.springframework.cassandra.core;
+
+import org.springframework.util.Assert;
+import org.springframework.util.StringUtils;
+
+/**
+ * CQL keywords.
+ *
+ * @see http://cassandra.apache.org/doc/cql3/CQL.html#appendixA
+ *
+ * @author Matthew T. Adams
+ */
+public enum ReservedKeyword {
+ ADD, ALTER, AND, ANY, APPLY, ASC, AUTHORIZE, BATCH, BEGIN, BY, COLUMNFAMILY, CREATE, DELETE, DESC, DROP, EACH_QUORUM, FROM, GRANT, IN, INDEX, INSERT, INTO, KEYSPACE, LIMIT, LOCAL_ONE, LOCAL_QUORUM, MODIFY, NORECURSIVE, OF, ON, ONE, ORDER, PRIMARY, QUORUM, REVOKE, SCHEMA, SELECT, SET, TABLE, THREE, TOKEN, TRUNCATE, TWO, UPDATE, USE, USING, WHERE, WITH;
+
+ /**
+ * @see ReservedKeyword#isReserved(String)
+ */
+ public static boolean isReserved(CharSequence candidate) {
+ Assert.notNull(candidate);
+ return isReserved(candidate.toString());
+ }
+
+ /**
+ * Returns whether the given string is a CQL reserved keyword. This comparison is done regardless of case.
+ */
+ public static boolean isReserved(String candidate) {
+
+ if (!StringUtils.hasText(candidate)) {
+ return false;
+ }
+
+ try {
+ Enum.valueOf(ReservedKeyword.class, candidate.toUpperCase());
+ return true;
+ } catch (IllegalArgumentException x) {
+ return false;
+ }
+ }
+}
diff --git a/spring-cassandra/src/main/java/org/springframework/cassandra/core/cql/CqlConstantType.java b/spring-cassandra/src/main/java/org/springframework/cassandra/core/cql/CqlConstantType.java
new file mode 100644
index 000000000..9fea872e3
--- /dev/null
+++ b/spring-cassandra/src/main/java/org/springframework/cassandra/core/cql/CqlConstantType.java
@@ -0,0 +1,41 @@
+package org.springframework.cassandra.core.cql;
+
+import static org.springframework.cassandra.core.cql.CqlConstantType.Regex.*;
+import java.util.regex.Pattern;
+
+public enum CqlConstantType {
+
+ STRING(STRING_PATTERN), INTEGER(INTEGER_PATTERN), FLOAT(FLOAT_PATTERN), BOOLEAN(BOOLEAN_PATTERN), UUID(UUID_PATTERN), BLOB(
+ BLOB_PATTERN);
+
+ private Pattern pattern;
+
+ private CqlConstantType(Pattern pattern) {
+ this.pattern = pattern;
+ }
+
+ public boolean matches(CharSequence candidate) {
+ return pattern.matcher(candidate).matches();
+ }
+
+ public static class Regex {
+
+ public static final String STRING_REGEX = "'((?:[^']+|'')*)'";
+ public static final Pattern STRING_PATTERN = Pattern.compile(STRING_REGEX);
+
+ public static final String INTEGER_REGEX = "\\-?[0-9]+";
+ public static final Pattern INTEGER_PATTERN = Pattern.compile(INTEGER_REGEX);
+
+ public static final String FLOAT_REGEX = "(\\-?[0-9]+(\\.[0-9]*)?([eE][+-]?[0-9+])?)|NaN|Infinity";
+ public static final Pattern FLOAT_PATTERN = Pattern.compile(FLOAT_REGEX);
+
+ public static final String BOOLEAN_REGEX = "(?i)true|false";
+ public static final Pattern BOOLEAN_PATTERN = Pattern.compile(BOOLEAN_REGEX);
+
+ public static final String UUID_REGEX = "(?i)[0-9a-f]{8}+\\-[0-9a-f]{4}+\\-[0-9a-f]{4}+\\-[0-9a-f]{4}+\\-[0-9a-f]{12}+";
+ public static final Pattern UUID_PATTERN = Pattern.compile(UUID_REGEX);
+
+ public static final String BLOB_REGEX = "(?i)0[x](0-9a-f)+";
+ public static final Pattern BLOB_PATTERN = Pattern.compile(BLOB_REGEX);
+ }
+}
\ No newline at end of file
diff --git a/spring-cassandra/src/main/java/org/springframework/cassandra/core/cql/CqlIdentifier.java b/spring-cassandra/src/main/java/org/springframework/cassandra/core/cql/CqlIdentifier.java
new file mode 100644
index 000000000..393e8508b
--- /dev/null
+++ b/spring-cassandra/src/main/java/org/springframework/cassandra/core/cql/CqlIdentifier.java
@@ -0,0 +1,202 @@
+package org.springframework.cassandra.core.cql;
+
+import java.util.regex.Pattern;
+
+import org.springframework.cassandra.core.ReservedKeyword;
+import org.springframework.util.Assert;
+
+import com.datastax.driver.core.KeyspaceMetadata;
+import com.datastax.driver.core.TableMetadata;
+
+/**
+ * This encapsulates the logic for CQL quoted and unquoted identifiers.
+ *
+ * CQL identifiers, when unquoted, are converted to lower case. When quoted, they are returned as-is with no lower
+ * casing and encased in double quotes. To render, use any of the methods {@link #toCql()},
+ * {@link #toCql(StringBuilder)}, or {@link #toString()}.
+ *
+ * @see #CqlIdentifier(String)
+ * @see #CqlIdentifier(String, boolean)
+ * @see #toCql()
+ * @see #toCql(StringBuilder)
+ * @see #toString()
+ *
+ * @author John McPeek
+ * @author Matthew T. Adams
+ */
+public final class CqlIdentifier implements Comparable {
+
+ public static final String UNQUOTED_REGEX = "(?i)[a-z][\\w]*";
+ public static final Pattern UNQUOTED = Pattern.compile(UNQUOTED_REGEX);
+
+ public static final String QUOTED_REGEX = "(?i)[a-z]([\\w]*(\"\")+[\\w]*)+";
+ public static final Pattern QUOTED = Pattern.compile(QUOTED_REGEX);
+
+ /**
+ * Factory method for {@link CqlIdentifier}. Convenient if imported statically.
+ *
+ * @see #CqlIdentifier(String)
+ */
+ public static CqlIdentifier cqlId(CharSequence identifier) {
+ return new CqlIdentifier(identifier);
+ }
+
+ /**
+ * Factory method for a force-quoted {@link CqlIdentifier}. Convenient if imported statically.
+ *
+ * @see #CqlIdentifier(String, boolean)
+ */
+ public static CqlIdentifier quotedCqlId(CharSequence identifier) {
+ return new CqlIdentifier(identifier, true);
+ }
+
+ /**
+ * Returns true if the given {@link CharSequence} is a legal unquoted identifier.
+ */
+ public static boolean isUnquotedIdentifier(CharSequence chars) {
+ return UNQUOTED.matcher(chars).matches() && !ReservedKeyword.isReserved(chars);
+ }
+
+ /**
+ * Returns true if the given {@link CharSequence} is a legal unquoted identifier.
+ */
+ public static boolean isQuotedIdentifier(CharSequence chars) {
+ return QUOTED.matcher(chars).matches() || ReservedKeyword.isReserved(chars);
+ }
+
+ private String identifier;
+ private String unquoted;
+ private boolean quoted;
+
+ /**
+ * Creates a new {@link CqlIdentifier} without force-quoting it. It may end up quoted, depending on its value.
+ *
+ * @see #cqlId(String)
+ */
+ public CqlIdentifier(CharSequence identifier) {
+ this(identifier, false);
+ }
+
+ /**
+ * Creates a new CQL identifier, optionally force-quoting it. Force-quoting can be used to preserve identifier case.
+ *
+ *
If the given identifier is a legal quoted identifier or forceQuote is true,
+ * {@link #isQuoted()} will return true and the identifier will be quoted when rendered.
+ *
If the given identifier is a legal unquoted identifier, {@link #isQuoted()} will return false,
+ * plus the name will be converted to lower case and rendered as such.
+ *
If the given identifier is illegal, an {@link IllegalArgumentException} is thrown.
+ *
+ *
+ * @see #cqlId(String)
+ * @see #quotedCqlId(String)
+ */
+ public CqlIdentifier(CharSequence identifier, boolean forceQuote) {
+ setIdentifier(identifier, forceQuote);
+ }
+
+ /**
+ * Tests & sets the given identifier.
+ */
+ private void setIdentifier(CharSequence identifier, boolean forceQuoting) {
+
+ Assert.notNull(identifier);
+
+ String string = identifier.toString();
+ Assert.hasText(string);
+
+ if (forceQuoting || isQuotedIdentifier(string)) {
+ this.unquoted = string;
+ this.identifier = "\"" + string + "\"";
+ quoted = true;
+ } else if (isUnquotedIdentifier(string)) {
+ this.identifier = this.unquoted = string.toLowerCase();
+ } else {
+ throw new IllegalArgumentException(String.format(
+ "given string [%s] is not a valid quoted or unquoted identifier", identifier));
+ }
+ }
+
+ /**
+ * Returns the identifier without encasing quotes, regardless of the value of {@link #isQuoted()}. For
+ * example, if {@link #isQuoted()} is true, then this value will be the same as {@link #toCql()} and
+ * {@link #toString()}.
+ *
+ * This is needed, for example, to get the correct {@link TableMetadata} from
+ * {@link KeyspaceMetadata#getTable(String)}: the given string must not be quoted.
+ */
+ public String getUnquoted() {
+ return unquoted;
+ }
+
+ /**
+ * Renders this identifier appropriately.
+ */
+ public String toCql() {
+ return identifier;
+ }
+
+ /**
+ * Appends the rendering of this identifier to the given {@link StringBuilder}, then returns that
+ * {@link StringBuilder}. If null is given, a new {@link StringBuilder} is created, appended to, and
+ * returned.
+ */
+ public StringBuilder toCql(StringBuilder sb) {
+ sb = sb == null ? new StringBuilder() : sb;
+ return sb.append(toCql());
+ }
+
+ /**
+ * Alias for {@link #toCql()}.
+ */
+ @Override
+ public String toString() {
+ return toCql();
+ }
+
+ /**
+ * Whether or not this identifier is quoted.
+ */
+ public boolean isQuoted() {
+ return quoted;
+ }
+
+ @Override
+ public int hashCode() {
+ return ((Boolean) quoted).hashCode() ^ identifier.hashCode();
+ }
+
+ /**
+ * Compares this {@link CqlIdentifier} to the given object. Note that if a {@link CharSequence} is given, a new
+ * {@link CqlIdentifier} is created from it and compared, such that a {@link CharSequence} can be effectively equal to
+ * a {@link CqlIdentifier}.
+ */
+ @Override
+ public boolean equals(Object that) {
+ if (this == that) {
+ return true;
+ }
+ if (that == null) {
+ return false;
+ }
+ if (!(that instanceof CqlIdentifier) && !(that instanceof CharSequence)) {
+ return false;
+ }
+
+ CqlIdentifier other = (that instanceof CqlIdentifier) ? (CqlIdentifier) that : cqlId((CharSequence) that);
+
+ return this.quoted == other.quoted && this.identifier.equals(other.identifier);
+ }
+
+ /**
+ * Unquoted identifiers sort before quoted ones. Otherwise, they compare according to their identifiers.
+ */
+ @Override
+ public int compareTo(CqlIdentifier that) {
+
+ int comparison = ((Boolean) this.quoted).compareTo(that.quoted);
+ if (comparison != 0) {
+ return comparison;
+ }
+ return this.identifier.compareTo(that.identifier);
+ }
+}
diff --git a/spring-cassandra/src/main/java/org/springframework/cassandra/core/cql/CqlStringUtils.java b/spring-cassandra/src/main/java/org/springframework/cassandra/core/cql/CqlStringUtils.java
index db4255afa..59670fce3 100644
--- a/spring-cassandra/src/main/java/org/springframework/cassandra/core/cql/CqlStringUtils.java
+++ b/spring-cassandra/src/main/java/org/springframework/cassandra/core/cql/CqlStringUtils.java
@@ -15,8 +15,6 @@
*/
package org.springframework.cassandra.core.cql;
-import java.util.regex.Pattern;
-
import com.datastax.driver.core.DataType;
public class CqlStringUtils {
@@ -33,9 +31,6 @@ public class CqlStringUtils {
return sb == null ? new StringBuilder() : sb;
}
- public static final String UNESCAPED_DOUBLE_QUOTE_REGEX = "TODO";
- public static final Pattern UNESCAPED_DOUBLE_QUOTE_PATTERN = Pattern.compile(UNESCAPED_DOUBLE_QUOTE_REGEX);
-
/**
* Renders the given string as a legal Cassandra string column or table option value, by escaping single quotes and
* encasing the result in single quotes. Given null, returns null.
@@ -51,15 +46,15 @@ public class CqlStringUtils {
/**
* Doubles single quote characters (' -> ''). Given null, returns null.
*/
- public static String escapeSingle(Object things) {
- return things == null ? (String) null : things.toString().replace(SINGLE_QUOTE, DOUBLE_SINGLE_QUOTE);
+ public static String escapeSingle(Object thing) {
+ return thing == null ? (String) null : thing.toString().replace(SINGLE_QUOTE, DOUBLE_SINGLE_QUOTE);
}
/**
* Doubles double quote characters (" -> ""). Given null, returns null.
*/
- public static String escapeDouble(Object things) {
- return things == null ? (String) null : things.toString().replace(DOUBLE_QUOTE, DOUBLE_DOUBLE_QUOTE);
+ public static String escapeDouble(Object thing) {
+ return thing == null ? (String) null : thing.toString().replace(DOUBLE_QUOTE, DOUBLE_DOUBLE_QUOTE);
}
/**
@@ -116,4 +111,21 @@ public class CqlStringUtils {
return s.append(TYPE_PARAMETER_SUFFIX).toString();
}
+
+ public static String unquote(String s) {
+ return unquote(s, "\"");
+ }
+
+ public static String unquote(String s, String quoteChar) {
+ if (s == null) {
+ return s;
+ }
+ if (!s.startsWith(quoteChar) || !s.endsWith(quoteChar)) {
+ return s;
+ }
+ if (s.length() <= 2) {
+ return s;
+ }
+ return s.substring(1, s.length() - 1);
+ }
}
diff --git a/spring-cassandra/src/main/java/org/springframework/cassandra/core/cql/generator/AddColumnCqlGenerator.java b/spring-cassandra/src/main/java/org/springframework/cassandra/core/cql/generator/AddColumnCqlGenerator.java
index 0801e8f5c..2849ab6ad 100644
--- a/spring-cassandra/src/main/java/org/springframework/cassandra/core/cql/generator/AddColumnCqlGenerator.java
+++ b/spring-cassandra/src/main/java/org/springframework/cassandra/core/cql/generator/AddColumnCqlGenerator.java
@@ -30,8 +30,8 @@ public class AddColumnCqlGenerator extends ColumnChangeCqlGenerator {
+ /**
+ * Entry point into the {@link AlterTableSpecification}'s fluent API to alter a table. Convenient if imported
+ * statically.
+ */
+ public static AlterTableSpecification alterTable() {
+ return new AlterTableSpecification();
+ }
+
/**
* The list of column changes.
*/
@@ -65,12 +73,4 @@ public class AlterTableSpecification extends TableOptionsSpecification getChanges() {
return Collections.unmodifiableList(changes);
}
-
- /**
- * Entry point into the {@link AlterTableSpecification}'s fluent API to alter a table. Convenient if imported
- * statically.
- */
- public static AlterTableSpecification alterTable() {
- return new AlterTableSpecification();
- }
}
diff --git a/spring-cassandra/src/main/java/org/springframework/cassandra/core/keyspace/ColumnChangeSpecification.java b/spring-cassandra/src/main/java/org/springframework/cassandra/core/keyspace/ColumnChangeSpecification.java
index 7b90158f9..5650de65a 100644
--- a/spring-cassandra/src/main/java/org/springframework/cassandra/core/keyspace/ColumnChangeSpecification.java
+++ b/spring-cassandra/src/main/java/org/springframework/cassandra/core/keyspace/ColumnChangeSpecification.java
@@ -15,7 +15,10 @@
*/
package org.springframework.cassandra.core.keyspace;
-import org.springframework.cassandra.core.CqlIdentifier;
+import static org.springframework.cassandra.core.cql.CqlIdentifier.cqlId;
+
+import org.springframework.cassandra.core.cql.CqlIdentifier;
+import org.springframework.util.Assert;
/**
* Base class for column change specifications.
@@ -24,21 +27,22 @@ import org.springframework.cassandra.core.CqlIdentifier;
*/
public abstract class ColumnChangeSpecification {
- private CqlIdentifier identifier;
+ protected CqlIdentifier name;
- public ColumnChangeSpecification(String name) {
+ protected ColumnChangeSpecification(String name) {
+ this(cqlId(name));
+ }
+
+ protected ColumnChangeSpecification(CqlIdentifier name) {
setName(name);
}
- private void setName(String name) {
- identifier = new CqlIdentifier(name);
+ protected void setName(CqlIdentifier name) {
+ Assert.notNull(name);
+ this.name = name;
}
- public String getName() {
- return identifier.getName();
- }
-
- public String getNameAsIdentifier() {
- return identifier.toCql();
+ public CqlIdentifier getName() {
+ return name;
}
}
diff --git a/spring-cassandra/src/main/java/org/springframework/cassandra/core/keyspace/ColumnSpecification.java b/spring-cassandra/src/main/java/org/springframework/cassandra/core/keyspace/ColumnSpecification.java
index abb7f40d4..6be13d7d1 100644
--- a/spring-cassandra/src/main/java/org/springframework/cassandra/core/keyspace/ColumnSpecification.java
+++ b/spring-cassandra/src/main/java/org/springframework/cassandra/core/keyspace/ColumnSpecification.java
@@ -18,11 +18,13 @@ package org.springframework.cassandra.core.keyspace;
import static org.springframework.cassandra.core.Ordering.ASCENDING;
import static org.springframework.cassandra.core.PrimaryKeyType.CLUSTERED;
import static org.springframework.cassandra.core.PrimaryKeyType.PARTITIONED;
+import static org.springframework.cassandra.core.cql.CqlIdentifier.cqlId;
import static org.springframework.cassandra.core.cql.CqlStringUtils.noNull;
-import org.springframework.cassandra.core.CqlIdentifier;
import org.springframework.cassandra.core.Ordering;
import org.springframework.cassandra.core.PrimaryKeyType;
+import org.springframework.cassandra.core.cql.CqlIdentifier;
+import org.springframework.util.Assert;
import com.datastax.driver.core.DataType;
@@ -44,7 +46,7 @@ public class ColumnSpecification {
*/
public static final Ordering DEFAULT_ORDERING = ASCENDING;
- private CqlIdentifier identifier;
+ private CqlIdentifier name;
private DataType type; // TODO: determining if we should be coupling this to Datastax Java Driver type?
private PrimaryKeyType keyType;
private Ordering ordering;
@@ -55,7 +57,12 @@ public class ColumnSpecification {
* @return this
*/
public ColumnSpecification name(String name) {
- identifier = new CqlIdentifier(name);
+ return name(cqlId(name));
+ }
+
+ public ColumnSpecification name(CqlIdentifier name) {
+ Assert.notNull(name);
+ this.name = name;
return this;
}
@@ -130,7 +137,7 @@ public class ColumnSpecification {
*
* @return this
*/
- /* package */ColumnSpecification keyType(PrimaryKeyType keyType) {
+ ColumnSpecification keyType(PrimaryKeyType keyType) {
this.keyType = keyType;
return this;
}
@@ -140,17 +147,13 @@ public class ColumnSpecification {
*
* @return this
*/
- /* package */ColumnSpecification ordering(Ordering ordering) {
+ ColumnSpecification ordering(Ordering ordering) {
this.ordering = ordering;
return this;
}
- public String getName() {
- return identifier.getName();
- }
-
- public String getNameAsIdentifier() {
- return identifier.toCql();
+ public CqlIdentifier getName() {
+ return name;
}
public DataType getType() {
@@ -170,7 +173,7 @@ public class ColumnSpecification {
}
public StringBuilder toCql(StringBuilder cql) {
- return (cql = noNull(cql)).append(identifier).append(" ").append(type);
+ return (cql = noNull(cql)).append(name).append(" ").append(type);
}
@Override
diff --git a/spring-cassandra/src/main/java/org/springframework/cassandra/core/keyspace/ColumnTypeChangeSpecification.java b/spring-cassandra/src/main/java/org/springframework/cassandra/core/keyspace/ColumnTypeChangeSpecification.java
index 8ee28b58c..185e1d644 100644
--- a/spring-cassandra/src/main/java/org/springframework/cassandra/core/keyspace/ColumnTypeChangeSpecification.java
+++ b/spring-cassandra/src/main/java/org/springframework/cassandra/core/keyspace/ColumnTypeChangeSpecification.java
@@ -15,6 +15,9 @@
*/
package org.springframework.cassandra.core.keyspace;
+import static org.springframework.cassandra.core.cql.CqlIdentifier.cqlId;
+
+import org.springframework.cassandra.core.cql.CqlIdentifier;
import org.springframework.util.Assert;
import com.datastax.driver.core.DataType;
@@ -29,6 +32,10 @@ public abstract class ColumnTypeChangeSpecification extends ColumnChangeSpecific
private DataType type;
public ColumnTypeChangeSpecification(String name, DataType type) {
+ this(cqlId(name), type);
+ }
+
+ public ColumnTypeChangeSpecification(CqlIdentifier name, DataType type) {
super(name);
setType(type);
}
diff --git a/spring-cassandra/src/main/java/org/springframework/cassandra/core/keyspace/CreateIndexSpecification.java b/spring-cassandra/src/main/java/org/springframework/cassandra/core/keyspace/CreateIndexSpecification.java
index d00437cd4..70afabf8c 100644
--- a/spring-cassandra/src/main/java/org/springframework/cassandra/core/keyspace/CreateIndexSpecification.java
+++ b/spring-cassandra/src/main/java/org/springframework/cassandra/core/keyspace/CreateIndexSpecification.java
@@ -15,7 +15,10 @@
*/
package org.springframework.cassandra.core.keyspace;
-import org.springframework.cassandra.core.CqlIdentifier;
+import static org.springframework.cassandra.core.cql.CqlIdentifier.cqlId;
+
+import org.springframework.cassandra.core.cql.CqlIdentifier;
+import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
@@ -27,10 +30,18 @@ import org.springframework.util.StringUtils;
public class CreateIndexSpecification extends IndexNameSpecification implements
IndexDescriptor {
+ /**
+ * Entry point into the {@link CreateIndexSpecification}'s fluent API to create a index. Convenient if imported
+ * statically.
+ */
+ public static CreateIndexSpecification createIndex() {
+ return new CreateIndexSpecification();
+ }
+
private boolean ifNotExists = false;
private boolean custom = false;
- private CqlIdentifier identifier;
- private String columnName;
+ private CqlIdentifier tableName;
+ private CqlIdentifier columnName;
private String using;
/**
@@ -56,6 +67,7 @@ public class CreateIndexSpecification extends IndexNameSpecification {
+ /**
+ * Entry point into the {@link CreateKeyspaceSpecification}'s fluent API to create a keyspace. Convenient if imported
+ * statically.
+ */
+ public static CreateKeyspaceSpecification createKeyspace() {
+ return new CreateKeyspaceSpecification();
+ }
+
private boolean ifNotExists = false;
/**
@@ -46,14 +55,6 @@ public class CreateKeyspaceSpecification extends KeyspaceSpecification {
+ /**
+ * Entry point into the {@link CreateTableSpecification}'s fluent API to create a table. Convenient if imported
+ * statically.
+ */
+ public static CreateTableSpecification createTable() {
+ return new CreateTableSpecification();
+ }
+
private boolean ifNotExists = false;
/**
@@ -52,14 +60,6 @@ public class CreateTableSpecification extends TableSpecification The subtype of the {@link IndexNameSpecification}
*
* @author David Webb
- * @param The subtype of the {@link IndexNameSpecification}
+ * @author Matthew T. Adams
*/
public abstract class IndexNameSpecification> {
/**
* The name of the index.
*/
- private CqlIdentifier identifier;
+ private CqlIdentifier name;
/**
* Sets the index name.
*
* @return this
*/
- @SuppressWarnings("unchecked")
public T name(String name) {
- identifier = new CqlIdentifier(name);
+ return name(cqlId(name));
+ }
+
+ @SuppressWarnings("unchecked")
+ public T name(CqlIdentifier name) {
+ Assert.notNull(name);
+ this.name = name;
return (T) this;
}
- public String getName() {
- return identifier.getName();
+ public CqlIdentifier getName() {
+ return name;
}
-
- public String getNameAsIdentifier() {
- return identifier.toCql();
- }
-
}
diff --git a/spring-cassandra/src/main/java/org/springframework/cassandra/core/keyspace/KeyspaceActionSpecification.java b/spring-cassandra/src/main/java/org/springframework/cassandra/core/keyspace/KeyspaceActionSpecification.java
index 62afe9249..74796b1cb 100644
--- a/spring-cassandra/src/main/java/org/springframework/cassandra/core/keyspace/KeyspaceActionSpecification.java
+++ b/spring-cassandra/src/main/java/org/springframework/cassandra/core/keyspace/KeyspaceActionSpecification.java
@@ -15,7 +15,10 @@
*/
package org.springframework.cassandra.core.keyspace;
-import org.springframework.cassandra.core.CqlIdentifier;
+import static org.springframework.cassandra.core.cql.CqlIdentifier.cqlId;
+
+import org.springframework.cassandra.core.cql.CqlIdentifier;
+import org.springframework.util.Assert;
/**
* Abstract builder class to support the construction of keyspace specifications.
@@ -29,7 +32,16 @@ public abstract class KeyspaceActionSpecification thatSpec = (KeyspaceActionSpecification>) that;
- return this.identifier.equals(thatSpec.identifier) && this.getClass().equals(that.getClass());
+ KeyspaceActionSpecification> other = (KeyspaceActionSpecification>) that;
+ return this.name.equals(other.name) && this.getClass().equals(that.getClass());
}
@Override
public int hashCode() {
- return this.identifier.hashCode() ^ this.getClass().hashCode();
+ return name.hashCode() ^ getClass().hashCode();
}
-
}
diff --git a/spring-cassandra/src/main/java/org/springframework/cassandra/core/keyspace/KeyspaceDescriptor.java b/spring-cassandra/src/main/java/org/springframework/cassandra/core/keyspace/KeyspaceDescriptor.java
index c8b68716e..f2a3b959f 100644
--- a/spring-cassandra/src/main/java/org/springframework/cassandra/core/keyspace/KeyspaceDescriptor.java
+++ b/spring-cassandra/src/main/java/org/springframework/cassandra/core/keyspace/KeyspaceDescriptor.java
@@ -17,6 +17,8 @@ package org.springframework.cassandra.core.keyspace;
import java.util.Map;
+import org.springframework.cassandra.core.cql.CqlIdentifier;
+
/**
* Describes a Keyspace.
*
@@ -27,12 +29,7 @@ public interface KeyspaceDescriptor {
/**
* Returns the name of the table.
*/
- String getName();
-
- /**
- * Returns the name of the table as an identifier or quoted identifier as appropriate.
- */
- String getNameAsIdentifier();
+ CqlIdentifier getName();
/**
* Returns an unmodifiable {@link Map} of keyspace options.
diff --git a/spring-cassandra/src/main/java/org/springframework/cassandra/core/keyspace/KeyspaceOptionsSpecification.java b/spring-cassandra/src/main/java/org/springframework/cassandra/core/keyspace/KeyspaceOptionsSpecification.java
index bb8a7a22d..a5458edd5 100644
--- a/spring-cassandra/src/main/java/org/springframework/cassandra/core/keyspace/KeyspaceOptionsSpecification.java
+++ b/spring-cassandra/src/main/java/org/springframework/cassandra/core/keyspace/KeyspaceOptionsSpecification.java
@@ -42,6 +42,7 @@ public abstract class KeyspaceOptionsSpecification options = new LinkedHashMap();
+ @Override
@SuppressWarnings("unchecked")
public T name(String name) {
return (T) super.name(name);
@@ -68,7 +69,7 @@ public abstract class KeyspaceOptionsSpecification getOptions() {
return Collections.unmodifiableMap(options);
}
-
}
diff --git a/spring-cassandra/src/main/java/org/springframework/cassandra/core/keyspace/KeyspaceSpecification.java b/spring-cassandra/src/main/java/org/springframework/cassandra/core/keyspace/KeyspaceSpecification.java
index 61b507228..79234dca9 100644
--- a/spring-cassandra/src/main/java/org/springframework/cassandra/core/keyspace/KeyspaceSpecification.java
+++ b/spring-cassandra/src/main/java/org/springframework/cassandra/core/keyspace/KeyspaceSpecification.java
@@ -20,6 +20,7 @@ package org.springframework.cassandra.core.keyspace;
* as a standalone {@link KeyspaceDescriptor}, independent of {@link CreateKeyspaceSpecification}.
*
* @author John McPeek
+ * @author Matthew T. Adams
*/
public class KeyspaceSpecification extends KeyspaceOptionsSpecification> implements
KeyspaceDescriptor {
diff --git a/spring-cassandra/src/main/java/org/springframework/cassandra/core/keyspace/TableDescriptor.java b/spring-cassandra/src/main/java/org/springframework/cassandra/core/keyspace/TableDescriptor.java
index fb23df778..0018ceed6 100644
--- a/spring-cassandra/src/main/java/org/springframework/cassandra/core/keyspace/TableDescriptor.java
+++ b/spring-cassandra/src/main/java/org/springframework/cassandra/core/keyspace/TableDescriptor.java
@@ -18,6 +18,8 @@ package org.springframework.cassandra.core.keyspace;
import java.util.List;
import java.util.Map;
+import org.springframework.cassandra.core.cql.CqlIdentifier;
+
/**
* Describes a table.
*
@@ -29,12 +31,7 @@ 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();
+ CqlIdentifier getName();
/**
* Returns an unmodifiable {@link List} of {@link ColumnSpecification}s.
diff --git a/spring-cassandra/src/main/java/org/springframework/cassandra/core/keyspace/TableNameSpecification.java b/spring-cassandra/src/main/java/org/springframework/cassandra/core/keyspace/TableNameSpecification.java
index d48914a71..fa98c2f63 100644
--- a/spring-cassandra/src/main/java/org/springframework/cassandra/core/keyspace/TableNameSpecification.java
+++ b/spring-cassandra/src/main/java/org/springframework/cassandra/core/keyspace/TableNameSpecification.java
@@ -15,7 +15,10 @@
*/
package org.springframework.cassandra.core.keyspace;
-import org.springframework.cassandra.core.CqlIdentifier;
+import static org.springframework.cassandra.core.cql.CqlIdentifier.cqlId;
+
+import org.springframework.cassandra.core.cql.CqlIdentifier;
+import org.springframework.util.Assert;
/**
* Abstract builder class to support the construction of table specifications.
@@ -28,24 +31,25 @@ public abstract class TableNameSpecification
/**
* The name of the table.
*/
- private CqlIdentifier identifier;
+ private CqlIdentifier name;
/**
* Sets the table name.
*
* @return this
*/
- @SuppressWarnings("unchecked")
public T name(String name) {
- identifier = new CqlIdentifier(name);
+ return name(cqlId(name));
+ }
+
+ @SuppressWarnings("unchecked")
+ public T name(CqlIdentifier name) {
+ Assert.notNull(name);
+ this.name = name;
return (T) this;
}
- public String getName() {
- return identifier.getName();
- }
-
- public String getNameAsIdentifier() {
- return identifier.toCql();
+ public CqlIdentifier getName() {
+ return name;
}
}
diff --git a/spring-cassandra/src/main/java/org/springframework/cassandra/core/keyspace/TableOptionsSpecification.java b/spring-cassandra/src/main/java/org/springframework/cassandra/core/keyspace/TableOptionsSpecification.java
index cbcccddf1..27b0d5abc 100644
--- a/spring-cassandra/src/main/java/org/springframework/cassandra/core/keyspace/TableOptionsSpecification.java
+++ b/spring-cassandra/src/main/java/org/springframework/cassandra/core/keyspace/TableOptionsSpecification.java
@@ -22,8 +22,11 @@ import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
+import org.springframework.cassandra.core.cql.CqlIdentifier;
import org.springframework.cassandra.core.cql.CqlStringUtils;
+import com.datastax.driver.core.DataType;
+
/**
* Abstract builder class to support the construction of table specifications that have table options, that is, those
* options normally specified by WITH ... AND ....
@@ -42,11 +45,18 @@ public abstract class TableOptionsSpecification options = new LinkedHashMap();
+ @Override
@SuppressWarnings("unchecked")
public T name(String name) {
return (T) super.name(name);
}
+ @Override
+ @SuppressWarnings("unchecked")
+ public T name(CqlIdentifier name) {
+ return (T) super.name(name);
+ }
+
/**
* Convenience method that calls with(option, null).
*
@@ -68,7 +78,7 @@ public abstract class TableOptionsSpecification extends TableOptionsSpecification extends TableOptionsSpecification extends TableOptionsSpecificationnull meaning ascending). Must
* be specified after all partition key columns and before any non-key columns.
@@ -98,6 +112,10 @@ public class TableSpecification extends TableOptionsSpecification extends TableOptionsSpecification extends TableOptionsSpecification getColumns() {
return Collections.unmodifiableList(columns);
}
@@ -145,6 +168,7 @@ public class TableSpecification extends TableOptionsSpecification getPartitionKeyColumns() {
return Collections.unmodifiableList(partitionKeyColumns);
}
@@ -152,6 +176,7 @@ public class TableSpecification extends TableOptionsSpecification getClusteredKeyColumns() {
return Collections.unmodifiableList(clusteredKeyColumns);
}
@@ -159,6 +184,7 @@ public class TableSpecification extends TableOptionsSpecification getPrimaryKeyColumns() {
ArrayList primaryKeyColumns = new ArrayList();
@@ -171,6 +197,7 @@ public class TableSpecification extends TableOptionsSpecification getNonKeyColumns() {
return Collections.unmodifiableList(nonKeyColumns);
}
diff --git a/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/core/cql/generator/CqlIndexSpecificationAssertions.java b/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/core/cql/generator/CqlIndexSpecificationAssertions.java
index e1880c77f..86f784edb 100644
--- a/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/core/cql/generator/CqlIndexSpecificationAssertions.java
+++ b/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/core/cql/generator/CqlIndexSpecificationAssertions.java
@@ -29,14 +29,14 @@ public class CqlIndexSpecificationAssertions {
public static void assertIndex(IndexDescriptor expected, String keyspace, Session session) {
IndexMetadata imd = session.getCluster().getMetadata().getKeyspace(keyspace.toLowerCase())
- .getTable(expected.getTableName()).getColumn(expected.getColumnName()).getIndex();
+ .getTable(expected.getTableName().toCql()).getColumn(expected.getColumnName().toCql()).getIndex();
- assertEquals(expected.getName().toLowerCase(), imd.getName().toLowerCase());
+ assertEquals(expected.getName(), imd.getName());
}
public static void assertNoIndex(IndexDescriptor expected, String keyspace, Session session) {
IndexMetadata imd = session.getCluster().getMetadata().getKeyspace(keyspace.toLowerCase())
- .getTable(expected.getTableName()).getColumn(expected.getColumnName()).getIndex();
+ .getTable(expected.getTableName().toCql()).getColumn(expected.getColumnName().toCql()).getIndex();
assertNull(imd);
}
diff --git a/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/core/cql/generator/CqlTableSpecificationAssertions.java b/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/core/cql/generator/CqlTableSpecificationAssertions.java
index d15f786e8..2e54dbf6a 100644
--- a/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/core/cql/generator/CqlTableSpecificationAssertions.java
+++ b/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/core/cql/generator/CqlTableSpecificationAssertions.java
@@ -42,9 +42,9 @@ public class CqlTableSpecificationAssertions {
public static void assertTable(TableDescriptor expected, String keyspace, Session session) {
TableMetadata tmd = session.getCluster().getMetadata().getKeyspace(keyspace.toLowerCase())
- .getTable(expected.getName());
+ .getTable(expected.getName().getUnquoted()); // TODO: talk to Datastax about unquoting
- assertEquals(expected.getName().toLowerCase(), tmd.getName().toLowerCase());
+ assertEquals(expected.getName().getUnquoted(), tmd.getName()); // TODO: talk to Datastax
assertPartitionKeyColumns(expected, tmd);
assertPrimaryKeyColumns(expected, tmd);
assertColumns(expected.getColumns(), tmd.getColumns());
@@ -53,7 +53,7 @@ public class CqlTableSpecificationAssertions {
public static void assertNoTable(DropTableSpecification expected, String keyspace, Session session) {
TableMetadata tmd = session.getCluster().getMetadata().getKeyspace(keyspace.toLowerCase())
- .getTable(expected.getName());
+ .getTable(expected.getName().toCql());
assertNull(tmd);
}
@@ -171,7 +171,7 @@ public class CqlTableSpecificationAssertions {
}
public static void assertColumn(ColumnSpecification expected, ColumnMetadata actual) {
- assertEquals(expected.getName().toLowerCase(), actual.getName().toLowerCase());
+ assertEquals(expected.getName().toCql(), actual.getName()); // TODO: expected.getName().getUnquoted()?
assertEquals(expected.getType(), actual.getType());
}
}
diff --git a/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/core/cql/generator/FunkyIdentifierIntegrationTest.java b/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/core/cql/generator/FunkyIdentifierIntegrationTest.java
new file mode 100644
index 000000000..645bdc507
--- /dev/null
+++ b/spring-cassandra/src/test/java/org/springframework/cassandra/test/integration/core/cql/generator/FunkyIdentifierIntegrationTest.java
@@ -0,0 +1,42 @@
+package org.springframework.cassandra.test.integration.core.cql.generator;
+
+import org.junit.Test;
+import org.springframework.cassandra.core.cql.generator.CreateTableCqlGenerator;
+import org.springframework.cassandra.core.keyspace.CreateTableSpecification;
+import org.springframework.cassandra.test.integration.AbstractKeyspaceCreatingIntegrationTest;
+import org.springframework.cassandra.test.unit.core.cql.generator.CreateTableCqlGeneratorTests.FunkyTableNameTest;
+
+import com.datastax.driver.core.DataType;
+
+public class FunkyIdentifierIntegrationTest extends AbstractKeyspaceCreatingIntegrationTest {
+
+ public FunkyIdentifierIntegrationTest() {
+ super(randomKeyspaceName());
+ }
+
+ @Test
+ public void testFunkyTableName() {
+ for (String name : FunkyTableNameTest.FUNKY_LEGAL_NAMES) {
+ SESSION.execute(new CreateTableCqlGenerator(CreateTableSpecification.createTable().name(name)
+ .partitionKeyColumn("key", DataType.text())).toCql());
+ }
+ }
+
+ @Test
+ public void testFunkyColumnName() {
+ String table = "funky";
+ int i = 0;
+ for (String name : FunkyTableNameTest.FUNKY_LEGAL_NAMES) {
+ SESSION.execute(new CreateTableCqlGenerator(CreateTableSpecification.createTable().name(table + i++)
+ .partitionKeyColumn(name, DataType.text())).toCql());
+ }
+ }
+
+ @Test
+ public void testFunkyTableAndColumnName() {
+ for (String name : FunkyTableNameTest.FUNKY_LEGAL_NAMES) {
+ SESSION.execute(new CreateTableCqlGenerator(CreateTableSpecification.createTable().name(name)
+ .partitionKeyColumn(name, DataType.text())).toCql());
+ }
+ }
+}
\ No newline at end of file
diff --git a/spring-cassandra/src/test/java/org/springframework/cassandra/test/unit/core/cql/CqlIdentifierTest.java b/spring-cassandra/src/test/java/org/springframework/cassandra/test/unit/core/cql/CqlIdentifierTest.java
index 0a8538795..c90d6d47e 100644
--- a/spring-cassandra/src/test/java/org/springframework/cassandra/test/unit/core/cql/CqlIdentifierTest.java
+++ b/spring-cassandra/src/test/java/org/springframework/cassandra/test/unit/core/cql/CqlIdentifierTest.java
@@ -15,21 +15,64 @@
*/
package org.springframework.cassandra.test.unit.core.cql;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.springframework.cassandra.core.CqlIdentifier.isQuotedIdentifier;
-import static org.springframework.cassandra.core.CqlIdentifier.isUnquotedIdentifier;
+import static org.junit.Assert.*;
+import static org.springframework.cassandra.core.cql.CqlIdentifier.cqlId;
+import static org.springframework.cassandra.core.cql.CqlIdentifier.quotedCqlId;
import org.junit.Test;
+import org.springframework.cassandra.core.ReservedKeyword;
+import org.springframework.cassandra.core.cql.CqlIdentifier;
public class CqlIdentifierTest {
@Test
- public void testIsQuotedIdentifier() throws Exception {
- assertFalse(isQuotedIdentifier("my\"id"));
- assertTrue(isQuotedIdentifier("my\"\"id"));
- assertFalse(isUnquotedIdentifier("my\"id"));
- assertTrue(isUnquotedIdentifier("myid"));
+ public void testUnquotedIdentifiers() {
+
+ String[] ids = new String[] { "foo", "Foo", "FOO", "a_", "a1" };
+
+ for (String id : ids) {
+ CqlIdentifier cqlId = cqlId(id);
+ assertFalse(cqlId.isQuoted());
+ assertEquals(id.toLowerCase(), cqlId.toCql());
+ }
}
+ @Test
+ public void testForceQuotedIdentifiers() {
+
+ String[] ids = new String[] { "foo", "Foo", "FOO", "a_", "a1" };
+
+ for (String id : ids) {
+ CqlIdentifier cqlId = quotedCqlId(id);
+ assertTrue(cqlId.isQuoted());
+ assertEquals("\"" + id + "\"", cqlId.toCql());
+ }
+ }
+
+ @Test
+ public void testReservedWordsEndUpQuoted() {
+
+ for (ReservedKeyword id : ReservedKeyword.values()) {
+ CqlIdentifier cqlId = cqlId(id.name());
+ assertTrue(cqlId.isQuoted());
+ assertEquals("\"" + id.name() + "\"", cqlId.toCql());
+
+ cqlId = cqlId(id.name().toLowerCase());
+ assertTrue(cqlId.isQuoted());
+ assertEquals("\"" + id.name().toLowerCase() + "\"", cqlId.toCql());
+ }
+ }
+
+ @Test
+ public void testIllegals() {
+ String[] illegals = new String[] { null, "", "a ", "a a", "a\"", "a'", "a''", "\"\"", "''", "-", "a-", "_", "_a" };
+ for (String illegal : illegals) {
+ try {
+ cqlId(illegal);
+ fail(String.format("identifier [%s] should have caused IllegalArgumentException", illegal));
+ } catch (IllegalArgumentException x) {
+ // :)
+ }
+ }
+ }
}
diff --git a/spring-cassandra/src/test/java/org/springframework/cassandra/test/unit/core/cql/generator/AlterTableCqlGeneratorTests.java b/spring-cassandra/src/test/java/org/springframework/cassandra/test/unit/core/cql/generator/AlterTableCqlGeneratorTests.java
index 4d24fc51a..50edc309f 100644
--- a/spring-cassandra/src/test/java/org/springframework/cassandra/test/unit/core/cql/generator/AlterTableCqlGeneratorTests.java
+++ b/spring-cassandra/src/test/java/org/springframework/cassandra/test/unit/core/cql/generator/AlterTableCqlGeneratorTests.java
@@ -41,7 +41,6 @@ public class AlterTableCqlGeneratorTests {
* Asserts that the preamble is first & correctly formatted in the given CQL string.
*/
public static void assertPreamble(String tableName, String cql) {
- System.out.println("cql: " + cql);
assertTrue(cql.startsWith("ALTER TABLE " + tableName + " "));
}
diff --git a/spring-cassandra/src/test/java/org/springframework/cassandra/test/unit/core/cql/generator/CreateTableCqlGeneratorTests.java b/spring-cassandra/src/test/java/org/springframework/cassandra/test/unit/core/cql/generator/CreateTableCqlGeneratorTests.java
index e43b89e80..abcd30d95 100644
--- a/spring-cassandra/src/test/java/org/springframework/cassandra/test/unit/core/cql/generator/CreateTableCqlGeneratorTests.java
+++ b/spring-cassandra/src/test/java/org/springframework/cassandra/test/unit/core/cql/generator/CreateTableCqlGeneratorTests.java
@@ -16,13 +16,20 @@
package org.springframework.cassandra.test.unit.core.cql.generator;
import static org.junit.Assert.assertTrue;
+import static org.springframework.cassandra.core.cql.CqlIdentifier.cqlId;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
import java.util.LinkedHashMap;
+import java.util.List;
import java.util.Map;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.cassandra.core.ReservedKeyword;
+import org.springframework.cassandra.core.cql.CqlIdentifier;
import org.springframework.cassandra.core.cql.generator.CreateTableCqlGenerator;
import org.springframework.cassandra.core.keyspace.CreateTableSpecification;
import org.springframework.cassandra.core.keyspace.Option;
@@ -40,7 +47,7 @@ public class CreateTableCqlGeneratorTests {
/**
* Asserts that the preamble is first & correctly formatted in the given CQL string.
*/
- public static void assertPreamble(String tableName, String cql) {
+ public static void assertPreamble(CqlIdentifier tableName, String cql) {
assertTrue(cql.startsWith("CREATE TABLE " + tableName + " "));
}
@@ -98,6 +105,7 @@ public class CreateTableCqlGeneratorTests {
public static abstract class CreateTableTest extends
TableOperationCqlGeneratorTest {
+ @Override
public CreateTableCqlGenerator generator() {
return new CreateTableCqlGenerator(specification);
}
@@ -105,12 +113,13 @@ public class CreateTableCqlGeneratorTests {
public static class BasicTest extends CreateTableTest {
- public String name = "mytable";
+ public CqlIdentifier name = cqlId("mytable");
public DataType partitionKeyType0 = DataType.text();
- public String partitionKey0 = "partitionKey0";
+ public CqlIdentifier partitionKey0 = cqlId("partitionKey0");
public DataType columnType1 = DataType.text();
public String column1 = "column1";
+ @Override
public CreateTableSpecification specification() {
return CreateTableSpecification.createTable().name(name).partitionKeyColumn(partitionKey0, partitionKeyType0)
.column(column1, columnType1);
@@ -122,18 +131,18 @@ public class CreateTableCqlGeneratorTests {
assertPreamble(name, cql);
assertColumns(String.format("%s %s, %s %s", partitionKey0, partitionKeyType0, column1, columnType1), cql);
- assertPrimaryKey(partitionKey0, cql);
+ assertPrimaryKey(partitionKey0.toCql(), cql);
}
}
public static class CompositePartitionKeyTest extends CreateTableTest {
- public String name = "composite_partition_key_table";
+ public CqlIdentifier name = cqlId("composite_partition_key_table");
public DataType partKeyType0 = DataType.text();
- public String partKey0 = "partKey0";
+ public CqlIdentifier partKey0 = cqlId("partKey0");
public DataType partKeyType1 = DataType.text();
- public String partKey1 = "partKey1";
- public String column0 = "column0";
+ public CqlIdentifier partKey1 = cqlId("partKey1");
+ public CqlIdentifier column0 = cqlId("column0");
public DataType columnType0 = DataType.text();
@Override
@@ -162,19 +171,20 @@ public class CreateTableCqlGeneratorTests {
*/
public static class ReadRepairChanceTest extends CreateTableTest {
- public String name = "mytable";
+ public CqlIdentifier name = cqlId("mytable");
public DataType partitionKeyType0 = DataType.text();
- public String partitionKey0 = "partitionKey0";
+ public CqlIdentifier partitionKey0 = cqlId("partitionKey0");
public DataType partitionKeyType1 = DataType.timestamp();
- public String partitionKey1 = "create_timestamp";
+ public CqlIdentifier partitionKey1 = cqlId("create_timestamp");
public DataType columnType1 = DataType.text();
- public String column1 = "column1";
+ public CqlIdentifier column1 = cqlId("column1");
public Double readRepairChance = 0.5;
+ @Override
public CreateTableSpecification specification() {
- return (CreateTableSpecification) CreateTableSpecification.createTable().name(name)
- .partitionKeyColumn(partitionKey0, partitionKeyType0).partitionKeyColumn(partitionKey1, partitionKeyType1)
- .column(column1, columnType1).with(TableOption.READ_REPAIR_CHANCE, readRepairChance);
+ return CreateTableSpecification.createTable().name(name).partitionKeyColumn(partitionKey0, partitionKeyType0)
+ .partitionKeyColumn(partitionKey1, partitionKeyType1).column(column1, columnType1)
+ .with(TableOption.READ_REPAIR_CHANCE, readRepairChance);
}
@Test
@@ -197,13 +207,13 @@ public class CreateTableCqlGeneratorTests {
*/
public static class MultipleOptionsTest extends CreateTableTest {
- public String name = "timeseries_table";
+ public CqlIdentifier name = cqlId("timeseries_table");
public DataType partitionKeyType0 = DataType.timeuuid();
- public String partitionKey0 = "tid";
+ public CqlIdentifier partitionKey0 = cqlId("tid");
public DataType partitionKeyType1 = DataType.timestamp();
- public String partitionKey1 = "create_timestamp";
+ public CqlIdentifier partitionKey1 = cqlId("create_timestamp");
public DataType columnType1 = DataType.text();
- public String column1 = "data_point";
+ public CqlIdentifier column1 = cqlId("data_point");
public Double readRepairChance = 0.5;
public Double dcLocalReadRepairChance = 0.7;
public Double bloomFilterFpChance = 0.001;
@@ -213,6 +223,7 @@ public class CreateTableCqlGeneratorTests {
public Map