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

org.postgresql.adba.communication.packets.DataRow Maven / Gradle / Ivy

package org.postgresql.adba.communication.packets;

import jdk.incubator.sql2.Result;
import jdk.incubator.sql2.SqlType;
import org.postgresql.adba.communication.TableCell;
import org.postgresql.adba.communication.packets.parts.ColumnDescription;
import org.postgresql.adba.util.BinaryHelper;

import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

public class DataRow implements Result.RowColumn, Result.OutColumn {
  private Map columnNames;
  private Map columns;
  private long rowNumber;
  private int currentPos = 1;

  /**
   * parses the bytes that describe one data row in a result set.
   * @param bytes bytes to parse
   * @param description the descriptions of the columns
   * @param rowNumber current row number in the result set
   */
  public DataRow(byte[] bytes, ColumnDescription[] description, long rowNumber) {
    this.rowNumber = rowNumber;

    short numOfColumns = BinaryHelper.readShort(bytes[0], bytes[1]);
    int pos = 2;
    int columnPos = 1;
    columns = new HashMap<>(numOfColumns);
    columnNames = new HashMap<>(numOfColumns);
    for (int i = 0; i < numOfColumns; i++) {
      int length = BinaryHelper.readInt(bytes[pos], bytes[pos + 1], bytes[pos + 2], bytes[pos + 3]);
      pos += 4;
      columnNames.put(description[i].getName().toLowerCase(), columnPos);
      columns.put(columnPos, new TableCell(bytes, pos, pos + length, description[i]));
      pos += length;
      columnPos++;
    }
  }

  @Override
  public long rowNumber() {
    return rowNumber;
  }

  @Override
  public void cancel() {

  }

  @Override
  public  T get(Class type) {
    TableCell tc = columns.get(currentPos);

    if (tc == null) {
      throw new IllegalArgumentException("no column with position " + currentPos);
    }

    if (tc.getStart() > tc.getStop()) { // handle the null special case
      return null;
    }

    switch (tc.getColumnDescription().getFormatCode()) {
      case TEXT:
        String data = new String(BinaryHelper.subBytes(tc.getBytes(), tc.getStart(), tc.getStop()), StandardCharsets.UTF_8);
        return (T)tc.getColumnDescription().getColumnType().getTextParser().apply(data, type);
      case BINARY:
        return (T)tc.getColumnDescription().getColumnType().getBinaryParser().apply(tc.getBytes(), tc.getStart(),
            tc.getStop(), type);
      default:
        throw new IllegalStateException("unimplemented switch case");
    }
  }

  @Override
  public String identifier() {
    return columns.get(currentPos).getColumnDescription().getName();
  }

  @Override
  public int index() {
    return currentPos;
  }

  @Override
  public int absoluteIndex() {
    return currentPos;
  }

  @Override
  public SqlType sqlType() {
    if (!columns.containsKey(currentPos)) {
      throw new IllegalArgumentException("no column with id " + currentPos);
    }

    return columns.get(currentPos).getColumnDescription().getColumnType().sqlType();
  }

  @Override
  public  Class javaType() {
    if (!columns.containsKey(currentPos)) {
      throw new IllegalArgumentException("no column with id " + currentPos);
    }

    return columns.get(currentPos).getColumnDescription().getColumnType().javaType();
  }

  @Override
  public long length() {
    TableCell tc = columns.get(currentPos);
    return tc.getStop() - tc.getStart();
  }

  @Override
  public int numberOfValuesRemaining() {
    return columns.size() - currentPos;
  }

  @Override
  public Column at(String id) {
    Integer newPos = columnNames.get(id.toLowerCase());

    if (newPos == null) {
      throw new IllegalArgumentException("no column with id " + id);
    }

    currentPos = newPos;
    return this;
  }

  @Override
  public Column at(int index) {
    if (!columns.containsKey(index)) {
      throw new IllegalArgumentException("no column with index " + index);
    }

    currentPos = index;
    return this;
  }

  @Override
  public Column slice(int numValues) {
    throw new RuntimeException("not implemented yet");

  }

  @Override
  public Column clone() {
    DataRow row;

    try {
      row = (DataRow) super.clone();
    } catch (CloneNotSupportedException e) {
      throw new Error();
    }

    row.columnNames = new HashMap<>(columnNames);
    row.columns = new HashMap<>(columns);
    row.rowNumber = rowNumber;
    row.currentPos = currentPos;

    return row;
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy