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

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

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

import com.google.common.collect.ImmutableList;
import com.scalar.db.sql.AndPredicateList;
import com.scalar.db.sql.Join;
import com.scalar.db.sql.JoinPredicate;
import com.scalar.db.sql.OrPredicateList;
import com.scalar.db.sql.Ordering;
import com.scalar.db.sql.Predicate;
import com.scalar.db.sql.Projection;
import com.scalar.db.sql.TableRef;
import com.scalar.db.sql.Term;
import com.scalar.db.sql.Value;
import com.scalar.db.sql.statement.SelectStatement;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nullable;

public final class SelectStatementBuilder {

  private SelectStatementBuilder() {}

  public static class Start {
    private final ImmutableList projections;

    Start(List projections) {
      this.projections = ImmutableList.copyOf(projections);
    }

    /**
     * Specifies the target table.
     *
     * @param namespaceName the namespace name of the target table
     * @param tableName the table name of the target table
     * @return a builder object
     */
    public AsOrJoinStartOrSelectWhereStart from(@Nullable String namespaceName, String tableName) {
      return new AsOrJoinStartOrSelectWhereStart(projections, namespaceName, tableName);
    }

    /**
     * Specifies the target table.
     *
     * @param tableName the table name of the target table
     * @return a builder object
     */
    public AsOrJoinStartOrSelectWhereStart from(String tableName) {
      return from(null, tableName);
    }
  }

  public static class AsOrJoinStartOrSelectWhereStart extends JoinStartOrSelectWhereStart {
    private AsOrJoinStartOrSelectWhereStart(
        ImmutableList projections, @Nullable String namespaceName, String tableName) {
      super(projections, namespaceName, tableName, null, new ArrayList<>());
    }

    /**
     * Specifies the alias of the target table.
     *
     * @param alias the alias of the target table
     * @return a builder object
     */
    public JoinStartOrSelectWhereStart as(String alias) {
      return new JoinStartOrSelectWhereStart(
          projections, namespaceName, tableName, alias, joinBuilders);
    }
  }

  public static class JoinStartOrSelectWhereStart extends SelectWhereStart {

    private JoinStartOrSelectWhereStart(
        ImmutableList projections,
        @Nullable String namespaceName,
        String tableName,
        @Nullable String alias,
        List joinBuilders) {
      super(projections, namespaceName, tableName, alias, joinBuilders);
    }

    /**
     * Specifies a INNER JOIN.
     *
     * @param namespaceName the namespace name of the target table
     * @param tableName the table name of the target table
     * @return a builder object
     */
    public OngoingJoinAsOrOn innerJoin(@Nullable String namespaceName, String tableName) {
      JoinBuilder joinBuilder = new JoinBuilder(Join.JoinType.INNER_JOIN, namespaceName, tableName);
      joinBuilders.add(joinBuilder);
      return new OngoingJoinAsOrOn(
          projections, super.namespaceName, super.tableName, alias, joinBuilders, joinBuilder);
    }

    /**
     * Specifies a INNER JOIN.
     *
     * @param tableName the table name of the target table
     * @return a builder object
     */
    public OngoingJoinAsOrOn innerJoin(String tableName) {
      return innerJoin(null, tableName);
    }

    /**
     * Specifies a LEFT OUTER JOIN.
     *
     * @param namespaceName the namespace name of the target table
     * @param tableName the table name of the target table
     * @return a builder object
     */
    public OngoingJoinAsOrOn leftOuterJoin(@Nullable String namespaceName, String tableName) {
      JoinBuilder joinBuilder =
          new JoinBuilder(Join.JoinType.LEFT_OUTER_JOIN, namespaceName, tableName);
      joinBuilders.add(joinBuilder);
      return new OngoingJoinAsOrOn(
          projections, super.namespaceName, super.tableName, alias, joinBuilders, joinBuilder);
    }

    /**
     * Specifies a LEFT OUTER JOIN.
     *
     * @param tableName the table name of the target table
     * @return a builder object
     */
    public OngoingJoinAsOrOn leftOuterJoin(String tableName) {
      return leftOuterJoin(null, tableName);
    }

    /**
     * Specifies a RIGHT OUTER JOIN.
     *
     * @param namespaceName the namespace name of the target table
     * @param tableName the table name of the target table
     * @return a builder object
     */
    public OngoingJoinAsOrOn rightOuterJoin(@Nullable String namespaceName, String tableName) {
      JoinBuilder joinBuilder =
          new JoinBuilder(Join.JoinType.RIGHT_OUTER_JOIN, namespaceName, tableName);
      joinBuilders.add(joinBuilder);
      return new OngoingJoinAsOrOn(
          projections, super.namespaceName, super.tableName, alias, joinBuilders, joinBuilder);
    }

    /**
     * Specifies a RIGHT OUTER JOIN.
     *
     * @param tableName the table name of the target table
     * @return a builder object
     */
    public OngoingJoinAsOrOn rightOuterJoin(String tableName) {
      return rightOuterJoin(null, tableName);
    }
  }

  public static class OngoingJoinAsOrOn extends OngoingJoinOn {

    private OngoingJoinAsOrOn(
        ImmutableList projections,
        @Nullable String namespaceName,
        String tableName,
        @Nullable String alias,
        List joinBuilders,
        JoinBuilder joinBuilder) {
      super(projections, namespaceName, tableName, alias, joinBuilders, joinBuilder);
    }

    /**
     * Specifies the alias of the target table.
     *
     * @param alias the alias of the target table
     * @return a builder object
     */
    public OngoingJoinOn as(String alias) {
      return new OngoingJoinOn(
          projections,
          namespaceName,
          tableName,
          super.alias,
          joinBuilders,
          joinBuilder.alias(alias));
    }
  }

  public static class OngoingJoinOn {

    protected final ImmutableList projections;
    @Nullable protected final String namespaceName;
    protected final String tableName;
    @Nullable protected final String alias;
    // These are package-private to suppress warning
    // "Class 'JoinBuilder' is exposed outside its defined visibility scope"
    final List joinBuilders;
    final JoinBuilder joinBuilder;

    private OngoingJoinOn(
        ImmutableList projections,
        @Nullable String namespaceName,
        String tableName,
        @Nullable String alias,
        List joinBuilders,
        JoinBuilder joinBuilder) {
      this.projections = projections;
      this.namespaceName = namespaceName;
      this.tableName = tableName;
      this.alias = alias;
      this.joinBuilders = joinBuilders;
      this.joinBuilder = joinBuilder;
    }

    /**
     * Specifies a join predicate.
     *
     * @param joinPredicate a join predicate to specify
     * @return a builder object
     */
    public OngoingJoinAndOrJoinStartOrSelectWhereStart on(JoinPredicate joinPredicate) {
      return new OngoingJoinAndOrJoinStartOrSelectWhereStart(
          projections,
          namespaceName,
          tableName,
          alias,
          joinBuilders,
          joinBuilder.joinPredicate(joinPredicate));
    }

    /**
     * Specifies join predicates.
     *
     * @param joinPredicates join predicates to specify
     * @return a builder object
     */
    public OngoingJoinAndOrJoinStartOrSelectWhereStart on(List joinPredicates) {
      return new OngoingJoinAndOrJoinStartOrSelectWhereStart(
          projections,
          namespaceName,
          tableName,
          alias,
          joinBuilders,
          joinBuilder.joinPredicates(joinPredicates));
    }
  }

  public static class OngoingJoinAndOrJoinStartOrSelectWhereStart
      extends JoinStartOrSelectWhereStart {

    private final JoinBuilder joinBuilder;

    private OngoingJoinAndOrJoinStartOrSelectWhereStart(
        ImmutableList projections,
        @Nullable String namespaceName,
        String tableName,
        @Nullable String alias,
        List joinBuilders,
        JoinBuilder joinBuilder) {
      super(projections, namespaceName, tableName, alias, joinBuilders);
      this.joinBuilder = joinBuilder;
    }

    /**
     * Specifies a join predicate.
     *
     * @param joinPredicate a join predicate
     * @return a builder object
     */
    public OngoingJoinAndOrJoinStartOrSelectWhereStart and(JoinPredicate joinPredicate) {
      joinBuilder.joinPredicate(joinPredicate);
      return this;
    }
  }

