moved create table from CqlUtils to cql generator

This commit is contained in:
Alex Shvid
2013-12-03 13:58:02 -08:00
parent 5c11d4aac2
commit 81a083af63
11 changed files with 150 additions and 100 deletions

View File

@@ -91,6 +91,10 @@ public class CreateTableCqlGenerator extends TableCqlGenerator<CreateTableSpecif
// end partition key clause
}
if (!clusteredKeys.isEmpty()) {
cql.append(", ");
}
appendColumnNames(cql, clusteredKeys);
cql.append(")");

View File

@@ -15,16 +15,15 @@
*/
package org.springframework.cassandra.core.keyspace;
import static org.springframework.cassandra.core.PrimaryKeyType.PARTITIONED;
import static org.springframework.cassandra.core.PrimaryKeyType.CLUSTERED;
import static org.springframework.cassandra.core.Ordering.ASCENDING;
import static org.springframework.cassandra.core.PrimaryKeyType.PARTITIONED;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.springframework.cassandra.core.PrimaryKeyType;
import org.springframework.cassandra.core.Ordering;
import org.springframework.cassandra.core.PrimaryKeyType;
import com.datastax.driver.core.DataType;
@@ -87,7 +86,7 @@ public class TableSpecification<T> extends TableOptionsSpecification<TableSpecif
* @return this
*/
public T clusteredKeyColumn(String name, DataType type) {
return clusteredKeyColumn(name, type, ASCENDING);
return clusteredKeyColumn(name, type, null);
}
/**

View File

@@ -15,6 +15,7 @@
*/
package org.springframework.data.cassandra.convert;
import org.springframework.cassandra.core.keyspace.CreateTableSpecification;
import org.springframework.data.cassandra.mapping.CassandraPersistentEntity;
import org.springframework.data.cassandra.mapping.CassandraPersistentProperty;
import org.springframework.data.convert.EntityConverter;
@@ -27,4 +28,6 @@ import org.springframework.data.convert.EntityConverter;
public interface CassandraConverter extends
EntityConverter<CassandraPersistentEntity<?>, CassandraPersistentProperty, Object, Object> {
CreateTableSpecification getCreateTableSpecification(CassandraPersistentEntity<?> entity);
}

View File

@@ -19,6 +19,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.cassandra.core.keyspace.CreateTableSpecification;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.convert.support.DefaultConversionService;
@@ -258,6 +259,52 @@ public class MappingCassandraConverter extends AbstractCassandraConverter implem
}
public CreateTableSpecification getCreateTableSpecification(CassandraPersistentEntity<?> entity) {
final CreateTableSpecification spec = new CreateTableSpecification();
spec.name(entity.getTable());
entity.doWithProperties(new PropertyHandler<CassandraPersistentProperty>() {
public void doWithPersistentProperty(CassandraPersistentProperty prop) {
if (prop.isCompositePrimaryKey()) {
CassandraPersistentEntity<?> pkEntity = mappingContext.getPersistentEntity(prop.getRawType());
pkEntity.doWithProperties(new PropertyHandler<CassandraPersistentProperty>() {
public void doWithPersistentProperty(CassandraPersistentProperty pkProp) {
if (pkProp.isPartitioned()) {
spec.partitionKeyColumn(pkProp.getColumnName(), pkProp.getDataType());
} else {
spec.clusteredKeyColumn(pkProp.getColumnName(), pkProp.getDataType(), pkProp.getOrdering());
}
}
});
} else {
if (prop.isIdProperty()) {
spec.partitionKeyColumn(prop.getColumnName(), prop.getDataType());
} else {
spec.column(prop.getColumnName(), prop.getDataType());
}
}
}
});
if (spec.getPartitionKeyColumns().isEmpty()) {
throw new MappingException("not found partition key in the entity " + entity.getType());
}
return spec;
}
@SuppressWarnings("unchecked")
private <T> Class<T> transformClassToBeanClassLoaderClass(Class<T> entity) {
try {

View File

@@ -83,7 +83,7 @@ public class CassandraAdminTemplate implements CassandraAdminOperations {
execute(new SessionCallback<Object>() {
public Object doInSession(Session s) throws DataAccessException {
String cql = CqlUtils.createTable(tableName, entity, mappingContext);
String cql = CqlUtils.createTable(tableName, entity, converter);
log.info("CREATE TABLE CQL -> " + cql);
s.execute(cql);
return null;

View File

@@ -249,7 +249,7 @@ public class CassandraKeyspaceFactoryBean implements FactoryBean<SpringDataKeysp
private void createNewTable(Session session, String useTableName, CassandraPersistentEntity<?> entity)
throws NoHostAvailableException {
String cql = CqlUtils.createTable(useTableName, entity, mappingContext);
String cql = CqlUtils.createTable(useTableName, entity, converter);
log.info("Execute on keyspace " + keyspace + " CQL " + cql);
session.execute(cql);
for (String indexCQL : CqlUtils.createIndexes(useTableName, entity)) {

View File

@@ -20,6 +20,7 @@ import java.lang.reflect.Field;
import java.util.List;
import java.util.Set;
import org.springframework.cassandra.core.Ordering;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.data.mapping.Association;
import org.springframework.data.mapping.model.AnnotationBasedPersistentProperty;
@@ -85,6 +86,16 @@ public class BasicCassandraPersistentProperty extends AnnotationBasedPersistentP
return annotation != null && StringUtils.hasText(annotation.value()) ? annotation.value() : field.getName();
}
/**
* Returns ordering for the column. Valid only for clustered columns.
*
* @return
*/
public Ordering getOrdering() {
Order annotation = getField().getAnnotation(Order.class);
return annotation != null ? annotation.value() : null;
}
/**
* Returns the data type information if exists.
*

View File

@@ -15,6 +15,7 @@
*/
package org.springframework.data.cassandra.mapping;
import org.springframework.cassandra.core.Ordering;
import org.springframework.data.mapping.PersistentProperty;
import com.datastax.driver.core.DataType;
@@ -40,6 +41,13 @@ public interface CassandraPersistentProperty extends PersistentProperty<Cassandr
*/
String getColumnName();
/**
* Returns ordering for the column. Valid only for clustered columns.
*
* @return
*/
Ordering getOrdering();
/**
* Returns the data type.
*

View File

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

View File

@@ -0,0 +1,34 @@
/*
* Copyright 2010-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.cassandra.mapping;
import org.springframework.cassandra.core.Ordering;
/**
* Annotation to define custom order for clustered column.
*
* @author Alex Shvid
*/
public @interface Order {
/**
* Ordering of the column in the table.
*
* @return
*/
Ordering value() default Ordering.ASCENDING;
}

View File

@@ -11,13 +11,14 @@ import org.springframework.cassandra.core.ConsistencyLevelResolver;
import org.springframework.cassandra.core.QueryOptions;
import org.springframework.cassandra.core.RetryPolicy;
import org.springframework.cassandra.core.RetryPolicyResolver;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.cassandra.core.cql.generator.CreateTableCqlGenerator;
import org.springframework.cassandra.core.keyspace.CreateTableSpecification;
import org.springframework.data.cassandra.convert.CassandraConverter;
import org.springframework.data.cassandra.exception.EntityWriterException;
import org.springframework.data.cassandra.mapping.CassandraPersistentEntity;
import org.springframework.data.cassandra.mapping.CassandraPersistentProperty;
import org.springframework.data.convert.EntityWriter;
import org.springframework.data.mapping.PropertyHandler;
import org.springframework.data.mapping.context.MappingContext;
import com.datastax.driver.core.ColumnMetadata;
import com.datastax.driver.core.DataType;
@@ -50,101 +51,14 @@ public abstract class CqlUtils {
* @return The CQL that can be passed to session.execute()
*/
public static String createTable(String tableName, final CassandraPersistentEntity<?> entity,
final MappingContext<? extends CassandraPersistentEntity<?>, CassandraPersistentProperty> mappingContext) {
CassandraConverter cassandraConverter) {
final StringBuilder str = new StringBuilder();
str.append("CREATE TABLE ");
str.append(tableName);
str.append('(');
CreateTableSpecification spec = cassandraConverter.getCreateTableSpecification(entity);
spec.name(tableName);
final List<String> clusteredIds = new ArrayList<String>();
final List<String> partitionedIds = new ArrayList<String>();
CreateTableCqlGenerator generator = new CreateTableCqlGenerator(spec);
entity.doWithProperties(new PropertyHandler<CassandraPersistentProperty>() {
public void doWithPersistentProperty(CassandraPersistentProperty prop) {
if (prop.isCompositePrimaryKey()) {
CassandraPersistentEntity<?> pkEntity = mappingContext.getPersistentEntity(prop.getRawType());
pkEntity.doWithProperties(new PropertyHandler<CassandraPersistentProperty>() {
public void doWithPersistentProperty(CassandraPersistentProperty pkProp) {
if (pkProp.isPartitioned()) {
partitionedIds.add(pkProp.getColumnName());
} else {
clusteredIds.add(pkProp.getColumnName());
}
if (str.charAt(str.length() - 1) != '(') {
str.append(',');
}
String columnName = pkProp.getColumnName();
str.append(columnName);
str.append(' ');
DataType dataType = pkProp.getDataType();
str.append(toCQL(dataType));
}
});
} else {
if (str.charAt(str.length() - 1) != '(') {
str.append(',');
}
String columnName = prop.getColumnName();
str.append(columnName);
str.append(' ');
DataType dataType = prop.getDataType();
str.append(toCQL(dataType));
if (prop.isIdProperty()) {
partitionedIds.add(prop.getColumnName());
}
}
}
});
if (partitionedIds.isEmpty()) {
throw new InvalidDataAccessApiUsageException("not found partition key in the entity " + entity.getType());
}
str.append(",PRIMARY KEY(");
if (partitionedIds.size() > 1) {
str.append('(');
}
for (String id : partitionedIds) {
if (str.charAt(str.length() - 1) != '(') {
str.append(',');
}
str.append(id);
}
if (partitionedIds.size() > 1) {
str.append(')');
}
for (String id : clusteredIds) {
str.append(',');
str.append(id);
}
str.append("));");
return str.toString();
return generator.toCql();
}
/**