From b354eba94bb0caff832d64cbb8dde43cda972f09 Mon Sep 17 00:00:00 2001 From: Mikhail2048 Date: Fri, 26 May 2023 22:40:17 +0300 Subject: [PATCH] Create table using provided name. Closes #1388 --- .../core/CassandraAdminOperations.java | 15 ++++++++++ .../core/CassandraAdminTemplate.java | 13 ++++++-- .../core/cql/keyspace/TableOption.java | 3 +- ...assandraAdminTemplateIntegrationTests.java | 30 ++++++++++++++++--- 4 files changed, 52 insertions(+), 9 deletions(-) diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraAdminOperations.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraAdminOperations.java index 8d28ae2fe..c9f3795f5 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraAdminOperations.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraAdminOperations.java @@ -32,6 +32,7 @@ import com.datastax.oss.driver.api.core.metadata.schema.TableMetadata; * @author Matthew T. Adams * @author Mark Paluch * @author Fabio J. Mendes + * @author Mikhail Polivakha */ public interface CassandraAdminOperations extends CassandraOperations { @@ -55,6 +56,20 @@ public interface CassandraAdminOperations extends CassandraOperations { void createTable(boolean ifNotExists, CqlIdentifier tableName, Class entityClass, Map optionsByName); + /** + * Create a table with the name, that is derived from the given {@code entityClass} and also fields corresponding to the + * same class. If the table already exists and parameter {@code ifNotExists} is {@literal true}, this is a no-op and + * {@literal false} is returned. If the table doesn't exist, parameter {@code ifNotExists} is ignored, the table is created + * and {@literal true} is returned. + * + * @param ifNotExists If true, will only create the table if it doesn't exist, else the create operation will be + * ignored. + * @param entityClass The class whose fields determine the columns created. + * @param optionsByName Table options, given by the string option name and the appropriate option value. + */ + void createTable(boolean ifNotExists, Class entityClass, Map optionsByName); + + /** * Drops a table based on the given {@link Class entity type}. The name of the table is derived from either the simple * name of the {@link Class entity class} or name of the table specified with the {@link Table} mapping annotation. diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraAdminTemplate.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraAdminTemplate.java index 596185ae7..182c800cc 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraAdminTemplate.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraAdminTemplate.java @@ -108,12 +108,13 @@ public class CassandraAdminTemplate extends CassandraTemplate implements Cassand } @Override - public void createTable(boolean ifNotExists, CqlIdentifier tableName, Class entityClass, Map optionsByName) { + public void createTable(boolean ifNotExists, CqlIdentifier tableName, Class entityClass, + Map optionsByName) { CassandraPersistentEntity entity = getConverter().getMappingContext().getRequiredPersistentEntity(entityClass); CreateTableSpecification createTableSpecification = this.schemaFactory - .getCreateTableSpecificationFor(entity, tableName) - .ifNotExists(ifNotExists); + .getCreateTableSpecificationFor(entity, tableName) + .ifNotExists(ifNotExists); if (!CollectionUtils.isEmpty(optionsByName)) { optionsByName.forEach((key, value) -> { @@ -129,6 +130,12 @@ public class CassandraAdminTemplate extends CassandraTemplate implements Cassand getCqlOperations().execute(CreateTableCqlGenerator.toCql(createTableSpecification)); } + @Override + public void createTable(boolean ifNotExists, Class entityClass, Map optionsByName) { + CassandraPersistentEntity entity = getConverter().getMappingContext().getRequiredPersistentEntity(entityClass); + this.createTable(ifNotExists, entity.getTableName(), entityClass, optionsByName); + } + @Override public void dropTable(Class entityClass) { dropTable(getTableName(entityClass)); diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/TableOption.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/TableOption.java index 0a23cbd0f..1a8a5d91c 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/TableOption.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/TableOption.java @@ -18,6 +18,7 @@ package org.springframework.data.cassandra.core.cql.keyspace; import java.util.Map; import org.springframework.lang.Nullable; +import org.springframework.util.StringUtils; /** * Enumeration that represents all known table options. If a table option is not listed here, but is supported by @@ -94,13 +95,11 @@ public enum TableOption implements Option { * @since 4.1.1 */ public static TableOption valueOfIgnoreCase(String optionName) { - for (TableOption value : values()) { if (value.getName().equalsIgnoreCase(optionName)) { return value; } } - throw new IllegalArgumentException(String.format("Unable to recognize specified Table option '%s'", optionName)); } diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/CassandraAdminTemplateIntegrationTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/CassandraAdminTemplateIntegrationTests.java index 7f9427e69..0f2251116 100755 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/CassandraAdminTemplateIntegrationTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/CassandraAdminTemplateIntegrationTests.java @@ -21,6 +21,7 @@ import java.time.LocalDate; import java.util.Collection; import java.util.Map; +import org.assertj.core.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.data.annotation.Id; @@ -83,28 +84,49 @@ class CassandraAdminTemplateIntegrationTests extends AbstractKeyspaceCreatingInt .isEqualTo(0.3); } + @Test + void shouldCreateTableWithNameDerivedFromEntityClass() { + cassandraAdminTemplate.createTable( + true, + SomeTable.class, + Map.of( + TableOption.COMMENT.getName(), "This is comment for table", TableOption.BLOOM_FILTER_FP_CHANCE.getName(), "0.3" + ) + ); + + TableMetadata someTable = getKeyspaceMetadata().getTables() + .values() + .stream() + .findFirst() + .orElse(null); + + Assertions.assertThat(someTable).isNotNull(); + Assertions.assertThat(someTable.getOptions().get(CqlIdentifier.fromCql(TableOption.COMMENT.getName()))).isEqualTo("This is comment for table"); + Assertions.assertThat(someTable.getOptions().get(CqlIdentifier.fromCql(TableOption.BLOOM_FILTER_FP_CHANCE.getName()))).isEqualTo(3); + } + @Test // DATACASS-173 void testCreateTables() { assertThat(getKeyspaceMetadata().getTables()).hasSize(0); - cassandraAdminTemplate.createTable(true, CqlIdentifier.fromCql("users"), User.class, null); + cassandraAdminTemplate.createTable(true, User.class, null); assertThat(getKeyspaceMetadata().getTables()).hasSize(1); - cassandraAdminTemplate.createTable(true, CqlIdentifier.fromCql("users"), User.class, null); + cassandraAdminTemplate.createTable(true, User.class, null); assertThat(getKeyspaceMetadata().getTables()).hasSize(1); } @Test void testDropTable() { - cassandraAdminTemplate.createTable(true, CqlIdentifier.fromCql("users"), User.class, null); + cassandraAdminTemplate.createTable(true, User.class, null); assertThat(getKeyspaceMetadata().getTables()).hasSize(1); cassandraAdminTemplate.dropTable(User.class); assertThat(getKeyspaceMetadata().getTables()).hasSize(0); - cassandraAdminTemplate.createTable(true, CqlIdentifier.fromCql("users"), User.class, null); + cassandraAdminTemplate.createTable(true, User.class, null); cassandraAdminTemplate.dropTable(CqlIdentifier.fromCql("users")); assertThat(getKeyspaceMetadata().getTables()).hasSize(0);