package net.sourceforge.mayfly.datastore.types; import junit.framework.TestCase; import junitx.framework.ObjectAssert; import junitx.framework.StringAssert; import net.sourceforge.mayfly.Database; import net.sourceforge.mayfly.MayflyException; import net.sourceforge.mayfly.datastore.Cell; import net.sourceforge.mayfly.datastore.DataStore; import net.sourceforge.mayfly.datastore.NullCell; import net.sourceforge.mayfly.datastore.StringCell; import net.sourceforge.mayfly.datastore.TimestampCell; import net.sourceforge.mayfly.evaluation.command.CreateTable; import net.sourceforge.mayfly.evaluation.expression.TestTimeSource; import net.sourceforge.mayfly.parser.Lexer; import net.sourceforge.mayfly.parser.Parser; import net.sourceforge.mayfly.util.MayflyAssert; import org.joda.time.LocalDateTime; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; public class TimestampDataTypeTest extends TestCase { public void testCoerce() throws Exception { TimestampCell cell = (TimestampCell) MayflyAssert.coerce( new TimestampDataType(), new StringCell("2038-12-01 03:43:07")); assertEquals(2038, cell.year()); } public void testCallsGenericCoerce() throws Exception { Cell coerced = MayflyAssert.coerce(new TimestampDataType(), NullCell.INSTANCE); ObjectAssert.assertInstanceOf(NullCell.class, coerced); } public void testCoerceFromTimestamp() throws Exception { TimestampCell in = new TimestampCell(2003, 1, 7, 13, 45, 00); TimestampCell coerced = (TimestampCell) MayflyAssert.coerce( new TimestampDataType(), in); assertEquals(13, coerced.hour()); } public void testStringToDate() throws Exception { checkFailure(""); checkFailure("123"); checkFailure("12345"); checkFailure("12345-01-01 00:00:00"); checkFailure("x1234-01-01 00:00:00"); checkFailure("1234-01-01 00:00:00x"); check(1234, 1, 1, 0, 0, 0, "1234-01-01 00:00:00"); checkFailure("1066"); checkFailure("1066x12-25"); checkFailure("106612-25"); check(1066, 12, 25, 0, 0, 0, "1066-12-25"); checkFailure("1066-12-25T00:00:00"); // Should allow this? checkFailure("1066-12-25 0:00:00"); checkFailure("1066-12-25 00:00:0"); check(1066, 12, 25, 23, 59, 43, "1066-12-25 23:59:43"); try { new TimestampDataType().stringToDate("1890-02-31 00:00:01"); fail(); } catch (MayflyException e) { assertEquals("Value 31 for dayOfMonth must be in the range [1,28]", e.getMessage()); } } public void testQuotingInMessage() throws Exception { try { new TimestampDataType().stringToDate("don't"); fail(); } catch (MayflyException e) { assertEquals( "'don''t' is not in format yyyy-mm-dd hh:mm:ss", e.getMessage()); } } private void check(int expectedYear, int expectedMonth, int expectedDay, int expectedHour, int expectedMinute, int expectedSecond, String input) { TimestampCell stamp = new TimestampDataType().stringToDate(input); assertEquals(expectedYear, stamp.year()); assertEquals(expectedMonth, stamp.month()); assertEquals(expectedDay, stamp.day()); assertEquals(expectedHour, stamp.hour()); assertEquals(expectedMinute, stamp.minute()); assertEquals(expectedSecond, stamp.second()); } private void checkFailure(String input) { try { new TimestampDataType().stringToDate(input); fail(); } catch (MayflyException e) { assertEquals("'" + input + "' is not in format yyyy-mm-dd hh:mm:ss", e.getMessage()); } } public void testEvaluationIsDelayed() throws Exception { TestTimeSource timeSource = new TestTimeSource(); String sql = "create table foo(a timestamp default current_timestamp)"; Parser parser = new Parser( new Lexer(sql).tokens(), false, timeSource); timeSource.advanceTo(1976, 7); CreateTable command = (CreateTable) parser.parse(); timeSource.advanceTo(1976, 8); Database database = new Database(); database.executeUpdate(command, DataStore.ANONYMOUS_SCHEMA_NAME); timeSource.advanceTo(1976, 9); database.execute("insert into foo() values()"); timeSource.advanceTo(1976, 10); database.execute("insert into foo() values()"); timeSource.advanceTo(1976, 11); ResultSet results = database.query("select a from foo order by a"); assertTrue(results.next()); StringAssert.assertStartsWith("1976-09", getStamp(results)); assertTrue(results.next()); StringAssert.assertStartsWith("1976-10", getStamp(results)); assertFalse(results.next()); } private String getStamp(ResultSet results) throws SQLException { Timestamp timestamp = results.getTimestamp(1); return new LocalDateTime(timestamp.getTime()) .toString(TimestampCell.FORMATTER); } }