/* * Copyright (C) 2012-2015 DataStax Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.datastax.driver.core.schemabuilder; import com.datastax.driver.core.DataType; import com.google.common.base.Optional; import java.util.List; import static com.datastax.driver.core.schemabuilder.SchemaStatement.validateNotEmpty; import static com.datastax.driver.core.schemabuilder.SchemaStatement.validateNotKeyWord; /** * An in-construction ALTER TABLE statement. */ public class Alter implements StatementStart { private Optional<String> keyspaceName = Optional.absent(); private String tableName; Alter(String keyspaceName, String tableName) { validateNotEmpty(keyspaceName, "Keyspace name"); validateNotEmpty(tableName, "Table name"); validateNotKeyWord(keyspaceName, String.format("The keyspace name '%s' is not allowed because it is a reserved keyword", keyspaceName)); validateNotKeyWord(tableName, String.format("The table name '%s' is not allowed because it is a reserved keyword", tableName)); this.tableName = tableName; this.keyspaceName = Optional.fromNullable(keyspaceName); } Alter(String tableName) { validateNotEmpty(tableName, "Table name"); validateNotKeyWord(tableName, String.format("The table name '%s' is not allowed because it is a reserved keyword", tableName)); this.tableName = tableName; } /** * Add an ALTER column clause (to change the column type) to this ALTER TABLE statement. * * @param columnName the name of the column to be altered. * @return a new {@link Alter.AlterColumn} instance. */ public AlterColumn alterColumn(String columnName) { validateNotEmpty(columnName, "Column to be altered"); validateNotKeyWord(columnName, String.format("The altered column name '%s' is not allowed because it is a reserved keyword", columnName)); return new AlterColumn(this, columnName); } /** * Add a new ADD column clause to this ALTER TABLE statement. * * @param columnName the name of the column to be added. * @return a new {@link Alter.AddColumn} instance. */ public AddColumn addColumn(String columnName) { validateNotEmpty(columnName, "Added column"); validateNotKeyWord(columnName, String.format("The new column name '%s' is not allowed because it is a reserved keyword", columnName)); return new AddColumn(this, columnName, false); } /** * Add a new ADD column clause to this ALTER TABLE statement, to add a static column. * * @param columnName the name of the column to be added. * @return a new {@link Alter.AddColumn} instance. */ public AddColumn addStaticColumn(String columnName) { validateNotEmpty(columnName, "Added static column"); validateNotKeyWord(columnName, String.format("The new static column name '%s' is not allowed because it is a reserved keyword", columnName)); return new AddColumn(this, columnName, true); } /** * Add a new DROP column clause to this ALTER TABLE statement. * <p/> * Note that you cannot drop a column that is part of the primary key. * * @param columnName the name of the column to be dropped. * @return the final ALTER TABLE DROP COLUMN statement. */ public SchemaStatement dropColumn(String columnName) { validateNotEmpty(columnName, "Column to be dropped"); validateNotKeyWord(columnName, String.format("The dropped column name '%s' is not allowed because it is a reserved keyword", columnName)); return SchemaStatement.fromQueryString(buildInternal() + " DROP " + columnName); } /** * Add a new RENAME column clause to this ALTER TABLE statement. * <p/> * Note that you can only rename a column that is part of the primary key. * * @param columnName the name of the column to be renamed. * @return a new {@link Alter.RenameColumn} instance. */ public RenameColumn renameColumn(String columnName) { validateNotEmpty(columnName, "Column to be renamed"); validateNotKeyWord(columnName, String.format("The renamed column name '%s' is not allowed because it is a reserved keyword", columnName)); return new RenameColumn(this, columnName); } /** * Add options (WITH clause) to this ALTER TABLE statement. * * @return a new {@link Alter.Options} instance. */ public Options withOptions() { return new Options(this); } /** * An ALTER column clause. */ public static class AlterColumn { private final Alter alter; private final String columnName; AlterColumn(Alter alter, String columnName) { this.alter = alter; this.columnName = columnName; } /** * Define the new type of the altered column. * * @param type the new type of the altered column. * @return the final statement. */ public SchemaStatement type(DataType type) { return SchemaStatement.fromQueryString( alter.buildInternal() + " ALTER " + columnName + " TYPE " + type.toString()); } /** * Define the new type of the altered column, when that type contains a UDT. * * @param udtType the UDT type. Use {@link SchemaBuilder#frozen(String)} or {@link SchemaBuilder#udtLiteral(String)}. * @return the final statement. */ public SchemaStatement udtType(UDTType udtType) { return SchemaStatement.fromQueryString( alter.buildInternal() + " ALTER " + columnName + " TYPE " + udtType.asCQLString()); } } /** * An ADD column clause. */ public static class AddColumn { private final Alter alter; private final String columnName; private final boolean staticColumn; AddColumn(Alter alter, String columnName, boolean staticColumn) { this.alter = alter; this.columnName = columnName; this.staticColumn = staticColumn; } /** * Define the type of the added column. * * @param type the type of the added column. * @return the final statement. */ public SchemaStatement type(DataType type) { return SchemaStatement.fromQueryString( alter.buildInternal() + " ADD " + columnName + " " + type.toString() + (staticColumn ? " static" : "")); } /** * Define the type of the added column, when that type contains a UDT. * * @param udtType the UDT type of the added column. * @return the final statement. */ public SchemaStatement udtType(UDTType udtType) { return SchemaStatement.fromQueryString( alter.buildInternal() + " ADD " + columnName + " " + udtType.asCQLString() + (staticColumn ? " static" : "")); } } /** * A RENAME column clause. */ public static class RenameColumn { private final Alter alter; private final String columnName; RenameColumn(Alter alter, String columnName) { this.alter = alter; this.columnName = columnName; } /** * Define the new name of the column. * * @param newColumnName the new name of the column. * @return the final statement. */ public SchemaStatement to(String newColumnName) { validateNotEmpty(newColumnName, "New column name"); validateNotKeyWord(newColumnName, String.format("The new column name '%s' is not allowed because it is a reserved keyword", newColumnName)); return SchemaStatement.fromQueryString( alter.buildInternal() + " RENAME " + columnName + " TO " + newColumnName); } } /** * The table options of an ALTER TABLE statement. */ public static class Options extends TableOptions<Options> { Options(Alter alter) { super(alter); } @Override protected void addSpecificOptions(List<String> options) { // nothing to do (no specific options) } } @Override public String buildInternal() { String tableSpec = keyspaceName.isPresent() ? keyspaceName.get() + "." + tableName : tableName; return SchemaStatement.STATEMENT_START + "ALTER TABLE " + tableSpec; } }