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

com.scalar.db.sql.CommandStatementExecutor Maven / Gradle / Ivy

There is a newer version: 3.14.0
Show newest version
package com.scalar.db.sql;

import com.google.common.annotations.VisibleForTesting;
import com.scalar.db.io.BooleanColumn;
import com.scalar.db.io.Column;
import com.scalar.db.io.TextColumn;
import com.scalar.db.sql.common.ColumnDefinitionsBuilder;
import com.scalar.db.sql.common.ColumnsRecord;
import com.scalar.db.sql.common.EmptyResultSet;
import com.scalar.db.sql.common.RecordsResultSet;
import com.scalar.db.sql.common.SingleColumnRecord;
import com.scalar.db.sql.common.SingleRecordResultSet;
import com.scalar.db.sql.metadata.NamespaceMetadata;
import com.scalar.db.sql.metadata.TableMetadata;
import com.scalar.db.sql.statement.AbortStatement;
import com.scalar.db.sql.statement.BeginStatement;
import com.scalar.db.sql.statement.CommandStatement;
import com.scalar.db.sql.statement.CommandStatementVisitor;
import com.scalar.db.sql.statement.CommitStatement;
import com.scalar.db.sql.statement.DescribeStatement;
import com.scalar.db.sql.statement.JoinStatement;
import com.scalar.db.sql.statement.PrepareStatement;
import com.scalar.db.sql.statement.ResumeStatement;
import com.scalar.db.sql.statement.RollbackStatement;
import com.scalar.db.sql.statement.SetModeStatement;
import com.scalar.db.sql.statement.ShowNamespacesStatement;
import com.scalar.db.sql.statement.ShowTablesStatement;
import com.scalar.db.sql.statement.StartTransactionStatement;
import com.scalar.db.sql.statement.SuspendStatement;
import com.scalar.db.sql.statement.UseStatement;
import com.scalar.db.sql.statement.ValidateStatement;
import com.scalar.db.sql.util.SqlUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import javax.annotation.concurrent.ThreadSafe;

@ThreadSafe
public class CommandStatementExecutor implements CommandStatementVisitor {

  private final CommandStatementValidator commandStatementValidator;

  CommandStatementExecutor() {
    commandStatementValidator = new CommandStatementValidator();
  }

  @VisibleForTesting
  CommandStatementExecutor(CommandStatementValidator commandStatementValidator) {
    this.commandStatementValidator = Objects.requireNonNull(commandStatementValidator);
  }

  public ResultSet execute(CommandStatement commandStatement, SqlSession sqlSession) {
    CommandStatement statement =
        SqlUtils.setNamespaceNameIfOmitted(
            commandStatement, sqlSession.getDefaultNamespaceName().orElse(null));
    commandStatementValidator.validate(statement);
    return statement.accept(this, sqlSession);
  }

  @Override
  public ResultSet visit(BeginStatement statement, SqlSession sqlSession) {
    sqlSession.begin();
    return createResultSetWithCurrentTransactionId(sqlSession);
  }

  @Override
  public ResultSet visit(StartTransactionStatement statement, SqlSession sqlSession) {
    sqlSession.start();
    return createResultSetWithCurrentTransactionId(sqlSession);
  }

  private ResultSet createResultSetWithCurrentTransactionId(SqlSession sqlSession) {
    Optional transactionId = sqlSession.getTransactionId();
    assert transactionId.isPresent();
    ColumnDefinitions columnDefinitions =
        ColumnDefinitionsBuilder.builder().add("transactionId", DataType.TEXT).build();
    return new SingleRecordResultSet(
        new SingleColumnRecord(
            TextColumn.of("transactionId", transactionId.get()), columnDefinitions),
        columnDefinitions);
  }

  @Override
  public ResultSet visit(JoinStatement statement, SqlSession sqlSession) {
    sqlSession.join(statement.transactionId);
    return EmptyResultSet.INSTANCE;
  }

  @Override
  public ResultSet visit(SuspendStatement statement, SqlSession sqlSession) {
    sqlSession.suspend();
    return EmptyResultSet.INSTANCE;
  }

  @Override
  public ResultSet visit(ResumeStatement statement, SqlSession sqlSession) {
    sqlSession.resume(statement.transactionId);
    return EmptyResultSet.INSTANCE;
  }

  @Override
  public ResultSet visit(PrepareStatement statement, SqlSession sqlSession) {
    sqlSession.prepare();
    return EmptyResultSet.INSTANCE;
  }

  @Override
  public ResultSet visit(ValidateStatement statement, SqlSession sqlSession) {
    sqlSession.validate();
    return EmptyResultSet.INSTANCE;
  }

  @Override
  public ResultSet visit(CommitStatement statement, SqlSession sqlSession) {
    sqlSession.commit();
    return EmptyResultSet.INSTANCE;
  }

  @Override
  public ResultSet visit(RollbackStatement statement, SqlSession sqlSession) {
    sqlSession.rollback();
    return EmptyResultSet.INSTANCE;
  }

  @Override
  public ResultSet visit(AbortStatement statement, SqlSession sqlSession) {
    sqlSession.abort();
    return EmptyResultSet.INSTANCE;
  }

  @Override
  public ResultSet visit(UseStatement statement, SqlSession sqlSession) {
    sqlSession.setDefaultNamespaceName(statement.namespaceName);
    return EmptyResultSet.INSTANCE;
  }

  @Override
  public ResultSet visit(SetModeStatement statement, SqlSession sqlSession) {
    sqlSession.setTransactionMode(statement.transactionMode);
    return EmptyResultSet.INSTANCE;
  }

  @Override
  public ResultSet visit(ShowNamespacesStatement statement, SqlSession sqlSession) {
    Map namespaces = sqlSession.getMetadata().getNamespaces();
    ColumnDefinitions columnDefinitions =
        ColumnDefinitionsBuilder.builder().add("namespaceName", DataType.TEXT).build();

    return new RecordsResultSet(
        namespaces.keySet().stream()
            .sorted()
            .map(
                n ->
                    (Record)
                        new SingleColumnRecord(
                            TextColumn.of("namespaceName", n), columnDefinitions))
            .iterator(),
        columnDefinitions);
  }

  @Override
  public ResultSet visit(ShowTablesStatement statement, SqlSession sqlSession) {
    NamespaceMetadata namespaceMetadata =
        sqlSession
            .getMetadata()
            .getNamespace(statement.namespaceName)
            .orElseThrow(
                () -> new IllegalArgumentException("Unknown namespace " + statement.namespaceName));
    ColumnDefinitions columnDefinitions =
        ColumnDefinitionsBuilder.builder().add("tableName", DataType.TEXT).build();

    return new RecordsResultSet(
        namespaceMetadata.getTables().keySet().stream()
            .sorted()
            .map(
                t ->
                    (Record)
                        new SingleColumnRecord(TextColumn.of("tableName", t), columnDefinitions))
            .iterator(),
        columnDefinitions);
  }

  @Override
  public ResultSet visit(DescribeStatement statement, SqlSession sqlSession) {
    TableMetadata tableMetadata =
        SqlUtils.getTableMetadata(sqlSession.getMetadata(), statement.table);
    ColumnDefinitions columnDefinitions =
        ColumnDefinitionsBuilder.builder()
            .add("columnName", DataType.TEXT)
            .add("type", DataType.TEXT)
            .add("isPrimaryKey", DataType.BOOLEAN)
            .add("isPartitionKey", DataType.BOOLEAN)
            .add("isClusteringKey", DataType.BOOLEAN)
            .add("clusteringOrder", DataType.TEXT)
            .add("isIndexed", DataType.BOOLEAN)
            .add("isEncrypted", DataType.BOOLEAN)
            .build();

    return new RecordsResultSet(
        tableMetadata.getColumns().values().stream()
            .map(
                c -> {
                  List> columns = new ArrayList<>();
                  columns.add(TextColumn.of("columnName", c.getName()));
                  columns.add(TextColumn.of("type", c.getDataType().name()));
                  columns.add(
                      BooleanColumn.of(
                          "isPrimaryKey", tableMetadata.isPrimaryKeyColumn(c.getName())));
                  columns.add(
                      BooleanColumn.of(
                          "isPartitionKey", tableMetadata.isPartitionKeyColumn(c.getName())));

                  boolean isClusteringKeyColumn = tableMetadata.isClusteringKeyColumn(c.getName());
                  columns.add(BooleanColumn.of("isClusteringKey", isClusteringKeyColumn));

                  if (isClusteringKeyColumn) {
                    columns.add(
                        TextColumn.of(
                            "clusteringOrder", tableMetadata.getClusteringKey().get(c).name()));
                  } else {
                    columns.add(TextColumn.ofNull("clusteringOrder"));
                  }

                  columns.add(
                      BooleanColumn.of(
                          "isIndexed", tableMetadata.getIndex(c.getName()).isPresent()));
                  columns.add(BooleanColumn.of("isEncrypted", c.isEncrypted()));

                  return (Record) new ColumnsRecord(columns, columnDefinitions);
                })
            .iterator(),
        columnDefinitions);
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy