Added CqlGenerators for Keyspace.

This commit is contained in:
john-mcpeek
2013-12-14 13:17:27 -05:00
parent b88b4afc69
commit 3d51fc150f
6 changed files with 570 additions and 0 deletions

View File

@@ -0,0 +1,121 @@
/*
* Copyright 2011-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cassandra.core.cql.generator;
import static org.springframework.cassandra.core.cql.CqlStringUtils.noNull;
import java.util.Map;
import org.springframework.cassandra.core.keyspace.AddColumnSpecification;
import org.springframework.cassandra.core.keyspace.AlterColumnSpecification;
import org.springframework.cassandra.core.keyspace.AlterKeyspaceSpecification;
import org.springframework.cassandra.core.keyspace.ColumnChangeSpecification;
import org.springframework.cassandra.core.keyspace.DropColumnSpecification;
import org.springframework.cassandra.core.keyspace.Option;
/**
* CQL generator for generating <code>ALTER TABLE</code> statements.
*
* @author Matthew T. Adams
*/
public class AlterKeyspaceCqlGenerator extends KeyspaceOptionsCqlGenerator<AlterKeyspaceSpecification> {
public AlterKeyspaceCqlGenerator(AlterKeyspaceSpecification specification) {
super(specification);
}
public StringBuilder toCql(StringBuilder cql) {
cql = noNull(cql);
preambleCql(cql);
// changesCql(cql);
// optionsCql(cql);
cql.append(";");
return cql;
}
protected StringBuilder preambleCql(StringBuilder cql) {
return noNull(cql).append("ALTER KEYSPACE ").append(spec().getNameAsIdentifier()).append(" ");
}
// protected StringBuilder changesCql(StringBuilder cql) {
// cql = noNull(cql);
//
// boolean first = true;
// for (ColumnChangeSpecification change : spec().getChanges()) {
// if (first) {
// first = false;
// } else {
// cql.append(" ");
// }
// getCqlGeneratorFor(change).toCql(cql);
// }
//
// return cql;
// }
//
// protected ColumnChangeCqlGenerator<?> getCqlGeneratorFor(ColumnChangeSpecification change) {
// if (change instanceof AddColumnSpecification) {
// return new AddColumnCqlGenerator((AddColumnSpecification) change);
// }
// if (change instanceof DropColumnSpecification) {
// return new DropColumnCqlGenerator((DropColumnSpecification) change);
// }
// if (change instanceof AlterColumnSpecification) {
// return new AlterColumnCqlGenerator((AlterColumnSpecification) change);
// }
// throw new IllegalArgumentException("unknown ColumnChangeSpecification type: " + change.getClass().getName());
// }
//
// @SuppressWarnings("unchecked")
// protected StringBuilder optionsCql(StringBuilder cql) {
// cql = noNull(cql);
//
// Map<String, Object> options = spec().getOptions();
// if (options == null || options.isEmpty()) {
// return cql;
// }
//
// cql.append(" WITH ");
// boolean first = true;
// for (String key : options.keySet()) {
// if (first) {
// first = false;
// } else {
// cql.append(" AND ");
// }
//
// cql.append(key);
//
// Object value = options.get(key);
// if (value == null) {
// continue;
// }
// cql.append(" = ");
//
// if (value instanceof Map) {
// optionValueMap((Map<Option, Object>) value, cql);
// continue;
// }
//
// // else just use value as string
// cql.append(value.toString());
// }
// return cql;
// }
}

View File

