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

com.scalar.db.storage.jdbc.query.SelectQuery Maven / Gradle / Ivy

Go to download

A universal transaction manager that achieves database-agnostic transactions and distributed transactions that span multiple databases

There is a newer version: 3.14.0
Show newest version
package com.scalar.db.storage.jdbc.query;

import com.google.common.collect.ImmutableSet;
import com.scalar.db.api.Scan;
import com.scalar.db.api.Scan.Conjunction;
import com.scalar.db.api.TableMetadata;
import com.scalar.db.io.Column;
import com.scalar.db.io.Key;
import com.scalar.db.storage.jdbc.RdbEngineStrategy;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.Set;

public interface SelectQuery extends Query {

  class Builder {
    final RdbEngineStrategy rdbEngine;
    final List projections;
    String schema;
    String table;
    TableMetadata tableMetadata;
    Optional partitionKey = Optional.empty();
    Optional clusteringKey = Optional.empty();
    Optional commonClusteringKey = Optional.empty();
    Optional> startColumn = Optional.empty();
    boolean startInclusive;
    Optional> endColumn = Optional.empty();
    boolean endInclusive;
    List orderings = Collections.emptyList();
    private int limit;
    boolean isRangeQuery;
    Optional indexedColumn = Optional.empty();
    boolean isConditionalQuery;
    boolean isRelationalQuery;
    Set conjunctions = Collections.emptySet();

    Builder(RdbEngineStrategy rdbEngine, List projections) {
      this.rdbEngine = rdbEngine;
      this.projections = projections;
    }

    public Builder from(String schema, String table, TableMetadata tableMetadata) {
      this.schema = schema;
      this.table = table;
      this.tableMetadata = tableMetadata;
      return this;
    }

    /*
     * Assumes this is called by get operations
     */
    public Builder where(Key partitionKey, Optional clusteringKey) {
      isConditionalQuery = true;
      this.partitionKey = Optional.of(partitionKey);
      this.clusteringKey = clusteringKey;
      setIndexInfoIfUsed(partitionKey);
      return this;
    }

    /*
     * Assumes this is called by scan operations
     */
    public Builder where(
        Key partitionKey,
        Optional startClusteringKey,
        boolean startInclusive,
        Optional endClusteringKey,
        boolean endInclusive) {
      isConditionalQuery = true;

      this.partitionKey = Optional.of(partitionKey);

      if (startClusteringKey.isPresent()) {
        commonClusteringKey =
            Optional.of(
                new Key(
                    startClusteringKey
                        .get()
                        .get()
                        .subList(0, startClusteringKey.get().size() - 1)));
      } else {
        endClusteringKey.ifPresent(
            values ->
                commonClusteringKey =
                    Optional.of(new Key(values.get().subList(0, values.size() - 1))));
      }

      if (startClusteringKey.isPresent()) {
        startColumn =
            Optional.of(
                startClusteringKey.get().getColumns().get(startClusteringKey.get().size() - 1));
        this.startInclusive = startInclusive;
      }

      if (endClusteringKey.isPresent()) {
        endColumn =
            Optional.of(endClusteringKey.get().getColumns().get(endClusteringKey.get().size() - 1));
        this.endInclusive = endInclusive;
      }

      isRangeQuery = true;
      setIndexInfoIfUsed(partitionKey);

      return this;
    }

    private void setIndexInfoIfUsed(Key partitionKey) {
      if (tableMetadata == null) {
        throw new IllegalStateException("tableMetadata is null");
      }

      if (partitionKey.size() > 1) {
        return;
      }

      String column = partitionKey.get().get(0).getName();
      if (!tableMetadata.getSecondaryIndexNames().contains(column)) {
        return;
      }

      indexedColumn = Optional.of(column);
    }

    /*
     * Assumes this is called by relational scan operations
     */
    public Builder where(Set conjunctions) {
      isRelationalQuery = true;
      this.conjunctions = ImmutableSet.copyOf(conjunctions);
      return this;
    }

    @SuppressFBWarnings("EI_EXPOSE_REP2")
    public Builder orderBy(List orderings) {
      this.orderings = orderings;
      return this;
    }

    public Builder limit(int limit) {
      this.limit = limit;
      return this;
    }

    public SelectQuery build() {
      if (limit > 0) {
        return rdbEngine.buildSelectQuery(this, limit);
      }
      return new SimpleSelectQuery(this);
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy