Skip to content

Commit cd444b2

Browse files
mipo256mp911de
authored andcommitted
Correctly apply TableOptions through CassandraAdminTemplate.createTable(…).
Closes: #359 Original pull request: #1385
1 parent d4bbdcb commit cd444b2

File tree

10 files changed

+76
-17
lines changed

10 files changed

+76
-17
lines changed

spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraAdminOperations.java

+1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ public interface CassandraAdminOperations extends CassandraOperations {
5555
void createTable(boolean ifNotExists, CqlIdentifier tableName, Class<?> entityClass,
5656
Map<String, Object> optionsByName);
5757

58+
5859
/**
5960
* Drops a table based on the given {@link Class entity type}. The name of the table is derived from either the simple
6061
* name of the {@link Class entity class} or name of the table specified with the {@link Table} mapping annotation.

spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraAdminTemplate.java

+17-4
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,10 @@
2929
import org.springframework.data.cassandra.core.cql.keyspace.CreateTableSpecification;
3030
import org.springframework.data.cassandra.core.cql.keyspace.DropTableSpecification;
3131
import org.springframework.data.cassandra.core.cql.keyspace.DropUserTypeSpecification;
32+
import org.springframework.data.cassandra.core.cql.keyspace.TableOption;
3233
import org.springframework.data.cassandra.core.mapping.CassandraPersistentEntity;
3334
import org.springframework.util.Assert;
35+
import org.springframework.util.CollectionUtils;
3436

3537
import com.datastax.oss.driver.api.core.CqlIdentifier;
3638
import com.datastax.oss.driver.api.core.CqlSession;
@@ -44,6 +46,7 @@
4446
* @author Fabio J. Mendes
4547
* @author John Blum
4648
* @author Vagif Zeynalov
49+
* @author Mikhail Polivakha
4750
*/
4851
public class CassandraAdminTemplate extends CassandraTemplate implements CassandraAdminOperations {
4952

@@ -105,13 +108,23 @@ public SchemaFactory getSchemaFactory() {
105108
}
106109

107110
@Override
108-
public void createTable(boolean ifNotExists, CqlIdentifier tableName, Class<?> entityClass,
109-
Map<String, Object> optionsByName) {
110-
111+
public void createTable(boolean ifNotExists, CqlIdentifier tableName, Class<?> entityClass, Map<String, Object> optionsByName) {
111112
CassandraPersistentEntity<?> entity = getConverter().getMappingContext().getRequiredPersistentEntity(entityClass);
112113

113114
CreateTableSpecification createTableSpecification = this.schemaFactory
114-
.getCreateTableSpecificationFor(entity, tableName).ifNotExists(ifNotExists);
115+
.getCreateTableSpecificationFor(entity, tableName)
116+
.ifNotExists(ifNotExists);
117+
118+
if (!CollectionUtils.isEmpty(optionsByName)) {
119+
optionsByName.forEach((key, value) -> {
120+
TableOption tableOption = TableOption.valueOfIgnoreCase(key);
121+
if (tableOption.requiresValue()) {
122+
createTableSpecification.with(tableOption, value);
123+
} else {
124+
createTableSpecification.with(tableOption);
125+
}
126+
});
127+
}
115128

116129
getCqlOperations().execute(CreateTableCqlGenerator.toCql(createTableSpecification));
117130
}

spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/EntityOperations.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ interface AdaptibleEntity<T> extends Entity<T> {
196196
StatementBuilder<Delete> appendVersionCondition(StatementBuilder<Delete> delete);
197197

198198
/**
199-
* Initializes the version property of the of the current entity if available.
199+
* Initializes the version property of the current entity if available.
200200
*
201201
* @return the entity with the version property updated if available.
202202
*/

spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/StatementFactory.java

+1
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,7 @@ public StatementBuilder<RegularInsert> insert(Object objectToInsert, WriteOption
295295
Assert.notNull(persistentEntity, "CassandraPersistentEntity must not be null");
296296

297297
boolean insertNulls;
298+
298299
if (options instanceof InsertOptions) {
299300

300301
InsertOptions insertOptions = (InsertOptions) options;

spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/MappingCassandraConverter.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -258,12 +258,12 @@ public ColumnTypeResolver getColumnTypeResolver() {
258258
@SuppressWarnings("unchecked")
259259
private <S> ConvertingPropertyAccessor<S> newConvertingPropertyAccessor(S source,
260260
CassandraPersistentEntity<?> entity) {
261-
262261
PersistentPropertyAccessor<S> propertyAccessor = source instanceof PersistentPropertyAccessor
263-
? (PersistentPropertyAccessor<S>) source
264-
: entity.getPropertyAccessor(source);
262+
? (PersistentPropertyAccessor<S>) source
263+
: entity.getPropertyAccessor(source);
265264

266265
return new ConvertingPropertyAccessor<>(propertyAccessor, getConversionService());
266+
267267
}
268268

269269
private <S> CassandraPersistentEntityParameterValueProvider newParameterValueProvider(ConversionContext context,

spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/SchemaFactory.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ public CreateTableSpecification getCreateTableSpecificationFor(CassandraPersiste
147147
if (property.isCompositePrimaryKey()) {
148148

149149
CassandraPersistentEntity<?> primaryKeyEntity = mappingContext
150-
.getRequiredPersistentEntity(property.getRawType());
150+
.getRequiredPersistentEntity(property.getRawType());
151151

152152
for (CassandraPersistentProperty primaryKeyProperty : primaryKeyEntity) {
153153

spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/UserTypeUtil.java

+3-7
Original file line numberDiff line numberDiff line change
@@ -43,29 +43,25 @@ static DataType potentiallyFreeze(DataType dataType) {
4343

4444
Assert.notNull(dataType, "DataType must not be null");
4545

46-
if (dataType instanceof ListType) {
46+
if (dataType instanceof ListType collectionType) {
4747

48-
ListType collectionType = (ListType) dataType;
4948
DataType elementType = collectionType.getElementType();
5049

5150
if (isCollectionType(elementType) || isNonFrozenUdt(elementType)) {
5251
return DataTypes.listOf(potentiallyFreeze(elementType), collectionType.isFrozen());
5352
}
5453
}
5554

56-
if (dataType instanceof SetType) {
55+
if (dataType instanceof SetType collectionType) {
5756

58-
SetType collectionType = (SetType) dataType;
5957
DataType elementType = collectionType.getElementType();
6058

6159
if (isCollectionType(elementType) || isNonFrozenUdt(elementType)) {
6260
return DataTypes.setOf(potentiallyFreeze(elementType), collectionType.isFrozen());
6361
}
6462
}
6563

66-
if (dataType instanceof MapType) {
67-
68-
MapType collectionType = (MapType) dataType;
64+
if (dataType instanceof MapType collectionType) {
6965

7066
DataType keyType = collectionType.getKeyType();
7167
DataType valueType = collectionType.getValueType();

spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/TableOption.java

+11
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import java.util.Map;
1919

2020
import org.springframework.lang.Nullable;
21+
import org.springframework.util.StringUtils;
2122

2223
/**
2324
* Enumeration that represents all known table options. If a table option is not listed here, but is supported by
@@ -26,6 +27,7 @@
2627
*
2728
* @author Matthew T. Adams
2829
* @author Mark Paluch
30+
* @author Mikhail Polivakha
2931
* @see CompactionOption
3032
* @see CompressionOption
3133
* @see CachingOption
@@ -84,6 +86,15 @@ public enum TableOption implements Option {
8486
this.delegate = new DefaultOption(name, type, requiresValue, escapesValue, quotesValue);
8587
}
8688

89+
public static TableOption valueOfIgnoreCase(String optionName) {
90+
for (TableOption value : values()) {
91+
if (value.getName().equalsIgnoreCase(optionName)) {
92+
return value;
93+
}
94+
}
95+
throw new IllegalArgumentException(String.format("Unable to recognize specified Table option '%s'", optionName));
96+
}
97+
8798
@Override
8899
public Class<?> getType() {
89100
return this.delegate.getType();

spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/TableSpecification.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ protected T column(CqlIdentifier name, DataType type, Optional<PrimaryKeyType> o
296296

297297
this.columns.add(column);
298298

299-
if (!optionalKeyType.isPresent()) {
299+
if (optionalKeyType.isEmpty()) {
300300
this.nonKeyColumns.add(column);
301301
}
302302

spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/CassandraAdminTemplateIntegrationTests.java

+37
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,19 @@
1717

1818
import static org.assertj.core.api.Assertions.*;
1919

20+
import java.time.LocalDate;
2021
import java.util.Collection;
22+
import java.util.Map;
2123

24+
import org.assertj.core.api.Assertions;
2225
import org.junit.jupiter.api.BeforeEach;
2326
import org.junit.jupiter.api.Test;
27+
import org.springframework.data.annotation.Id;
2428
import org.springframework.data.cassandra.core.convert.MappingCassandraConverter;
2529
import org.springframework.data.cassandra.core.cql.generator.DropTableCqlGenerator;
2630
import org.springframework.data.cassandra.core.cql.keyspace.DropTableSpecification;
31+
import org.springframework.data.cassandra.core.cql.keyspace.TableOption;
32+
import org.springframework.data.cassandra.core.mapping.Table;
2733
import org.springframework.data.cassandra.domain.User;
2834
import org.springframework.data.cassandra.test.util.AbstractKeyspaceCreatingIntegrationTests;
2935

@@ -36,6 +42,7 @@
3642
* Integration tests for {@link CassandraAdminTemplate}.
3743
*
3844
* @author Mark Paluch
45+
* @author Mikhail Polivakha
3946
*/
4047
class CassandraAdminTemplateIntegrationTests extends AbstractKeyspaceCreatingIntegrationTests {
4148

@@ -59,6 +66,27 @@ private KeyspaceMetadata getKeyspaceMetadata() {
5966
return getSession().getKeyspace().flatMap(metadata::getKeyspace).get();
6067
}
6168

69+
@Test
70+
void givenAdminTemplate_whenCreateTableWithOptions_ThenCreatedTableContainsTheseOptions() {
71+
cassandraAdminTemplate.createTable(
72+
true,
73+
CqlIdentifier.fromCql("someTable"),
74+
SomeTable.class,
75+
Map.of(
76+
TableOption.COMMENT.getName(), "This is comment for table",
77+
TableOption.BLOOM_FILTER_FP_CHANCE.getName(), "0.3"
78+
)
79+
);
80+
81+
TableMetadata someTable = getKeyspaceMetadata().getTables().values().stream().findFirst().orElse(null);
82+
83+
Assertions.assertThat(someTable).isNotNull();
84+
Assertions.assertThat(someTable.getOptions().get(CqlIdentifier.fromCql(TableOption.COMMENT.getName())))
85+
.isEqualTo("This is comment for table");
86+
Assertions.assertThat(someTable.getOptions().get(CqlIdentifier.fromCql(TableOption.BLOOM_FILTER_FP_CHANCE.getName())))
87+
.isEqualTo(0.3);
88+
}
89+
6290
@Test // DATACASS-173
6391
void testCreateTables() {
6492

@@ -85,4 +113,13 @@ void testDropTable() {
85113

86114
assertThat(getKeyspaceMetadata().getTables()).hasSize(0);
87115
}
116+
117+
@Table("someTable")
118+
private static class SomeTable {
119+
120+
@Id
121+
private String name;
122+
private Integer number;
123+
private LocalDate createdAt;
124+
}
88125
}

0 commit comments

Comments
 (0)