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 d2f9fb488..a7ada1aa1 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 @@ -23,12 +23,9 @@ import org.springframework.data.cassandra.core.convert.SchemaFactory; import org.springframework.data.cassandra.core.cql.CqlOperations; import org.springframework.data.cassandra.core.cql.SessionCallback; -import org.springframework.data.cassandra.core.cql.generator.CreateTableCqlGenerator; -import org.springframework.data.cassandra.core.cql.generator.DropTableCqlGenerator; -import org.springframework.data.cassandra.core.cql.generator.DropUserTypeCqlGenerator; +import org.springframework.data.cassandra.core.cql.generator.CqlGenerator; import org.springframework.data.cassandra.core.cql.keyspace.CreateTableSpecification; -import org.springframework.data.cassandra.core.cql.keyspace.DropTableSpecification; -import org.springframework.data.cassandra.core.cql.keyspace.DropUserTypeSpecification; +import org.springframework.data.cassandra.core.cql.keyspace.SpecificationBuilder; import org.springframework.data.cassandra.core.cql.keyspace.TableOption; import org.springframework.data.cassandra.core.mapping.CassandraPersistentEntity; import org.springframework.util.Assert; @@ -127,7 +124,7 @@ public void createTable(boolean ifNotExists, CqlIdentifier tableName, Class e }); } - getCqlOperations().execute(CreateTableCqlGenerator.toCql(createTableSpecification)); + getCqlOperations().execute(CqlGenerator.toCql(createTableSpecification)); } @Override @@ -143,7 +140,7 @@ public void dropTable(CqlIdentifier tableName) { @Override public void dropTable(boolean ifExists, CqlIdentifier tableName) { - String dropTableCql = DropTableCqlGenerator.toCql(DropTableSpecification.dropTable(tableName).ifExists(ifExists)); + String dropTableCql = CqlGenerator.toCql(SpecificationBuilder.dropTable(tableName).ifExists(ifExists)); getCqlOperations().execute(dropTableCql); } @@ -153,7 +150,7 @@ public void dropUserType(CqlIdentifier typeName) { Assert.notNull(typeName, "Type name must not be null"); - String dropUserTypeCql = DropUserTypeCqlGenerator.toCql(DropUserTypeSpecification.dropType(typeName)); + String dropUserTypeCql = CqlGenerator.toCql(SpecificationBuilder.dropType(typeName)); getCqlOperations().execute(dropUserTypeCql); } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraPersistentEntitySchemaCreator.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraPersistentEntitySchemaCreator.java index 50ce708c6..2ece03948 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraPersistentEntitySchemaCreator.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraPersistentEntitySchemaCreator.java @@ -24,9 +24,8 @@ import java.util.stream.Collectors; import org.jetbrains.annotations.NotNull; -import org.springframework.data.cassandra.core.cql.generator.CreateIndexCqlGenerator; -import org.springframework.data.cassandra.core.cql.generator.CreateTableCqlGenerator; -import org.springframework.data.cassandra.core.cql.generator.CreateUserTypeCqlGenerator; + +import org.springframework.data.cassandra.core.cql.generator.CqlGenerator; import org.springframework.data.cassandra.core.cql.keyspace.CreateIndexSpecification; import org.springframework.data.cassandra.core.cql.keyspace.CreateTableSpecification; import org.springframework.data.cassandra.core.cql.keyspace.CreateUserTypeSpecification; @@ -96,7 +95,7 @@ public CassandraPersistentEntitySchemaCreator(CassandraMappingContext mappingCon public void createTables(boolean ifNotExists) { createTableSpecifications(ifNotExists).stream() // - .map(CreateTableCqlGenerator::toCql) // + .map(CqlGenerator::toCql) // .forEach(cql -> this.cassandraAdminOperations.getCqlOperations().execute(cql)); } @@ -123,7 +122,7 @@ protected List createTableSpecifications(boolean ifNot public void createIndexes(boolean ifNotExists) { createIndexSpecifications(ifNotExists).stream() // - .map(CreateIndexCqlGenerator::toCql) // + .map(CqlGenerator::toCql) // .forEach(cql -> this.cassandraAdminOperations.getCqlOperations().execute(cql)); } @@ -150,7 +149,7 @@ protected List createIndexSpecifications(boolean ifNot public void createUserTypes(boolean ifNotExists) { createUserTypeSpecifications(ifNotExists).stream() // - .map(CreateUserTypeCqlGenerator::toCql) // + .map(CqlGenerator::toCql) // .forEach(cql -> this.cassandraAdminOperations.getCqlOperations().execute(cql)); } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/IndexSpecificationFactory.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/IndexSpecificationFactory.java index 1c957d26d..1693330c0 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/IndexSpecificationFactory.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/IndexSpecificationFactory.java @@ -27,6 +27,7 @@ import org.springframework.core.annotation.AnnotatedElementUtils; import org.springframework.data.cassandra.core.cql.keyspace.CreateIndexSpecification; +import org.springframework.data.cassandra.core.cql.keyspace.SpecificationBuilder; import org.springframework.data.cassandra.core.mapping.CassandraPersistentProperty; import org.springframework.data.cassandra.core.mapping.Indexed; import org.springframework.data.cassandra.core.mapping.SASI; @@ -136,9 +137,9 @@ static CreateIndexSpecification createIndexSpecification(@Nullable CqlIdentifier CreateIndexSpecification index; if (StringUtils.hasText(annotation.value())) { - index = CreateIndexSpecification.createIndex(keyspace, CqlIdentifier.fromCql(annotation.value())); + index = SpecificationBuilder.createIndex(keyspace, CqlIdentifier.fromCql(annotation.value())); } else { - index = CreateIndexSpecification.createIndex(keyspace, null); + index = SpecificationBuilder.createIndex(keyspace, null); } return index.columnName(property.getRequiredColumnName()); @@ -150,9 +151,9 @@ private static CreateIndexSpecification createIndexSpecification(@Nullable CqlId CreateIndexSpecification index; if (StringUtils.hasText(annotation.value())) { - index = CreateIndexSpecification.createIndex(keyspace, CqlIdentifier.fromCql(annotation.value())); + index = SpecificationBuilder.createIndex(keyspace, CqlIdentifier.fromCql(annotation.value())); } else { - index = CreateIndexSpecification.createIndex(keyspace, null); + index = SpecificationBuilder.createIndex(keyspace, null); } index.using("org.apache.cassandra.index.sasi.SASIIndex") // diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/SchemaFactory.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/SchemaFactory.java index a4e9a3b11..f416fb115 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/SchemaFactory.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/SchemaFactory.java @@ -15,8 +15,6 @@ */ package org.springframework.data.cassandra.core.convert; -import static org.springframework.data.cassandra.core.cql.keyspace.CreateTableSpecification.*; - import java.util.ArrayList; import java.util.List; import java.util.Objects; @@ -24,6 +22,7 @@ import org.springframework.data.cassandra.core.cql.keyspace.CreateIndexSpecification; import org.springframework.data.cassandra.core.cql.keyspace.CreateTableSpecification; import org.springframework.data.cassandra.core.cql.keyspace.CreateUserTypeSpecification; +import org.springframework.data.cassandra.core.cql.keyspace.SpecificationBuilder; import org.springframework.data.cassandra.core.mapping.CassandraPersistentEntity; import org.springframework.data.cassandra.core.mapping.CassandraPersistentProperty; import org.springframework.data.cassandra.core.mapping.EmbeddedEntityOperations; @@ -141,7 +140,7 @@ public CreateTableSpecification getCreateTableSpecificationFor(CassandraPersiste Assert.notNull(tableName, "Table name must not be null"); Assert.notNull(entity, "CassandraPersistentEntity must not be null"); - CreateTableSpecification specification = createTable(entity.getKeyspace(), tableName); + CreateTableSpecification specification = SpecificationBuilder.createTable(entity.getKeyspace(), tableName); for (CassandraPersistentProperty property : entity) { @@ -296,7 +295,7 @@ public CreateUserTypeSpecification getCreateUserTypeSpecificationFor(CassandraPe Assert.notNull(entity, "CassandraPersistentEntity must not be null"); - CreateUserTypeSpecification specification = CreateUserTypeSpecification.createType(entity.getKeyspace(), + CreateUserTypeSpecification specification = SpecificationBuilder.createType(entity.getKeyspace(), entity.getTableName()); for (CassandraPersistentProperty property : entity) { diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/generator/CqlGenerator.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/generator/CqlGenerator.java new file mode 100644 index 000000000..5c77302fb --- /dev/null +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/generator/CqlGenerator.java @@ -0,0 +1,93 @@ +/* + * Copyright 2024 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 + * + * https://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.core.cql.generator; + +import org.springframework.data.cassandra.core.cql.keyspace.*; + +/** + * Entrypoint for CQL generation of {@link CqlSpecification} objects representing DML statements such as table creations + * or keyspace drops. For example: + * + *
+ * DropUserTypeSpecification spec = SpecificationBuilder.dropType("address");
+ * String cql = CqlGenerator.toCql(spec);
+ * 
+ * + * @author Mark Paluch + * @since 4.4 + * @see SpecificationBuilder + */ +public final class CqlGenerator { + + private CqlGenerator() { + // utility class, no instances + } + + /** + * Entrypoint for CQL generation of {@link CqlSpecification} objects. + * + * @param specification the CQL specification to generate CQL for. + * @return the generated CQL from {@link CqlSpecification}. + */ + public static String toCql(CqlSpecification specification) { + + if (specification instanceof CreateKeyspaceSpecification createKeyspace) { + return CreateKeyspaceCqlGenerator.toCql(createKeyspace); + } + + if (specification instanceof AlterKeyspaceSpecification alterKeyspace) { + return AlterKeyspaceCqlGenerator.toCql(alterKeyspace); + } + + if (specification instanceof DropKeyspaceSpecification dropKeyspace) { + return DropKeyspaceCqlGenerator.toCql(dropKeyspace); + } + + if (specification instanceof CreateTableSpecification createTable) { + return CreateTableCqlGenerator.toCql(createTable); + } + + if (specification instanceof AlterTableSpecification alterTable) { + return AlterTableCqlGenerator.toCql(alterTable); + } + + if (specification instanceof DropTableSpecification dropTable) { + return DropTableCqlGenerator.toCql(dropTable); + } + + if (specification instanceof CreateUserTypeSpecification createType) { + return CreateUserTypeCqlGenerator.toCql(createType); + } + + if (specification instanceof AlterUserTypeSpecification alterType) { + return AlterUserTypeCqlGenerator.toCql(alterType); + } + + if (specification instanceof DropUserTypeSpecification dropType) { + return DropUserTypeCqlGenerator.toCql(dropType); + } + + if (specification instanceof CreateIndexSpecification createIndex) { + return CreateIndexCqlGenerator.toCql(createIndex); + } + + if (specification instanceof DropIndexSpecification dropIndex) { + return DropIndexCqlGenerator.toCql(dropIndex); + } + + throw new UnsupportedOperationException(String.format("CQL specification %s is not supported", specification)); + } +} diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/AlterKeyspaceSpecification.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/AlterKeyspaceSpecification.java index 918b05130..c851aabb7 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/AlterKeyspaceSpecification.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/AlterKeyspaceSpecification.java @@ -22,7 +22,8 @@ * * @author Mark Paluch */ -public class AlterKeyspaceSpecification extends KeyspaceOptionsSpecification { +public class AlterKeyspaceSpecification extends KeyspaceOptionsSpecification + implements CqlSpecification { private AlterKeyspaceSpecification(CqlIdentifier name) { super(name); diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/AlterTableSpecification.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/AlterTableSpecification.java index 61c0986d3..47f198c2f 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/AlterTableSpecification.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/AlterTableSpecification.java @@ -38,7 +38,8 @@ * @see TableOptionsSpecification * @see org.springframework.data.cassandra.core.cql.generator.AlterTableCqlGenerator */ -public class AlterTableSpecification extends TableOptionsSpecification { +public class AlterTableSpecification extends TableOptionsSpecification + implements CqlSpecification { /** * The list of column changes. @@ -81,7 +82,7 @@ public static AlterTableSpecification alterTable(CqlIdentifier tableName) { * @return a new {@link AlterTableSpecification}. * @since 4.4 */ - public static AlterTableSpecification alterTable(CqlIdentifier keyspace, CqlIdentifier tableName) { + public static AlterTableSpecification alterTable(@Nullable CqlIdentifier keyspace, CqlIdentifier tableName) { return new AlterTableSpecification(keyspace, tableName); } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/AlterUserTypeSpecification.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/AlterUserTypeSpecification.java index 422cdff11..7068b0d8b 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/AlterUserTypeSpecification.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/AlterUserTypeSpecification.java @@ -32,7 +32,7 @@ * @since 1.5 * @see CqlIdentifier */ -public class AlterUserTypeSpecification extends UserTypeNameSpecification { +public class AlterUserTypeSpecification extends UserTypeNameSpecification implements CqlSpecification { private final List changes = new ArrayList<>(); @@ -58,7 +58,7 @@ public static AlterUserTypeSpecification alterType(String typeName) { * @param typeName must not be {@literal null}. * @return a new {@link AlterUserTypeSpecification}. */ - private static AlterUserTypeSpecification alterType(CqlIdentifier typeName) { + public static AlterUserTypeSpecification alterType(CqlIdentifier typeName) { return new AlterUserTypeSpecification(null, typeName); } @@ -70,8 +70,9 @@ private static AlterUserTypeSpecification alterType(CqlIdentifier typeName) { * @param keyspace can be {@literal null}. * @param typeName must not be {@literal null}. * @return a new {@link AlterUserTypeSpecification}. + * @since 4.4 */ - private static AlterUserTypeSpecification alterType(@Nullable CqlIdentifier keyspace, CqlIdentifier typeName) { + public static AlterUserTypeSpecification alterType(@Nullable CqlIdentifier keyspace, CqlIdentifier typeName) { return new AlterUserTypeSpecification(keyspace, typeName); } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/CqlSpecification.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/CqlSpecification.java new file mode 100644 index 000000000..4e5c5bd01 --- /dev/null +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/CqlSpecification.java @@ -0,0 +1,24 @@ +/* + * Copyright 2024 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 + * + * https://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.core.cql.keyspace; + +/** + * Marker interface for CQL specification objects that describe CQL keyspace objects. + * + * @author Mark Paluch + * @since 4.4 + */ +public interface CqlSpecification {} diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/CreateIndexSpecification.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/CreateIndexSpecification.java index 73a0d2946..29a4442e0 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/CreateIndexSpecification.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/CreateIndexSpecification.java @@ -34,7 +34,7 @@ * @author Mark Paluch */ public class CreateIndexSpecification extends IndexNameSpecification - implements IndexDescriptor { + implements IndexDescriptor, CqlSpecification { private @Nullable CqlIdentifier tableName; @@ -57,7 +57,7 @@ private CreateIndexSpecification(@Nullable CqlIdentifier keyspace, @Nullable Cql } /** - * Entry point into the {@link CreateIndexSpecification}'s fluent API to create a index. Convenient if imported + * Entry point into the {@link CreateIndexSpecification}'s fluent API to create an index. Convenient if imported * statically. */ public static CreateIndexSpecification createIndex() { @@ -65,7 +65,7 @@ public static CreateIndexSpecification createIndex() { } /** - * Entry point into the {@link CreateIndexSpecification}'s fluent API given {@code indexName} to create a index. + * Entry point into the {@link CreateIndexSpecification}'s fluent API given {@code indexName} to create an index. * Convenient if imported statically. * * @param indexName must not be {@literal null} or empty. @@ -76,7 +76,7 @@ public static CreateIndexSpecification createIndex(String indexName) { } /** - * Entry point into the {@link CreateIndexSpecification}'s fluent API given {@code indexName} to create a index. + * Entry point into the {@link CreateIndexSpecification}'s fluent API given {@code indexName} to create an index. * Convenient if imported statically. * * @param indexName must not be {@literal null}. diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/CreateKeyspaceSpecification.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/CreateKeyspaceSpecification.java index b38176b42..5d2d149f5 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/CreateKeyspaceSpecification.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/CreateKeyspaceSpecification.java @@ -28,7 +28,7 @@ * @author Mark Paluch */ public class CreateKeyspaceSpecification extends KeyspaceOptionsSpecification - implements KeyspaceDescriptor { + implements KeyspaceDescriptor, CqlSpecification { private boolean ifNotExists = false; diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/CreateTableSpecification.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/CreateTableSpecification.java index 0037b9a2c..396815c1b 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/CreateTableSpecification.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/CreateTableSpecification.java @@ -25,7 +25,7 @@ * @author Matthew T. Adams * @author Mark Paluch */ -public class CreateTableSpecification extends TableSpecification { +public class CreateTableSpecification extends TableSpecification implements CqlSpecification { private boolean ifNotExists = false; diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/CreateUserTypeSpecification.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/CreateUserTypeSpecification.java index 13d278b33..e7474bf32 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/CreateUserTypeSpecification.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/CreateUserTypeSpecification.java @@ -27,7 +27,8 @@ * @since 1.5 * @see CqlIdentifier */ -public class CreateUserTypeSpecification extends UserTypeSpecification { +public class CreateUserTypeSpecification extends UserTypeSpecification + implements CqlSpecification { private boolean ifNotExists; @@ -36,39 +37,39 @@ private CreateUserTypeSpecification(@Nullable CqlIdentifier keyspace, CqlIdentif } /** - * Entry point into the {@link CreateUserTypeSpecification}'s fluent API given {@code name} to create a type. + * Entry point into the {@link CreateUserTypeSpecification}'s fluent API given {@code typeName} to create a type. * Convenient if imported statically. * - * @param name must not {@literal null} or empty. + * @param typeName must not {@literal null} or empty. * @return a new {@link CreateUserTypeSpecification}. */ - public static CreateUserTypeSpecification createType(String name) { - return new CreateUserTypeSpecification(null, CqlIdentifier.fromCql(name)); + public static CreateUserTypeSpecification createType(String typeName) { + return new CreateUserTypeSpecification(null, CqlIdentifier.fromCql(typeName)); } /** - * Entry point into the {@link CreateUserTypeSpecification}'s fluent API given {@code name} to create a type. + * Entry point into the {@link CreateUserTypeSpecification}'s fluent API given {@code typeName} to create a type. * Convenient if imported statically. * - * @param name must not {@literal null}. + * @param typeName must not {@literal null}. * @return a new {@link CreateUserTypeSpecification}. */ - public static CreateUserTypeSpecification createType(CqlIdentifier name) { - return new CreateUserTypeSpecification(null, name); + public static CreateUserTypeSpecification createType(CqlIdentifier typeName) { + return new CreateUserTypeSpecification(null, typeName); } /** - * Entry point into the {@link CreateUserTypeSpecification}'s fluent API given {@code name} to create a type. + * Entry point into the {@link CreateUserTypeSpecification}'s fluent API given {@code typeName} to create a type. * Convenient if imported statically. Uses the default keyspace if {@code keyspace} is null; otherwise, of the * {@code keyspace} is not {@link null}, then the UDT name is prefixed with {@code keyspace}. * * @param keyspace can be {@literal null}. - * @param name must not {@literal null}. + * @param typeName must not {@literal null}. * @return a new {@link CreateUserTypeSpecification}. * @since 4.4 */ - public static CreateUserTypeSpecification createType(@Nullable CqlIdentifier keyspace, CqlIdentifier name) { - return new CreateUserTypeSpecification(keyspace, name); + public static CreateUserTypeSpecification createType(@Nullable CqlIdentifier keyspace, CqlIdentifier typeName) { + return new CreateUserTypeSpecification(keyspace, typeName); } /** diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/DropIndexSpecification.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/DropIndexSpecification.java index f40c4fdda..3b1856532 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/DropIndexSpecification.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/DropIndexSpecification.java @@ -26,7 +26,7 @@ * @author David Webb * @author Mark Paluch */ -public class DropIndexSpecification extends IndexNameSpecification { +public class DropIndexSpecification extends IndexNameSpecification implements CqlSpecification { private DropIndexSpecification(@Nullable CqlIdentifier keyspace, CqlIdentifier name) { super(keyspace, name); diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/DropKeyspaceSpecification.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/DropKeyspaceSpecification.java index 10e2bb568..195120029 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/DropKeyspaceSpecification.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/DropKeyspaceSpecification.java @@ -25,7 +25,7 @@ * * @author Mark Paluch */ -public class DropKeyspaceSpecification extends KeyspaceActionSpecification { +public class DropKeyspaceSpecification extends KeyspaceActionSpecification implements CqlSpecification { private boolean ifExists; diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/DropTableSpecification.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/DropTableSpecification.java index 89043efb3..603e7cd4e 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/DropTableSpecification.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/DropTableSpecification.java @@ -25,7 +25,7 @@ * @author Matthew T. Adams * @author Mark Paluch */ -public class DropTableSpecification extends TableNameSpecification { +public class DropTableSpecification extends TableNameSpecification implements CqlSpecification { private boolean ifExists = false; diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/DropUserTypeSpecification.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/DropUserTypeSpecification.java index 6d58f6dde..8a3bfa312 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/DropUserTypeSpecification.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/DropUserTypeSpecification.java @@ -27,7 +27,7 @@ * @since 1.5 * @see CqlIdentifier */ -public class DropUserTypeSpecification extends UserTypeNameSpecification { +public class DropUserTypeSpecification extends UserTypeNameSpecification implements CqlSpecification { private boolean ifExists; @@ -36,39 +36,39 @@ private DropUserTypeSpecification(@Nullable CqlIdentifier keyspace, CqlIdentifie } /** - * Entry point into the {@link DropUserTypeSpecification}'s fluent API given {@code name} to drop a type. Convenient - * if imported statically. + * Entry point into the {@link DropUserTypeSpecification}'s fluent API given {@code typeName} to drop a type. + * Convenient if imported statically. * - * @param name must not be {@code null} or empty. + * @param typeName must not be {@code null} or empty. * @return a new {@link DropUserTypeSpecification}. */ - public static DropUserTypeSpecification dropType(String name) { - return new DropUserTypeSpecification(null, CqlIdentifier.fromCql(name)); + public static DropUserTypeSpecification dropType(String typeName) { + return new DropUserTypeSpecification(null, CqlIdentifier.fromCql(typeName)); } /** - * Entry point into the {@link DropUserTypeSpecification}'s fluent API given {@code name} to drop a type. Convenient - * if imported statically. + * Entry point into the {@link DropUserTypeSpecification}'s fluent API given {@code typeName} to drop a type. + * Convenient if imported statically. * - * @param name must not be {@code null} or empty. + * @param typeName must not be {@code null} or empty. * @return a new {@link DropUserTypeSpecification}. */ - public static DropUserTypeSpecification dropType(CqlIdentifier name) { - return new DropUserTypeSpecification(null, name); + public static DropUserTypeSpecification dropType(CqlIdentifier typeName) { + return new DropUserTypeSpecification(null, typeName); } /** - * Entry point into the {@link DropUserTypeSpecification}'s fluent API given {@code name} to drop a type. Convenient - * if imported statically. Uses the default keyspace if {@code keyspace} is null; otherwise, of the {@code keyspace} - * is not {@link null}, then the UDT name is prefixed with {@code keyspace}. + * Entry point into the {@link DropUserTypeSpecification}'s fluent API given {@code typeName} to drop a type. + * Convenient if imported statically. Uses the default keyspace if {@code keyspace} is null; otherwise, of the + * {@code keyspace} is not {@link null}, then the UDT name is prefixed with {@code keyspace}. * * @param keyspace can be {@code null}. - * @param name must not be {@code null} or empty. + * @param typeName must not be {@code null} or empty. * @return a new {@link DropUserTypeSpecification}. * @since 4.4 */ - public static DropUserTypeSpecification dropType(@Nullable CqlIdentifier keyspace, CqlIdentifier name) { - return new DropUserTypeSpecification(keyspace, name); + public static DropUserTypeSpecification dropType(@Nullable CqlIdentifier keyspace, CqlIdentifier typeName) { + return new DropUserTypeSpecification(keyspace, typeName); } /** diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/SpecificationBuilder.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/SpecificationBuilder.java new file mode 100644 index 000000000..cb1aae4e9 --- /dev/null +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/SpecificationBuilder.java @@ -0,0 +1,584 @@ +/* + * Copyright 2024 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 + * + * https://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.core.cql.keyspace; + +import org.springframework.lang.Nullable; +import org.springframework.util.ObjectUtils; + +import com.datastax.oss.driver.api.core.CqlIdentifier; +import com.datastax.oss.driver.api.core.type.DataType; + +/** + * Entrypoint to create CQL specifications to add, alter and delete CQL objects such as tables and index. + *

+ * Specifications can be rendered to CQL using + * {@link org.springframework.data.cassandra.core.cql.generator.CqlGenerator#toCql(CqlSpecification)} for direct usage + * with the database. + * + * @author Mark Paluch + * @since 4.4 + * @see org.springframework.data.cassandra.core.cql.generator.CqlGenerator + */ +public final class SpecificationBuilder { + + private SpecificationBuilder() { + // utility class, no instances + } + + // ------------------------------------------------------------------------- + // Methods dealing with keyspace creation, alteration, and deletion. + // ------------------------------------------------------------------------- + + /** + * Entry point into the {@link CreateKeyspaceSpecification}'s fluent API given {@code name} to create a keyspace. + * Convenient if imported statically. + * + * @param name must not be {@literal null} or empty. + * @return a new {@link CreateKeyspaceSpecification}. + */ + public static CreateKeyspaceSpecification createKeyspace(String name) { + return CreateKeyspaceSpecification.createKeyspace(name); + } + + /** + * Entry point into the {@link CreateKeyspaceSpecification}'s fluent API given {@code name} to create a keyspace. + * Convenient if imported statically. + * + * @param name must not be {@literal null}. + * @return a new {@link CreateKeyspaceSpecification}. + */ + public static CreateKeyspaceSpecification createKeyspace(CqlIdentifier name) { + return CreateKeyspaceSpecification.createKeyspace(name); + } + + /** + * Entry point into the {@link AlterKeyspaceSpecification}'s fluent API given {@code name} to alter a keyspace. + * Convenient if imported statically. + * + * @param name must not be {@literal null} or empty. + * @return a new {@link AlterKeyspaceSpecification}. + */ + public static AlterKeyspaceSpecification alterKeyspace(String name) { + return AlterKeyspaceSpecification.alterKeyspace(name); + } + + /** + * Entry point into the {@link AlterKeyspaceSpecification}'s fluent API given {@code name} to alter a keyspace. + * Convenient if imported statically. + * + * @param name must not be {@literal null} or empty. + * @return a new {@link AlterKeyspaceSpecification}. + */ + public static AlterKeyspaceSpecification alterKeyspace(CqlIdentifier name) { + return AlterKeyspaceSpecification.alterKeyspace(name); + } + + /** + * Create a new {@link DropKeyspaceSpecification} for the given {@code name}. + * + * @param name must not be {@literal null} or empty. + * @return a new {@link DropKeyspaceSpecification}. + */ + public static DropKeyspaceSpecification dropKeyspace(String name) { + return DropKeyspaceSpecification.dropKeyspace(name); + } + + /** + * Create a new {@link DropKeyspaceSpecification} for the given {@code name}. + * + * @param name must not be {@literal null}. + * @return a new {@link DropKeyspaceSpecification}. + */ + public static DropKeyspaceSpecification dropKeyspace(CqlIdentifier name) { + return DropKeyspaceSpecification.dropKeyspace(name); + } + + // ------------------------------------------------------------------------- + // Methods dealing with table creation, alteration, and deletion. + // ------------------------------------------------------------------------- + + /** + * Entry point into the {@link CreateTableSpecification}'s fluent API given {@code tableName} to create a table. + * Convenient if imported statically. + * + * @param tableName must not be {@literal null} or empty. + * @return a new {@link CreateTableSpecification}. + */ + public static CreateTableSpecification createTable(String tableName) { + return CreateTableSpecification.createTable(tableName); + } + + /** + * Entry point into the {@link CreateTableSpecification}'s fluent API given {@code tableName} to create a table. + * Convenient if imported statically. Uses the default keyspace if {@code keyspace} is null; otherwise, of the + * {@code keyspace} is not {@link null}, then the table name is prefixed with {@code keyspace}. + * + * @param keyspace can be {@literal null}. + * @param tableName must not be {@literal null}. + * @return a new {@link CreateTableSpecification}. + */ + public static CreateTableSpecification createTable(@Nullable String keyspace, String tableName) { + return createTable(getOptionalKeyspace(keyspace), CqlIdentifier.fromCql(tableName)); + } + + /** + * Entry point into the {@link CreateTableSpecification}'s fluent API given {@code tableName} to create a table. + * Convenient if imported statically. + * + * @param tableName must not be {@literal null}. + * @return a new {@link CreateTableSpecification}. + */ + public static CreateTableSpecification createTable(CqlIdentifier tableName) { + return CreateTableSpecification.createTable(tableName); + } + + /** + * Entry point into the {@link CreateTableSpecification}'s fluent API given {@code tableName} to create a table. + * Convenient if imported statically. Uses the default keyspace if {@code keyspace} is null; otherwise, of the + * {@code keyspace} is not {@link null}, then the table name is prefixed with {@code keyspace}. + * + * @param keyspace can be {@literal null}. + * @param tableName must not be {@literal null}. + * @return a new {@link CreateTableSpecification}. + */ + public static CreateTableSpecification createTable(@Nullable CqlIdentifier keyspace, CqlIdentifier tableName) { + return CreateTableSpecification.createTable(keyspace, tableName); + } + + /** + * Entry point into the {@link AlterTableSpecification}'s fluent API given {@code tableName} to alter a table. + * Convenient if imported statically. + * + * @param tableName must not be {@literal null} or empty. + * @return a new {@link AlterTableSpecification}. + */ + public static AlterTableSpecification alterTable(String tableName) { + return AlterTableSpecification.alterTable(tableName); + } + + /** + * Entry point into the {@link AlterTableSpecification}'s fluent API given {@code tableName} to alter a table. + * Convenient if imported statically. Uses the default keyspace if {@code keyspace} is null; otherwise, of the + * {@code keyspace} is not {@link null}, then the table name is prefixed with {@code keyspace}. + * + * @param keyspace can be {@literal null}. + * @param tableName must not be {@literal null}. + * @return a new {@link AlterTableSpecification}. + */ + public static AlterTableSpecification alterTable(@Nullable String keyspace, String tableName) { + return alterTable(getOptionalKeyspace(keyspace), CqlIdentifier.fromCql(tableName)); + } + + /** + * Entry point into the {@link AlterTableSpecification}'s fluent API given {@code tableName} to alter a table. + * Convenient if imported statically. + * + * @param tableName must not be {@literal null}. + * @return a new {@link AlterTableSpecification}. + */ + public static AlterTableSpecification alterTable(CqlIdentifier tableName) { + return AlterTableSpecification.alterTable(null, tableName); + } + + /** + * Entry point into the {@link AlterTableSpecification}'s fluent API given {@code tableName} to alter a table. + * Convenient if imported statically. Uses the default keyspace if {@code keyspace} is null; otherwise, of the + * {@code keyspace} is not {@link null}, then the table name is prefixed with {@code keyspace}. + * + * @param keyspace can be {@literal null}. + * @param tableName must not be {@literal null}. + * @return a new {@link AlterTableSpecification}. + */ + public static AlterTableSpecification alterTable(@Nullable CqlIdentifier keyspace, CqlIdentifier tableName) { + return AlterTableSpecification.alterTable(keyspace, tableName); + } + + /** + * Entry point into the {@link DropTableSpecification}'s fluent API {@code tableName} to drop a table. Convenient if + * imported statically. + * + * @param tableName must not be {@literal null} or empty. + * @return a new {@link DropTableSpecification}. + */ + public static DropTableSpecification dropTable(String tableName) { + return DropTableSpecification.dropTable(tableName); + } + + /** + * Entry point into the {@link DropTableSpecification}'s fluent API given {@code tableName} to drop a table. + * Convenient if imported statically. Uses the default keyspace if {@code keyspace} is null; otherwise, of the + * {@code keyspace} is not {@link null}, then the table name is prefixed with {@code keyspace}. + * + * @param keyspace can be {@literal null}. + * @param tableName must not be {@literal null}. + * @return a new {@link DropTableSpecification}. + */ + public static DropTableSpecification dropTable(@Nullable String keyspace, String tableName) { + return dropTable(getOptionalKeyspace(keyspace), CqlIdentifier.fromCql(tableName)); + } + + /** + * Entry point into the {@link DropTableSpecification}'s fluent API given {@code tableName} to drop a table. + * Convenient if imported statically. + * + * @param tableName must not be {@literal null}. + * @return a new {@link DropTableSpecification}. + */ + public static DropTableSpecification dropTable(CqlIdentifier tableName) { + return DropTableSpecification.dropTable(tableName); + } + + /** + * Entry point into the {@link DropTableSpecification}'s fluent API given {@code tableName} to drop a table. + * Convenient if imported statically. Uses the default keyspace if {@code keyspace} is null; otherwise, of the + * {@code keyspace} is not {@link null}, then the table name is prefixed with {@code keyspace}. + * + * @param keyspace can be {@literal null}. + * @param tableName must not be {@literal null}. + * @return a new {@link DropTableSpecification}. + */ + public static DropTableSpecification dropTable(@Nullable CqlIdentifier keyspace, CqlIdentifier tableName) { + return DropTableSpecification.dropTable(keyspace, tableName); + } + + // ------------------------------------------------------------------------- + // Methods dealing with table column alteration. + // ------------------------------------------------------------------------- + + /** + * Create a new {@link AddColumnSpecification} for the given {@code name} and {@link DataType}. + * + * @param name must not be {@literal null} or empty. + * @param type must not be {@literal null}. + * @return a new {@link AddColumnSpecification}. + */ + public static AddColumnSpecification addColumn(String name, DataType type) { + return AddColumnSpecification.addColumn(name, type); + } + + /** + * Create a new {@link AddColumnSpecification} for the given {@code name} and {@link DataType}. + * + * @param name must not be {@literal null}. + * @param type must not be {@literal null}. + * @return a new {@link AddColumnSpecification}. + */ + public static AddColumnSpecification addColumn(CqlIdentifier name, DataType type) { + return AddColumnSpecification.addColumn(name, type); + } + + /** + * Entry point into the {@link AlterColumnSpecification}'s fluent API given {@code name} and {@link DataType} to alter + * a column. Convenient if imported statically. + * + * @param name must not be {@literal null} or empty. + * @param type must not be {@literal null}. + * @return a new {@link AlterColumnSpecification}. + */ + public static AlterColumnSpecification alterColumn(String name, DataType type) { + return AlterColumnSpecification.alterColumn(name, type); + } + + /** + * Entry point into the {@link AlterColumnSpecification}'s fluent API given {@code name} and {@link DataType} to alter + * a column. Convenient if imported statically. + * + * @param name must not be {@literal null}. + * @param type must not be {@literal null}. + * @return a new {@link AlterColumnSpecification}. + */ + public static AlterColumnSpecification alterColumn(CqlIdentifier name, DataType type) { + return AlterColumnSpecification.alterColumn(name, type); + } + + /** + * Create a new {@link DropColumnSpecification} for the given {@code name}. + * + * @param name must not be {@literal null} or empty. + */ + public static DropColumnSpecification dropColumn(String name) { + return DropColumnSpecification.dropColumn(name); + } + + /** + * Create a new {@link DropColumnSpecification} for the given {@code name}. + * + * @param name must not be {@literal null} or empty. + */ + public static DropColumnSpecification dropColumn(CqlIdentifier name) { + return DropColumnSpecification.dropColumn(name); + } + + // ------------------------------------------------------------------------- + // Methods dealing with index creation and deletion. + // ------------------------------------------------------------------------- + + /** + * Entry point into the {@link CreateIndexSpecification}'s fluent API to create an index. Convenient if imported + * statically. + */ + public static CreateIndexSpecification createIndex() { + return CreateIndexSpecification.createIndex(); + } + + /** + * Entry point into the {@link CreateIndexSpecification}'s fluent API given {@code indexName} to create an index. + * Convenient if imported statically. + * + * @param indexName must not be {@literal null} or empty. + * @return a new {@link CreateIndexSpecification}. + */ + public static CreateIndexSpecification createIndex(String indexName) { + return CreateIndexSpecification.createIndex(indexName); + } + + /** + * Entry point into the {@link CreateIndexSpecification}'s fluent API given {@code indexName} to create an index. + * Convenient if imported statically. + * + * @param indexName must not be {@literal null} or empty. + * @return a new {@link CreateIndexSpecification}. + */ + public static CreateIndexSpecification createIndex(@Nullable String keyspace, String indexName) { + return createIndex(getOptionalKeyspace(keyspace), CqlIdentifier.fromCql(indexName)); + } + + /** + * Entry point into the {@link CreateIndexSpecification}'s fluent API given {@code indexName} to create an index. + * Convenient if imported statically. + * + * @param indexName must not be {@literal null}. + * @return a new {@link CreateIndexSpecification}. + */ + public static CreateIndexSpecification createIndex(CqlIdentifier indexName) { + return CreateIndexSpecification.createIndex(null, indexName); + } + + /** + * Entry point into the {@link CreateIndexSpecification}'s fluent API given {@code keyspace} and {@code indexName} to + * create an index. Convenient if imported statically. Uses the default keyspace if {@code keyspace} is null; + * otherwise, of the {@code keyspace} is not {@link null}, then the index and table name are prefixed with + * {@code keyspace}. + * + * @param keyspace can be {@literal null}. + * @param indexName can be {@literal null}. + * @return a new {@link CreateIndexSpecification}. + */ + public static CreateIndexSpecification createIndex(@Nullable CqlIdentifier keyspace, + @Nullable CqlIdentifier indexName) { + return CreateIndexSpecification.createIndex(keyspace, indexName); + } + + /** + * Create a new {@link DropIndexSpecification} for the given {@code indexName}. + * + * @param indexName must not be {@literal null} or empty. + * @return a new {@link DropIndexSpecification}. + */ + public static DropIndexSpecification dropIndex(String indexName) { + return DropIndexSpecification.dropIndex(indexName); + } + + /** + * Create a new {@link DropIndexSpecification} for the given {@code indexName}. Uses the default keyspace if + * {@code keyspace} is null; otherwise, of the {@code keyspace} is not {@link null}, then the index name is prefixed + * with {@code keyspace}. + * + * @param keyspace can be {@literal null}. + * @param indexName must not be {@literal null}. + * @return a new {@link DropIndexSpecification}. + */ + public static DropIndexSpecification dropIndex(@Nullable String keyspace, String indexName) { + return dropIndex(getOptionalKeyspace(keyspace), CqlIdentifier.fromCql(indexName)); + } + + /** + * Create a new {@link DropIndexSpecification} for the given {@code indexName}. + * + * @param indexName must not be {@literal null}. + * @return a new {@link DropIndexSpecification}. + */ + public static DropIndexSpecification dropIndex(CqlIdentifier indexName) { + return DropIndexSpecification.dropIndex(null, indexName); + } + + /** + * Create a new {@link DropIndexSpecification} for the given {@code indexName}. Uses the default keyspace if + * {@code keyspace} is null; otherwise, of the {@code keyspace} is not {@link null}, then the index name is prefixed + * with {@code keyspace}. + * + * @param keyspace can be {@literal null}. + * @param indexName must not be {@literal null}. + * @return a new {@link DropIndexSpecification}. + */ + public static DropIndexSpecification dropIndex(@Nullable CqlIdentifier keyspace, CqlIdentifier indexName) { + return DropIndexSpecification.dropIndex(keyspace, indexName); + } + + // ------------------------------------------------------------------------- + // Methods dealing with user type creation, alteration, and deletion. + // ------------------------------------------------------------------------- + + /** + * Entry point into the {@link CreateUserTypeSpecification}'s fluent API given {@code name} to create a type. + * Convenient if imported statically. + * + * @param typeName must not {@literal null} or empty. + * @return a new {@link CreateUserTypeSpecification}. + */ + public static CreateUserTypeSpecification createType(String typeName) { + return CreateUserTypeSpecification.createType(typeName); + } + + /** + * Entry point into the {@link CreateUserTypeSpecification}'s fluent API given {@code name} to create a type. + * Convenient if imported statically. Uses the default keyspace if {@code keyspace} is null; otherwise, of the + * {@code keyspace} is not {@link null}, then the UDT name is prefixed with {@code keyspace}. + * + * @param keyspace can be {@literal null}. + * @param typeName must not {@literal null}. + * @return a new {@link CreateUserTypeSpecification}. + */ + public static CreateUserTypeSpecification createType(@Nullable String keyspace, String typeName) { + return createType(getOptionalKeyspace(keyspace), CqlIdentifier.fromCql(typeName)); + } + + /** + * Entry point into the {@link CreateUserTypeSpecification}'s fluent API given {@code typeName} to create a type. + * Convenient if imported statically. + * + * @param name must not {@literal null}. + * @return a new {@link CreateUserTypeSpecification}. + */ + public static CreateUserTypeSpecification createType(CqlIdentifier name) { + return CreateUserTypeSpecification.createType(name); + } + + /** + * Entry point into the {@link CreateUserTypeSpecification}'s fluent API given {@code typeName} to create a type. + * Convenient if imported statically. Uses the default keyspace if {@code keyspace} is null; otherwise, of the + * {@code keyspace} is not {@link null}, then the UDT name is prefixed with {@code keyspace}. + * + * @param keyspace can be {@literal null}. + * @param name must not {@literal null}. + * @return a new {@link CreateUserTypeSpecification}. + */ + public static CreateUserTypeSpecification createType(@Nullable CqlIdentifier keyspace, CqlIdentifier name) { + return CreateUserTypeSpecification.createType(keyspace, name); + } + + /** + * Entry point into the {@link AlterColumnSpecification}'s fluent API given {@code typeName} to alter a user type. + * Convenient if imported statically. + * + * @param typeName must not be {@literal null} or empty. + * @return a new {@link AlterUserTypeSpecification}. + */ + public static AlterUserTypeSpecification alterType(String typeName) { + return AlterUserTypeSpecification.alterType(typeName); + } + + /** + * Entry point into the {@link AlterUserTypeSpecification}'s fluent API given {@code typeName} to alter a type. + * Convenient if imported statically. Uses the default keyspace if {@code keyspace} is null; otherwise, of the + * {@code keyspace} is not {@link null}, then the table name is prefixed with {@code keyspace}. + * + * @param keyspace can be {@literal null}. + * @param typeName must not be {@literal null}. + * @return a new {@link AlterUserTypeSpecification}. + */ + private static AlterUserTypeSpecification alterType(@Nullable String keyspace, String typeName) { + return alterType(getOptionalKeyspace(keyspace), CqlIdentifier.fromCql(typeName)); + } + + /** + * Entry point into the {@link AlterUserTypeSpecification}'s fluent API given {@code typeName} to alter a type. + * Convenient if imported statically. + * + * @param typeName must not be {@literal null}. + * @return a new {@link AlterUserTypeSpecification}. + */ + private static AlterUserTypeSpecification alterType(CqlIdentifier typeName) { + return AlterUserTypeSpecification.alterType(typeName); + } + + /** + * Entry point into the {@link AlterUserTypeSpecification}'s fluent API given {@code typeName} to alter a type. + * Convenient if imported statically. Uses the default keyspace if {@code keyspace} is null; otherwise, of the + * {@code keyspace} is not {@link null}, then the table name is prefixed with {@code keyspace}. + * + * @param keyspace can be {@literal null}. + * @param typeName must not be {@literal null}. + * @return a new {@link AlterUserTypeSpecification}. + */ + private static AlterUserTypeSpecification alterType(@Nullable CqlIdentifier keyspace, CqlIdentifier typeName) { + return AlterUserTypeSpecification.alterType(keyspace, typeName); + } + + /** + * Entry point into the {@link DropUserTypeSpecification}'s fluent API given {@code typeName} to drop a type. + * Convenient if imported statically. + * + * @param typeName must not be {@code null} or empty. + * @return a new {@link DropUserTypeSpecification}. + */ + public static DropUserTypeSpecification dropType(String typeName) { + return DropUserTypeSpecification.dropType(typeName); + } + + /** + * Entry point into the {@link DropUserTypeSpecification}'s fluent API given {@code typeName} to drop a type. + * Convenient if imported statically. Uses the default keyspace if {@code keyspace} is null; otherwise, of the + * {@code keyspace} is not {@link null}, then the UDT name is prefixed with {@code keyspace}. + * + * @param keyspace can be {@code null}. + * @param typeName must not be {@code null} or empty. + * @return a new {@link DropUserTypeSpecification}. + */ + public static DropUserTypeSpecification dropType(@Nullable String keyspace, String typeName) { + return dropType(getOptionalKeyspace(keyspace), CqlIdentifier.fromCql(typeName)); + } + + /** + * Entry point into the {@link DropUserTypeSpecification}'s fluent API given {@code typeName} to drop a type. + * Convenient if imported statically. + * + * @param typeName must not be {@code null} or empty. + * @return a new {@link DropUserTypeSpecification}. + */ + public static DropUserTypeSpecification dropType(CqlIdentifier typeName) { + return DropUserTypeSpecification.dropType(typeName); + } + + /** + * Entry point into the {@link DropUserTypeSpecification}'s fluent API given {@code typeName} to drop a type. + * Convenient if imported statically. Uses the default keyspace if {@code keyspace} is null; otherwise, of the + * {@code keyspace} is not {@link null}, then the UDT name is prefixed with {@code keyspace}. + * + * @param keyspace can be {@code null}. + * @param typeName must not be {@code null} or empty. + * @return a new {@link DropUserTypeSpecification}. + */ + public static DropUserTypeSpecification dropType(@Nullable CqlIdentifier keyspace, CqlIdentifier typeName) { + return DropUserTypeSpecification.dropType(keyspace, typeName); + } + + @Nullable + private static CqlIdentifier getOptionalKeyspace(@Nullable String keyspace) { + return ObjectUtils.isEmpty(keyspace) ? null : CqlIdentifier.fromCql(keyspace); + } + +} diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/TableSpecification.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/TableSpecification.java index 144833506..85feba0f6 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/TableSpecification.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/keyspace/TableSpecification.java @@ -24,6 +24,7 @@ import org.springframework.data.cassandra.core.cql.Ordering; import org.springframework.data.cassandra.core.cql.PrimaryKeyType; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import com.datastax.oss.driver.api.core.CqlIdentifier; @@ -69,7 +70,7 @@ protected TableSpecification(CqlIdentifier name) { super(name); } - protected TableSpecification(CqlIdentifier keyspace, CqlIdentifier name) { + protected TableSpecification(@Nullable CqlIdentifier keyspace, CqlIdentifier name) { super(keyspace, name); } 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 3c83d52f0..c35322894 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 @@ -23,10 +23,11 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; + import org.springframework.data.annotation.Id; import org.springframework.data.cassandra.core.convert.MappingCassandraConverter; -import org.springframework.data.cassandra.core.cql.generator.DropTableCqlGenerator; -import org.springframework.data.cassandra.core.cql.keyspace.DropTableSpecification; +import org.springframework.data.cassandra.core.cql.generator.CqlGenerator; +import org.springframework.data.cassandra.core.cql.keyspace.SpecificationBuilder; import org.springframework.data.cassandra.core.cql.keyspace.TableOption; import org.springframework.data.cassandra.core.mapping.Table; import org.springframework.data.cassandra.domain.User; @@ -56,7 +57,7 @@ void before() { Collection tables = keyspace.getTables().values(); for (TableMetadata table : tables) { cassandraAdminTemplate.getCqlOperations() - .execute(DropTableCqlGenerator.toCql(DropTableSpecification.dropTable(table.getName()))); + .execute(CqlGenerator.toCql(SpecificationBuilder.dropTable(table.getName()))); } } diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/convert/IndexCreationIntegrationTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/convert/IndexCreationIntegrationTests.java index 58cb32a6d..b561a0765 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/convert/IndexCreationIntegrationTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/convert/IndexCreationIntegrationTests.java @@ -23,9 +23,9 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; + import org.springframework.data.annotation.Id; -import org.springframework.data.cassandra.core.cql.generator.CreateIndexCqlGenerator; -import org.springframework.data.cassandra.core.cql.generator.CreateTableCqlGenerator; +import org.springframework.data.cassandra.core.cql.generator.CqlGenerator; import org.springframework.data.cassandra.core.cql.keyspace.CreateIndexSpecification; import org.springframework.data.cassandra.core.cql.keyspace.CreateTableSpecification; import org.springframework.data.cassandra.core.mapping.BasicCassandraPersistentEntity; @@ -67,8 +67,8 @@ void shouldCreateSecondaryIndex() throws InterruptedException { CreateTableSpecification createTable = schemaFactory.getCreateTableSpecificationFor(entity); List createIndexes = schemaFactory.getCreateIndexSpecificationsFor(entity); - session.execute(CreateTableCqlGenerator.toCql(createTable)); - createIndexes.forEach(it -> session.execute(CreateIndexCqlGenerator.toCql(it))); + session.execute(CqlGenerator.toCql(createTable)); + createIndexes.forEach(it -> session.execute(CqlGenerator.toCql(it))); Thread.sleep(500); // index creation is async so we do poor man's sync to await completion @@ -85,8 +85,8 @@ void shouldCreateSasiIndex() throws InterruptedException { CreateTableSpecification createTable = schemaFactory.getCreateTableSpecificationFor(entity); List createIndexes = schemaFactory.getCreateIndexSpecificationsFor(entity); - session.execute(CreateTableCqlGenerator.toCql(createTable)); - createIndexes.forEach(it -> session.execute(CreateIndexCqlGenerator.toCql(it))); + session.execute(CqlGenerator.toCql(createTable)); + createIndexes.forEach(it -> session.execute(CqlGenerator.toCql(it))); Thread.sleep(500); // index creation is async so we do poor man's sync to await completion diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/convert/MappingCassandraConverterTupleIntegrationTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/convert/MappingCassandraConverterTupleIntegrationTests.java index 1c5044a35..c9faa31bf 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/convert/MappingCassandraConverterTupleIntegrationTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/convert/MappingCassandraConverterTupleIntegrationTests.java @@ -26,6 +26,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; @@ -35,7 +36,7 @@ import org.springframework.data.cassandra.config.SchemaAction; import org.springframework.data.cassandra.core.StatementFactory; import org.springframework.data.cassandra.core.cql.WriteOptions; -import org.springframework.data.cassandra.core.cql.generator.CreateUserTypeCqlGenerator; +import org.springframework.data.cassandra.core.cql.generator.CqlGenerator; import org.springframework.data.cassandra.core.cql.keyspace.CreateUserTypeSpecification; import org.springframework.data.cassandra.core.cql.util.StatementBuilder; import org.springframework.data.cassandra.core.mapping.CassandraMappingContext; @@ -103,7 +104,7 @@ void setUp() { CreateUserTypeSpecification createAddress = schemaFactory .getCreateUserTypeSpecificationFor(mappingContext.getRequiredPersistentEntity(AddressUserType.class)); - this.session.execute(CreateUserTypeCqlGenerator.toCql(createAddress)); + this.session.execute(CqlGenerator.toCql(createAddress)); String ddl = "CREATE TABLE person (id text, " + "tuplevalue tuple," // + "mapoftuples map, text>>>, " // diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/convert/SchemaFactoryUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/convert/SchemaFactoryUnitTests.java index 2341f70e2..c90e6cc22 100755 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/convert/SchemaFactoryUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/convert/SchemaFactoryUnitTests.java @@ -36,8 +36,7 @@ import org.springframework.data.annotation.Id; import org.springframework.data.cassandra.core.cql.Ordering; import org.springframework.data.cassandra.core.cql.PrimaryKeyType; -import org.springframework.data.cassandra.core.cql.generator.CreateIndexCqlGenerator; -import org.springframework.data.cassandra.core.cql.generator.CreateTableCqlGenerator; +import org.springframework.data.cassandra.core.cql.generator.CqlGenerator; import org.springframework.data.cassandra.core.cql.keyspace.ColumnSpecification; import org.springframework.data.cassandra.core.cql.keyspace.CreateIndexSpecification; import org.springframework.data.cassandra.core.cql.keyspace.CreateIndexSpecification.ColumnFunction; @@ -597,7 +596,7 @@ void createTableShouldConsiderKeyspaces() { assertThat(getColumnType("mapped", specification).asCql(true, true)).isEqualTo("frozen"); assertThat(getColumnType("human", specification).asCql(true, true)).isEqualTo("frozen"); - String cql = CreateTableCqlGenerator.toCql(specification); + String cql = CqlGenerator.toCql(specification); assertThat(cql).contains("CREATE TABLE some_ks.withkeyspace"); assertThat(cql).contains("mapped frozen"); @@ -614,7 +613,7 @@ void createIndexShouldConsiderKeyspace() { assertThat(index).hasSize(1).extracting(CreateIndexSpecification::getKeyspace) .contains(CqlIdentifier.fromCql("some_ks")); - String cql = CreateIndexCqlGenerator.toCql(index.get(0)); + String cql = CqlGenerator.toCql(index.get(0)); assertThat(cql).contains("CREATE INDEX ON some_ks.withkeyspace (id)"); } diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/AlterTableCqlGeneratorIntegrationTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/AlterTableCqlGeneratorIntegrationTests.java index 0d8e0ce63..59eed38ce 100755 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/AlterTableCqlGeneratorIntegrationTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/AlterTableCqlGeneratorIntegrationTests.java @@ -24,6 +24,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.data.cassandra.core.cql.keyspace.AlterTableSpecification; +import org.springframework.data.cassandra.core.cql.keyspace.SpecificationBuilder; import org.springframework.data.cassandra.core.cql.keyspace.TableOption; import org.springframework.data.cassandra.core.cql.keyspace.TableOption.CachingOption; import org.springframework.data.cassandra.core.cql.keyspace.TableOption.KeyCachingOption; @@ -65,7 +66,7 @@ void alterTableAlterColumnType() { session.execute( "CREATE TABLE addamsFamily (name varchar PRIMARY KEY, gender varchar,\n" + " lastknownlocation bigint);"); - AlterTableSpecification spec = AlterTableSpecification.alterTable("addamsFamily").alter("lastKnownLocation", + AlterTableSpecification spec = SpecificationBuilder.alterTable("addamsFamily").alter("lastKnownLocation", DataTypes.VARINT); execute(spec); @@ -83,7 +84,7 @@ void alterTableAlterListColumnType() { session.execute( "CREATE TABLE addamsFamily (name varchar PRIMARY KEY, gender varchar,\n" + " lastknownlocation list);"); - AlterTableSpecification spec = AlterTableSpecification.alterTable("addamsFamily").alter("lastKnownLocation", + AlterTableSpecification spec = SpecificationBuilder.alterTable("addamsFamily").alter("lastKnownLocation", DataTypes.listOf(DataTypes.TEXT)); execute(spec); @@ -99,7 +100,7 @@ void alterTableAddColumn() { session.execute( "CREATE TABLE addamsFamily (name varchar PRIMARY KEY, gender varchar,\n" + " lastknownlocation varchar);"); - AlterTableSpecification spec = AlterTableSpecification.alterTable("addamsFamily").add("gravesite", DataTypes.TEXT); + AlterTableSpecification spec = SpecificationBuilder.alterTable("addamsFamily").add("gravesite", DataTypes.TEXT); execute(spec); @@ -113,7 +114,7 @@ void alterTableAddListColumn() { session.execute("CREATE TABLE users (user_name varchar PRIMARY KEY);"); - AlterTableSpecification spec = AlterTableSpecification.alterTable("users").add("top_places", + AlterTableSpecification spec = SpecificationBuilder.alterTable("users").add("top_places", DataTypes.listOf(DataTypes.ASCII)); execute(spec); @@ -128,7 +129,7 @@ void alterTableDropColumn() { session.execute("CREATE TABLE addamsFamily (name varchar PRIMARY KEY, gender varchar);"); - AlterTableSpecification spec = AlterTableSpecification.alterTable("addamsFamily").drop("gender"); + AlterTableSpecification spec = SpecificationBuilder.alterTable("addamsFamily").drop("gender"); execute(spec); @@ -140,7 +141,7 @@ void alterTableRenameColumn() { session.execute("CREATE TABLE addamsFamily (name varchar PRIMARY KEY, firstname varchar);"); - AlterTableSpecification spec = AlterTableSpecification.alterTable("addamsFamily").rename("name", "newname"); + AlterTableSpecification spec = SpecificationBuilder.alterTable("addamsFamily").rename("name", "newname"); execute(spec); @@ -157,7 +158,7 @@ void alterTableAddCaching() { cachingMap.put(CachingOption.KEYS, KeyCachingOption.NONE); cachingMap.put(CachingOption.ROWS_PER_PARTITION, "15"); - AlterTableSpecification spec = AlterTableSpecification.alterTable("users").with(TableOption.CACHING, cachingMap); + AlterTableSpecification spec = SpecificationBuilder.alterTable("users").with(TableOption.CACHING, cachingMap); execute(spec); @@ -165,7 +166,7 @@ void alterTableAddCaching() { } private void execute(AlterTableSpecification spec) { - session.execute(new AlterTableCqlGenerator(spec).toCql()); + session.execute(CqlGenerator.toCql(spec)); } private TableMetadata getTableMetadata(String table) { diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/AlterTableCqlGeneratorUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/AlterTableCqlGeneratorUnitTests.java index 61c63398a..160d4ee80 100755 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/AlterTableCqlGeneratorUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/AlterTableCqlGeneratorUnitTests.java @@ -22,6 +22,7 @@ import org.junit.jupiter.api.Test; import org.springframework.data.cassandra.core.cql.keyspace.AlterTableSpecification; +import org.springframework.data.cassandra.core.cql.keyspace.SpecificationBuilder; import org.springframework.data.cassandra.core.cql.keyspace.TableOption; import org.springframework.data.cassandra.core.cql.keyspace.TableOption.CachingOption; import org.springframework.data.cassandra.core.cql.keyspace.TableOption.KeyCachingOption; @@ -40,7 +41,7 @@ class AlterTableCqlGeneratorUnitTests { @Test // DATACASS-192 void alterTableAlterColumnType() { - AlterTableSpecification spec = AlterTableSpecification.alterTable("addamsFamily").alter("lastKnownLocation", + AlterTableSpecification spec = SpecificationBuilder.alterTable("addamsFamily").alter("lastKnownLocation", DataTypes.UUID); assertThat(toCql(spec)).isEqualTo("ALTER TABLE addamsfamily ALTER lastknownlocation TYPE uuid;"); @@ -49,7 +50,7 @@ void alterTableAlterColumnType() { @Test // DATACASS-192 void alterTableAlterListColumnType() { - AlterTableSpecification spec = AlterTableSpecification.alterTable("addamsFamily").alter("lastKnownLocation", + AlterTableSpecification spec = SpecificationBuilder.alterTable("addamsFamily").alter("lastKnownLocation", DataTypes.listOf(DataTypes.ASCII)); assertThat(toCql(spec)).isEqualTo("ALTER TABLE addamsfamily ALTER lastknownlocation TYPE list;"); @@ -58,7 +59,7 @@ void alterTableAlterListColumnType() { @Test // DATACASS-192 void alterTableAddColumn() { - AlterTableSpecification spec = AlterTableSpecification.alterTable("addamsFamily").add("gravesite", DataTypes.TEXT); + AlterTableSpecification spec = SpecificationBuilder.alterTable("addamsFamily").add("gravesite", DataTypes.TEXT); assertThat(toCql(spec)).isEqualTo("ALTER TABLE addamsfamily ADD gravesite text;"); } @@ -66,7 +67,7 @@ void alterTableAddColumn() { @Test // DATACASS-192 void alterTableAddListColumn() { - AlterTableSpecification spec = AlterTableSpecification.alterTable("users").add("top_places", + AlterTableSpecification spec = SpecificationBuilder.alterTable("users").add("top_places", DataTypes.listOf(DataTypes.ASCII)); assertThat(toCql(spec)).isEqualTo("ALTER TABLE users ADD top_places list;"); @@ -75,7 +76,7 @@ void alterTableAddListColumn() { @Test // DATACASS-192 void alterTableDropColumn() { - AlterTableSpecification spec = AlterTableSpecification.alterTable("addamsFamily").drop("gender"); + AlterTableSpecification spec = SpecificationBuilder.alterTable("addamsFamily").drop("gender"); assertThat(toCql(spec)).isEqualTo("ALTER TABLE addamsfamily DROP gender;"); } @@ -83,7 +84,7 @@ void alterTableDropColumn() { @Test // DATACASS-192 void alterTableRenameColumn() { - AlterTableSpecification spec = AlterTableSpecification.alterTable("addamsFamily").rename("firstname", "lastname"); + AlterTableSpecification spec = SpecificationBuilder.alterTable("addamsFamily").rename("firstname", "lastname"); assertThat(toCql(spec)).isEqualTo("ALTER TABLE addamsfamily RENAME firstname TO lastname;"); } @@ -91,7 +92,7 @@ void alterTableRenameColumn() { @Test // DATACASS-192 void alterTableAddCommentAndTableOption() { - AlterTableSpecification spec = AlterTableSpecification.alterTable("addamsFamily") + AlterTableSpecification spec = SpecificationBuilder.alterTable("addamsFamily") .with(TableOption.READ_REPAIR_CHANCE, 0.2f).with(TableOption.COMMENT, "A most excellent and useful table"); assertThat(toCql(spec)).isEqualTo( @@ -101,7 +102,7 @@ void alterTableAddCommentAndTableOption() { @Test // DATACASS-192 void alterTableAddColumnAndComment() { - AlterTableSpecification spec = AlterTableSpecification.alterTable("addamsFamily") + AlterTableSpecification spec = SpecificationBuilder.alterTable("addamsFamily") .add("top_places", DataTypes.listOf(DataTypes.ASCII)).add("other", DataTypes.listOf(DataTypes.ASCII)) .with(TableOption.COMMENT, "A most excellent and useful table"); @@ -116,13 +117,13 @@ void alterTableAddCaching() { cachingMap.put(CachingOption.KEYS, KeyCachingOption.NONE); cachingMap.put(CachingOption.ROWS_PER_PARTITION, "15"); - AlterTableSpecification spec = AlterTableSpecification.alterTable("users").with(TableOption.CACHING, cachingMap); + AlterTableSpecification spec = SpecificationBuilder.alterTable("users").with(TableOption.CACHING, cachingMap); assertThat(toCql(spec)) .isEqualTo("ALTER TABLE users WITH caching = { 'keys' : 'none', 'rows_per_partition' : '15' };"); } private String toCql(AlterTableSpecification spec) { - return new AlterTableCqlGenerator(spec).toCql(); + return CqlGenerator.toCql(spec); } } diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/AlterUserTypeCqlGeneratorIntegrationTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/AlterUserTypeCqlGeneratorIntegrationTests.java index 24f09d8ed..1f571126f 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/AlterUserTypeCqlGeneratorIntegrationTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/AlterUserTypeCqlGeneratorIntegrationTests.java @@ -17,11 +17,12 @@ import static org.assertj.core.api.Assertions.*; import static org.junit.Assume.*; -import static org.springframework.data.cassandra.core.cql.generator.AlterUserTypeCqlGenerator.*; +import static org.springframework.data.cassandra.core.cql.generator.CqlGenerator.*; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.data.cassandra.core.cql.keyspace.AlterUserTypeSpecification; +import org.springframework.data.cassandra.core.cql.keyspace.SpecificationBuilder; import org.springframework.data.cassandra.support.CassandraVersion; import org.springframework.data.cassandra.test.util.AbstractKeyspaceCreatingIntegrationTests; import org.springframework.data.util.Version; @@ -52,7 +53,7 @@ void setUp() throws Exception { @Test // DATACASS-172 void alterTypeShouldAddField() { - AlterUserTypeSpecification spec = AlterUserTypeSpecification.alterType("address")// + AlterUserTypeSpecification spec = SpecificationBuilder.alterType("address")// .add("street", DataTypes.TEXT); session.execute(toCql(spec)); @@ -63,7 +64,7 @@ void alterTypeShouldAlterField() { assumeTrue(cassandraVersion.isLessThan(CASSANDRA_3_10) && cassandraVersion.isLessThan(CASSANDRA_3_0_10)); - AlterUserTypeSpecification spec = AlterUserTypeSpecification.alterType("address")// + AlterUserTypeSpecification spec = SpecificationBuilder.alterType("address")// .alter("zip", DataTypes.TEXT); session.execute(toCql(spec)); @@ -72,7 +73,7 @@ void alterTypeShouldAlterField() { @Test // DATACASS-172 void alterTypeShouldRenameField() { - AlterUserTypeSpecification spec = AlterUserTypeSpecification.alterType("address")// + AlterUserTypeSpecification spec = SpecificationBuilder.alterType("address")// .rename("zip", "zap"); session.execute(toCql(spec)); @@ -81,7 +82,7 @@ void alterTypeShouldRenameField() { @Test // DATACASS-172 void alterTypeShouldRenameFields() { - AlterUserTypeSpecification spec = AlterUserTypeSpecification.alterType("address")// + AlterUserTypeSpecification spec = SpecificationBuilder.alterType("address")// .rename("zip", "zap") // .rename("state", "county"); @@ -90,11 +91,11 @@ void alterTypeShouldRenameFields() { @Test // DATACASS-172 void generationFailsIfNameIsNotSet() { - assertThatNullPointerException().isThrownBy(() -> toCql(AlterUserTypeSpecification.alterType(null))); + assertThatNullPointerException().isThrownBy(() -> toCql(SpecificationBuilder.alterType(null))); } @Test // DATACASS-172 void generationFailsWithoutFields() { - assertThatIllegalArgumentException().isThrownBy(() -> toCql(AlterUserTypeSpecification.alterType("hello"))); + assertThatIllegalArgumentException().isThrownBy(() -> toCql(SpecificationBuilder.alterType("hello"))); } } diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/AlterUserTypeCqlGeneratorUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/AlterUserTypeCqlGeneratorUnitTests.java index 19a26618f..a068e73cd 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/AlterUserTypeCqlGeneratorUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/AlterUserTypeCqlGeneratorUnitTests.java @@ -16,10 +16,10 @@ package org.springframework.data.cassandra.core.cql.generator; import static org.assertj.core.api.Assertions.*; -import static org.springframework.data.cassandra.core.cql.generator.AlterUserTypeCqlGenerator.*; import org.junit.jupiter.api.Test; import org.springframework.data.cassandra.core.cql.keyspace.AlterUserTypeSpecification; +import org.springframework.data.cassandra.core.cql.keyspace.SpecificationBuilder; import com.datastax.oss.driver.api.core.type.DataTypes; @@ -33,43 +33,44 @@ class AlterUserTypeCqlGeneratorUnitTests { @Test // DATACASS-172 void alterTypeShouldAddField() { - AlterUserTypeSpecification spec = AlterUserTypeSpecification.alterType("address") // + AlterUserTypeSpecification spec = SpecificationBuilder.alterType("address") // .add("zip", DataTypes.TEXT); - assertThat(toCql(spec)).isEqualTo("ALTER TYPE address ADD zip text;"); + assertThat(CqlGenerator.toCql(spec)).isEqualTo("ALTER TYPE address ADD zip text;"); } @Test // DATACASS-172 void alterTypeShouldAlterField() { - AlterUserTypeSpecification spec = AlterUserTypeSpecification.alterType("address") // + AlterUserTypeSpecification spec = SpecificationBuilder.alterType("address") // .alter("zip", DataTypes.TEXT); - assertThat(toCql(spec)).isEqualTo("ALTER TYPE address ALTER zip TYPE text;"); + assertThat(CqlGenerator.toCql(spec)).isEqualTo("ALTER TYPE address ALTER zip TYPE text;"); } @Test // DATACASS-172 void alterTypeShouldRenameField() { - AlterUserTypeSpecification spec = AlterUserTypeSpecification.alterType("address") // + AlterUserTypeSpecification spec = SpecificationBuilder.alterType("address") // .rename("zip", "zap"); - assertThat(toCql(spec)).isEqualTo("ALTER TYPE address RENAME zip TO zap;"); + assertThat(CqlGenerator.toCql(spec)).isEqualTo("ALTER TYPE address RENAME zip TO zap;"); } @Test // DATACASS-172 void alterTypeShouldRenameFields() { - AlterUserTypeSpecification spec = AlterUserTypeSpecification.alterType("address") // + AlterUserTypeSpecification spec = SpecificationBuilder.alterType("address") // .rename("zip", "zap") // .rename("city", "county"); - assertThat(toCql(spec)).isEqualTo("ALTER TYPE address RENAME zip TO zap AND city TO county;"); + assertThat(CqlGenerator.toCql(spec)).isEqualTo("ALTER TYPE address RENAME zip TO zap AND city TO county;"); } @Test // DATACASS-172 void generationFailsWithoutFields() { - assertThatIllegalArgumentException().isThrownBy(() -> toCql(AlterUserTypeSpecification.alterType("hello"))); + assertThatIllegalArgumentException() + .isThrownBy(() -> AlterUserTypeCqlGenerator.toCql(AlterUserTypeSpecification.alterType("hello"))); } } diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/CreateIndexCqlGeneratorUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/CreateIndexCqlGeneratorUnitTests.java index d2e2677e1..e06eb8544 100755 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/CreateIndexCqlGeneratorUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/CreateIndexCqlGeneratorUnitTests.java @@ -20,6 +20,7 @@ import org.junit.jupiter.api.Test; import org.springframework.data.cassandra.core.cql.keyspace.CreateIndexSpecification; +import org.springframework.data.cassandra.core.cql.keyspace.SpecificationBuilder; import com.datastax.oss.driver.api.core.CqlIdentifier; @@ -35,67 +36,67 @@ class CreateIndexCqlGeneratorUnitTests { @Test // DATACASS-213 void createIndex() { - CreateIndexSpecification spec = CreateIndexSpecification.createIndex("myindex").tableName("mytable") + CreateIndexSpecification spec = SpecificationBuilder.createIndex("myindex").tableName("mytable") .columnName("column"); - assertThat(CreateIndexCqlGenerator.toCql(spec)).isEqualTo("CREATE INDEX myindex ON mytable (column);"); + assertThat(CqlGenerator.toCql(spec)).isEqualTo("CREATE INDEX myindex ON mytable (column);"); } @Test // GH-921 void shouldConsiderKeyspace() { - CreateIndexSpecification spec = CreateIndexSpecification + CreateIndexSpecification spec = SpecificationBuilder .createIndex(CqlIdentifier.fromCql("myks"), CqlIdentifier.fromCql("myindex")).tableName("mytable") .columnName("column"); - assertThat(CreateIndexCqlGenerator.toCql(spec)).isEqualTo("CREATE INDEX myks.myindex ON myks.mytable (column);"); + assertThat(CqlGenerator.toCql(spec)).isEqualTo("CREATE INDEX myks.myindex ON myks.mytable (column);"); } @Test // DATACASS-213 void createCustomIndex() { - CreateIndexSpecification spec = CreateIndexSpecification.createIndex("myindex").tableName("mytable") + CreateIndexSpecification spec = SpecificationBuilder.createIndex("myindex").tableName("mytable") .columnName("column").using("indexclass"); - assertThat(CreateIndexCqlGenerator.toCql(spec)) + assertThat(CqlGenerator.toCql(spec)) .isEqualTo("CREATE CUSTOM INDEX myindex ON mytable (column) USING 'indexclass';"); } @Test // DATACASS-213 void createIndexOnKeys() { - CreateIndexSpecification spec = CreateIndexSpecification.createIndex().tableName("mytable").keys() + CreateIndexSpecification spec = SpecificationBuilder.createIndex().tableName("mytable").keys() .columnName("column"); - assertThat(CreateIndexCqlGenerator.toCql(spec)).isEqualTo("CREATE INDEX ON mytable (KEYS(column));"); + assertThat(CqlGenerator.toCql(spec)).isEqualTo("CREATE INDEX ON mytable (KEYS(column));"); } @Test // DATACASS-213 void createIndexIfNotExists() { - CreateIndexSpecification spec = CreateIndexSpecification.createIndex().tableName("mytable").columnName("column") + CreateIndexSpecification spec = SpecificationBuilder.createIndex().tableName("mytable").columnName("column") .ifNotExists(); - assertThat(CreateIndexCqlGenerator.toCql(spec)).isEqualTo("CREATE INDEX IF NOT EXISTS ON mytable (column);"); + assertThat(CqlGenerator.toCql(spec)).isEqualTo("CREATE INDEX IF NOT EXISTS ON mytable (column);"); } @Test // DATACASS-306 void createIndexWithOptions() { - CreateIndexSpecification spec = CreateIndexSpecification.createIndex().tableName("mytable").columnName("column") + CreateIndexSpecification spec = SpecificationBuilder.createIndex().tableName("mytable").columnName("column") .withOption("foo", "b'a'r").withOption("type", "PREFIX"); - assertThat(CreateIndexCqlGenerator.toCql(spec)) + assertThat(CqlGenerator.toCql(spec)) .isEqualTo("CREATE INDEX ON mytable (column) WITH OPTIONS = {'foo': 'b''a''r', 'type': 'PREFIX'};"); } @Test // GH-1281 void createIndexWithQuotation() { - CreateIndexSpecification spec = CreateIndexSpecification.createIndex("order_dob").columnName("\"order\"") + CreateIndexSpecification spec = SpecificationBuilder.createIndex("order_dob").columnName("\"order\"") .tableName(CqlIdentifier.fromInternal("order")); - assertThat(CreateIndexCqlGenerator.toCql(spec)).isEqualTo("CREATE INDEX order_dob ON \"order\" (\"order\");"); + assertThat(CqlGenerator.toCql(spec)).isEqualTo("CREATE INDEX order_dob ON \"order\" (\"order\");"); } } diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/CreateKeyspaceCqlGeneratorUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/CreateKeyspaceCqlGeneratorUnitTests.java index 37f815c86..e8a354d23 100755 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/CreateKeyspaceCqlGeneratorUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/CreateKeyspaceCqlGeneratorUnitTests.java @@ -26,6 +26,7 @@ import org.springframework.data.cassandra.core.cql.keyspace.KeyspaceAttributes; import org.springframework.data.cassandra.core.cql.keyspace.KeyspaceOption; import org.springframework.data.cassandra.core.cql.keyspace.Option; +import org.springframework.data.cassandra.core.cql.keyspace.SpecificationBuilder; import org.springframework.data.cassandra.support.RandomKeyspaceName; /** @@ -81,7 +82,7 @@ static class BasicTest extends CreateKeyspaceTest { public CreateKeyspaceSpecification specification() { keyspace = name; - return CreateKeyspaceSpecification.createKeyspace(keyspace) + return SpecificationBuilder.createKeyspace(keyspace) .with(KeyspaceOption.REPLICATION, replicationMap).with(KeyspaceOption.DURABLE_WRITES, durableWrites); } diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/CreateTableCqlGeneratorIntegrationTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/CreateTableCqlGeneratorIntegrationTests.java index ecff73078..9c22ff595 100755 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/CreateTableCqlGeneratorIntegrationTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/CreateTableCqlGeneratorIntegrationTests.java @@ -44,10 +44,9 @@ void setUp() { session.execute("DROP TABLE IF EXISTS person;"); session.execute("DROP TABLE IF EXISTS address;"); - session.execute("DROP KEYSPACE IF EXISTS CreateTableCqlGenerator_it;"); + session.execute("DROP KEYSPACE IF EXISTS CqlGenerator_it;"); session.execute( - "CREATE KEYSPACE CreateTableCqlGenerator_it WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1};"); - + "CREATE KEYSPACE CqlGenerator_it WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1};"); } @Test // DATACASS-518 @@ -58,7 +57,7 @@ void shouldGenerateSimpleTable() { .clusteredKeyColumn("date_of_birth", DataTypes.DATE) // .column("name", DataTypes.ASCII); - session.execute(CreateTableCqlGenerator.toCql(table)); + session.execute(CqlGenerator.toCql(table)); } @Test // DATACASS-518 @@ -71,7 +70,7 @@ void shouldGenerateTableWithClusterKeyOrdering() { .clusteredKeyColumn("age", DataTypes.SMALLINT) // .column("name", DataTypes.ASCII); - session.execute(CreateTableCqlGenerator.toCql(table)); + session.execute(CqlGenerator.toCql(table)); TableMetadata person = session.getMetadata().getKeyspace(getKeyspace()).flatMap(it -> it.getTable("person")).get(); assertThat(person.getPartitionKey()).hasSize(2); @@ -86,7 +85,7 @@ void shouldGenerateTableWithClusterKeyAndOptions() { .clusteredKeyColumn("date_of_birth", DataTypes.DATE, Ordering.ASCENDING) // .column("name", DataTypes.ASCII).with(TableOption.COMPACT_STORAGE); - session.execute(CreateTableCqlGenerator.toCql(table)); + session.execute(CqlGenerator.toCql(table)); TableMetadata person = session.getMetadata().getKeyspace(getKeyspace()).flatMap(it -> it.getTable("person")).get(); assertThat(person.getPartitionKey()).hasSize(1); @@ -97,15 +96,15 @@ void shouldGenerateTableWithClusterKeyAndOptions() { void shouldGenerateTableInOtherKeyspace() { CreateTableSpecification table = CreateTableSpecification - .createTable(CqlIdentifier.fromCql("CreateTableCqlGenerator_it"), CqlIdentifier.fromCql("person")) // + .createTable(CqlIdentifier.fromCql("CqlGenerator_it"), CqlIdentifier.fromCql("person")) // .partitionKeyColumn("id", DataTypes.ASCII) // .clusteredKeyColumn("date_of_birth", DataTypes.DATE, Ordering.ASCENDING) // .column("name", DataTypes.ASCII).with(TableOption.COMPACT_STORAGE); - session.execute(CreateTableCqlGenerator.toCql(table)); + session.execute(CqlGenerator.toCql(table)); - TableMetadata person = session.getMetadata().getKeyspace("CreateTableCqlGenerator_it") - .flatMap(it -> it.getTable("person")).get(); + TableMetadata person = session.getMetadata().getKeyspace("CqlGenerator_it").flatMap(it -> it.getTable("person")) + .get(); assertThat(person.getPartitionKey()).hasSize(1); assertThat(person.getClusteringColumns()).hasSize(1); } diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/CreateTableCqlGeneratorUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/CreateTableCqlGeneratorUnitTests.java index d16959082..8b7d77aeb 100755 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/CreateTableCqlGeneratorUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/CreateTableCqlGeneratorUnitTests.java @@ -16,7 +16,6 @@ package org.springframework.data.cassandra.core.cql.generator; import static org.assertj.core.api.Assertions.*; -import static org.springframework.data.cassandra.core.cql.generator.CreateTableCqlGenerator.*; import java.util.LinkedHashMap; import java.util.Map; @@ -57,7 +56,7 @@ void shouldGenerateCorrectCQL() { CreateTableSpecification table = CreateTableSpecification.createTable(name) .partitionKeyColumn(partitionKey0, partitionKeyType0).column(column1, columnType1); - String cql = toCql(table); + String cql = CqlGenerator.toCql(table); assertPreamble(name, cql); assertColumns("partitionkey0 text, column1 text", cql); assertPrimaryKey(partitionKey0.toString(), cql); @@ -78,7 +77,7 @@ void shouldGenerateCompositePrimaryKey() { .partitionKeyColumn(partKey0, partKeyType0).partitionKeyColumn(partKey1, partKeyType1) .column(column0, columnType0); - String cql = toCql(table); + String cql = CqlGenerator.toCql(table); assertPreamble(name, cql); assertColumns("partkey0 text, partkey1 text, column0 text", cql); @@ -101,7 +100,7 @@ void shouldGenerateTableOptions() { .partitionKeyColumn(partitionKey0, partitionKeyType0).partitionKeyColumn(partitionKey1, partitionKeyType1) .column(column1, columnType1).with(TableOption.READ_REPAIR_CHANCE, readRepairChance); - String cql = toCql(table); + String cql = CqlGenerator.toCql(table); assertPreamble(name, cql); assertColumns("partitionkey0 text, create_timestamp timestamp, column1 text", cql); @@ -149,7 +148,7 @@ void shouldGenerateMultipleOptions() { .with(TableOption.DCLOCAL_READ_REPAIR_CHANCE, dcLocalReadRepairChance) .with(TableOption.GC_GRACE_SECONDS, gcGraceSeconds); - String cql = toCql(table); + String cql = CqlGenerator.toCql(table); assertPreamble(name, cql); assertColumns("tid timeuuid, create_timestamp timestamp, data_point text", cql); @@ -170,7 +169,7 @@ void createTableWithOrderedClustering() { .clusteredKeyColumn("date_of_birth", DataTypes.DATE, Ordering.ASCENDING) // .column("name", DataTypes.ASCII); - assertThat(toCql(table)).isEqualTo("CREATE TABLE person (id ascii, date_of_birth date, name ascii, " // + assertThat(CqlGenerator.toCql(table)).isEqualTo("CREATE TABLE person (id ascii, date_of_birth date, name ascii, " // + "PRIMARY KEY (id, date_of_birth)) " // + "WITH CLUSTERING ORDER BY (date_of_birth ASC);"); } @@ -183,7 +182,7 @@ void createTableWithOrderedClusteringAndOptions() { .clusteredKeyColumn("date_of_birth", DataTypes.DATE, Ordering.ASCENDING) // .column("name", DataTypes.ASCII).with(TableOption.COMPACT_STORAGE); - assertThat(toCql(table)).isEqualTo("CREATE TABLE person (id ascii, date_of_birth date, name ascii, " // + assertThat(CqlGenerator.toCql(table)).isEqualTo("CREATE TABLE person (id ascii, date_of_birth date, name ascii, " // + "PRIMARY KEY (id, date_of_birth)) " // + "WITH CLUSTERING ORDER BY (date_of_birth ASC) AND COMPACT STORAGE;"); } @@ -197,10 +196,9 @@ void createTableWithStaticColumns() { .column("name", DataTypes.ASCII) .staticColumn("country", DataTypes.ASCII); - assertThat(toCql(table)).isEqualTo("CREATE TABLE person (" - + "id ascii, date_of_birth date, name ascii, country ascii STATIC, " - + "PRIMARY KEY (id, date_of_birth)) " - + "WITH CLUSTERING ORDER BY (date_of_birth ASC);"); + assertThat(CqlGenerator.toCql(table)) + .isEqualTo("CREATE TABLE person (" + "id ascii, date_of_birth date, name ascii, country ascii STATIC, " + + "PRIMARY KEY (id, date_of_birth)) " + "WITH CLUSTERING ORDER BY (date_of_birth ASC);"); } @Test // GH-921 @@ -210,7 +208,7 @@ void shouldConsiderKeyspace() { .createTable(CqlIdentifier.fromCql("myks"), CqlIdentifier.fromCql("person")) .partitionKeyColumn("id", DataTypes.ASCII); - assertThat(toCql(table)).isEqualTo("CREATE TABLE myks.person (" + "id ascii, " + "PRIMARY KEY (id));"); + assertThat(CqlGenerator.toCql(table)).isEqualTo("CREATE TABLE myks.person (" + "id ascii, " + "PRIMARY KEY (id));"); } /** diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/CreateUserTypeCqlGeneratorIntegrationTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/CreateUserTypeCqlGeneratorIntegrationTests.java index 491ad2a0a..83f877a75 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/CreateUserTypeCqlGeneratorIntegrationTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/CreateUserTypeCqlGeneratorIntegrationTests.java @@ -16,13 +16,13 @@ package org.springframework.data.cassandra.core.cql.generator; import static org.assertj.core.api.Assertions.*; -import static org.springframework.data.cassandra.core.cql.generator.CreateUserTypeCqlGenerator.*; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.data.cassandra.core.cql.keyspace.CreateTableSpecification; import org.springframework.data.cassandra.core.cql.keyspace.CreateUserTypeSpecification; +import org.springframework.data.cassandra.core.cql.keyspace.SpecificationBuilder; import org.springframework.data.cassandra.test.util.AbstractKeyspaceCreatingIntegrationTests; import com.datastax.oss.driver.api.core.CqlIdentifier; @@ -52,12 +52,12 @@ void setUp() throws Exception { @Test // DATACASS-172 void createUserType() { - CreateUserTypeSpecification spec = CreateUserTypeSpecification // + CreateUserTypeSpecification spec = SpecificationBuilder // .createType("address") // .field("zip", DataTypes.ASCII) // .field("city", DataTypes.TEXT); - session.execute(toCql(spec)); + session.execute(CqlGenerator.toCql(spec)); KeyspaceMetadata keyspace = session.getMetadata().getKeyspace(session.getKeyspace().get()).get(); UserDefinedType address = keyspace.getUserDefinedType("address").get(); @@ -67,11 +67,11 @@ void createUserType() { @Test // DATACASS-172 void createUserTypeIfNotExists() { - CreateUserTypeSpecification spec = CreateUserTypeSpecification // + CreateUserTypeSpecification spec = SpecificationBuilder // .createType("address").ifNotExists().field("zip", DataTypes.ASCII) // .field("city", DataTypes.TEXT); - session.execute(toCql(spec)); + session.execute(CqlGenerator.toCql(spec)); KeyspaceMetadata keyspace = session.getMetadata().getKeyspace(session.getKeyspace().get()).get(); UserDefinedType address = keyspace.getUserDefinedType("address").get(); @@ -81,11 +81,11 @@ void createUserTypeIfNotExists() { @Test // DATACASS-172, DATACASS-424 void createNestedUserType() { - CreateUserTypeSpecification addressSpec = CreateUserTypeSpecification // + CreateUserTypeSpecification addressSpec = SpecificationBuilder // .createType("address").ifNotExists().field("zip", DataTypes.ASCII) // .field("city", DataTypes.TEXT); - session.execute(toCql(addressSpec)); + session.execute(CqlGenerator.toCql(addressSpec)); KeyspaceMetadata keyspace = session.getMetadata().getKeyspace(session.getKeyspace().get()).get(); UserDefinedType address = keyspace.getUserDefinedType("address").get(); @@ -94,26 +94,26 @@ void createNestedUserType() { .createType("person").ifNotExists().field("address", address.copy(true)) // .field("city", DataTypes.TEXT); - session.execute(toCql(personSpec)); + session.execute(CqlGenerator.toCql(personSpec)); } @Test // DATACASS-172 void shouldGenerateTypeAndTableInOtherKeyspace() { - CreateUserTypeSpecification spec = CreateUserTypeSpecification // + CreateUserTypeSpecification spec = SpecificationBuilder // .createType(CqlIdentifier.fromCql("CreateUserTypeCqlGenerator_it"), CqlIdentifier.fromCql("address")) .ifNotExists().field("zip", DataTypes.ASCII) // .field("city", DataTypes.TEXT); - session.execute(toCql(spec)); + session.execute(CqlGenerator.toCql(spec)); - CreateTableSpecification table = CreateTableSpecification + CreateTableSpecification table = SpecificationBuilder .createTable(CqlIdentifier.fromCql("CreateUserTypeCqlGenerator_it"), CqlIdentifier.fromCql("person")) .partitionKeyColumn("id", DataTypes.ASCII)// .column("udtref", new ShallowUserDefinedType(CqlIdentifier.fromCql("CreateUserTypeCqlGenerator_it"), CqlIdentifier.fromCql("address"), true)); - session.execute(CreateTableCqlGenerator.toCql(table)); + session.execute(CqlGenerator.toCql(table)); KeyspaceMetadata keyspace = session.getMetadata().getKeyspace("CreateUserTypeCqlGenerator_it").get(); UserDefinedType address = keyspace.getUserDefinedType("address").get(); diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/CreateUserTypeCqlGeneratorUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/CreateUserTypeCqlGeneratorUnitTests.java index ff4a373f9..d2f35785b 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/CreateUserTypeCqlGeneratorUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/CreateUserTypeCqlGeneratorUnitTests.java @@ -16,11 +16,11 @@ package org.springframework.data.cassandra.core.cql.generator; import static org.assertj.core.api.Assertions.*; -import static org.springframework.data.cassandra.core.cql.generator.CreateUserTypeCqlGenerator.*; import org.junit.jupiter.api.Test; import org.springframework.data.cassandra.core.cql.keyspace.CreateUserTypeSpecification; +import org.springframework.data.cassandra.core.cql.keyspace.SpecificationBuilder; import com.datastax.oss.driver.api.core.CqlIdentifier; import com.datastax.oss.driver.api.core.type.DataTypes; @@ -35,11 +35,11 @@ class CreateUserTypeCqlGeneratorUnitTests { @Test // DATACASS-172 void createUserType() { - CreateUserTypeSpecification spec = CreateUserTypeSpecification // + CreateUserTypeSpecification spec = SpecificationBuilder // .createType("address") // .field("city", DataTypes.TEXT); - assertThat(toCql(spec)).isEqualTo("CREATE TYPE address (city text);"); + assertThat(CqlGenerator.toCql(spec)).isEqualTo("CREATE TYPE address (city text);"); } @Test // DATACASS-921 @@ -49,7 +49,7 @@ void shouldConsiderKeyspace() { .createType(CqlIdentifier.fromCql("myks"), CqlIdentifier.fromCql("address")) // .field("city", DataTypes.TEXT); - assertThat(toCql(spec)).isEqualTo("CREATE TYPE myks.address (city text);"); + assertThat(CqlGenerator.toCql(spec)).isEqualTo("CREATE TYPE myks.address (city text);"); } @Test // DATACASS-172 @@ -60,7 +60,7 @@ void createMultiFieldUserType() { .field("zip", DataTypes.ASCII) // .field("city", DataTypes.TEXT); - assertThat(toCql(spec)).isEqualTo("CREATE TYPE address (zip ascii, city text);"); + assertThat(CqlGenerator.toCql(spec)).isEqualTo("CREATE TYPE address (zip ascii, city text);"); } @Test // DATACASS-172 @@ -70,11 +70,12 @@ void createUserTypeIfNotExists() { .createType("address").ifNotExists().field("zip", DataTypes.ASCII) // .field("city", DataTypes.TEXT); - assertThat(toCql(spec)).isEqualTo("CREATE TYPE IF NOT EXISTS address (zip ascii, city text);"); + assertThat(CqlGenerator.toCql(spec)).isEqualTo("CREATE TYPE IF NOT EXISTS address (zip ascii, city text);"); } @Test // DATACASS-172 void generationFailsWithoutFields() { - assertThatIllegalArgumentException().isThrownBy(() -> toCql(CreateUserTypeSpecification.createType("hello"))); + assertThatIllegalArgumentException() + .isThrownBy(() -> CqlGenerator.toCql(CreateUserTypeSpecification.createType("hello"))); } } diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/DropIndexCqlGeneratorUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/DropIndexCqlGeneratorUnitTests.java index 17cafbcc8..01569c51f 100755 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/DropIndexCqlGeneratorUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/DropIndexCqlGeneratorUnitTests.java @@ -44,7 +44,7 @@ void shouldConsiderKeyspace() { DropIndexSpecification spec = DropIndexSpecification.dropIndex(CqlIdentifier.fromCql("foo"), CqlIdentifier.fromCql("bar")); - assertThat(DropIndexCqlGenerator.toCql(spec)).isEqualTo("DROP INDEX foo.bar;"); + assertThat(CqlGenerator.toCql(spec)).isEqualTo("DROP INDEX foo.bar;"); } /** diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/DropKeyspaceCqlGeneratorUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/DropKeyspaceCqlGeneratorUnitTests.java index e486250f5..aebe7bd3b 100755 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/DropKeyspaceCqlGeneratorUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/DropKeyspaceCqlGeneratorUnitTests.java @@ -19,6 +19,7 @@ import org.junit.jupiter.api.Test; import org.springframework.data.cassandra.core.cql.keyspace.DropKeyspaceSpecification; +import org.springframework.data.cassandra.core.cql.keyspace.SpecificationBuilder; import org.springframework.data.cassandra.support.RandomKeyspaceName; /** @@ -49,7 +50,7 @@ static class BasicTest extends DropTableTest { @Override public DropKeyspaceSpecification specification() { - return DropKeyspaceSpecification.dropKeyspace(name); + return SpecificationBuilder.dropKeyspace(name); } @Override diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/DropTableCqlGeneratorUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/DropTableCqlGeneratorUnitTests.java index 795853302..580a01d03 100755 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/DropTableCqlGeneratorUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/DropTableCqlGeneratorUnitTests.java @@ -20,6 +20,7 @@ import org.junit.jupiter.api.Test; import org.springframework.data.cassandra.core.cql.keyspace.DropTableSpecification; +import org.springframework.data.cassandra.core.cql.keyspace.SpecificationBuilder; import com.datastax.oss.driver.api.core.CqlIdentifier; @@ -41,10 +42,10 @@ private static void assertStatement(String tableName, boolean ifExists, String c @Test // GH-921 void shouldConsiderKeyspace() { - DropTableSpecification spec = DropTableSpecification.dropTable(CqlIdentifier.fromCql("foo"), + DropTableSpecification spec = SpecificationBuilder.dropTable(CqlIdentifier.fromCql("foo"), CqlIdentifier.fromCql("bar")); - assertThat(DropTableCqlGenerator.toCql(spec)).isEqualTo("DROP TABLE foo.bar;"); + assertThat(CqlGenerator.toCql(spec)).isEqualTo("DROP TABLE foo.bar;"); } /** diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/DropUserTypeCqlGeneratorUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/DropUserTypeCqlGeneratorUnitTests.java index 69ada769f..d039cd590 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/DropUserTypeCqlGeneratorUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/cql/generator/DropUserTypeCqlGeneratorUnitTests.java @@ -16,11 +16,11 @@ package org.springframework.data.cassandra.core.cql.generator; import static org.assertj.core.api.Assertions.*; -import static org.springframework.data.cassandra.core.cql.generator.DropUserTypeCqlGenerator.*; import org.junit.jupiter.api.Test; import org.springframework.data.cassandra.core.cql.keyspace.DropUserTypeSpecification; +import org.springframework.data.cassandra.core.cql.keyspace.SpecificationBuilder; import com.datastax.oss.driver.api.core.CqlIdentifier; @@ -34,25 +34,25 @@ class DropUserTypeCqlGeneratorUnitTests { @Test // DATACASS-172 void shouldDropUserType() { - DropUserTypeSpecification spec = DropUserTypeSpecification.dropType("address"); + DropUserTypeSpecification spec = SpecificationBuilder.dropType("address"); - assertThat(toCql(spec)).isEqualTo("DROP TYPE address;"); + assertThat(CqlGenerator.toCql(spec)).isEqualTo("DROP TYPE address;"); } @Test // GH-921 void shouldConsiderKeyspace() { - DropUserTypeSpecification spec = DropUserTypeSpecification.dropType(CqlIdentifier.fromCql("foo"), + DropUserTypeSpecification spec = SpecificationBuilder.dropType(CqlIdentifier.fromCql("foo"), CqlIdentifier.fromCql("bar")); - assertThat(toCql(spec)).isEqualTo("DROP TYPE foo.bar;"); + assertThat(CqlGenerator.toCql(spec)).isEqualTo("DROP TYPE foo.bar;"); } @Test // DATACASS-172 void shouldDropUserTypeIfExists() { - DropUserTypeSpecification spec = DropUserTypeSpecification.dropType("address").ifExists(); + DropUserTypeSpecification spec = SpecificationBuilder.dropType("address").ifExists(); - assertThat(toCql(spec)).isEqualTo("DROP TYPE IF EXISTS address;"); + assertThat(CqlGenerator.toCql(spec)).isEqualTo("DROP TYPE IF EXISTS address;"); } } diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/QueryDerivationIntegrationTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/QueryDerivationIntegrationTests.java index 8c338f7a7..16d70a769 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/QueryDerivationIntegrationTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/QueryDerivationIntegrationTests.java @@ -37,7 +37,7 @@ import org.springframework.data.annotation.Id; import org.springframework.data.cassandra.config.SchemaAction; import org.springframework.data.cassandra.core.CassandraOperations; -import org.springframework.data.cassandra.core.cql.generator.CreateIndexCqlGenerator; +import org.springframework.data.cassandra.core.cql.generator.CqlGenerator; import org.springframework.data.cassandra.core.cql.keyspace.CreateIndexSpecification; import org.springframework.data.cassandra.core.mapping.Embedded; import org.springframework.data.cassandra.core.mapping.Indexed; @@ -179,7 +179,7 @@ public void shouldFindByMappedUdt() throws InterruptedException { CreateIndexSpecification indexSpecification = CreateIndexSpecification.createIndex("person_main_address") .ifNotExists().tableName("person").columnName("mainaddress"); - template.getCqlOperations().execute(CreateIndexCqlGenerator.toCql(indexSpecification)); + template.getCqlOperations().execute(CqlGenerator.toCql(indexSpecification)); // Give Cassandra some time to build the index Thread.sleep(500); @@ -195,7 +195,7 @@ public void shouldFindByMappedUdtStringQuery() throws InterruptedException { CreateIndexSpecification indexSpecification = CreateIndexSpecification.createIndex("person_main_address") .ifNotExists().tableName("person").columnName("mainaddress"); - template.getCqlOperations().execute(CreateIndexCqlGenerator.toCql(indexSpecification)); + template.getCqlOperations().execute(CqlGenerator.toCql(indexSpecification)); // Give Cassandra some time to build the index Thread.sleep(500); @@ -231,7 +231,7 @@ public void executesCollectionQueryWithDtoDynamicallyProjected() throws Exceptio CreateIndexSpecification indexSpecification = CreateIndexSpecification.createIndex("fn_starts_with").ifNotExists() .tableName("person").columnName("nickname").using("org.apache.cassandra.index.sasi.SASIIndex"); - template.getCqlOperations().execute(CreateIndexCqlGenerator.toCql(indexSpecification)); + template.getCqlOperations().execute(CqlGenerator.toCql(indexSpecification)); // Give Cassandra some time to build the index Thread.sleep(500); @@ -251,7 +251,7 @@ public void shouldFindByNumberOfChildren() throws Exception { CreateIndexSpecification indexSpecification = CreateIndexSpecification.createIndex("person_number_of_children") .ifNotExists().tableName("person").columnName("numberofchildren"); - template.getCqlOperations().execute(CreateIndexCqlGenerator.toCql(indexSpecification)); + template.getCqlOperations().execute(CqlGenerator.toCql(indexSpecification)); // Give Cassandra some time to build the index Thread.sleep(500); @@ -267,7 +267,7 @@ public void shouldFindByLocalDate() throws InterruptedException { CreateIndexSpecification indexSpecification = CreateIndexSpecification.createIndex("person_created_date") .ifNotExists().tableName("person").columnName("createddate"); - template.getCqlOperations().execute(CreateIndexCqlGenerator.toCql(indexSpecification)); + template.getCqlOperations().execute(CqlGenerator.toCql(indexSpecification)); // Give Cassandra some time to build the index Thread.sleep(500); @@ -300,7 +300,7 @@ public void shouldUseStartsWithQuery() throws InterruptedException { CreateIndexSpecification indexSpecification = CreateIndexSpecification.createIndex("fn_starts_with").ifNotExists() .tableName("person").columnName("nickname").using("org.apache.cassandra.index.sasi.SASIIndex"); - template.getCqlOperations().execute(CreateIndexCqlGenerator.toCql(indexSpecification)); + template.getCqlOperations().execute(CqlGenerator.toCql(indexSpecification)); // Give Cassandra some time to build the index Thread.sleep(500); @@ -320,7 +320,7 @@ public void shouldUseContainsQuery() throws InterruptedException { .tableName("person").columnName("nickname").using("org.apache.cassandra.index.sasi.SASIIndex") .withOption("mode", "CONTAINS"); - template.getCqlOperations().execute(CreateIndexCqlGenerator.toCql(indexSpecification)); + template.getCqlOperations().execute(CqlGenerator.toCql(indexSpecification)); // Give Cassandra some time to build the index Thread.sleep(500); diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/cdi/CassandraOperationsProducer.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/cdi/CassandraOperationsProducer.java index 8b937d6db..4b6081a8e 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/cdi/CassandraOperationsProducer.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/cdi/CassandraOperationsProducer.java @@ -28,10 +28,9 @@ import org.springframework.data.cassandra.core.CassandraPersistentEntitySchemaCreator; import org.springframework.data.cassandra.core.CassandraPersistentEntitySchemaDropper; import org.springframework.data.cassandra.core.convert.MappingCassandraConverter; -import org.springframework.data.cassandra.core.cql.generator.CreateKeyspaceCqlGenerator; -import org.springframework.data.cassandra.core.cql.generator.DropKeyspaceCqlGenerator; +import org.springframework.data.cassandra.core.cql.generator.CqlGenerator; import org.springframework.data.cassandra.core.cql.keyspace.CreateKeyspaceSpecification; -import org.springframework.data.cassandra.core.cql.keyspace.DropKeyspaceSpecification; +import org.springframework.data.cassandra.core.cql.keyspace.SpecificationBuilder; import org.springframework.data.cassandra.core.mapping.CassandraMappingContext; import org.springframework.data.cassandra.core.mapping.CassandraPersistentEntity; import org.springframework.data.cassandra.core.mapping.SimpleUserTypeResolver; @@ -73,7 +72,7 @@ public CassandraOperations createCassandraOperations(CqlSession session) throws CreateKeyspaceSpecification createKeyspaceSpecification = CreateKeyspaceSpecification.createKeyspace(KEYSPACE_NAME) .ifNotExists(); - cassandraTemplate.getCqlOperations().execute(CreateKeyspaceCqlGenerator.toCql(createKeyspaceSpecification)); + cassandraTemplate.getCqlOperations().execute(CqlGenerator.toCql(createKeyspaceSpecification)); cassandraTemplate.getCqlOperations().execute("USE " + KEYSPACE_NAME); CassandraPersistentEntitySchemaDropper schemaDropper = new CassandraPersistentEntitySchemaDropper(mappingContext, @@ -105,7 +104,7 @@ public CassandraOperations createQualifiedCassandraOperations(CassandraOperation public void close(@Disposes CassandraOperations cassandraOperations) { cassandraOperations.getCqlOperations() - .execute(DropKeyspaceCqlGenerator.toCql(DropKeyspaceSpecification.dropKeyspace(KEYSPACE_NAME))); + .execute(CqlGenerator.toCql(SpecificationBuilder.dropKeyspace(KEYSPACE_NAME))); } public void close(@Disposes CqlSession cqlSession) { diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/support/SchemaTestUtils.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/support/SchemaTestUtils.java index 0fb8db8bb..4fab57862 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/support/SchemaTestUtils.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/support/SchemaTestUtils.java @@ -20,8 +20,8 @@ import org.springframework.data.cassandra.core.CassandraOperations; import org.springframework.data.cassandra.core.convert.SchemaFactory; import org.springframework.data.cassandra.core.cql.SessionCallback; +import org.springframework.data.cassandra.core.cql.generator.CqlGenerator; import org.springframework.data.cassandra.core.cql.generator.CreateTableCqlGenerator; -import org.springframework.data.cassandra.core.cql.generator.CreateUserTypeCqlGenerator; import org.springframework.data.cassandra.core.cql.keyspace.CreateTableSpecification; import org.springframework.data.cassandra.core.cql.keyspace.CreateUserTypeSpecification; import org.springframework.data.cassandra.core.mapping.CassandraMappingContext; @@ -93,7 +93,7 @@ private static void potentiallyCreateUdtFor(CassandraPersistentEntity persist CreateUserTypeSpecification udtspec = schemaFactory.getCreateUserTypeSpecificationFor(persistentEntity) .ifNotExists(); - operations.getCqlOperations().execute(CreateUserTypeCqlGenerator.toCql(udtspec)); + operations.getCqlOperations().execute(CqlGenerator.toCql(udtspec)); } else { diff --git a/src/main/antora/modules/ROOT/examples/CreateKeyspaceConfiguration.java b/src/main/antora/modules/ROOT/examples/CreateKeyspaceConfiguration.java index de99aa603..922e9ffdd 100644 --- a/src/main/antora/modules/ROOT/examples/CreateKeyspaceConfiguration.java +++ b/src/main/antora/modules/ROOT/examples/CreateKeyspaceConfiguration.java @@ -33,7 +33,7 @@ public class CreateKeyspaceConfiguration extends AbstractCassandraConfiguration @Override protected List getKeyspaceCreations() { - CreateKeyspaceSpecification specification = CreateKeyspaceSpecification.createKeyspace("my_keyspace") + CreateKeyspaceSpecification specification = SpecificationBuilder.createKeyspace("my_keyspace") .with(KeyspaceOption.DURABLE_WRITES, true) .withNetworkReplication(DataCenterReplication.of("foo", 1), DataCenterReplication.of("bar", 2)); diff --git a/src/main/antora/modules/ROOT/examples/Specifications.java b/src/main/antora/modules/ROOT/examples/Specifications.java new file mode 100644 index 000000000..4220a9d5f --- /dev/null +++ b/src/main/antora/modules/ROOT/examples/Specifications.java @@ -0,0 +1,52 @@ +/* + * Copyright 2020-2024 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 + * + * https://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.example; + +public class Specifications { + + public void document() { + // tag::keyspace[] + + CqlSpecification createKeyspace = SpecificationBuilder.createKeyspace("my_keyspace") + .with(KeyspaceOption.REPLICATION, KeyspaceAttributes.newSimpleReplication()) + .with(KeyspaceOption.DURABLE_WRITES, true); + + // results in CREATE KEYSPACE my_keyspace WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '1'} AND durable_writes = true + String cql = CqlGenerator.toCql(createKeyspace); + // end::keyspace[] + + // tag::table[] + + CreateTableSpecification createTable = CreateTableSpecification.createTable("my_table") + .partitionKeyColumn("last_name", DataTypes.TEXT) + .partitionKeyColumn("first_name", DataTypes.TEXT) + .column("age", DataTypes.INT); + + // results in CREATE TABLE my_table (last_name text, first_name text, age int, PRIMARY KEY(last_name, first_name)) + String cql = CqlGenerator.toCql(createTable); + // end::table[] + + // tag::index[] + + CreateIndexSpecification spec = SpecificationBuilder.createIndex() + .tableName("mytable").keys().columnName("column"); + + // results in CREATE INDEX ON mytable (KEYS(column)) + String cql = CqlGenerator.toCql(createTable); + // end::index[] + } + +} diff --git a/src/main/antora/modules/ROOT/pages/cassandra/schema-management.adoc b/src/main/antora/modules/ROOT/pages/cassandra/schema-management.adoc index ec16bdd3f..ca954a1d5 100644 --- a/src/main/antora/modules/ROOT/pages/cassandra/schema-management.adoc +++ b/src/main/antora/modules/ROOT/pages/cassandra/schema-management.adoc @@ -4,6 +4,54 @@ Apache Cassandra is a data store that requires a schema definition prior to any data interaction. Spring Data for Apache Cassandra can support you with schema creation. +[[cql-specifications]] +== CQL Specifications + +CQL specifications are an abstraction to represent CQL DDL actions such as table creations or keyspace drops. +Specifications are available for the following CQL object types: + +* Keyspace +* Table +* Index +* User-defined Type + +NOTE: Variants of Cassandra can support Materialized Views, User-defined functions, roles and many more object types. +Spring Data for Apache Cassandra provides only specifications for the above listed types. + +These can be used to CREATE, ALTER, and DROP CQL objects through a fluent interface. `SpecificationBuilder` is the entry point to build such a specification. +You can use later on `CqlGenerator.toCql(…)` to easily render CQL from a specification. + +See the following examples to create a specification for keyspace creation, table creation, and index creation. + +.Specifying a Cassandra keyspace +==== +.Java +[indent=0,source,java] +---- +include::example$Specifications.java[tags=keyspace] +---- +==== + +.Specifying a Cassandra table +==== +.Java +[indent=0,source,java] +---- +include::example$Specifications.java[tags=table] +---- +==== + +.Specifying a Cassandra index +==== +.Java +[indent=0,source,java] +---- +include::example$Specifications.java[tags=index] +---- +==== + +You can use specifications together with the configuration API to define keyspace creation and schema actions. + [[keyspaces-and-lifecycle-scripts]] == Keyspaces and Lifecycle Scripts @@ -105,6 +153,7 @@ The following example gets a value from a system property: ---- + <1> Get the value for `enabled` from a system property called `INITIALIZE_KEYSPACE`. ==== @@ -155,7 +204,6 @@ include::example$SessionFactoryInitializerConfiguration.java[tags=class] ---- ==== - In this example, the two `test-data` scripts use `@@` as statement separator and only the `db-schema.cql` uses `;`. This configuration specifies that the default separator is `@@` and overrides that default for the `db-schema` script.