  public static class SelectWhereStart extends Buildable
      implements WhereStart {
    private SelectWhereStart(
        ImmutableList projections,
        @Nullable String namespaceName,
        String tableName,
        @Nullable String alias,
        List joinBuilders) {
      super(
          projections,
          namespaceName,
          tableName,
          alias,
          joinBuilders,
          null,
          ImmutableList.builder(),
          ImmutableList.builder());
    }

    @Override
    public SelectOngoingWhere where(Predicate predicate) {
      return new SelectOngoingWhere(
          projections,
          namespaceName,
          tableName,
          alias,
          joinBuilders,
          predicate,
          andPredicateListsBuilder,
          orPredicateListsBuilder);
    }

    @Override
    public SelectOngoingWhereOr where(List predicates) {
      return where(AndPredicateList.predicates(ImmutableList.copyOf(predicates)).build());
    }

    @Override
    public SelectOngoingWhereOr where(AndPredicateList andPredicateList) {
      return new SelectOngoingWhereOr(
          projections,
          namespaceName,
          tableName,
          alias,
          joinBuilders,
          andPredicateListsBuilder.add(andPredicateList),
          orPredicateListsBuilder);
    }

    @Override
    public SelectOngoingWhereAnd where(OrPredicateList orPredicateList) {
      return new SelectOngoingWhereAnd(
          projections,
          namespaceName,
          tableName,
          alias,
          joinBuilders,
          andPredicateListsBuilder,
          orPredicateListsBuilder.add(orPredicateList));
    }

    @Override
    public SelectOngoingWhereOr whereOr(List andPredicateLists) {
      return new SelectOngoingWhereOr(
          projections,
          namespaceName,
          tableName,
          alias,
          joinBuilders,
          andPredicateListsBuilder.addAll(andPredicateLists),
          orPredicateListsBuilder);
    }

    @Override
    public SelectOngoingWhereAnd whereAnd(List orPredicateLists) {
      return new SelectOngoingWhereAnd(
          projections,
          namespaceName,
          tableName,
          alias,
          joinBuilders,
          andPredicateListsBuilder,
          orPredicateListsBuilder.addAll(orPredicateLists));
    }
  }

  public static class SelectOngoingWhere extends Buildable
      implements OngoingWhere {
    private SelectOngoingWhere(
        ImmutableList projections,
        @Nullable String namespaceName,
        String tableName,
        @Nullable String alias,
        List joinBuilders,
        Predicate predicate,
        ImmutableList.Builder andPredicateListsBuilder,
        ImmutableList.Builder orPredicateListsBuilder) {
      super(
          projections,
          namespaceName,
          tableName,
          alias,
          joinBuilders,
          predicate,
          andPredicateListsBuilder,
          orPredicateListsBuilder);
    }

    @Override
    public SelectOngoingWhereAnd and(Predicate predicate) {
      return new SelectOngoingWhereAnd(
          projections,
          namespaceName,
          tableName,
          alias,
          joinBuilders,
          andPredicateListsBuilder,
          orPredicateListsBuilder
              .add(OrPredicateList.predicate(this.predicate).build())
              .add(OrPredicateList.predicate(predicate).build()));
    }

    @Override
    public SelectOngoingWhereAnd and(OrPredicateList orPredicateList) {
      return new SelectOngoingWhereAnd(
          projections,
          namespaceName,
          tableName,
          alias,
          joinBuilders,
          andPredicateListsBuilder,
          orPredicateListsBuilder
              .add(OrPredicateList.predicate(this.predicate).build())
              .add(orPredicateList));
    }

    @Override
    public SelectOngoingWhereOr or(Predicate predicate) {
      return new SelectOngoingWhereOr(
          projections,
          namespaceName,
          tableName,
          alias,
          joinBuilders,
          andPredicateListsBuilder
              .add(AndPredicateList.predicate(this.predicate).build())
              .add(AndPredicateList.predicate(predicate).build()),
          orPredicateListsBuilder);
    }

    @Override
    public SelectOngoingWhereOr or(AndPredicateList andPredicateList) {
      return new SelectOngoingWhereOr(
          projections,
          namespaceName,
          tableName,
          alias,
          joinBuilders,
          andPredicateListsBuilder
              .add(AndPredicateList.predicate(this.predicate).build())
              .add(andPredicateList),
          orPredicateListsBuilder);
    }
  }

  public static class SelectOngoingWhereAnd extends Buildable
      implements OngoingWhereAnd {
    private SelectOngoingWhereAnd(
        ImmutableList projections,
        @Nullable String namespaceName,
        String tableName,
        @Nullable String alias,
        List joinBuilders,
        ImmutableList.Builder andPredicateListsBuilder,
        ImmutableList.Builder orPredicateListsBuilder) {
      super(
          projections,
          namespaceName,
          tableName,
          alias,
          joinBuilders,
          null,
          andPredicateListsBuilder,
          orPredicateListsBuilder);
    }

    @Override
    public SelectOngoingWhereAnd and(Predicate predicate) {
      orPredicateListsBuilder.add(OrPredicateList.predicate(predicate).build());
      return this;
    }

    @Override
    public SelectOngoingWhereAnd and(OrPredicateList orPredicateList) {
      orPredicateListsBuilder.add(orPredicateList);
      return this;
    }
  }

