package tap.data; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.sql.Connection; import java.sql.ResultSet; import java.util.GregorianCalendar; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import adql.db.DBType; import adql.parser.ADQLParser; import adql.query.ADQLQuery; import adql.translator.AstroH2Translator; import tap.db_testtools.DBTools; import tap.metadata.TAPColumn; public class TestResultSetTableIterator { private static Connection conn; @BeforeClass public static void setUpBeforeClass() throws Exception{ DBTools.createTestDB(); conn = DBTools.createConnection("h2", null, null, DBTools.DB_TEST_PATH, DBTools.DB_TEST_USER, DBTools.DB_TEST_PWD); } @AfterClass public static void tearDownAfterClass() throws Exception{ DBTools.closeConnection(conn); DBTools.dropTestDB(); } @Test public void testWithRSNULL(){ try{ new ResultSetTableIterator(null); fail("The constructor should have failed, because: the given ResultSet is NULL."); }catch(Exception ex){ assertEquals("java.lang.NullPointerException", ex.getClass().getName()); assertEquals("Missing ResultSet object over which to iterate!", ex.getMessage()); } } @Test public void testWithData(){ TableIterator it = null; try{ ResultSet rs = DBTools.select(conn, "SELECT hip, ra, dec, vmag FROM hipparcos LIMIT 10;"); it = new ResultSetTableIterator(rs); // TEST there is column metadata before starting the iteration: assertTrue(it.getMetadata() != null); final int expectedNbLines = 10, expectedNbColumns = 4; int countLines = 0, countColumns = 0; while(it.nextRow()){ // count lines: countLines++; // reset columns count: countColumns = 0; while(it.hasNextCol()){ it.nextCol(); // count columns countColumns++; // TEST the column type is set (not null): assertTrue(it.getColType() != null); } // TEST that all columns have been read: assertEquals(expectedNbColumns, countColumns); } // TEST that all lines have been read: assertEquals(expectedNbLines, countLines); }catch(Exception ex){ ex.printStackTrace(System.err); fail("An exception occurs while reading a correct ResultSet (containing some valid rows)."); }finally{ if (it != null){ try{ it.close(); }catch(DataReadException dre){} } } } @Test public void testWithEmptySet(){ TableIterator it = null; try{ ResultSet rs = DBTools.select(conn, "SELECT * FROM hipparcos WHERE hip = 1056;"); it = new ResultSetTableIterator(rs); // TEST there is column metadata before starting the iteration: assertTrue(it.getMetadata() != null); int countLines = 0; // count lines: while(it.nextRow()) countLines++; // TEST that no line has been read: assertEquals(countLines, 0); }catch(Exception ex){ ex.printStackTrace(System.err); fail("An exception occurs while reading a correct ResultSet (containing some valid rows)."); }finally{ if (it != null){ try{ it.close(); }catch(DataReadException dre){} } } } @Test public void testWithClosedSet(){ try{ // create a valid ResultSet: ResultSet rs = DBTools.select(conn, "SELECT * FROM hipparcos WHERE hip = 1056;"); // close the ResultSet: rs.close(); // TRY to create a TableIterator with a closed ResultSet: new ResultSetTableIterator(rs); fail("The constructor should have failed, because: the given ResultSet is closed."); }catch(Exception ex){ assertEquals(ex.getClass().getName(), "tap.data.DataReadException"); } } @Test public void testDateFormat(){ ResultSet rs = null; try{ // create a valid ResultSet: rs = DBTools.select(conn, "SELECT * FROM hipparcos LIMIT 1;"); // Create the iterator: ResultSetTableIterator rsit = new ResultSetTableIterator(rs); assertTrue(rsit.nextRow()); assertTrue(rsit.hasNextCol()); rsit.nextCol(); // Set a date-time: GregorianCalendar cal = new GregorianCalendar(); cal.set(2017, GregorianCalendar.FEBRUARY, 1, 15, 13, 56); // 1st Feb. 2017 - 15:13:56 CET // Try to format it from a java.SQL.Timestamp into a ISO8601 date-time: assertEquals("2017-02-01T14:13:56Z", rsit.formatColValue(new java.sql.Timestamp(cal.getTimeInMillis()))); // Try to format it from a java.UTIL.Date into an ISO8601 date-time: assertEquals("2017-02-01T14:13:56Z", rsit.formatColValue(cal.getTime())); // Try to format it from a java.SQL.Date into a simple date (no time indication): assertEquals("2017-02-01", rsit.formatColValue(new java.sql.Date(cal.getTimeInMillis()))); // Try to format it into a simple time (no date indication): assertEquals("15:13:56", rsit.formatColValue(new java.sql.Time(cal.getTimeInMillis()))); }catch(Exception ex){ ex.printStackTrace(System.err); fail("An exception occurs while formatting dates/times."); }finally{ if (rs != null){ try{ rs.close(); }catch(Exception ex){} } } } @Test public void testGeometryColumns(){ ResultSet rs = null; try{ ADQLQuery query = (new ADQLParser()).parseQuery("SELECT TOP 1 POINT('', ra, dec), CENTROID(CIRCLE('', ra, dec, 2)), BOX('', ra-1, dec-2, ra+1, dec+2), CIRCLE('', ra, dec, 2) FROM hipparcos;"); // create a valid ResultSet: rs = DBTools.select(conn, (new AstroH2Translator()).translate(query)); // Create the iterator: ResultSetTableIterator rsit = new ResultSetTableIterator(rs, query.getResultingColumns()); assertTrue(rsit.nextRow()); // Fetch the metadata: TAPColumn[] cols = rsit.getMetadata(); assertEquals(4, cols.length); // Check that the two first columns are POINTs: for(int i = 0; i < 2; i++) assertEquals(DBType.DBDatatype.POINT, cols[i].getDatatype().type); // Check that the next columns are REGIONs: for(int i = 2; i < 3; i++) assertEquals(DBType.DBDatatype.REGION, cols[i].getDatatype().type); }catch(Exception ex){ ex.printStackTrace(System.err); fail("An exception occurs while checking geometrical functions datatypes."); }finally{ if (rs != null){ try{ rs.close(); }catch(Exception ex){} } } } @Test public void testSQLFunctions(){ ResultSet rs = null; try{ ADQLQuery query = (new ADQLParser()).parseQuery("SELECT COUNT(*), MIN(vmag), AVG(plx) FROM hipparcos;"); // create a valid ResultSet: rs = DBTools.select(conn, (new AstroH2Translator()).translate(query)); // Create the iterator: ResultSetTableIterator rsit = new ResultSetTableIterator(rs, query.getResultingColumns()); assertTrue(rsit.nextRow()); // Fetch the metadata: TAPColumn[] cols = rsit.getMetadata(); assertEquals(3, cols.length); // Check that the first column is a BIGINT: assertEquals(DBType.DBDatatype.BIGINT, cols[0].getDatatype().type); // Check that the two next columns are REAL: for(int i = 1; i < 3; i++) assertEquals(DBType.DBDatatype.REAL, cols[i].getDatatype().type); }catch(Exception ex){ ex.printStackTrace(System.err); fail("An exception occurs while checking SQL functions datatypes"); }finally{ if (rs != null){ try{ rs.close(); }catch(Exception ex){} } } } }