public static HashResult fromJDBCResultSet()

in spanner-data-validator-java/src/main/java/com/google/migration/dto/HashResult.java [173:326]


  public static HashResult fromJDBCResultSet(ResultSet resultSet,
      Integer keyIndex,
      String rangeFieldType,
      Boolean adjustTimestampPrecision,
      Integer timestampThresholdIndex)
      throws SQLException {
    HashResult retVal = new HashResult();

    ResultSetMetaData rsMetaData = resultSet.getMetaData();
    int colCount = rsMetaData.getColumnCount();
    StringBuilder sbConcatCols = new StringBuilder();
    for(int i = 0; i < colCount; i++) {
      int colOrdinal = i+1;
      int type = rsMetaData.getColumnType(colOrdinal);

      // https://docs.oracle.com/javase/8/docs/api/constant-values.html
      // look for (java.sql.Types)
      switch (type) {
        case Types.CHAR:
        case Types.VARCHAR:
        case Types.LONGVARCHAR:
          String val = resultSet.getString(colOrdinal);
          if(val != null && !resultSet.wasNull()) {
            sbConcatCols.append(val);
          }
          break;
        case Types.ARRAY:
          Array arrayVal = resultSet.getArray(colOrdinal);
          if(arrayVal != null && !resultSet.wasNull()) {
            String[] vals = (String[])arrayVal.getArray();
            for(int j = 0; j < vals.length; j++) {
              sbConcatCols.append(vals[j]);
            }
          }
          break;
        // TODO: we're assuming OTHER is jsonb (FIX)
        case Types.OTHER:
          String otherVal = resultSet.getString(colOrdinal);
          if(otherVal != null && !resultSet.wasNull()) {
            sbConcatCols.append(getNormalizedJsonString(otherVal));
          }
          break;
        case Types.LONGVARBINARY:
        case Types.VARBINARY:
          byte[] bytes = resultSet.getBytes(colOrdinal);
          if(bytes != null && !resultSet.wasNull()) {
            sbConcatCols.append(Base64.encodeBase64String(bytes));
          }
          break;
        case Types.BIT:
        case Types.BOOLEAN:
          Boolean boolVal = resultSet.getBoolean(colOrdinal);
          if(boolVal != null && !resultSet.wasNull()) {
            // https://stackoverflow.com/questions/39561112/getting-boolean-from-resultset
            sbConcatCols.append(boolVal);
          }
          break;
        case Types.INTEGER:
          Integer intVal = resultSet.getInt(colOrdinal);
          if(intVal != null && !resultSet.wasNull()) {
            sbConcatCols.append(intVal);
          }
          break;
        case Types.DOUBLE:
          Double doubleVal = resultSet.getDouble(colOrdinal);
          if(doubleVal != null && !resultSet.wasNull()) {
            sbConcatCols.append(doubleVal);
          }
          break;
        case Types.REAL:
          Float floatVal = resultSet.getFloat(colOrdinal);
          if(floatVal != null && !resultSet.wasNull()) {
            sbConcatCols.append(floatVal);
          }
          break;
        case Types.TINYINT:
          Short shortVal = resultSet.getShort(colOrdinal);
          if(shortVal != null && !resultSet.wasNull()) {
            sbConcatCols.append(shortVal);
          }
          break;
        case Types.BIGINT:
          Long longVal = resultSet.getLong(colOrdinal);
          if(longVal != null && !resultSet.wasNull()) {
            sbConcatCols.append(longVal);
          }
          break;
        case Types.DECIMAL:
          //DECIMAL is mapped to Spanner NUMERIC which does not store trailing zeros
          //Strip the trailing zeros from the source result before comparing
          BigDecimal decimalVal = new BigDecimal(resultSet.getBigDecimal(colOrdinal).stripTrailingZeros().toPlainString());
          if(decimalVal != null && !resultSet.wasNull()) {
            sbConcatCols.append(decimalVal);
          }
          break;
        case Types.DATE:
          Date dateVal = resultSet.getDate(colOrdinal);
          if(dateVal != null && !resultSet.wasNull()) {
            LocalDate localDate = dateVal.toLocalDate();
            sbConcatCols.append(String.format("%d%d%d",
                localDate.getYear(),
                localDate.getMonth().getValue(),
                localDate.getDayOfMonth()));
          }
          break;
        case Types.TIMESTAMP:
        case Types.TIME_WITH_TIMEZONE:
          // TODO: This uses millisecond precision; consider using microsecond precision
          java.sql.Timestamp timestampVal = resultSet.getTimestamp(colOrdinal);
          if(timestampVal != null && !resultSet.wasNull()) {
            Long rawTimestamp = timestampVal.getTime();
            if (adjustTimestampPrecision)
              rawTimestamp = rawTimestamp / 1000;
            sbConcatCols.append(rawTimestamp);
            if(timestampThresholdIndex >= 0) {
              if(i == timestampThresholdIndex) {
                retVal.timestampThresholdValue = rawTimestamp;
                if(adjustTimestampPrecision)
                  retVal.timestampThresholdValue = retVal.timestampThresholdValue * 1000;
              }
            }
          }
          break;
        default:
          LOG.error(String.format("Unsupported type: %d", type));
          throw new RuntimeException(String.format("Unsupported type: %d", type));
      } // switch
    } // for

    switch(rangeFieldType) {
      case TableSpec.UUID_FIELD_TYPE:
      case TableSpec.STRING_FIELD_TYPE:
        retVal.key = resultSet.getString(keyIndex+1);
        break;
      case TableSpec.TIMESTAMP_FIELD_TYPE:
        retVal.key = resultSet.getTimestamp(keyIndex+1).toString();
        break;
      case TableSpec.INT_FIELD_TYPE:
        retVal.key = String.valueOf(resultSet.getInt(keyIndex+1));
        break;
      case TableSpec.LONG_FIELD_TYPE:
        retVal.key = String.valueOf(resultSet.getLong(keyIndex+1));
        break;
      default:
        throw new RuntimeException(String.format("Unexpected range field type %s", rangeFieldType));
    }

    retVal.rangeFieldType = rangeFieldType;
    retVal.origValue = sbConcatCols.toString();
    retVal.sha256 = Helpers.sha256(retVal.origValue);
    retVal.isSource = true;

    return retVal;
  }