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

com.scalar.db.sql.statement.UpsertStatement Maven / Gradle / Ivy

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

import com.google.common.collect.ImmutableList;
import com.scalar.db.sql.BindMarker;
import com.scalar.db.sql.NamedBindMarker;
import com.scalar.db.sql.PositionalBindMarker;
import com.scalar.db.sql.TableRef;
import com.scalar.db.sql.Term;
import com.scalar.db.sql.Value;
import com.scalar.db.sql.common.SqlError;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import javax.annotation.concurrent.Immutable;

@Immutable
public class UpsertStatement
    implements DmlStatement,
        BindableStatement,
        NamespaceNameOmittable {

  public final TableRef table;
  public final ImmutableList columnNames;
  public final ImmutableList> valuesList;

  private UpsertStatement(
      TableRef table,
      ImmutableList columnNames,
      ImmutableList> valuesList) {
    this.table = Objects.requireNonNull(table);
    this.columnNames = Objects.requireNonNull(columnNames);
    this.valuesList = Objects.requireNonNull(valuesList);
  }

  @Override
  public UpsertStatement bind(List positionalValues) {
    Iterator positionalValuesIterator = positionalValues.iterator();
    return create(
        table,
        columnNames,
        valuesList.stream()
            .map(values -> bindValues(values, positionalValuesIterator))
            .collect(ImmutableList.toImmutableList()));
  }

  @Override
  public UpsertStatement bind(Map namedValues) {
    return create(
        table,
        columnNames,
        valuesList.stream()
            .map(values -> bindValues(values, namedValues))
            .collect(ImmutableList.toImmutableList()));
  }

  private ImmutableList bindValues(
      List values, Iterator positionalValueIterator) {
    return values.stream()
        .map(
            v -> {
              if (positionalValueIterator.hasNext() && v instanceof BindMarker) {
                if (v instanceof NamedBindMarker) {
                  throw new IllegalArgumentException(
                      SqlError.NAMED_BIND_MARKER_NOT_ALLOWED.buildMessage());
                }
                return positionalValueIterator.next();
              } else {
                return v;
              }
            })
        .collect(ImmutableList.toImmutableList());
  }

  private ImmutableList bindValues(List values, Map namedValues) {
    return values.stream()
        .map(
            v -> {
              if (v instanceof BindMarker) {
                if (v instanceof PositionalBindMarker) {
                  throw new IllegalArgumentException(
                      SqlError.POSITIONAL_BIND_MARKER_NOT_ALLOWED.buildMessage());
                }
                String name = ((NamedBindMarker) v).name;
                if (namedValues.containsKey(name)) {
                  return namedValues.get(name);
                } else {
                  return v;
                }
              } else {
                return v;
              }
            })
        .collect(ImmutableList.toImmutableList());
  }

  @Override
  public String toSql() {
    StringBuilder builder = new StringBuilder("UPSERT INTO ");
    StatementUtils.appendTable(builder, table);

    if (!columnNames.isEmpty()) {
      builder.append('(');
      StatementUtils.appendObjectNames(builder, columnNames);
      builder.append(')');
    }

    builder.append(" VALUES ");

    boolean valuesFirst = true;
    for (ImmutableList values : valuesList) {
      if (!valuesFirst) {
        builder.append(',');
      } else {
        valuesFirst = false;
      }

      builder.append('(');
      boolean valueFirst = true;
      for (Term value : values) {
        if (!valueFirst) {
          builder.append(',');
        } else {
          valueFirst = false;
        }

        StatementUtils.appendTerm(builder, value);
      }
      builder.append(')');
    }

    return builder.toString();
  }

  @Override
  public  R accept(StatementVisitor visitor, C context) {
    return visitor.visit(this, context);
  }

  @Override
  public  R accept(DmlStatementVisitor visitor, C context) {
    return visitor.visit(this, context);
  }

  @Override
  public boolean namespaceNameOmitted() {
    return table.namespaceName == null;
  }

  @Override
  public UpsertStatement setNamespaceNameIfOmitted(String namespaceName) {
    if (namespaceNameOmitted()) {
      return create(TableRef.of(namespaceName, table.tableName), columnNames, valuesList);
    }
    return this;
  }

  @Override
  public String toString() {
    return toSql();
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (!(o instanceof UpsertStatement)) {
      return false;
    }
    UpsertStatement that = (UpsertStatement) o;
    return Objects.equals(table, that.table)
        && Objects.equals(columnNames, that.columnNames)
        && Objects.equals(valuesList, that.valuesList);
  }

  @Override
  public int hashCode() {
    return Objects.hash(table, columnNames, valuesList);
  }

  public static UpsertStatement create(
      TableRef table,
      ImmutableList columnNames,
      ImmutableList> valuesList) {
    return new UpsertStatement(table, columnNames, valuesList);
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy