All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.scalar.db.sql.statement.builder.CreateTableStatementBuilder Maven / Gradle / Ivy

package com.scalar.db.sql.statement.builder;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.scalar.db.sql.ClusteringOrder;
import com.scalar.db.sql.DataType;
import com.scalar.db.sql.TableRef;
import com.scalar.db.sql.statement.CreateTableStatement;
import java.util.Map;
import javax.annotation.Nullable;

public class CreateTableStatementBuilder {

  private CreateTableStatementBuilder() {}

  public static class Start extends WithPartitionKey {
    Start(@Nullable String namespaceName, String tableName) {
      super(namespaceName, tableName, false);
    }

    /**
     * Specifies that the table should not be created if it already exists.
     *
     * @return a builder object
     */
    public WithPartitionKey ifNotExists() {
      return new WithPartitionKey(namespaceName, tableName, true);
    }

    /**
     * Specifies whether the table should not be created if it already exists.
     *
     * @param ifNotExists whether the table should not be created if it already exists
     * @return a builder object
     */
    public WithPartitionKey ifNotExists(boolean ifNotExists) {
      return new WithPartitionKey(namespaceName, tableName, ifNotExists);
    }
  }

  public static class WithPartitionKey {
    protected final @Nullable String namespaceName;
    protected final String tableName;
    private final boolean ifNotExists;

    private WithPartitionKey(
        @Nullable String namespaceName, String tableName, boolean ifNotExists) {
      this.namespaceName = namespaceName;
      this.tableName = tableName;
      this.ifNotExists = ifNotExists;
    }

    /**
     * Adds a partition key column definition. This includes the column declaration (you don't need
     * an additional {@link Buildable#withColumn(String, DataType)} or {@link
     * Buildable#withColumns(Map)} call). Partition key columns are added in the order of their
     * declaration.
     *
     * @param columnName the column name of the partition key column
     * @param dataType the data type of the partition key column
     * @return a builder object
     */
    public Buildable withPartitionKey(String columnName, DataType dataType) {
      ImmutableMap.Builder columnsBuilder = ImmutableMap.builder();
      columnsBuilder.put(columnName, dataType);
      ImmutableSet.Builder partitionKeyColumnNamesBuilder = ImmutableSet.builder();
      partitionKeyColumnNamesBuilder.add(columnName);
      return new Buildable(
          namespaceName, tableName, ifNotExists, columnsBuilder, partitionKeyColumnNamesBuilder);
    }

    /**
     * Adds partition key column definitions. This includes the column declarations (you don't need
     * an additional {@link Buildable#withColumn(String, DataType)} or {@link
     * Buildable#withColumns(Map)} call). Partition key columns are added in the order of their
     * declaration.
     *
     * @param columnNameAndDataTypeMap a map of the column names and the data types of the partition
     *     key columns
     * @return a builder object
     */
    public Buildable withPartitionKey(Map columnNameAndDataTypeMap) {
      ImmutableMap.Builder columnsBuilder = ImmutableMap.builder();
      columnsBuilder.putAll(columnNameAndDataTypeMap);
      ImmutableSet.Builder partitionKeyColumnNamesBuilder = ImmutableSet.builder();
      partitionKeyColumnNamesBuilder.addAll(columnNameAndDataTypeMap.keySet());
      return new Buildable(
          namespaceName, tableName, ifNotExists, columnsBuilder, partitionKeyColumnNamesBuilder);
    }
  }

  public static class Buildable {
    @Nullable private final String namespaceName;
    private final String tableName;
    private final boolean ifNotExists;
    private final ImmutableMap.Builder columnsBuilder;
    private final ImmutableSet.Builder partitionKeyColumnNamesBuilder;
    private final ImmutableSet.Builder clusteringKeyColumnNamesBuilder =
        ImmutableSet.builder();
    private final ImmutableMap.Builder clusteringOrdersBuilder =
        ImmutableMap.builder();
    private final ImmutableMap.Builder optionsBuilder = ImmutableMap.builder();

    private Buildable(
        @Nullable String namespaceName,
        String tableName,
        boolean ifNotExists,
        ImmutableMap.Builder columnsBuilder,
        ImmutableSet.Builder partitionKeyColumnNamesBuilder) {
      this.namespaceName = namespaceName;
      this.tableName = tableName;
      this.ifNotExists = ifNotExists;
      this.columnsBuilder = columnsBuilder;
      this.partitionKeyColumnNamesBuilder = partitionKeyColumnNamesBuilder;
    }

    /**
     * Adds a partition key column definition. This includes the column declaration (you don't need
     * an additional {@link #withColumn(String, DataType)} or {@link #withColumns(Map)} call).
     * Partition key columns are added in the order of their declaration.
     *
     * @param columnName the column name of the partition key column
     * @param dataType the data type of the partition key column
     * @return a builder object
     */
    public Buildable withPartitionKey(String columnName, DataType dataType) {
      columnsBuilder.put(columnName, dataType);
      partitionKeyColumnNamesBuilder.add(columnName);
      return this;
    }

    /**
     * Adds partition key column definitions. This includes the column declarations (you don't need
     * an additional {@link #withColumn(String, DataType)} or {@link #withColumns(Map)} call).
     * Partition key columns are added in the order of their declaration.
     *
     * @param columnNameAndDataTypeMap a map of the column names and the data types of the partition
     *     key columns
     * @return a builder object
     */
    public Buildable withPartitionKey(Map columnNameAndDataTypeMap) {
      columnsBuilder.putAll(columnNameAndDataTypeMap);
      partitionKeyColumnNamesBuilder.addAll(columnNameAndDataTypeMap.keySet());
      return this;
    }

    /**
     * Adds a clustering key column definition. This includes the column declaration (you don't need
     * an additional {@link #withColumn(String, DataType)} or {@link #withColumns(Map)} call).
     * Clustering key columns are added in the order of their declaration.
     *
     * @param columnName the column name of the clustering key column
     * @param dataType the data type of the clustering key column
     * @return a builder object
     */
    public Buildable withClusteringKey(String columnName, DataType dataType) {
      columnsBuilder.put(columnName, dataType);
      clusteringKeyColumnNamesBuilder.add(columnName);
      return this;
    }

    /**
     * Adds clustering key column definitions. This includes the column declarations (you don't need
     * an additional {@link #withColumn(String, DataType)} or {@link #withColumns(Map)} call).
     * Clustering key columns are added in the order of their declaration.
     *
     * @param columnNameAndDataTypeMap a map of the column names and the data types of the
     *     clustering key columns
     * @return a builder object
     */
    public Buildable withClusteringKey(Map columnNameAndDataTypeMap) {
      columnsBuilder.putAll(columnNameAndDataTypeMap);
      clusteringKeyColumnNamesBuilder.addAll(columnNameAndDataTypeMap.keySet());
      return this;
    }

    /**
     * Specifies clustering order for the specified clustering key column.
     *
     * @param columnName the column name of the clustering key column
     * @param clusteringOrder the clustering order of the specified clustering key column
     * @return a builder object
     */
    public Buildable withClusteringOrder(String columnName, ClusteringOrder clusteringOrder) {
      if (!clusteringKeyColumnNamesBuilder.build().contains(columnName)) {
        throw new IllegalArgumentException(columnName + " is not a clustering key column");
      }

      clusteringOrdersBuilder.put(columnName, clusteringOrder);
      return this;
    }

    /**
     * Specifies clustering orders for the specified clustering key columns.
     *
     * @param columnNameAndClusteringOrderMap a map of the column names and the clustering orders of
     *     the clustering key columns
     * @return a builder object
     */
    public Buildable withClusteringOrders(
        Map columnNameAndClusteringOrderMap) {
      columnNameAndClusteringOrderMap
          .keySet()
          .forEach(
              c -> {
                if (!clusteringKeyColumnNamesBuilder.build().contains(c)) {
                  throw new IllegalArgumentException(c + " is not a clustering key column");
                }
              });
      clusteringOrdersBuilder.putAll(columnNameAndClusteringOrderMap);
      return this;
    }

    /**
     * Adds a column definition.
     *
     * @param columnName a column name to add
     * @param dataType a data type to add
     * @return a builder object
     */
    public Buildable withColumn(String columnName, DataType dataType) {
      columnsBuilder.put(columnName, dataType);
      return this;
    }

    /**
     * Adds column definitions.
     *
     * @param columnNameAndDataTypeMap a map of column names and data types to add
     * @return a builder object
     */
    public Buildable withColumns(Map columnNameAndDataTypeMap) {
      columnsBuilder.putAll(columnNameAndDataTypeMap);
      return this;
    }

    /**
     * Adds a creation option.
     *
     * @param name an option name to add
     * @param value an option value to add
     * @return a builder object
     */
    public Buildable withOption(String name, String value) {
      optionsBuilder.put(name, value);
      return this;
    }

    /**
     * Adds creation options.
     *
     * @param options options to add
     * @return a builder object
     */
    public Buildable withOptions(Map options) {
      optionsBuilder.putAll(options);
      return this;
    }

    /**
     * Builds a CreateTableStatement object.
     *
     * @return a CreateTableStatement object
     */
    public CreateTableStatement build() {
      return CreateTableStatement.create(
          TableRef.of(namespaceName, tableName),
          ifNotExists,
          columnsBuilder.build(),
          partitionKeyColumnNamesBuilder.build(),
          clusteringKeyColumnNamesBuilder.build(),
          clusteringOrdersBuilder.build(),
          optionsBuilder.build());
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy