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

io.stargate.db.Result Maven / Gradle / Ivy

There is a newer version: 2.1.0-BETA-19
Show newest version
/*
 * Copyright The Stargate Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.stargate.db;

import com.datastax.oss.driver.shaded.guava.common.base.Preconditions;
import io.stargate.db.schema.Column;
import java.nio.ByteBuffer;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.UUID;
import javax.annotation.Nullable;
import org.apache.cassandra.stargate.transport.ProtocolException;
import org.apache.cassandra.stargate.utils.MD5Digest;

public abstract class Result {
  public enum Kind {
    Void(1),
    Rows(2),
    SetKeyspace(3),
    Prepared(4),
    SchemaChange(5);

    public final int id;

    Kind(int id) {
      this.id = id;
    }

    public static Kind fromId(int id) {
      for (Kind k : values()) {
        if (k.id == id) return k;
      }
      throw new ProtocolException(String.format("Unknown kind id %d for RESULT message", id));
    }
  }

  public final Kind kind;
  private UUID tracingId;
  private @Nullable List warnings;

  private Result(Kind kind) {
    this.kind = kind;
  }

  public Result setTracingId(UUID tracingId) {
    this.tracingId = tracingId;
    return this;
  }

  public Result setWarnings(@Nullable List warnings) {
    Preconditions.checkState(this.warnings == null, "Warnings have already been set.");
    this.warnings = warnings;
    return this;
  }

  public UUID getTracingId() {
    return tracingId;
  }

  public @Nullable List getWarnings() {
    return warnings;
  }

  public static class Rows extends Result {
    public final List> rows;
    public final ResultMetadata resultMetadata;

    public Rows(List> rows, ResultMetadata resultMetadata) {
      super(Kind.Rows);
      this.rows = rows;
      this.resultMetadata = resultMetadata;
    }

    @Override
    public String toString() {
      return "ROWS " + resultMetadata;
    }
  }

  public static class Void extends Result {
    public Void() {
      super(Kind.Void);
    }

    @Override
    public String toString() {
      return "EMPTY RESULT";
    }
  }

  public static class SetKeyspace extends Result {
    public final String keyspace;

    public SetKeyspace(String keyspace) {
      super(Kind.SetKeyspace);
      this.keyspace = keyspace;
    }

    @Override
    public String toString() {
      return "RESULT set keyspace " + keyspace;
    }
  }

  public static class Prepared extends Result {
    public final MD5Digest statementId;
    public final MD5Digest resultMetadataId;
    public final ResultMetadata resultMetadata;
    public final PreparedMetadata metadata;

    public Prepared(
        MD5Digest statementId,
        MD5Digest resultMetadataId,
        ResultMetadata resultMetadata,
        PreparedMetadata preparedMetadata) {
      super(Kind.Prepared);
      this.statementId = statementId;
      this.resultMetadataId = resultMetadataId;
      this.resultMetadata = resultMetadata;
      this.metadata = preparedMetadata;
    }

    @Override
    public String toString() {
      return "RESULT PREPARED "
          + statementId
          + " "
          + metadata
          + " (resultMetadata="
          + resultMetadata
          + ")";
    }
  }

  public static class SchemaChange extends Result {
    public final SchemaChangeMetadata metadata;

    public SchemaChange(SchemaChangeMetadata metadata) {
      super(Kind.SchemaChange);
      this.metadata = metadata;
    }

    @Override
    public String toString() {
      return "RESULT schema change " + metadata;
    }
  }

  public enum Flag {
    // The order of that enum matters!!
    GLOBAL_TABLES_SPEC(1),
    HAS_MORE_PAGES(2),
    NO_METADATA(3),
    METADATA_CHANGED(4);

    public final int id;

    Flag(int id) {
      this.id = id;
    }

    public static Flag fromId(int id) {
      for (Flag f : values()) {
        if (f.id == id) return f;
      }
      throw new ProtocolException(String.format("Unknown flag id %d in RESULT message", id));
    }

    public static EnumSet deserialize(int flags) {
      EnumSet set = EnumSet.noneOf(Flag.class);
      Flag[] values = Flag.values();
      for (int n = 0; n < values.length; n++) {
        if ((flags & (1 << n)) != 0) {
          set.add(values[n]);
        }
      }
      return set;
    }

    public static int serialize(EnumSet flags) {
      int i = 0;
      for (Flag flag : flags) {
        i |= 1 << flag.ordinal();
      }
      return i;
    }
  }

  public static class ResultMetadata {
    public static final ResultMetadata EMPTY =
        new ResultMetadata(
            EnumSet.of(Flag.NO_METADATA),
            Collections.emptyList(),
            MD5Digest.compute(new byte[0]),
            null);

    public final EnumSet flags;
    public final int columnCount;
    /**
     * The definition of the columns for each row in the result set. Please note that the objects in
     * this list are not "true" columns, in the sense that 1) some may not correspond to a declared
     * column at all (for instance, {@code ttl(c)}) and 2) even for definition that correspond to a
     * genuine column, some of information may not be set. For instance, the {@link Column#kind()}
     * method may well return {@code null}, even if the column is otherwise a partition column. The
     * only things that can be safely relied upon for a column are it's keyspace and table name, the
     * name of what it represents and the type.
     *
     * 

Practically, if you get a column {@code c} from this list that correspond to a genuine * column "c" in table "k.t", and {@code t} is that {@link io.stargate.db.schema.Table} schema, * do no assume that {@code c.equals(t.column(c.name()))} (because the {@link Column#kind} or * {@link Column#order} may differ). */ // TODO: we may want to try to have a specific class here instead of Column to make it very // clear that those aren't entirely the same concept that the Column object in the schema. public final List columns; public final MD5Digest resultMetadataId; public ByteBuffer pagingState; public ResultMetadata( EnumSet flags, int columnCount, List columns, MD5Digest resultMetadataId, ByteBuffer pagingState) { this.flags = flags; this.columnCount = columnCount; this.columns = columns; this.resultMetadataId = resultMetadataId; this.pagingState = pagingState; } public ResultMetadata( EnumSet flags, List columns, MD5Digest resultMetadataId, ByteBuffer pagingState) { this.flags = flags; this.columnCount = columns.size(); this.columns = columns; this.resultMetadataId = resultMetadataId; this.pagingState = pagingState; } } public static class PreparedMetadata { public final EnumSet flags; public final List columns; public final short[] partitionKeyBindIndexes; public PreparedMetadata( EnumSet flags, List columns, short[] partitionKeyBindIndexes) { this.flags = flags; this.columns = columns; this.partitionKeyBindIndexes = partitionKeyBindIndexes; } } public static class SchemaChangeMetadata { public final String change; public final String target; public final String keyspace; public final String name; public final List argTypes; public SchemaChangeMetadata( String change, String target, String keyspace, String name, List argTypes) { this.change = change; this.target = target; this.keyspace = keyspace; this.name = name; if (!target.equals("KEYSPACE")) { assert this.name != null : "Table, type, function or aggregate name should be set for non-keyspace schema change events"; } this.argTypes = argTypes; } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy