class SqlResultSetReader {

  public static Table read(ResultSet resultSet) throws SQLException {

    ResultSetMetaData metaData = resultSet.getMetaData();
    Table table = Table.create();

    // Setup the columns and add to the table
    for (int i = 1; i <= metaData.getColumnCount(); i++) {
      ColumnType type =
          getColumnType(metaData.getColumnType(i), metaData.getScale(i), metaData.getPrecision(i));

      Preconditions.checkState(
          type != null,
          "No column type found for %s as specified for column %s",
          metaData.getColumnType(i),
          metaData.getColumnName(i));

      Column<?> newColumn = type.create(metaData.getColumnLabel(i));
      table.addColumns(newColumn);
    }

    // Add the rows
    while (resultSet.next()) {
      for (int i = 1; i <= metaData.getColumnCount(); i++) {
        Column<?> column =
            table.column(i - 1); // subtract 1 because results sets originate at 1 not 0
        if (column instanceof ShortColumn) {
          appendToColumn(column, resultSet, resultSet.getShort(i));
        } else if (column instanceof IntColumn) {
          appendToColumn(column, resultSet, resultSet.getInt(i));
        } else if (column instanceof LongColumn) {
          appendToColumn(column, resultSet, resultSet.getLong(i));
        } else if (column instanceof FloatColumn) {
          appendToColumn(column, resultSet, resultSet.getFloat(i));
        } else if (column instanceof DoubleColumn) {
          appendToColumn(column, resultSet, resultSet.getDouble(i));
        } else if (column instanceof BooleanColumn) {
          appendToColumn(column, resultSet, resultSet.getBoolean(i));
        } else {
          column.appendObj(resultSet.getObject(i));
        }
      }
    }
    return table;
  }

}