Refine API to create and render CQL object specifications.

We now expose specification entrypoints at SpecificationBuilder and a generic generator at CqlGenerator.toCql(…).

Closes #1506
This commit is contained in:
Mark Paluch
2024-07-25 16:22:50 +02:00
parent e154ef6c40
commit 41805cc300
43 changed files with 1010 additions and 202 deletions

View File

@@ -23,12 +23,9 @@ import org.springframework.data.cassandra.core.convert.CassandraConverter;
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 class CassandraAdminTemplate extends CassandraTemplate implements Cassand
});
}
getCqlOperations().execute(CreateTableCqlGenerator.toCql(createTableSpecification));
getCqlOperations().execute(CqlGenerator.toCql(createTableSpecification));
}
@Override
@@ -143,7 +140,7 @@ public class CassandraAdminTemplate extends CassandraTemplate implements Cassand
@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 class CassandraAdminTemplate extends CassandraTemplate implements Cassand
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);
}

View File

@@ -24,9 +24,8 @@ import java.util.Set;
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 class CassandraPersistentEntitySchemaCreator {
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 @@ public class CassandraPersistentEntitySchemaCreator {
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 @@ public class CassandraPersistentEntitySchemaCreator {
public void createUserTypes(boolean ifNotExists) {
createUserTypeSpecifications(ifNotExists).stream() //
.map(CreateUserTypeCqlGenerator::toCql) //
.map(CqlGenerator::toCql) //
.forEach(cql -> this.cassandraAdminOperations.getCqlOperations().execute(cql));
}

View File

@@ -27,6 +27,7 @@ import java.util.function.BiConsumer;
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 @@ class IndexSpecificationFactory {
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 @@ class IndexSpecificationFactory {
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") //

View File

@@ -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 java.util.Objects;
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 class SchemaFactory {
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 class SchemaFactory {
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) {

View File

@@ -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:
*
* <pre class="code">
* DropUserTypeSpecification spec = SpecificationBuilder.dropType("address");
* String cql = CqlGenerator.toCql(spec);
* </pre>
*
* @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));
}
}

View File

@@ -22,7 +22,8 @@ import com.datastax.oss.driver.api.core.CqlIdentifier;
*
* @author Mark Paluch
*/
public class AlterKeyspaceSpecification extends KeyspaceOptionsSpecification<AlterKeyspaceSpecification> {
public class AlterKeyspaceSpecification extends KeyspaceOptionsSpecification<AlterKeyspaceSpecification>
implements CqlSpecification {
private AlterKeyspaceSpecification(CqlIdentifier name) {
super(name);

View File

@@ -38,7 +38,8 @@ import com.datastax.oss.driver.api.core.type.DataType;
* @see TableOptionsSpecification
* @see org.springframework.data.cassandra.core.cql.generator.AlterTableCqlGenerator
*/
public class AlterTableSpecification extends TableOptionsSpecification<AlterTableSpecification> {
public class AlterTableSpecification extends TableOptionsSpecification<AlterTableSpecification>
implements CqlSpecification {
/**
* The list of column changes.
@@ -81,7 +82,7 @@ public class AlterTableSpecification extends TableOptionsSpecification<AlterTabl
* @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);
}

View File

@@ -32,7 +32,7 @@ import com.datastax.oss.driver.api.core.type.DataType;
* @since 1.5
* @see CqlIdentifier
*/
public class AlterUserTypeSpecification extends UserTypeNameSpecification {
public class AlterUserTypeSpecification extends UserTypeNameSpecification implements CqlSpecification {
private final List<ColumnChangeSpecification> changes = new ArrayList<>();
@@ -58,7 +58,7 @@ public class AlterUserTypeSpecification extends UserTypeNameSpecification {
* @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 @@ public class AlterUserTypeSpecification extends UserTypeNameSpecification {
* @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);
}

View File

@@ -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 {}

View File

@@ -34,7 +34,7 @@ import com.datastax.oss.driver.api.core.CqlIdentifier;
* @author Mark Paluch
*/
public class CreateIndexSpecification extends IndexNameSpecification<CreateIndexSpecification>
implements IndexDescriptor {
implements IndexDescriptor, CqlSpecification {
private @Nullable CqlIdentifier tableName;
@@ -57,7 +57,7 @@ public class CreateIndexSpecification extends IndexNameSpecification<CreateIndex
}
/**
* 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 class CreateIndexSpecification extends IndexNameSpecification<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 class CreateIndexSpecification extends IndexNameSpecification<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}.

View File

@@ -28,7 +28,7 @@ import com.datastax.oss.driver.api.core.CqlIdentifier;
* @author Mark Paluch
*/
public class CreateKeyspaceSpecification extends KeyspaceOptionsSpecification<CreateKeyspaceSpecification>
implements KeyspaceDescriptor {
implements KeyspaceDescriptor, CqlSpecification {
private boolean ifNotExists = false;

View File

@@ -25,7 +25,7 @@ import com.datastax.oss.driver.api.core.CqlIdentifier;
* @author Matthew T. Adams
* @author Mark Paluch
*/
public class CreateTableSpecification extends TableSpecification<CreateTableSpecification> {
public class CreateTableSpecification extends TableSpecification<CreateTableSpecification> implements CqlSpecification {
private boolean ifNotExists = false;

View File

@@ -27,7 +27,8 @@ import com.datastax.oss.driver.api.core.CqlIdentifier;
* @since 1.5
* @see CqlIdentifier
*/
public class CreateUserTypeSpecification extends UserTypeSpecification<CreateUserTypeSpecification> {
public class CreateUserTypeSpecification extends UserTypeSpecification<CreateUserTypeSpecification>
implements CqlSpecification {
private boolean ifNotExists;
@@ -36,39 +37,39 @@ public class CreateUserTypeSpecification extends UserTypeSpecification<CreateUse
}
/**
* 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);
}
/**

View File

@@ -26,7 +26,7 @@ import com.datastax.oss.driver.api.core.CqlIdentifier;
* @author David Webb
* @author Mark Paluch
*/
public class DropIndexSpecification extends IndexNameSpecification<DropIndexSpecification> {
public class DropIndexSpecification extends IndexNameSpecification<DropIndexSpecification> implements CqlSpecification {
private DropIndexSpecification(@Nullable CqlIdentifier keyspace, CqlIdentifier name) {
super(keyspace, name);

View File

@@ -25,7 +25,7 @@ import com.datastax.oss.driver.api.core.CqlIdentifier;
*
* @author Mark Paluch
*/
public class DropKeyspaceSpecification extends KeyspaceActionSpecification {
public class DropKeyspaceSpecification extends KeyspaceActionSpecification implements CqlSpecification {
private boolean ifExists;

View File

@@ -25,7 +25,7 @@ import com.datastax.oss.driver.api.core.CqlIdentifier;
* @author Matthew T. Adams
* @author Mark Paluch
*/
public class DropTableSpecification extends TableNameSpecification {
public class DropTableSpecification extends TableNameSpecification implements CqlSpecification {
private boolean ifExists = false;

View File

@@ -27,7 +27,7 @@ import com.datastax.oss.driver.api.core.CqlIdentifier;
* @since 1.5
* @see CqlIdentifier
*/
public class DropUserTypeSpecification extends UserTypeNameSpecification {
public class DropUserTypeSpecification extends UserTypeNameSpecification implements CqlSpecification {
private boolean ifExists;
@@ -36,39 +36,39 @@ public class DropUserTypeSpecification extends UserTypeNameSpecification {
}
/**
* 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);
}
/**

View File

@@ -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.
* <p>
* 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);
}
}

View File

@@ -24,6 +24,7 @@ import java.util.Optional;
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 @@ public class TableSpecification<T> extends TableOptionsSpecification<TableSpecif
super(name);
}
protected TableSpecification(CqlIdentifier keyspace, CqlIdentifier name) {
protected TableSpecification(@Nullable CqlIdentifier keyspace, CqlIdentifier name) {
super(keyspace, name);
}

View File

@@ -23,10 +23,11 @@ import java.util.Map;
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 @@ class CassandraAdminTemplateIntegrationTests extends AbstractKeyspaceCreatingInt
Collection<TableMetadata> tables = keyspace.getTables().values();
for (TableMetadata table : tables) {
cassandraAdminTemplate.getCqlOperations()
.execute(DropTableCqlGenerator.toCql(DropTableSpecification.dropTable(table.getName())));
.execute(CqlGenerator.toCql(SpecificationBuilder.dropTable(table.getName())));
}
}

View File

@@ -23,9 +23,9 @@ import java.util.Map;
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 @@ class IndexCreationIntegrationTests extends AbstractKeyspaceCreatingIntegrationT
CreateTableSpecification createTable = schemaFactory.getCreateTableSpecificationFor(entity);
List<CreateIndexSpecification> 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 @@ class IndexCreationIntegrationTests extends AbstractKeyspaceCreatingIntegrationT
CreateTableSpecification createTable = schemaFactory.getCreateTableSpecificationFor(entity);
List<CreateIndexSpecification> 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

View File

@@ -26,6 +26,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
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.annotation.Transient;
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 @@ public class MappingCassandraConverterTupleIntegrationTests extends AbstractSpri
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<text,int>," //
+ "mapoftuples map<text, frozen<tuple<address, list<text>, text>>>, " //

View File

@@ -36,8 +36,7 @@ import org.springframework.core.convert.converter.Converter;
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 @@ public class SchemaFactoryUnitTests {
assertThat(getColumnType("mapped", specification).asCql(true, true)).isEqualTo("frozen<mappedudt>");
assertThat(getColumnType("human", specification).asCql(true, true)).isEqualTo("frozen<udt_ks.udtwithkeyspace>");
String cql = CreateTableCqlGenerator.toCql(specification);
String cql = CqlGenerator.toCql(specification);
assertThat(cql).contains("CREATE TABLE some_ks.withkeyspace");
assertThat(cql).contains("mapped frozen<mappedudt>");
@@ -614,7 +613,7 @@ public class SchemaFactoryUnitTests {
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)");
}

View File

@@ -24,6 +24,7 @@ import java.util.Map;
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 @@ class AlterTableCqlGeneratorIntegrationTests extends AbstractKeyspaceCreatingInt
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 @@ class AlterTableCqlGeneratorIntegrationTests extends AbstractKeyspaceCreatingInt
session.execute(
"CREATE TABLE addamsFamily (name varchar PRIMARY KEY, gender varchar,\n" + " lastknownlocation list<ascii>);");
AlterTableSpecification spec = AlterTableSpecification.alterTable("addamsFamily").alter("lastKnownLocation",
AlterTableSpecification spec = SpecificationBuilder.alterTable("addamsFamily").alter("lastKnownLocation",
DataTypes.listOf(DataTypes.TEXT));
execute(spec);
@@ -99,7 +100,7 @@ class AlterTableCqlGeneratorIntegrationTests extends AbstractKeyspaceCreatingInt
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 @@ class AlterTableCqlGeneratorIntegrationTests extends AbstractKeyspaceCreatingInt
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 @@ class AlterTableCqlGeneratorIntegrationTests extends AbstractKeyspaceCreatingInt
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 @@ class AlterTableCqlGeneratorIntegrationTests extends AbstractKeyspaceCreatingInt
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 @@ class AlterTableCqlGeneratorIntegrationTests extends AbstractKeyspaceCreatingInt
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 @@ class AlterTableCqlGeneratorIntegrationTests extends AbstractKeyspaceCreatingInt
}
private void execute(AlterTableSpecification spec) {
session.execute(new AlterTableCqlGenerator(spec).toCql());
session.execute(CqlGenerator.toCql(spec));
}
private TableMetadata getTableMetadata(String table) {

View File

@@ -22,6 +22,7 @@ import java.util.Map;
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 @@ class AlterTableCqlGeneratorUnitTests {
@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<ascii>;");
@@ -58,7 +59,7 @@ class AlterTableCqlGeneratorUnitTests {
@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 @@ class AlterTableCqlGeneratorUnitTests {
@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<ascii>;");
@@ -75,7 +76,7 @@ class AlterTableCqlGeneratorUnitTests {
@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 @@ class AlterTableCqlGeneratorUnitTests {
@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 @@ class AlterTableCqlGeneratorUnitTests {
@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 @@ class AlterTableCqlGeneratorUnitTests {
@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 @@ class AlterTableCqlGeneratorUnitTests {
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);
}
}

View File

@@ -17,11 +17,12 @@ package org.springframework.data.cassandra.core.cql.generator;
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 @@ class AlterUserTypeCqlGeneratorIntegrationTests extends AbstractKeyspaceCreating
@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 @@ class AlterUserTypeCqlGeneratorIntegrationTests extends AbstractKeyspaceCreating
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 @@ class AlterUserTypeCqlGeneratorIntegrationTests extends AbstractKeyspaceCreating
@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 @@ class AlterUserTypeCqlGeneratorIntegrationTests extends AbstractKeyspaceCreating
@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 @@ class AlterUserTypeCqlGeneratorIntegrationTests extends AbstractKeyspaceCreating
@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")));
}
}

View File

@@ -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")));
}
}

View File

@@ -20,6 +20,7 @@ import static org.assertj.core.api.Assertions.*;
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\");");
}
}

View File

@@ -26,6 +26,7 @@ import org.springframework.data.cassandra.core.cql.keyspace.DefaultOption;
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 @@ public class CreateKeyspaceCqlGeneratorUnitTests {
public CreateKeyspaceSpecification specification() {
keyspace = name;
return CreateKeyspaceSpecification.createKeyspace(keyspace)
return SpecificationBuilder.createKeyspace(keyspace)
.with(KeyspaceOption.REPLICATION, replicationMap).with(KeyspaceOption.DURABLE_WRITES, durableWrites);
}

View File

@@ -44,10 +44,9 @@ class CreateTableCqlGeneratorIntegrationTests extends AbstractKeyspaceCreatingIn
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 @@ class CreateTableCqlGeneratorIntegrationTests extends AbstractKeyspaceCreatingIn
.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 @@ class CreateTableCqlGeneratorIntegrationTests extends AbstractKeyspaceCreatingIn
.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 @@ class CreateTableCqlGeneratorIntegrationTests extends AbstractKeyspaceCreatingIn
.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 @@ class CreateTableCqlGeneratorIntegrationTests extends AbstractKeyspaceCreatingIn
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);
}

View File

@@ -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 @@ class CreateTableCqlGeneratorUnitTests {
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 @@ class CreateTableCqlGeneratorUnitTests {
.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 @@ class CreateTableCqlGeneratorUnitTests {
.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 @@ class CreateTableCqlGeneratorUnitTests {
.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 @@ class CreateTableCqlGeneratorUnitTests {
.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 @@ class CreateTableCqlGeneratorUnitTests {
.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 @@ class CreateTableCqlGeneratorUnitTests {
.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 @@ class CreateTableCqlGeneratorUnitTests {
.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));");
}
/**

View File

@@ -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 @@ class CreateUserTypeCqlGeneratorIntegrationTests extends AbstractKeyspaceCreatin
@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 @@ class CreateUserTypeCqlGeneratorIntegrationTests extends AbstractKeyspaceCreatin
@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 @@ class CreateUserTypeCqlGeneratorIntegrationTests extends AbstractKeyspaceCreatin
@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 @@ class CreateUserTypeCqlGeneratorIntegrationTests extends AbstractKeyspaceCreatin
.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();

View File

@@ -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 @@ class CreateUserTypeCqlGeneratorUnitTests {
.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 @@ class CreateUserTypeCqlGeneratorUnitTests {
.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 @@ class CreateUserTypeCqlGeneratorUnitTests {
.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")));
}
}

View File

@@ -44,7 +44,7 @@ public class DropIndexCqlGeneratorUnitTests {
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;");
}
/**

View File

@@ -19,6 +19,7 @@ import static org.assertj.core.api.Assertions.*;
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 @@ class DropKeyspaceCqlGeneratorUnitTests {
@Override
public DropKeyspaceSpecification specification() {
return DropKeyspaceSpecification.dropKeyspace(name);
return SpecificationBuilder.dropKeyspace(name);
}
@Override

View File

@@ -20,6 +20,7 @@ import static org.assertj.core.api.Assertions.*;
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 @@ class DropTableCqlGeneratorUnitTests {
@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;");
}
/**

View File

@@ -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;");
}
}

View File

@@ -37,7 +37,7 @@ import org.springframework.dao.IncorrectResultSizeDataAccessException;
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 @@ class QueryDerivationIntegrationTests extends AbstractSpringDataEmbeddedCassandr
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 @@ class QueryDerivationIntegrationTests extends AbstractSpringDataEmbeddedCassandr
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 @@ class QueryDerivationIntegrationTests extends AbstractSpringDataEmbeddedCassandr
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 @@ class QueryDerivationIntegrationTests extends AbstractSpringDataEmbeddedCassandr
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 @@ class QueryDerivationIntegrationTests extends AbstractSpringDataEmbeddedCassandr
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 @@ class QueryDerivationIntegrationTests extends AbstractSpringDataEmbeddedCassandr
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 @@ class QueryDerivationIntegrationTests extends AbstractSpringDataEmbeddedCassandr
.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);

View File

@@ -28,10 +28,9 @@ import org.springframework.data.cassandra.core.CassandraOperations;
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 @@ class CassandraOperationsProducer {
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 @@ class CassandraOperationsProducer {
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) {

View File

@@ -20,8 +20,8 @@ import java.util.Optional;
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 @@ public class SchemaTestUtils {
CreateUserTypeSpecification udtspec = schemaFactory.getCreateUserTypeSpecificationFor(persistentEntity)
.ifNotExists();
operations.getCqlOperations().execute(CreateUserTypeCqlGenerator.toCql(udtspec));
operations.getCqlOperations().execute(CqlGenerator.toCql(udtspec));
} else {

View File

@@ -33,7 +33,7 @@ public class CreateKeyspaceConfiguration extends AbstractCassandraConfiguration
@Override
protected List<CreateKeyspaceSpecification> 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));

View File

@@ -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[]
}
}

View File

@@ -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:
<cassandra:script location="..."/>
</cassandra:initialize-database>
----
<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.