@@ -0,0 +1,201 @@
/*
* Copyright 2011-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cassandra.core.cql.generator;
import static org.springframework.cassandra.core.PrimaryKeyType.CLUSTERED;
import static org.springframework.cassandra.core.PrimaryKeyType.PARTITIONED;
import static org.springframework.cassandra.core.cql.CqlStringUtils.noNull;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.springframework.cassandra.core.keyspace.ColumnSpecification;
import org.springframework.cassandra.core.keyspace.CreateKeyspaceSpecification;
import org.springframework.cassandra.core.keyspace.Option;
/**
* CQL generator for generating a <code>CREATE TABLE</code> statement.
*
* @author Matthew T. Adams
* @author Alex Shvid
*/
public class CreateKeyspaceCqlGenerator extends KeyspaceCqlGenerator<CreateKeyspaceSpecification> {
public CreateKeyspaceCqlGenerator(CreateKeyspaceSpecification specification) {
super(specification);
}
public StringBuilder toCql(StringBuilder cql) {
cql = noNull(cql);
preambleCql(cql);
optionsCql(cql);
cql.append(";");
return cql;
}
protected StringBuilder preambleCql(StringBuilder cql) {
return noNull(cql).append("CREATE KEYSPACE ").append(spec().getIfNotExists() ? "IF NOT EXISTS " : "")
.append(spec().getNameAsIdentifier());
}
protected void optionsCql(StringBuilder cql) {
cql = noNull(cql);
cql.append("WITH REPLICATION =");
}
// @SuppressWarnings("unchecked")
// protected StringBuilder columnsAndOptionsCql(StringBuilder cql) {
//
// cql = noNull(cql);
//
// // begin columns
// cql.append(" (");
//
// List<ColumnSpecification> partitionKeys = new ArrayList<ColumnSpecification>();
// List<ColumnSpecification> clusterKeys = new ArrayList<ColumnSpecification>();
// for (ColumnSpecification col : spec().getColumns()) {
// col.toCql(cql).append(", ");
//
// if (col.getKeyType() == PARTITIONED) {
// partitionKeys.add(col);
// } else if (col.getKeyType() == CLUSTERED) {
// clusterKeys.add(col);
// }
// }
//
// // begin primary key clause
// cql.append("PRIMARY KEY (");
//
// if (partitionKeys.size() > 1) {
// // begin partition key clause
// cql.append("(");
// }
//
// appendColumnNames(cql, partitionKeys);
//
// if (partitionKeys.size() > 1) {
// cql.append(")");
// // end partition key clause
// }
//
// if (!clusterKeys.isEmpty()) {
// cql.append(", ");
// }
//
// appendColumnNames(cql, clusterKeys);
//
// cql.append(")");
// // end primary key clause
//
// cql.append(")");
// // end columns
//
// StringBuilder ordering = createOrderingClause(clusterKeys);
// // begin options
// // begin option clause
// Map<String, Object> options = spec().getOptions();
//
// if (ordering != null || !options.isEmpty()) {
//
// // option preamble
// boolean first = true;
// cql.append(" WITH ");
// // end option preamble
//
// if (ordering != null) {
// cql.append(ordering);
// first = false;
// }
// if (!options.isEmpty()) {
// for (String name : options.keySet()) {
// // append AND if we're not on first option
// if (first) {
// first = false;
// } else {
// cql.append(" AND ");
// }
//
// // append <name> = <value>
// cql.append(name);
//
// Object value = options.get(name);
// if (value == null) { // then assume string-only, valueless option like "COMPACT STORAGE"
// continue;
// }
//
// cql.append(" = ");
//
// if (value instanceof Map) {
// optionValueMap((Map<Option, Object>) value, cql);
// continue; // end non-empty value map
// }
//
// // else just use value as string
// cql.append(value.toString());
// }
// }
// }
// // end options
//
// return cql;
// }
// private static StringBuilder createOrderingClause(List<ColumnSpecification> columns) {
// StringBuilder ordering = null;
// boolean first = true;
// for (ColumnSpecification col : columns) {
//
// if (col.getOrdering() != null) { // then ordering specified
// if (ordering == null) { // then initialize ordering clause
// ordering = new StringBuilder().append("CLUSTERING ORDER BY (");
// }
// if (first) {
// first = false;
// } else {
// ordering.append(", ");
// }
// ordering.append(col.getName()).append(" ").append(col.getOrdering().cql());
// }
// }
// if (ordering != null) { // then end ordering option
// ordering.append(")");
// }
// return ordering;
// }
//
// private static void appendColumnNames(StringBuilder str, List<ColumnSpecification> columns) {
//
// boolean first = true;
// for (ColumnSpecification col : columns) {
// if (first) {
// first = false;
// } else {
// str.append(", ");
// }
// str.append(col.getName());
//
// }
//
// }
}

View File

@@ -0,0 +1,37 @@
/*
* Copyright 2011-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cassandra.core.cql.generator;
import static org.springframework.cassandra.core.cql.CqlStringUtils.noNull;
import org.springframework.cassandra.core.keyspace.DropKeyspaceSpecification;
/**
* CQL generator for generating a <code>DROP TABLE</code> statement.
*
* @author Matthew T. Adams
*/
public class DropKeyspaceCqlGenerator extends KeyspaceNameCqlGenerator<DropKeyspaceSpecification> {
public DropKeyspaceCqlGenerator(DropKeyspaceSpecification specification) {
super(specification);
}
public StringBuilder toCql(StringBuilder cql) {
return noNull(cql).append("DROP KEYSPACE ").append(spec().getIfExists() ? "IF EXISTS " : "")
.append(spec().getNameAsIdentifier()).append(";");
}
}

View File

@@ -0,0 +1,80 @@
/*
* Copyright 2011-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cassandra.core.cql.generator;
import static org.springframework.cassandra.core.cql.CqlStringUtils.escapeSingle;
import static org.springframework.cassandra.core.cql.CqlStringUtils.noNull;
import static org.springframework.cassandra.core.cql.CqlStringUtils.singleQuote;
import java.util.Map;
import org.springframework.cassandra.core.keyspace.KeyspaceSpecification;
import org.springframework.cassandra.core.keyspace.Option;
/**
* Base class that contains behavior common to CQL generation for table operations.
*
* @author Matthew T. Adams
* @param T The subtype of this class for which this is a CQL generator.
*/
public abstract class KeyspaceCqlGenerator<T extends KeyspaceSpecification<T>> extends
KeyspaceOptionsCqlGenerator<KeyspaceSpecification<T>> {
public KeyspaceCqlGenerator(KeyspaceSpecification<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;
}
}

View File

@@ -0,0 +1,51 @@
/*
* Copyright 2011-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cassandra.core.cql.generator;
import org.springframework.cassandra.core.keyspace.KeyspaceNameSpecification;
import org.springframework.util.Assert;
public abstract class KeyspaceNameCqlGenerator<T extends KeyspaceNameSpecification<T>> {
public abstract StringBuilder toCql(StringBuilder cql);
private KeyspaceNameSpecification<T> specification;
public KeyspaceNameCqlGenerator(KeyspaceNameSpecification<T> specification) {
setSpecification(specification);
}
protected void setSpecification(KeyspaceNameSpecification<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();
}
}

View File

@@ -0,0 +1,80 @@
/*
* Copyright 2011-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.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.KeyspaceOptionsSpecification;
import org.springframework.cassandra.core.keyspace.Option;
/**
* 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 KeyspaceOptionsCqlGenerator<T extends KeyspaceOptionsSpecification<T>> extends
KeyspaceNameCqlGenerator<KeyspaceOptionsSpecification<T>> {
public KeyspaceOptionsCqlGenerator(KeyspaceOptionsSpecification<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;
}
}