content: /*
   * Licensed to the Apache Software Foundation (ASF) under one or more
   * contributor license agreements.  See the NOTICE file distributed with
   * this work for additional information regarding copyright ownership.
   * The ASF licenses this file to you 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 org.apache.calcite.avatica;
  
  import org.apache.calcite.avatica.remote.TypedValue;
  import org.apache.calcite.avatica.util.ArrayFactoryImpl;
  import org.apache.calcite.avatica.util.ArrayImpl;
  import org.apache.calcite.avatica.util.DateTimeUtils;
  import org.apache.calcite.avatica.util.StructImpl;
  import org.apache.calcite.avatica.util.Unsafe;
  
  import org.junit.AfterClass;
  import org.junit.BeforeClass;
  import org.junit.Test;
  import org.junit.runner.RunWith;
  import org.junit.runners.Parameterized;
  import org.junit.runners.Parameterized.Parameters;
  
  import java.io.InputStream;
  import java.io.Reader;
  import java.math.BigDecimal;
  import java.math.BigInteger;
  import java.net.URL;
  import java.sql.Array;
  import java.sql.Blob;
  import java.sql.Clob;
  import java.sql.Connection;
  import java.sql.DatabaseMetaData;
  import java.sql.Date;
  import java.sql.NClob;
  import java.sql.Ref;
  import java.sql.ResultSet;
  import java.sql.SQLDataException;
  import java.sql.SQLException;
  import java.sql.SQLXML;
  import java.sql.Struct;
  import java.sql.Time;
  import java.sql.Timestamp;
  import java.sql.Types;
  import java.util.Arrays;
  import java.util.Calendar;
  import java.util.Collection;
  import java.util.Collections;
  import java.util.List;
  import java.util.Map;
  import java.util.Properties;
  import java.util.TimeZone;
  
  import static org.hamcrest.CoreMatchers.isA;
  import static org.hamcrest.MatcherAssert.assertThat;
  import static org.junit.Assert.assertEquals;
  import static org.junit.Assert.assertNull;
  import static org.junit.Assert.assertTrue;
  import static org.junit.Assert.fail;
  
  /**
   * Test {@code ResultSet#getXXX} conversions.
   */
  @RunWith(Parameterized.class)
  public class AvaticaResultSetConversionsTest {
  
    // UTC: 2016-10-10 20:18:38.123
    // October 10 is considered DST in all time zones that observe DST (both hemispheres), so tests
    // using this value will cover daylight time zone conversion when run in a location that observes
    // DST. This is just a matter of coverage; all tests must succeed no matter where the host is.
    private static final long DST_INSTANT = 1476130718123L;
    private static final String DST_DATE_STRING = "2016-10-10";
    private static final String DST_TIME_STRING = "20:18:38";
    private static final String DST_TIMESTAMP_STRING = "2016-10-10 20:18:38";
  
    // UTC: 2016-11-14 11:32:03.242
    // There is no date where all time zones (both hemispheres) are on standard time, but all northern
    // time zones observe standard time by mid-November. Tests using this value may or may not
    // exercise standard time zone conversion, but this is just a matter of coverage; all tests must
    // succeed no matter where the host is.
    private static final long STANDARD_INSTANT = 1479123123242L;
  
    // UTC: 00:24:36.123
    private static final long VALID_TIME = 1476123L;
  
    // UTC: 41:05:12.242
    private static final long OVERFLOW_TIME = 147912242L;
  
    /**
     * A fake test driver for test.
     */
    private static final class TestDriver extends UnregisteredDriver {
  
      @Override protected DriverVersion createDriverVersion() {
        return new DriverVersion("test", "test 0.0.0", "test", "test 0.0.0", false, 0, 0, 0, 0);
      }
  
      @Override protected String getConnectStringPrefix() {
        return "jdbc:test";
      }
  
      @Override public Meta createMeta(AvaticaConnection connection) {
        return new TestMetaImpl(connection);
      }
    }
  
    /**
     * Fake meta implementation for test driver.
     */
    public static final class TestMetaImpl extends MetaImpl {
      public TestMetaImpl(AvaticaConnection connection) {
        super(connection);
      }
  
      @Override public StatementHandle prepare(ConnectionHandle ch, String sql, long maxRowCount) {
        throw new UnsupportedOperationException();
      }
  
      @SuppressWarnings("deprecation")
      @Override public ExecuteResult prepareAndExecute(StatementHandle h, String sql,
          long maxRowCount, PrepareCallback callback) throws NoSuchStatementException {
        throw new UnsupportedOperationException();
      }
  
      @Override public ExecuteResult prepareAndExecute(StatementHandle h, String sql,
          long maxRowCount, int maxRowsInFirstFrame, PrepareCallback callback)
          throws NoSuchStatementException {
        assertEquals("SELECT * FROM TABLE", sql);
        List<ColumnMetaData> columns = Arrays.asList(
            columnMetaData("bool", 0,
                ColumnMetaData.scalar(Types.BOOLEAN, "BOOLEAN",
                    ColumnMetaData.Rep.PRIMITIVE_BOOLEAN),
                DatabaseMetaData.columnNoNulls),
            columnMetaData("byte", 1,
                ColumnMetaData.scalar(Types.TINYINT, "TINYINT",
                    ColumnMetaData.Rep.PRIMITIVE_BYTE),
                DatabaseMetaData.columnNoNulls),
            columnMetaData("short", 2,
                ColumnMetaData.scalar(Types.SMALLINT, "SMALLINT",
                    ColumnMetaData.Rep.PRIMITIVE_SHORT),
                DatabaseMetaData.columnNoNulls),
            columnMetaData("medium", 3,
                ColumnMetaData.scalar(Types.INTEGER, "MEDIUMINT",
                    ColumnMetaData.Rep.PRIMITIVE_INT),
                DatabaseMetaData.columnNoNulls),
            columnMetaData("int", 4,
                ColumnMetaData.scalar(Types.INTEGER, "INTEGER",
                    ColumnMetaData.Rep.PRIMITIVE_INT),
                DatabaseMetaData.columnNoNulls),
            columnMetaData("long", 5,
                ColumnMetaData.scalar(Types.BIGINT, "BIGINT",
                    ColumnMetaData.Rep.PRIMITIVE_LONG),
                DatabaseMetaData.columnNoNulls),
            columnMetaData("byte_unsigned", 6,
                ColumnMetaData.scalar(Types.TINYINT, "TINYINT_UNSIGNED",
                    ColumnMetaData.Rep.PRIMITIVE_SHORT),
                DatabaseMetaData.columnNoNulls, false),
            columnMetaData("short_unsigned", 7,
                ColumnMetaData.scalar(Types.SMALLINT, "SMALLINT_UNSIGNED",
                    ColumnMetaData.Rep.PRIMITIVE_INT),
                DatabaseMetaData.columnNoNulls, false),
            columnMetaData("medium_unsigned", 8,
                ColumnMetaData.scalar(Types.INTEGER, "MEDIUMINT_UNSIGNED",
                    ColumnMetaData.Rep.PRIMITIVE_INT),
                DatabaseMetaData.columnNoNulls, false),
            columnMetaData("int_unsigned", 9,
                ColumnMetaData.scalar(Types.INTEGER, "INTEGER_UNSIGNED",
                    ColumnMetaData.Rep.PRIMITIVE_LONG),
                DatabaseMetaData.columnNoNulls, false),
            columnMetaData("long_unsigned", 10,
                ColumnMetaData.scalar(Types.BIGINT, "BIGINT_UNSIGNED",
                    ColumnMetaData.Rep.NUMBER),
                DatabaseMetaData.columnNoNulls, false),
            columnMetaData("float", 11,
                ColumnMetaData.scalar(Types.REAL, "REAL",
                    ColumnMetaData.Rep.FLOAT),
                DatabaseMetaData.columnNoNulls),
            columnMetaData("double", 12,
                ColumnMetaData.scalar(Types.FLOAT, "FLOAT",
                    ColumnMetaData.Rep.DOUBLE),
                DatabaseMetaData.columnNoNulls),
            columnMetaData("string", 13,
                ColumnMetaData.scalar(Types.VARCHAR, "VARCHAR",
                    ColumnMetaData.Rep.STRING),
                DatabaseMetaData.columnNoNulls),
            columnMetaData("date", 14,
                ColumnMetaData.scalar(Types.DATE, "DATE",
                    ColumnMetaData.Rep.JAVA_SQL_DATE),
                DatabaseMetaData.columnNoNulls),
            columnMetaData("time", 15,
                ColumnMetaData.scalar(Types.TIME, "TIME",
                    ColumnMetaData.Rep.JAVA_SQL_TIME),
                DatabaseMetaData.columnNoNulls),
            columnMetaData("timestamp", 16,
                ColumnMetaData.scalar(Types.TIMESTAMP, "TIMESTAMP",
                    ColumnMetaData.Rep.JAVA_SQL_TIMESTAMP),
                DatabaseMetaData.columnNoNulls),
            columnMetaData("array", 17,
                ColumnMetaData.array(
                    ColumnMetaData.scalar(Types.INTEGER, "INTEGER",
                        ColumnMetaData.Rep.PRIMITIVE_INT),
                    "ARRAY",
                    ColumnMetaData.Rep.ARRAY),
                DatabaseMetaData.columnNoNulls),
            columnMetaData("struct", 18,
                ColumnMetaData.struct(
                    Arrays.asList(
                        columnMetaData("int", 0,
                            ColumnMetaData.scalar(Types.INTEGER, "INTEGER",
                                ColumnMetaData.Rep.PRIMITIVE_INT),
                            DatabaseMetaData.columnNoNulls),
                        columnMetaData("bool", 1,
                            ColumnMetaData.scalar(Types.BOOLEAN, "BOOLEAN",
                                ColumnMetaData.Rep.PRIMITIVE_BOOLEAN),
                            DatabaseMetaData.columnNoNulls))),
                DatabaseMetaData.columnNoNulls),
            columnMetaData("bit", 19,
                ColumnMetaData.scalar(Types.BIT, "BIT",
                    ColumnMetaData.Rep.PRIMITIVE_BOOLEAN),
                DatabaseMetaData.columnNoNulls),
            columnMetaData("null", 20,
                ColumnMetaData.scalar(Types.NULL, "NULL",
                    ColumnMetaData.Rep.OBJECT),
                DatabaseMetaData.columnNullable),
            columnMetaData("date_array", 21,
                ColumnMetaData.array(
                    ColumnMetaData.scalar(Types.DATE, "DATE",
                        ColumnMetaData.Rep.PRIMITIVE_INT),
                    "ARRAY",
                    ColumnMetaData.Rep.ARRAY),
                DatabaseMetaData.columnNoNulls),
            columnMetaData("timestamp_array", 22,
                ColumnMetaData.array(
                    ColumnMetaData.scalar(Types.TIMESTAMP, "TIMESTAMP",
                        ColumnMetaData.Rep.PRIMITIVE_LONG),
                    "ARRAY",
                    ColumnMetaData.Rep.ARRAY),
                DatabaseMetaData.columnNoNulls),
            columnMetaData("time_array", 23,
                ColumnMetaData.array(
                    ColumnMetaData.scalar(Types.TIME, "TIME",
                        ColumnMetaData.Rep.NUMBER),
                    "ARRAY",
                    ColumnMetaData.Rep.ARRAY),
                DatabaseMetaData.columnNoNulls),
            columnMetaData("decimal_array", 24,
                ColumnMetaData.array(
                    ColumnMetaData.scalar(Types.DECIMAL, "DECIMAL",
                        ColumnMetaData.Rep.PRIMITIVE_DOUBLE),
                    "ARRAY",
                    ColumnMetaData.Rep.ARRAY),
                DatabaseMetaData.columnNoNulls));
  
        List<Object> row = Collections.<Object>singletonList(
            new Object[] {
                true, (byte) 1, (short) 2, 3, 3, 4L, (short) 2, 3, 4L, 4L,
                new BigInteger("7"), 5.0f, 6.0d, "testvalue",
                new Date(DST_INSTANT), new Time(DST_INSTANT),
                new Timestamp(DST_INSTANT),
                Arrays.asList(1, 2, 3),
                new StructImpl(Arrays.asList(42, false)),
                true,
                null,
                Arrays.asList(123, 18234),
                Arrays.asList(DST_INSTANT, STANDARD_INSTANT),
                Arrays.asList(VALID_TIME, OVERFLOW_TIME),
                Arrays.asList(1, 1.1)
            });
  
        CursorFactory factory = CursorFactory.deduce(columns, null);
        Frame frame = new Frame(0, true, row);
  
        Signature signature = Signature.create(columns, sql,
            Collections.<AvaticaParameter>emptyList(), factory, StatementType.SELECT);
        try {
          synchronized (callback.getMonitor()) {
            callback.clear();
            callback.assign(signature, frame, -1);
          }
          callback.execute();
        } catch (SQLException e) {
          throw new RuntimeException();
        }
        MetaResultSet rs = MetaResultSet.create(h.connectionId, 0, false, signature, null);
        return new ExecuteResult(Collections.singletonList(rs));
      }
  
      @Override public ExecuteBatchResult prepareAndExecuteBatch(StatementHandle h,
          List<String> sqlCommands) throws NoSuchStatementException {
        throw new UnsupportedOperationException();
      }
  
      @Override public ExecuteBatchResult executeBatch(StatementHandle h,
          List<List<TypedValue>> parameterValues) throws NoSuchStatementException {
        throw new UnsupportedOperationException();
      }
  
      @Override public Frame fetch(StatementHandle h, long offset, int fetchMaxRowCount)
          throws NoSuchStatementException, MissingResultsException {
        throw new UnsupportedOperationException();
      }
  
      @SuppressWarnings("deprecation")
      @Override public ExecuteResult execute(StatementHandle h, List<TypedValue> parameterValues,
          long maxRowCount) throws NoSuchStatementException {
        throw new UnsupportedOperationException();
      }
  
      @Override public ExecuteResult execute(StatementHandle h, List<TypedValue> parameterValues,
          int maxRowsInFirstFrame) throws NoSuchStatementException {
        throw new UnsupportedOperationException();
      }
  
      @Override public void closeStatement(StatementHandle h) {
      }
  
      @Override public boolean syncResults(StatementHandle sh, QueryState state, long offset)
          throws NoSuchStatementException {
        throw new UnsupportedOperationException();
      }
  
      @Override public void commit(ConnectionHandle ch) {
        throw new UnsupportedOperationException();
      }
  
      @Override public void rollback(ConnectionHandle ch) {
        throw new UnsupportedOperationException();
      }
    }
  
    /**
     * Base accessor test helper.
     */
    private static class AccessorTestHelper {
      protected final Getter g;
  
      protected AccessorTestHelper(Getter g) {
        this.g = g;
      }
  
      public void testGetString(ResultSet resultSet) throws SQLException {
        g.getString(resultSet);
      }
  
      public void testGetBoolean(ResultSet resultSet) throws SQLException {
        try {
          g.getBoolean(resultSet);
          fail("Was expecting to throw SQLDataException");
        } catch (Exception e) {
          assertThat(e, isA((Class) SQLDataException.class)); // success
        }
      }
  
      public void testGetByte(ResultSet resultSet) throws SQLException {
        try {
          g.getByte(resultSet);
          fail("Was expecting to throw SQLDataException");
        } catch (Exception e) {
          assertThat(e, isA((Class) SQLDataException.class)); // success
        }
      }
  
      public void testGetShort(ResultSet resultSet) throws SQLException {
        try {
          g.getShort(resultSet);
          fail("Was expecting to throw SQLDataException");
        } catch (Exception e) {
          assertThat(e, isA((Class) SQLDataException.class)); // success
        }
      }
  
      public void testGetInt(ResultSet resultSet) throws SQLException {
        try {
          g.getInt(resultSet);
          fail("Was expecting to throw SQLDataException");
        } catch (Exception e) {
          assertThat(e, isA((Class) SQLDataException.class)); // success
        }
      }
  
      public void testGetLong(ResultSet resultSet) throws SQLException {
        try {
          g.getLong(resultSet);
          fail("Was expecting to throw SQLDataException");
        } catch (Exception e) {
          assertThat(e, isA((Class) SQLDataException.class)); // success
        }
      }
  
      public void testGetFloat(ResultSet resultSet) throws SQLException {
        try {
          g.getFloat(resultSet);
          fail("Was expecting to throw SQLDataException");
        } catch (Exception e) {
          assertThat(e, isA((Class) SQLDataException.class)); // success
        }
      }
  
      public void testGetDouble(ResultSet resultSet) throws SQLException {
        try {
          g.getDouble(resultSet);
          fail("Was expecting to throw SQLDataException");
        } catch (Exception e) {
          assertThat(e, isA((Class) SQLDataException.class)); // success
        }
      }
  
      public void testGetDecimal(ResultSet resultSet) throws SQLException {
        try {
          g.getBigDecimal(resultSet);
          fail("Was expecting to throw SQLDataException");
        } catch (Exception e) {
          assertThat(e, isA((Class) SQLDataException.class)); // success
        }
      }
  
      public void testGetBytes(ResultSet resultSet) throws SQLException {
        try {
          g.getBytes(resultSet);
          fail("Was expecting to throw SQLDataException");
        } catch (Exception e) {
          assertThat(e, isA((Class) SQLDataException.class)); // success
        }
      }
  
      public void testGetAsciiStream(ResultSet resultSet) throws SQLException {
        try {
          g.getAsciiStream(resultSet);
          fail("Was expecting to throw SQLDataException");
        } catch (Exception e) {
          assertThat(e, isA((Class) SQLDataException.class)); // success
        }
      }
  
      public void testGetBinaryStream(ResultSet resultSet) throws SQLException {
        try {
          g.getBinaryStream(resultSet);
          fail("Was expecting to throw SQLDataException");
        } catch (Exception e) {
          assertThat(e, isA((Class) SQLDataException.class)); // success
        }
      }
  
      public void testGetObject(ResultSet resultSet) throws SQLException {
        g.getObject(resultSet);
      }
  
      public void testGetCharacterStream(ResultSet resultSet) throws SQLException {
        try {
          g.getCharacterStream(resultSet);
          fail("Was expecting to throw SQLDataException");
        } catch (Exception e) {
          assertThat(e, isA((Class) SQLDataException.class)); // success
        }
      }
  
      public void testGetObject(ResultSet resultSet, Map<String, Class<?>> map) throws SQLException {
        try {
          g.getObject(resultSet, map);
          fail("Was expecting to throw SQLDataException");
        } catch (Exception e) {
          assertThat(e, isA((Class) SQLDataException.class)); // success
        }
      }
  
      public void testGetRef(ResultSet resultSet) throws SQLException {
        try {
          g.getRef(resultSet);
          fail("Was expecting to throw SQLDataException");
        } catch (Exception e) {
          assertThat(e, isA((Class) SQLDataException.class)); // success
        }
      }
  
      public void testGetBlob(ResultSet resultSet) throws SQLException {
        try {
          g.getBlob(resultSet);
          fail("Was expecting to throw SQLDataException");
        } catch (Exception e) {
          assertThat(e, isA((Class) SQLDataException.class)); // success
        }
      }
  
      public void testGetClob(ResultSet resultSet) throws SQLException {
        try {
          g.getBlob(resultSet);
          fail("Was expecting to throw SQLDataException");
        } catch (Exception e) {
          assertThat(e, isA((Class) SQLDataException.class)); // success
        }
      }
  
      public void testGetArray(ResultSet resultSet) throws SQLException {
        try {
          g.getArray(resultSet);
          fail("Was expecting to throw SQLDataException");
        } catch (Exception e) {
          assertThat(e, isA((Class) SQLDataException.class)); // success
        }
      }
  
      public void testGetDate(ResultSet resultSet, Calendar calendar) throws SQLException {
        try {
          g.getDate(resultSet, calendar);
          fail("Was expecting to throw SQLDataException");
        } catch (Exception e) {
          assertThat(e, isA((Class) SQLDataException.class)); // success
        }
      }
  
      public void testGetTime(ResultSet resultSet, Calendar calendar) throws SQLException {
        try {
          g.getTime(resultSet, calendar);
          fail("Was expecting to throw SQLDataException");
        } catch (Exception e) {
          assertThat(e, isA((Class) SQLDataException.class)); // success
        }
      }
  
      public void testGetTimestamp(ResultSet resultSet, Calendar calendar) throws SQLException {
        try {
          g.getTimestamp(resultSet, calendar);
          fail("Was expecting to throw SQLDataException");
        } catch (Exception e) {
          assertThat(e, isA((Class) SQLDataException.class)); // success
        }
      }
  
      public void testGetStruct(ResultSet resultSet) throws SQLException {
        try {
          g.getStruct(resultSet);
          fail("Was expecting to throw SQLDataException");
        } catch (Exception e) {
          assertThat(e, isA((Class) SQLDataException.class)); // success
        }
      }
  
      public void getURL(ResultSet resultSet) throws SQLException {
        try {
          g.getURL(resultSet);
          fail("Was expecting to throw SQLDataException");
        } catch (Exception e) {
          assertThat(e, isA((Class) SQLDataException.class)); // success
        }
      }
  
      public void testGetNClob(ResultSet resultSet) throws SQLException {
        try {
          g.getNClob(resultSet);
          fail("Was expecting to throw SQLDataException");
        } catch (Exception e) {
          assertThat(e, isA((Class) SQLDataException.class)); // success
        }
      }
  
      public void testGetSQLXML(ResultSet resultSet) throws SQLException {
        try {
          g.getSQLXML(resultSet);
          fail("Was expecting to throw SQLDataException");
        } catch (Exception e) {
          assertThat(e, isA((Class) SQLDataException.class)); // success
        }
      }
  
      public void testGetNString(ResultSet resultSet) throws SQLException {
        try {
          g.getNString(resultSet);
          fail("Was expecting to throw SQLDataException");
        } catch (Exception e) {
          assertThat(e, isA((Class) SQLDataException.class)); // success
        }
      }
  
      public void testGetNCharacterStream(ResultSet resultSet) throws SQLException {
        try {
          g.getNCharacterStream(resultSet);
          fail("Was expecting to throw SQLDataException");
        } catch (Exception e) {
          assertThat(e, isA((Class) SQLDataException.class)); // success
        }
      }
    }
  
    /**
     * Accessor test helper for boolean column.
     */
    private static final class BooleanAccessorTestHelper extends AccessorTestHelper {
      private BooleanAccessorTestHelper(Getter g) {
        super(g);
      }
  
      @Override public void testGetString(ResultSet resultSet) throws SQLException {
        assertEquals("true", g.getString(resultSet));
      }
  
      @Override public void testGetBoolean(ResultSet resultSet) throws SQLException {
        assertEquals(true, g.getBoolean(resultSet));
      }
  
      @Override public void testGetByte(ResultSet resultSet) throws SQLException {
        assertEquals((byte) 1, g.getByte(resultSet));
      }
  
      @Override public void testGetShort(ResultSet resultSet) throws SQLException {
        assertEquals((short) 1, g.getShort(resultSet));
      }
  
      @Override public void testGetInt(ResultSet resultSet) throws SQLException {
        assertEquals(1, g.getInt(resultSet));
      }
  
      @Override public void testGetLong(ResultSet resultSet) throws SQLException {
        assertEquals(1L, g.getLong(resultSet));
      }
  
      @Override public void testGetDecimal(ResultSet resultSet) throws SQLException {
        assertEquals(BigDecimal.ONE, g.getBigDecimal(resultSet));
      }
  
      @Override public void testGetFloat(ResultSet resultSet) throws SQLException {
        assertEquals(1.0f, g.getFloat(resultSet), 0);
      }
  
      @Override public void testGetDouble(ResultSet resultSet) throws SQLException {
        assertEquals(1.0d, g.getDouble(resultSet), 0);
      }
    }
  
    /**
     * Accessor test helper for array column.
     */
    private static final class ArrayAccessorTestHelper extends AccessorTestHelper {
      private ArrayAccessorTestHelper(Getter g) {
        super(g);
      }
  
      @Override public void testGetArray(ResultSet resultSet) throws SQLException {
        ColumnMetaData.ScalarType intType =
            ColumnMetaData.scalar(Types.INTEGER, "INTEGER", ColumnMetaData.Rep.INTEGER);
        Array expectedArray =
            new ArrayFactoryImpl(Unsafe.localCalendar().getTimeZone()).createArray(
                intType, Arrays.asList(1, 2, 3));
        assertTrue(ArrayImpl.equalContents(expectedArray, g.getArray(resultSet)));
      }
    }
  
    /**
     * Accessor test helper for decimal array column.
     */
    private static final class DecimalArrayAccessorTestHelper extends AccessorTestHelper {
      private DecimalArrayAccessorTestHelper(Getter g) {
        super(g);
      }
  
      @Override public void testGetArray(ResultSet resultSet) throws SQLException {
        ColumnMetaData.ScalarType intType =
            ColumnMetaData.scalar(Types.DECIMAL, "DECIMAL", ColumnMetaData.Rep.PRIMITIVE_DOUBLE);
        Array expectedArray =
            new ArrayFactoryImpl(Unsafe.localCalendar().getTimeZone()).createArray(
                intType, Arrays.asList(1, 1.1));
        assertTrue(ArrayImpl.equalContents(expectedArray, g.getArray(resultSet)));
      }
    }
  
    /**
     * Accessor test helper for date array column.
     */
    private static final class DateArrayAccessorTestHelper extends AccessorTestHelper {
      private DateArrayAccessorTestHelper(Getter g) {
        super(g);
      }
  
      @Override public void testGetArray(ResultSet resultSet) throws SQLException {
        ColumnMetaData.ScalarType intType =
            ColumnMetaData.scalar(Types.DATE, "DATE", ColumnMetaData.Rep.PRIMITIVE_INT);
        Array expectedArray =
            new ArrayFactoryImpl(TimeZone.getTimeZone("UTC")).createArray(
                intType, Arrays.asList(123, 18234));
        assertTrue(ArrayImpl.equalContents(expectedArray, g.getArray(resultSet)));
      }
    }
  
    /**
     * Accessor test helper for time array column.
     */
    private static final class TimeArrayAccessorTestHelper extends AccessorTestHelper {
      private TimeArrayAccessorTestHelper(Getter g) {
        super(g);
      }
  
      @Override public void testGetArray(ResultSet resultSet) throws SQLException {
        ColumnMetaData.ScalarType intType =
            ColumnMetaData.scalar(Types.TIME, "TIME", ColumnMetaData.Rep.NUMBER);
        Array expectedArray =
            new ArrayFactoryImpl(TimeZone.getTimeZone("UTC")).createArray(
                intType, Arrays.asList(VALID_TIME, OVERFLOW_TIME));
        assertTrue(ArrayImpl.equalContents(expectedArray, g.getArray(resultSet)));
      }
    }
  
    /**
     * Accessor test helper for timestamp array column.
     */
    private static final class TimestampArrayAccessorTestHelper extends AccessorTestHelper {
      private TimestampArrayAccessorTestHelper(Getter g) {
        super(g);
      }
  
      @Override public void testGetArray(ResultSet resultSet) throws SQLException {
        ColumnMetaData.ScalarType intType =
            ColumnMetaData.scalar(Types.TIMESTAMP, "TIMESTAMP", ColumnMetaData.Rep.PRIMITIVE_LONG);
        Array expectedArray =
            new ArrayFactoryImpl(TimeZone.getTimeZone("UTC")).createArray(
                intType, Arrays.asList(DST_INSTANT, STANDARD_INSTANT));
        assertTrue(ArrayImpl.equalContents(expectedArray, g.getArray(resultSet)));
      }
    }
  
    /**
     * Accessor test helper for row column.
     */
    private static final class StructAccessorTestHelper extends AccessorTestHelper {
      private StructAccessorTestHelper(Getter g) {
        super(g);
      }
  
      @Override public void testGetStruct(ResultSet resultSet) throws SQLException {
        Struct expectedStruct = new StructImpl(Arrays.asList(42, false));
        assertEquals(expectedStruct, g.getStruct(resultSet));
      }
    }
  
    /**
     * Accessor test helper for the (null) object column.
     */
    private static final class NullObjectAccessorTestHelper extends AccessorTestHelper {
      private NullObjectAccessorTestHelper(Getter g) {
        super(g);
      }
  
      @Override public void testGetString(ResultSet resultSet) throws SQLException {
        assertNull(g.getString(resultSet));
      }
  
      @Override public void testGetObject(ResultSet resultSet) throws SQLException {
        assertNull(g.getObject(resultSet));
      }
    }
  
    /**
     * Accessor test helper for the byte column.
     */
    private static final class ByteAccessorTestHelper extends AccessorTestHelper {
      private ByteAccessorTestHelper(Getter g) {
        super(g);
      }
  
      @Override public void testGetString(ResultSet resultSet) throws SQLException {
        assertEquals("1", g.getString(resultSet));
      }
  
      @Override public void testGetBoolean(ResultSet resultSet) throws SQLException {
        assertEquals(true, g.getBoolean(resultSet));
      }
  
      @Override public void testGetByte(ResultSet resultSet) throws SQLException {
        assertEquals((byte) 1, g.getByte(resultSet));
      }
  
      @Override public void testGetShort(ResultSet resultSet) throws SQLException {
        assertEquals((short) 1, g.getShort(resultSet));
      }
  
      @Override public void testGetInt(ResultSet resultSet) throws SQLException {
        assertEquals(1, g.getInt(resultSet));
      }
  
      @Override public void testGetLong(ResultSet resultSet) throws SQLException {
        assertEquals(1L, g.getLong(resultSet));
      }
  
      @Override public void testGetDecimal(ResultSet resultSet) throws SQLException {
        assertEquals(BigDecimal.ONE, g.getBigDecimal(resultSet));
      }
  
      @Override public void testGetFloat(ResultSet resultSet) throws SQLException {
        assertEquals(1.0f, g.getFloat(resultSet), 0);
      }
  
      @Override public void testGetDouble(ResultSet resultSet) throws SQLException {
        assertEquals(1.0d, g.getDouble(resultSet), 0);
      }
    }
  
    /**
     * Accessor test helper for the short column.
     */
    private static final class ShortAccessorTestHelper extends AccessorTestHelper {
      private ShortAccessorTestHelper(Getter g) {
        super(g);
      }
  
      @Override public void testGetString(ResultSet resultSet) throws SQLException {
        assertEquals("2", g.getString(resultSet));
      }
  
      @Override public void testGetBoolean(ResultSet resultSet) throws SQLException {
        assertEquals(true, g.getBoolean(resultSet));
      }
  
      @Override public void testGetByte(ResultSet resultSet) throws SQLException {
        assertEquals((byte) 2, g.getByte(resultSet));
      }
  
      @Override public void testGetShort(ResultSet resultSet) throws SQLException {
        assertEquals((short) 2, g.getShort(resultSet));
      }
  
      @Override public void testGetInt(ResultSet resultSet) throws SQLException {
        assertEquals(2, g.getInt(resultSet));
      }
  
      @Override public void testGetLong(ResultSet resultSet) throws SQLException {
        assertEquals(2L, g.getLong(resultSet));
      }
  
      @Override public void testGetDecimal(ResultSet resultSet) throws SQLException {
        assertEquals(new BigDecimal(2), g.getBigDecimal(resultSet));
      }
  
      @Override public void testGetFloat(ResultSet resultSet) throws SQLException {
        assertEquals(2.0f, g.getFloat(resultSet), 0);
      }
  
      @Override public void testGetDouble(ResultSet resultSet) throws SQLException {
        assertEquals(2.0d, g.getDouble(resultSet), 0);
      }
    }
  
    /**
     * Accessor test helper for the int column.
     */
    private static final class IntAccessorTestHelper extends AccessorTestHelper {
      private IntAccessorTestHelper(Getter g) {
        super(g);
      }
  
      @Override public void testGetString(ResultSet resultSet) throws SQLException {
        assertEquals("3", g.getString(resultSet));
      }
  
      @Override public void testGetBoolean(ResultSet resultSet) throws SQLException {
        assertEquals(true, g.getBoolean(resultSet));
      }
  
      @Override public void testGetByte(ResultSet resultSet) throws SQLException {
        assertEquals((byte) 3, g.getByte(resultSet));
      }
  
      @Override public void testGetShort(ResultSet resultSet) throws SQLException {
        assertEquals((short) 3, g.getShort(resultSet));
      }
  
      @Override public void testGetInt(ResultSet resultSet) throws SQLException {
        assertEquals(3, g.getInt(resultSet));
      }
  
      @Override public void testGetLong(ResultSet resultSet) throws SQLException {
        assertEquals(3L, g.getLong(resultSet));
      }
  
      @Override public void testGetDecimal(ResultSet resultSet) throws SQLException {
        assertEquals(new BigDecimal(3), g.getBigDecimal(resultSet));
      }
  
      @Override public void testGetFloat(ResultSet resultSet) throws SQLException {
        assertEquals(3.0f, g.getFloat(resultSet), 0);
      }
  
      @Override public void testGetDouble(ResultSet resultSet) throws SQLException {
        assertEquals(3.0d, g.getDouble(resultSet), 0);
      }
    }
  
    /**
     * Accessor test helper for the long column.
     */
    private static final class LongAccessorTestHelper extends AccessorTestHelper {
      private LongAccessorTestHelper(Getter g) {
        super(g);
      }
  
      @Override public void testGetString(ResultSet resultSet) throws SQLException {
        assertEquals("4", g.getString(resultSet));
      }
  
      @Override public void testGetBoolean(ResultSet resultSet) throws SQLException {
        assertEquals(true, g.getBoolean(resultSet));
      }
  
      @Override public void testGetByte(ResultSet resultSet) throws SQLException {
        assertEquals((byte) 4, g.getByte(resultSet));
      }
  
      @Override public void testGetShort(ResultSet resultSet) throws SQLException {
        assertEquals((short) 4, g.getShort(resultSet));
      }
  
      @Override public void testGetInt(ResultSet resultSet) throws SQLException {
        assertEquals(4, g.getInt(resultSet));
      }
  
      @Override public void testGetLong(ResultSet resultSet) throws SQLException {
        assertEquals(4L, g.getLong(resultSet));
      }
  
      @Override public void testGetDecimal(ResultSet resultSet) throws SQLException {
        assertEquals(new BigDecimal(4), g.getBigDecimal(resultSet));
      }
  
      @Override public void testGetFloat(ResultSet resultSet) throws SQLException {
        assertEquals(4.0f, g.getFloat(resultSet), 0);
      }
  
      @Override public void testGetDouble(ResultSet resultSet) throws SQLException {
        assertEquals(4.0d, g.getDouble(resultSet), 0);
      }
    }
  
    /**
     * Accessor test helper for the long unsigned column.
     */
    private static final class LongUnsingedAccessorTestHelper extends AccessorTestHelper {
      private LongUnsingedAccessorTestHelper(Getter g) {
        super(g);
      }
  
      @Override public void testGetString(ResultSet resultSet) throws SQLException {
        assertEquals("7", g.getString(resultSet));
      }
  
      @Override public void testGetBoolean(ResultSet resultSet) throws SQLException {
        assertEquals(true, g.getBoolean(resultSet));
      }
  
      @Override public void testGetByte(ResultSet resultSet) throws SQLException {
        assertEquals((byte) 7, g.getByte(resultSet));
      }
  
      @Override public void testGetShort(ResultSet resultSet) throws SQLException {
        assertEquals((short) 7, g.getShort(resultSet));
      }
  
      @Override public void testGetInt(ResultSet resultSet) throws SQLException {
        assertEquals(7, g.getInt(resultSet));
      }
  
      @Override public void testGetLong(ResultSet resultSet) throws SQLException {
        assertEquals(7L, g.getLong(resultSet));
      }
  
      @Override public void testGetDecimal(ResultSet resultSet) throws SQLException {
        assertEquals(new BigDecimal(7), g.getBigDecimal(resultSet));
      }
  
      @Override public void testGetFloat(ResultSet resultSet) throws SQLException {
        assertEquals(7.0f, g.getFloat(resultSet), 0);
      }
  
      @Override public void testGetDouble(ResultSet resultSet) throws SQLException {
        assertEquals(7.0d, g.getDouble(resultSet), 0);
      }
    }
  
    /**
     * accessor test helper for the float column
     */
    private static final class FloatAccessorTestHelper extends AccessorTestHelper {
      private FloatAccessorTestHelper(Getter g) {
        super(g);
      }
  
      @Override public void testGetString(ResultSet resultSet) throws SQLException {
        assertEquals("5.0", g.getString(resultSet));
      }
  
      @Override public void testGetBoolean(ResultSet resultSet) throws SQLException {
        assertEquals(true, g.getBoolean(resultSet));
      }
  
      @Override public void testGetByte(ResultSet resultSet) throws SQLException {
        assertEquals((byte) 5, g.getByte(resultSet));
      }
  
      @Override public void testGetShort(ResultSet resultSet) throws SQLException {
        assertEquals((short) 5, g.getShort(resultSet));
      }
  
      @Override public void testGetInt(ResultSet resultSet) throws SQLException {
        assertEquals(5, g.getInt(resultSet));
      }
  
      @Override public void testGetLong(ResultSet resultSet) throws SQLException {
        assertEquals(5L, g.getLong(resultSet));
      }
  
      @Override public void testGetDecimal(ResultSet resultSet) throws SQLException {
        assertEquals(new BigDecimal(5).setScale(1), g.getBigDecimal(resultSet));
      }
  
      @Override public void testGetFloat(ResultSet resultSet) throws SQLException {
        assertEquals(5.0f, g.getFloat(resultSet), 0);
      }
  
      @Override public void testGetDouble(ResultSet resultSet) throws SQLException {
        assertEquals(5.0d, g.getDouble(resultSet), 0);
      }
    }
  
    /**
     * Accessor test helper for the double column.
     */
    private static final class DoubleAccessorTestHelper extends AccessorTestHelper {
      private DoubleAccessorTestHelper(Getter g) {
        super(g);
      }
  
      @Override public void testGetString(ResultSet resultSet) throws SQLException {
        assertEquals("6.0", g.getString(resultSet));
      }
  
      @Override public void testGetBoolean(ResultSet resultSet) throws SQLException {
        assertEquals(true, g.getBoolean(resultSet));
      }
  
      @Override public void testGetByte(ResultSet resultSet) throws SQLException {
        assertEquals((byte) 6, g.getByte(resultSet));
      }
  
      @Override public void testGetShort(ResultSet resultSet) throws SQLException {
        assertEquals((short) 6, g.getShort(resultSet));
      }
  
      @Override public void testGetInt(ResultSet resultSet) throws SQLException {
        assertEquals(6, g.getInt(resultSet));
      }
  
      @Override public void testGetLong(ResultSet resultSet) throws SQLException {
        assertEquals(6L, g.getLong(resultSet));
      }
  
      @Override public void testGetDecimal(ResultSet resultSet) throws SQLException {
        assertEquals(new BigDecimal(6).setScale(1), g.getBigDecimal(resultSet));
      }
  
      @Override public void testGetFloat(ResultSet resultSet) throws SQLException {
        assertEquals(6.0f, g.getFloat(resultSet), 0);
      }
  
      @Override public void testGetDouble(ResultSet resultSet) throws SQLException {
        assertEquals(6.0d, g.getDouble(resultSet), 0);
      }
    }
  
    /**
     * Accessor test helper for the date column.
     */
    private static final class DateAccessorTestHelper extends AccessorTestHelper {
      private DateAccessorTestHelper(Getter g) {
        super(g);
      }
  
      @Override public void testGetString(ResultSet resultSet) throws SQLException {
        assertEquals(DST_DATE_STRING, g.getString(resultSet));
      }
  
      @Override public void testGetBoolean(ResultSet resultSet) throws SQLException {
        assertEquals(true, g.getBoolean(resultSet));
      }
  
      @Override public void testGetByte(ResultSet resultSet) throws SQLException {
        assertEquals((byte) -68, g.getByte(resultSet));
      }
  
      @Override public void testGetShort(ResultSet resultSet) throws SQLException {
        assertEquals((short) 17084, g.getShort(resultSet));
      }
  
      @Override public void testGetInt(ResultSet resultSet) throws SQLException {
        assertEquals(17084, g.getInt(resultSet));
      }
  
      @Override public void testGetLong(ResultSet resultSet) throws SQLException {
        assertEquals(17084, g.getLong(resultSet));
      }
  
      @Override public void testGetDate(ResultSet resultSet, Calendar calendar) throws SQLException {
        assertEquals(new Date(DST_INSTANT), g.getDate(resultSet, calendar));
      }
    }
  
    /**
     * accessor test helper for the time column
     */
    private static final class TimeAccessorTestHelper extends AccessorTestHelper {
      private TimeAccessorTestHelper(Getter g) {
        super(g);
      }
  
      @Override public void testGetString(ResultSet resultSet) throws SQLException {
        assertEquals(DST_TIME_STRING, g.getString(resultSet));
      }
  
      @Override public void testGetBoolean(ResultSet resultSet) throws SQLException {
        assertEquals(true, g.getBoolean(resultSet));
      }
  
      @Override public void testGetByte(ResultSet resultSet) throws SQLException {
        assertEquals((byte) DST_INSTANT, g.getByte(resultSet));
      }
  
      @Override public void testGetShort(ResultSet resultSet) throws SQLException {
        assertEquals((short) (DST_INSTANT % DateTimeUtils.MILLIS_PER_DAY), g.getShort(resultSet));
      }
  
      @Override public void testGetInt(ResultSet resultSet) throws SQLException {
        assertEquals((int) (DST_INSTANT % DateTimeUtils.MILLIS_PER_DAY), g.getInt(resultSet));
      }
  
      @Override public void testGetLong(ResultSet resultSet) throws SQLException {
        assertEquals(DST_INSTANT % DateTimeUtils.MILLIS_PER_DAY, g.getLong(resultSet));
      }
  
      @Override public void testGetTime(ResultSet resultSet, Calendar calendar) throws SQLException {
        assertEquals(new Time(DST_INSTANT), g.getTime(resultSet, calendar));
      }
    }
  
    /**
     * accessor test helper for the timestamp column
     */
    private static final class TimestampAccessorTestHelper extends AccessorTestHelper {
      private TimestampAccessorTestHelper(Getter g) {
        super(g);
      }
  
      @Override public void testGetString(ResultSet resultSet) throws SQLException {
        assertEquals(DST_TIMESTAMP_STRING, g.getString(resultSet));
      }
  
      @Override public void testGetBoolean(ResultSet resultSet) throws SQLException {
        assertEquals(true, g.getBoolean(resultSet));
      }
  
      @Override public void testGetByte(ResultSet resultSet) throws SQLException {
        assertEquals((byte) DST_INSTANT, g.getByte(resultSet));
      }
  
      @Override public void testGetShort(ResultSet resultSet) throws SQLException {
        assertEquals((short) DST_INSTANT, g.getShort(resultSet));
      }
  
      @Override public void testGetInt(ResultSet resultSet) throws SQLException {
        assertEquals((int) DST_INSTANT, g.getInt(resultSet));
      }
  
      @Override public void testGetLong(ResultSet resultSet) throws SQLException {
        assertEquals(DST_INSTANT, g.getLong(resultSet));
      }
  
      @Override public void testGetDate(ResultSet resultSet, Calendar calendar) throws SQLException {
        assertEquals(new Date(DST_INSTANT), g.getDate(resultSet, calendar));
      }
  
      @Override public void testGetTime(ResultSet resultSet, Calendar calendar) throws SQLException {
        assertEquals(new Time(DST_INSTANT), g.getTime(resultSet, calendar));
      }
  
      @Override public void testGetTimestamp(ResultSet resultSet, Calendar calendar)
          throws SQLException {
        assertEquals(new Timestamp(DST_INSTANT), g.getTimestamp(resultSet, calendar));
      }
    }
  
    /**
     * accessor test helper for the string column
     */
    private static final class StringAccessorTestHelper extends AccessorTestHelper {
      private StringAccessorTestHelper(Getter g) {
        super(g);
      }
  
      @Override public void testGetString(ResultSet resultSet) throws SQLException {
        assertEquals("testvalue", g.getString(resultSet));
      }
    }
  
    private static final Calendar UTC_CALENDAR = DateTimeUtils.calendar();
  
    private static Connection connection = null;
    private static ResultSet resultSet = null;
  
    @BeforeClass
    public static void executeQuery() throws SQLException {
      Properties properties = new Properties();
      properties.setProperty("timeZone", "GMT");
  
      connection = new TestDriver().connect("jdbc:test", properties);
      resultSet = connection.createStatement().executeQuery("SELECT * FROM TABLE");
      resultSet.next(); // move to the first record
    }
  
    @AfterClass
    public static void cleanupQuery() throws SQLException {
      if (resultSet != null) {
        resultSet.close();
      }
  
      if (connection != null) {
        connection.close();
      }
    }
  
    @Parameters(name = "{index}: {0}")
    public static Collection<AccessorTestHelper> data() {
      return Arrays.asList(
          new BooleanAccessorTestHelper(new OrdinalGetter(1)),
          new BooleanAccessorTestHelper(new LabelGetter("bool")),
          new ByteAccessorTestHelper(new OrdinalGetter(2)),
          new ByteAccessorTestHelper(new LabelGetter("byte")),
          new ShortAccessorTestHelper(new OrdinalGetter(3)),
          new ShortAccessorTestHelper(new LabelGetter("short")),
          new IntAccessorTestHelper(new OrdinalGetter(4)),
          new IntAccessorTestHelper(new LabelGetter("medium")),
          new IntAccessorTestHelper(new OrdinalGetter(5)),
          new IntAccessorTestHelper(new LabelGetter("int")),
          new LongAccessorTestHelper(new OrdinalGetter(6)),
          new LongAccessorTestHelper(new LabelGetter("long")),
          new ShortAccessorTestHelper(new OrdinalGetter(7)),
          new ShortAccessorTestHelper(new LabelGetter("byte_unsigned")),
          new IntAccessorTestHelper(new OrdinalGetter(8)),
          new IntAccessorTestHelper(new LabelGetter("short_unsigned")),
          new LongAccessorTestHelper(new OrdinalGetter(9)),
          new LongAccessorTestHelper(new LabelGetter("medium_unsigned")),
          new LongAccessorTestHelper(new OrdinalGetter(10)),
          new LongAccessorTestHelper(new LabelGetter("int_unsigned")),
          new LongUnsingedAccessorTestHelper(new OrdinalGetter(11)),
          new LongUnsingedAccessorTestHelper(new LabelGetter("long_unsigned")),
          new FloatAccessorTestHelper(new OrdinalGetter(12)),
          new FloatAccessorTestHelper(new LabelGetter("float")),
          new DoubleAccessorTestHelper(new OrdinalGetter(13)),
          new DoubleAccessorTestHelper(new LabelGetter("double")),
          new StringAccessorTestHelper(new OrdinalGetter(14)),
          new StringAccessorTestHelper(new LabelGetter("string")),
          new DateAccessorTestHelper(new OrdinalGetter(15)),
          new DateAccessorTestHelper(new LabelGetter("date")),
          new TimeAccessorTestHelper(new OrdinalGetter(16)),
          new TimeAccessorTestHelper(new LabelGetter("time")),
          new TimestampAccessorTestHelper(new OrdinalGetter(17)),
          new TimestampAccessorTestHelper(new LabelGetter("timestamp")),
          new ArrayAccessorTestHelper(new OrdinalGetter(18)),
          new ArrayAccessorTestHelper(new LabelGetter("array")),
          new StructAccessorTestHelper(new OrdinalGetter(19)),
          new StructAccessorTestHelper(new LabelGetter("struct")),
          new BooleanAccessorTestHelper(new OrdinalGetter(20)),
          new BooleanAccessorTestHelper(new LabelGetter("bit")),
          new NullObjectAccessorTestHelper(new OrdinalGetter(21)),
          new NullObjectAccessorTestHelper(new LabelGetter("null")),
          new DateArrayAccessorTestHelper(new OrdinalGetter(22)),
          new DateArrayAccessorTestHelper(new LabelGetter("date_array")),
          new TimestampArrayAccessorTestHelper(new OrdinalGetter(23)),
          new TimestampArrayAccessorTestHelper(new LabelGetter("timestamp_array")),
          new TimeArrayAccessorTestHelper(new OrdinalGetter(24)),
          new TimeArrayAccessorTestHelper(new LabelGetter("time_array")),
          new DecimalArrayAccessorTestHelper(new OrdinalGetter(25)),
          new DecimalArrayAccessorTestHelper(new LabelGetter("decimal_array")));
    }
  
    private final AccessorTestHelper testHelper;
  
    public AvaticaResultSetConversionsTest(AccessorTestHelper testHelper) {
      this.testHelper = testHelper;
    }
  
    @Test
    public void testGetString() throws SQLException {
      testHelper.testGetString(resultSet);
    }
  
    @Test
    public void testGetBoolean() throws SQLException {
      testHelper.testGetBoolean(resultSet);
    }
  
    @Test
    public void testGetByte() throws SQLException {
      testHelper.testGetByte(resultSet);
    }
  
    @Test
    public void testGetShort() throws SQLException {
      testHelper.testGetShort(resultSet);
    }
  
    @Test
    public void testGetInt() throws SQLException {
      testHelper.testGetInt(resultSet);
    }
  
    @Test
    public void testGetLong() throws SQLException {
      testHelper.testGetLong(resultSet);
    }
  
    @Test
    public void testGetFloat() throws SQLException {
      testHelper.testGetFloat(resultSet);
    }
  
    @Test
    public void testGetDouble() throws SQLException {
      testHelper.testGetDouble(resultSet);
    }
  
    @Test
    public void testGetDecimal() throws SQLException {
      testHelper.testGetDecimal(resultSet);
    }
  
    @Test
    public void testGetBytes() throws SQLException {
      testHelper.testGetBytes(resultSet);
    }
  
    @Test
    public void testGetAsciiStream() throws SQLException {
      testHelper.testGetAsciiStream(resultSet);
    }
  
    @Test
    public void testGetBinaryStream() throws SQLException {
      testHelper.testGetBinaryStream(resultSet);
    }
  
    @Test
    public void testGetObject() throws SQLException {
      testHelper.testGetObject(resultSet);
    }
  
    @Test
    public void testGetCharacterStream() throws SQLException {
      testHelper.testGetCharacterStream(resultSet);
    }
  
    @Test
    public void testGetObjectWithMap() throws SQLException {
      testHelper.testGetObject(resultSet, Collections.<String, Class<?>>emptyMap());
    }
  
    @Test
    public void testGetRef() throws SQLException {
      testHelper.testGetRef(resultSet);
    }
  
    @Test
    public void testGetBlob() throws SQLException {
      testHelper.testGetBlob(resultSet);
    }
  
    @Test
    public void testGetClob() throws SQLException {
      testHelper.testGetClob(resultSet);
    }
  
    @Test
    public void testGetArray() throws SQLException {
      testHelper.testGetArray(resultSet);
    }
  
    @Test
    public void testGetDate() throws SQLException {
      testHelper.testGetDate(resultSet, UTC_CALENDAR);
    }
  
    @Test
    public void testGetTime() throws SQLException {
      testHelper.testGetTime(resultSet, UTC_CALENDAR);
    }
  
    @Test
    public void testGetTimestamp() throws SQLException {
      testHelper.testGetTimestamp(resultSet, UTC_CALENDAR);
    }
  
    @Test
    public void getURL() throws SQLException {
      testHelper.getURL(resultSet);
    }
  
    @Test
    public void testGetNClob() throws SQLException {
      testHelper.testGetNClob(resultSet);
    }
  
    @Test
    public void testGetSQLXML() throws SQLException {
      testHelper.testGetSQLXML(resultSet);
    }
  
    @Test
    public void testGetNString() throws SQLException {
      testHelper.testGetNString(resultSet);
    }
  
    @Test
    public void testGetNCharacterStream() throws SQLException {
      testHelper.testGetNCharacterStream(resultSet);
    }
  
    /** Retrieves a value from a particular column of a result set, in
     * whatever type the caller chooses. */
    interface Getter {
      byte getByte(ResultSet r) throws SQLException;
      short getShort(ResultSet r) throws SQLException;
      int getInt(ResultSet r) throws SQLException;
      long getLong(ResultSet r) throws SQLException;
      float getFloat(ResultSet r) throws SQLException;
      double getDouble(ResultSet r) throws SQLException;
      BigDecimal getBigDecimal(ResultSet r) throws SQLException;
      boolean getBoolean(ResultSet r) throws SQLException;
      Date getDate(ResultSet r) throws SQLException;
      Date getDate(ResultSet r, Calendar c) throws SQLException;
      Time getTime(ResultSet r) throws SQLException;
      Time getTime(ResultSet r, Calendar c) throws SQLException;
      Timestamp getTimestamp(ResultSet r) throws SQLException;
      Timestamp getTimestamp(ResultSet r, Calendar c) throws SQLException;
      String getString(ResultSet r) throws SQLException;
      String getNString(ResultSet r) throws SQLException;
      byte[] getBytes(ResultSet r) throws SQLException;
      InputStream getAsciiStream(ResultSet r) throws SQLException;
      InputStream getBinaryStream(ResultSet r) throws SQLException;
      Array getArray(ResultSet r) throws SQLException;
      Struct getStruct(ResultSet r) throws SQLException;
      Object getCharacterStream(ResultSet r) throws SQLException;
      Object getNCharacterStream(ResultSet r) throws SQLException;
      Object getObject(ResultSet r) throws SQLException;
      Object getObject(ResultSet r, Map<String, Class<?>> map) throws SQLException;
      Object getRef(ResultSet r) throws SQLException;
      Object getBlob(ResultSet r) throws SQLException;
      Object getClob(ResultSet r) throws SQLException;
      Object getNClob(ResultSet r) throws SQLException;
      Object getURL(ResultSet r) throws SQLException;
      Object getSQLXML(ResultSet r) throws SQLException;
    }
  
    /** Retrieves the value of a column in a result set, addressing by column
     * label. */
    static class OrdinalGetter implements Getter {
      final int ordinal;
  
      OrdinalGetter(int ordinal) {
        this.ordinal = ordinal;
      }
  
      public byte getByte(ResultSet r) throws SQLException {
        return r.getByte(ordinal);
      }
  
      public short getShort(ResultSet r) throws SQLException {
        return r.getShort(ordinal);
      }
  
      public int getInt(ResultSet r) throws SQLException {
        return r.getInt(ordinal);
      }
  
      public long getLong(ResultSet r) throws SQLException {
        return r.getLong(ordinal);
      }
  
      public float getFloat(ResultSet r) throws SQLException {
        return r.getFloat(ordinal);
      }
  
      public double getDouble(ResultSet r) throws SQLException {
        return r.getDouble(ordinal);
      }
  
      public BigDecimal getBigDecimal(ResultSet r) throws SQLException {
        return r.getBigDecimal(ordinal);
      }
  
      public boolean getBoolean(ResultSet r) throws SQLException {
        return r.getBoolean(ordinal);
      }
  
      public Date getDate(ResultSet r) throws SQLException {
        return r.getDate(ordinal);
      }
  
      public Date getDate(ResultSet r, Calendar c) throws SQLException {
        return r.getDate(ordinal, c);
      }
  
      public Time getTime(ResultSet r) throws SQLException {
        return r.getTime(ordinal);
      }
  
      public Time getTime(ResultSet r, Calendar c) throws SQLException {
        return r.getTime(ordinal, c);
      }
  
      public Timestamp getTimestamp(ResultSet r) throws SQLException {
        return r.getTimestamp(ordinal);
      }
  
      public Timestamp getTimestamp(ResultSet r, Calendar c) throws SQLException {
        return r.getTimestamp(ordinal, c);
      }
  
      public String getString(ResultSet r) throws SQLException {
        return r.getString(ordinal);
      }
  
      public String getNString(ResultSet r) throws SQLException {
        return r.getNString(ordinal);
      }
  
      public byte[] getBytes(ResultSet r) throws SQLException {
        return r.getBytes(ordinal);
      }
  
      public InputStream getAsciiStream(ResultSet r) throws SQLException {
        return r.getAsciiStream(ordinal);
      }
  
      public InputStream getBinaryStream(ResultSet r) throws SQLException {
        return r.getBinaryStream(ordinal);
      }
  
      public Object getCharacterStream(ResultSet r) throws SQLException {
        return r.getCharacterStream(ordinal);
      }
  
      public Object getNCharacterStream(ResultSet r) throws SQLException {
        return r.getNCharacterStream(ordinal);
      }
  
      public Object getObject(ResultSet r) throws SQLException {
        return r.getObject(ordinal);
      }
  
      public Object getObject(ResultSet r, Map<String, Class<?>> map)
          throws SQLException {
        return r.getObject(ordinal, map);
      }
  
      public Object getRef(ResultSet r) throws SQLException {
        return r.getRef(ordinal);
      }
  
      public Object getBlob(ResultSet r) throws SQLException {
        return r.getBlob(ordinal);
      }
  
      public Object getClob(ResultSet r) throws SQLException {
        return r.getClob(ordinal);
      }
  
      public Object getNClob(ResultSet r) throws SQLException {
        return r.getNClob(ordinal);
      }
  
      public Object getURL(ResultSet r) throws SQLException {
        return r.getURL(ordinal);
      }
  
      public Object getSQLXML(ResultSet r) throws SQLException {
        return r.getSQLXML(ordinal);
      }
  
      public Array getArray(ResultSet r) throws SQLException {
        return r.getArray(ordinal);
      }
  
      public Struct getStruct(ResultSet r) throws SQLException {
        return (Struct) r.getObject(ordinal);
      }
    }
  
    /** Retrieves the value of a column in a result set, addressing by column
     * label. */
    static class LabelGetter implements Getter {
      final String label;
  
      LabelGetter(String label) {
        this.label = label;
      }
  
      public byte getByte(ResultSet r) throws SQLException {
        return r.getByte(label);
      }
  
      public short getShort(ResultSet r) throws SQLException {
        return r.getShort(label);
      }
  
      public int getInt(ResultSet r) throws SQLException {
        return r.getInt(label);
      }
  
      public long getLong(ResultSet r) throws SQLException {
        return r.getLong(label);
      }
  
      public float getFloat(ResultSet r) throws SQLException {
        return r.getFloat(label);
      }
  
      public double getDouble(ResultSet r) throws SQLException {
        return r.getDouble(label);
      }
  
      public BigDecimal getBigDecimal(ResultSet r) throws SQLException {
        return r.getBigDecimal(label);
      }
  
      public boolean getBoolean(ResultSet r) throws SQLException {
        return r.getBoolean(label);
      }
  
      public Date getDate(ResultSet r) throws SQLException {
        return r.getDate(label);
      }
  
      public Date getDate(ResultSet r, Calendar c) throws SQLException {
        return r.getDate(label, c);
      }
  
      public Time getTime(ResultSet r) throws SQLException {
        return r.getTime(label);
      }
  
      public Time getTime(ResultSet r, Calendar c) throws SQLException {
        return r.getTime(label, c);
      }
  
      public Timestamp getTimestamp(ResultSet r) throws SQLException {
        return r.getTimestamp(label);
      }
  
      public Timestamp getTimestamp(ResultSet r, Calendar c) throws SQLException {
        return r.getTimestamp(label, c);
      }
  
      public String getString(ResultSet r) throws SQLException {
        return r.getString(label);
      }
  
      public String getNString(ResultSet r) throws SQLException {
        return r.getNString(label);
      }
  
      public byte[] getBytes(ResultSet r) throws SQLException {
        return r.getBytes(label);
      }
  
      public InputStream getAsciiStream(ResultSet r) throws SQLException {
        return r.getAsciiStream(label);
      }
  
      public InputStream getBinaryStream(ResultSet r) throws SQLException {
        return r.getBinaryStream(label);
      }
  
      public Reader getCharacterStream(ResultSet r) throws SQLException {
        return r.getCharacterStream(label);
      }
  
      public Reader getNCharacterStream(ResultSet r) throws SQLException {
        return r.getNCharacterStream(label);
      }
  
      public Object getObject(ResultSet r) throws SQLException {
        return r.getObject(label);
      }
  
      public Object getObject(ResultSet r, Map<String, Class<?>> map)
          throws SQLException {
        return r.getObject(label, map);
      }
  
      public Ref getRef(ResultSet r) throws SQLException {
        return r.getRef(label);
      }
  
      public Blob getBlob(ResultSet r) throws SQLException {
        return r.getBlob(label);
      }
  
      public Clob getClob(ResultSet r) throws SQLException {
        return r.getClob(label);
      }
  
      public NClob getNClob(ResultSet r) throws SQLException {
        return r.getNClob(label);
      }
  
      public URL getURL(ResultSet r) throws SQLException {
        return r.getURL(label);
      }
  
      public SQLXML getSQLXML(ResultSet r) throws SQLException {
        return r.getSQLXML(label);
      }
  
      public Array getArray(ResultSet r) throws SQLException {
        return r.getArray(label);
      }
  
      public Struct getStruct(ResultSet r) throws SQLException {
        return (Struct) r.getObject(label);
      }
    }
  }
  
  // End AvaticaResultSetConversionsTest.java
  