  public static class SelectOngoingWhereOr extends Buildable
      implements OngoingWhereOr {
    private SelectOngoingWhereOr(
        ImmutableList projections,
        @Nullable String namespaceName,
        String tableName,
        @Nullable String alias,
        List joinBuilders,
        ImmutableList.Builder andPredicateListsBuilder,
        ImmutableList.Builder orPredicateListsBuilder) {
      super(
          projections,
          namespaceName,
          tableName,
          alias,
          joinBuilders,
          null,
          andPredicateListsBuilder,
          orPredicateListsBuilder);
    }

    @Override
    public SelectOngoingWhereOr or(Predicate predicate) {
      andPredicateListsBuilder.add(AndPredicateList.predicate(predicate).build());
      return this;
    }

    @Override
    public SelectOngoingWhereOr or(AndPredicateList andPredicateList) {
      andPredicateListsBuilder.add(andPredicateList);
      return this;
    }
  }

  public static class Buildable {
    protected final ImmutableList projections;
    @Nullable protected final String namespaceName;
    protected final String tableName;
    @Nullable protected final String alias;
    // This is package-private to suppress warning
    // "Class 'JoinBuilder' is exposed outside its defined visibility scope"
    final List joinBuilders;
    @Nullable protected final Predicate predicate;
    protected final ImmutableList.Builder andPredicateListsBuilder;
    protected final ImmutableList.Builder orPredicateListsBuilder;
    private ImmutableList orderings = ImmutableList.of();
    private Term limit;

    private Buildable(
        ImmutableList projections,
        @Nullable String namespaceName,
        String tableName,
        @Nullable String alias,
        List joinBuilders,
        @Nullable Predicate predicate,
        ImmutableList.Builder andPredicateListsBuilder,
        ImmutableList.Builder orPredicateListsBuilder) {
      this.projections = projections;
      this.namespaceName = namespaceName;
      this.tableName = tableName;
      this.alias = alias;
      this.joinBuilders = joinBuilders;
      this.predicate = predicate;
      this.andPredicateListsBuilder = andPredicateListsBuilder;
      this.orPredicateListsBuilder = orPredicateListsBuilder;
    }

    /**
     * Adds orderings.
     *
     * @param orderings orderings to add
     * @return a builder object
     */
    public Buildable orderBy(Ordering... orderings) {
      this.orderings = ImmutableList.copyOf(orderings);
      return this;
    }

    /**
     * Adds orderings.
     *
     * @param orderings orderings to add
     * @return a builder object
     */
    public Buildable orderBy(List orderings) {
      this.orderings = ImmutableList.copyOf(orderings);
      return this;
    }

    /**
     * Specifies limit.
     *
     * @param limit limit
     * @return a builder object
     */
    public Buildable limit(int limit) {
      this.limit = Value.ofInt(limit);
      return this;
    }

    /**
     * Specifies limit.
     *
     * @param limit limit
     * @return a builder object
     */
    public Buildable limit(Term limit) {
      this.limit = limit;
      return this;
    }

    /**
     * Builds a SelectStatement object.
     *
     * @return a SelectStatement object
     */
    public SelectStatement build() {
      return SelectStatement.create(
          projections,
          TableRef.of(namespaceName, tableName),
          alias,
          joinBuilders.stream().map(JoinBuilder::build).collect(ImmutableList.toImmutableList()),
          StatementBuilderUtils.buildAndPredicateLists(predicate, andPredicateListsBuilder),
          StatementBuilderUtils.buildOrPredicateLists(orPredicateListsBuilder),
          orderings,
          limit != null ? limit : Value.ofInt(0));
    }
  }

  private static class JoinBuilder {
    private final Join.JoinType joinType;
    @Nullable private final String namespaceName;
    private final String tableName;
    @Nullable private String alias;
    private final ImmutableList.Builder joinPredicatesBuilder =
        ImmutableList.builder();

    public JoinBuilder(Join.JoinType joinType, @Nullable String namespaceName, String tableName) {
      this.joinType = joinType;
      this.namespaceName = namespaceName;
      this.tableName = tableName;
    }

    public JoinBuilder alias(@Nullable String alias) {
      this.alias = alias;
      return this;
    }

    public JoinBuilder joinPredicate(JoinPredicate joinPredicate) {
      joinPredicatesBuilder.add(joinPredicate);
      return this;
    }

    public JoinBuilder joinPredicates(List joinPredicates) {
      joinPredicatesBuilder.addAll(joinPredicates);
      return this;
    }

    public Join build() {
      return Join.create(
          joinType, TableRef.of(namespaceName, tableName), alias, joinPredicatesBuilder.build());
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy