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

com.databricks.jdbc.core.ArrowToJavaObjectConverter Maven / Gradle / Ivy

There is a newer version: 2.6.40-patch-1
Show newest version
package com.databricks.jdbc.core;

import com.databricks.sdk.service.sql.ColumnInfoTypeName;
import java.math.BigDecimal;
import java.sql.Date;
import java.sql.Timestamp;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Arrays;
import java.util.List;
import org.apache.arrow.vector.util.Text;

public class ArrowToJavaObjectConverter {
  private static List DATE_FORMATTERS =
      Arrays.asList(
          DateTimeFormatter.ofPattern("yyyy-MM-dd"),
          DateTimeFormatter.ofPattern("yyyy/MM/dd"),
          DateTimeFormatter.ofPattern("yyyy.MM.dd"),
          DateTimeFormatter.ofPattern("yyyyMMdd"),
          DateTimeFormatter.ofPattern("dd-MM-yyyy"),
          DateTimeFormatter.ofPattern("dd/MM/yyyy"),
          DateTimeFormatter.ofPattern("dd.MM.yyyy"),
          DateTimeFormatter.ofPattern("ddMMyyyy"),
          DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"),
          DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss"),
          DateTimeFormatter.ofPattern("yyyy.MM.dd HH:mm:ss"),
          DateTimeFormatter.ofPattern("yyyyMMdd HH:mm:ss"),
          DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss"),
          DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss"),
          DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss"),
          DateTimeFormatter.ofPattern("ddMMyyyy HH:mm:ss"),
          DateTimeFormatter.ISO_LOCAL_DATE_TIME,
          DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS"),
          DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"),
          DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"),
          DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SS"),
          DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.S"),
          DateTimeFormatter.RFC_1123_DATE_TIME);

  // TODO (Madhav): Check Arrow to JSON conversion
  public static Object convert(Object object, ColumnInfoTypeName requiredType)
      throws DatabricksSQLException {
    if (object == null) {
      return null;
    }
    switch (requiredType) {
      case BYTE:
        return convertToByte(object);
      case SHORT:
        return convertToShort(object);
      case INT:
        return convertToInteger(object);
      case LONG:
        return convertToLong(object);
      case FLOAT:
        return convertToFloat(object);
      case DOUBLE:
        return convertToDouble(object);
      case DECIMAL:
        return convertToBigDecimal(object);
      case BINARY:
        return convertToByteArray(object);
      case BOOLEAN:
        return convertToBoolean(object);
      case CHAR:
        return convertToChar(object);
      case STRING:
        // Struct and Array are present in Arrow data in the VARCHAR ValueVector format
      case STRUCT:
      case ARRAY:
      case MAP:
        return convertToString(object);
      case DATE:
        return convertToDate(object);
      case TIMESTAMP:
        return convertToTimestamp(object);
      case NULL:
        return null;
      default:
        throw new DatabricksSQLException("Unsupported type");
    }
  }

  private static Object convertToTimestamp(Object object) throws DatabricksSQLException {
    if (object instanceof Text) {
      return convertArrowTextToTimestamp(object.toString());
    }
    // Divide by 1000 since we need to convert from microseconds to milliseconds.
    Instant instant =
        Instant.ofEpochMilli(
            object instanceof Integer ? ((int) object) / 1000 : ((long) object) / 1000);
    return Timestamp.from(instant);
  }

  private static Object convertArrowTextToTimestamp(String arrowText)
      throws DatabricksSQLException {
    LocalDateTime localDateTime = parseDate(arrowText);
    return Timestamp.valueOf(localDateTime);
  }

  private static LocalDateTime parseDate(String text) throws DatabricksSQLException {
    for (DateTimeFormatter formatter : DATE_FORMATTERS) {
      try {
        return LocalDateTime.parse(text, formatter);
      } catch (DateTimeParseException e) {
        // Continue to try the next format
      }
    }
    throw new DatabricksSQLException("Unsupported text for conversion: " + text);
  }

  private static Date convertToDate(Object object) throws DatabricksSQLException {
    if (object instanceof Text) {
      LocalDateTime localDateTime = parseDate(object.toString());
      return java.sql.Date.valueOf(localDateTime.toLocalDate());
    }
    LocalDate localDate = LocalDate.ofEpochDay((int) object);
    return Date.valueOf(localDate);
  }

  private static char convertToChar(Object object) throws DatabricksSQLException {
    return (object.toString()).charAt(0);
  }

  private static String convertToString(Object object) throws DatabricksSQLException {
    return object.toString();
  }

  private static boolean convertToBoolean(Object object) throws DatabricksSQLException {
    if (object instanceof Text) {
      return Boolean.parseBoolean(object.toString());
    }
    return (boolean) object;
  }

  private static byte[] convertToByteArray(Object object) throws DatabricksSQLException {
    if (object instanceof Text) {
      return object.toString().getBytes();
    }
    return (byte[]) object;
  }

  private static byte convertToByte(Object object) throws DatabricksSQLException {
    if (object instanceof Text) {
      return Byte.parseByte(object.toString());
    }
    if (object instanceof Number) {
      return ((Number) object).byteValue();
    }
    return (byte) object;
  }

  private static short convertToShort(Object object) throws DatabricksSQLException {
    if (object instanceof Text) {
      return Short.parseShort(object.toString());
    }
    if (object instanceof Number) {
      return ((Number) object).shortValue();
    }
    return (short) object;
  }

  private static BigDecimal convertToBigDecimal(Object object) throws DatabricksSQLException {
    if (object instanceof Text) {
      return new BigDecimal(object.toString());
    }
    return (BigDecimal) object;
  }

  private static double convertToDouble(Object object) throws DatabricksSQLException {
    if (object instanceof Text) {
      return Double.parseDouble(object.toString());
    }
    if (object instanceof Number) {
      return ((Number) object).doubleValue();
    }
    return (double) object;
  }

  private static float convertToFloat(Object object) throws DatabricksSQLException {
    if (object instanceof Text) {
      return Float.parseFloat(object.toString());
    }
    if (object instanceof Number) {
      return ((Number) object).floatValue();
    }
    return (float) object;
  }

  private static int convertToInteger(Object object) throws DatabricksSQLException {
    if (object instanceof Text) {
      return Integer.parseInt(object.toString());
    }
    if (object instanceof Number) {
      return ((Number) object).intValue();
    }
    return (int) object;
  }

  private static long convertToLong(Object object) throws DatabricksSQLException {
    if (object instanceof Text) {
      return Long.parseLong(object.toString());
    }
    if (object instanceof Number) {
      return ((Number) object).longValue();
    }
    return (long) object;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy