|
|
|
@ -25,15 +25,23 @@ import java.io.Reader;
|
|
|
|
|
import java.io.StringReader;
|
|
|
|
|
import java.math.BigDecimal;
|
|
|
|
|
import java.sql.ResultSetMetaData;
|
|
|
|
|
import java.sql.Timestamp;
|
|
|
|
|
import java.text.SimpleDateFormat;
|
|
|
|
|
import java.time.Instant;
|
|
|
|
|
import java.time.LocalDate;
|
|
|
|
|
import java.time.LocalDateTime;
|
|
|
|
|
import java.time.Month;
|
|
|
|
|
import java.time.ZoneId;
|
|
|
|
|
import java.time.ZoneOffset;
|
|
|
|
|
import java.time.ZonedDateTime;
|
|
|
|
|
import java.time.format.DateTimeFormatter;
|
|
|
|
|
import java.time.temporal.ChronoUnit;
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
import java.util.Arrays;
|
|
|
|
|
import java.util.Calendar;
|
|
|
|
|
import java.util.Date;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.TimeZone;
|
|
|
|
|
import java.util.logging.Logger;
|
|
|
|
|
|
|
|
|
|
import static org.hamcrest.MatcherAssert.assertThat;
|
|
|
|
|
import static org.hamcrest.Matchers.equalTo;
|
|
|
|
@ -50,6 +58,8 @@ import static org.junit.jupiter.api.Assertions.fail;
|
|
|
|
|
*/
|
|
|
|
|
public abstract class CommonTest {
|
|
|
|
|
|
|
|
|
|
private static final Logger logger = Logger.getLogger(CommonTest.class.getName());
|
|
|
|
|
|
|
|
|
|
final static String TEST_TABLE_NAME = "dbtest";
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -60,7 +70,7 @@ public abstract class CommonTest {
|
|
|
|
|
|
|
|
|
|
protected Database db;
|
|
|
|
|
|
|
|
|
|
protected Date now = new Date();
|
|
|
|
|
protected LocalDateTime now = LocalDateTime.now().truncatedTo(ChronoUnit.MILLIS);
|
|
|
|
|
|
|
|
|
|
protected LocalDate localDateNow = LocalDate.now();
|
|
|
|
|
|
|
|
|
@ -68,7 +78,7 @@ public abstract class CommonTest {
|
|
|
|
|
public void setupJdbc() throws Exception {
|
|
|
|
|
dbp = createDatabaseProvider(new OptionsOverride() {
|
|
|
|
|
@Override
|
|
|
|
|
public Date currentDate() {
|
|
|
|
|
public LocalDateTime currentDate() {
|
|
|
|
|
return now;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -197,8 +207,8 @@ public abstract class CommonTest {
|
|
|
|
|
assertArrayEquals("More".getBytes(), rs.getBlobBytesOrNull("bin_blob"));
|
|
|
|
|
assertArrayEquals("More".getBytes(), rs.getBlobBytesOrZeroLen(9));
|
|
|
|
|
assertArrayEquals("More".getBytes(), rs.getBlobBytesOrZeroLen("bin_blob"));
|
|
|
|
|
assertEquals(now, rs.getDateOrNull(10));
|
|
|
|
|
assertEquals(now, rs.getDateOrNull("date_millis"));
|
|
|
|
|
assertEquals(now, rs.getLocalDateTimeOrNull(10));
|
|
|
|
|
assertEquals(now, rs.getLocalDateTimeOrNull("date_millis"));
|
|
|
|
|
assertEquals(localDateNow, rs.getLocalDateOrNull(11));
|
|
|
|
|
assertEquals(localDateNow, rs.getLocalDateOrNull("local_date"));
|
|
|
|
|
return null;
|
|
|
|
@ -217,7 +227,7 @@ public abstract class CommonTest {
|
|
|
|
|
assertEquals("T", rs.getStringOrNull());
|
|
|
|
|
assertEquals("World", rs.getClobStringOrNull());
|
|
|
|
|
assertArrayEquals("More".getBytes(), rs.getBlobBytesOrNull());
|
|
|
|
|
assertEquals(now, rs.getDateOrNull());
|
|
|
|
|
assertEquals(now, rs.getLocalDateTimeOrNull());
|
|
|
|
|
assertEquals(localDateNow, rs.getLocalDateOrNull());
|
|
|
|
|
return null;
|
|
|
|
|
});
|
|
|
|
@ -350,8 +360,8 @@ public abstract class CommonTest {
|
|
|
|
|
assertNull(rs.getClobStringOrNull("str_lob"));
|
|
|
|
|
assertNull(rs.getBlobBytesOrNull(9));
|
|
|
|
|
assertNull(rs.getBlobBytesOrNull("bin_blob"));
|
|
|
|
|
assertNull(rs.getDateOrNull(10));
|
|
|
|
|
assertNull(rs.getDateOrNull("date_millis"));
|
|
|
|
|
assertNull(rs.getLocalDateTimeOrNull(10));
|
|
|
|
|
assertNull(rs.getLocalDateTimeOrNull("date_millis"));
|
|
|
|
|
assertNull(rs.getLocalDateOrNull(11));
|
|
|
|
|
assertNull(rs.getLocalDateOrNull("local_date"));
|
|
|
|
|
return null;
|
|
|
|
@ -381,8 +391,8 @@ public abstract class CommonTest {
|
|
|
|
|
assertEquals("World", rs.getClobStringOrNull("str_lob"));
|
|
|
|
|
assertArrayEquals("More".getBytes(), rs.getBlobBytesOrNull(9));
|
|
|
|
|
assertArrayEquals("More".getBytes(), rs.getBlobBytesOrNull("bin_blob"));
|
|
|
|
|
assertEquals(now, rs.getDateOrNull(10));
|
|
|
|
|
assertEquals(now, rs.getDateOrNull("date_millis"));
|
|
|
|
|
assertEquals(now, rs.getLocalDateTimeOrNull(10));
|
|
|
|
|
assertEquals(now, rs.getLocalDateTimeOrNull("date_millis"));
|
|
|
|
|
assertEquals(localDateNow, rs.getLocalDateOrNull(11));
|
|
|
|
|
assertEquals(localDateNow, rs.getLocalDateOrNull("local_date"));
|
|
|
|
|
return null;
|
|
|
|
@ -457,8 +467,8 @@ public abstract class CommonTest {
|
|
|
|
|
assertNull(rs.getClobStringOrNull("str_lob"));
|
|
|
|
|
assertNull(rs.getBlobBytesOrNull(9));
|
|
|
|
|
assertNull(rs.getBlobBytesOrNull("bin_blob"));
|
|
|
|
|
assertNull(rs.getDateOrNull(10));
|
|
|
|
|
assertNull(rs.getDateOrNull("date_millis"));
|
|
|
|
|
assertNull(rs.getLocalDateTimeOrNull(10));
|
|
|
|
|
assertNull(rs.getLocalDateTimeOrNull("date_millis"));
|
|
|
|
|
assertNull(rs.getLocalDateOrNull(11));
|
|
|
|
|
assertNull(rs.getLocalDateOrNull("local_date"));
|
|
|
|
|
return null;
|
|
|
|
@ -491,8 +501,8 @@ public abstract class CommonTest {
|
|
|
|
|
assertEquals("World", rs.getClobStringOrNull("str_lob"));
|
|
|
|
|
assertArrayEquals("More".getBytes(), rs.getBlobBytesOrNull(9));
|
|
|
|
|
assertArrayEquals("More".getBytes(), rs.getBlobBytesOrNull("bin_blob"));
|
|
|
|
|
assertEquals(now, rs.getDateOrNull(10));
|
|
|
|
|
assertEquals(now, rs.getDateOrNull("date_millis"));
|
|
|
|
|
assertEquals(now, rs.getLocalDateTimeOrNull(10));
|
|
|
|
|
assertEquals(now, rs.getLocalDateTimeOrNull("date_millis"));
|
|
|
|
|
assertEquals(localDateNow, rs.getLocalDateOrNull(11));
|
|
|
|
|
assertEquals(localDateNow, rs.getLocalDateOrNull("local_date"));
|
|
|
|
|
return null;
|
|
|
|
@ -560,8 +570,8 @@ public abstract class CommonTest {
|
|
|
|
|
assertNull(rs.getClobStringOrNull("str_lob"));
|
|
|
|
|
assertNull(rs.getBlobBytesOrNull(9));
|
|
|
|
|
assertNull(rs.getBlobBytesOrNull("bin_blob"));
|
|
|
|
|
assertNull(rs.getDateOrNull(10));
|
|
|
|
|
assertNull(rs.getDateOrNull("date_millis"));
|
|
|
|
|
assertNull(rs.getLocalDateTimeOrNull(10));
|
|
|
|
|
assertNull(rs.getLocalDateTimeOrNull("date_millis"));
|
|
|
|
|
assertNull(rs.getLocalDateOrNull(11));
|
|
|
|
|
assertNull(rs.getLocalDateOrNull("local_date"));
|
|
|
|
|
return null;
|
|
|
|
@ -1324,10 +1334,9 @@ public abstract class CommonTest {
|
|
|
|
|
@Test
|
|
|
|
|
public void argBigDecimal38Precision38() {
|
|
|
|
|
new Schema().addTable("dbtest").addColumn("i").asBigDecimal(38, 38).schema().execute(db);
|
|
|
|
|
|
|
|
|
|
BigDecimal value = new BigDecimal("0.99999999999999999999999999999999999999"); // 38 digits
|
|
|
|
|
db.toInsert("insert into dbtest (i) values (?)").argBigDecimal(value).insert(1);
|
|
|
|
|
System.out.println(db.toSelect("select i from dbtest").queryBigDecimalOrNull());
|
|
|
|
|
logger.info(db.toSelect("select i from dbtest").queryBigDecimalOrNull().toString());
|
|
|
|
|
assertEquals(value,
|
|
|
|
|
db.toSelect("select i from dbtest where i=?").argBigDecimal(value).queryBigDecimalOrNull());
|
|
|
|
|
}
|
|
|
|
@ -1379,7 +1388,7 @@ public abstract class CommonTest {
|
|
|
|
|
.insertReturning("dbtest", "pk", rs -> {
|
|
|
|
|
assertTrue(rs.next());
|
|
|
|
|
assertEquals(Long.valueOf(1L), rs.getLongOrNull(1));
|
|
|
|
|
assertThat(rs.getDateOrNull(2), equalTo(now));
|
|
|
|
|
assertThat(rs.getLocalDateTimeOrNull(2), equalTo(now));
|
|
|
|
|
assertFalse(rs.next());
|
|
|
|
|
return null;
|
|
|
|
|
}, "d");
|
|
|
|
@ -1511,13 +1520,13 @@ public abstract class CommonTest {
|
|
|
|
|
.addColumn("d").asDate().table().schema()
|
|
|
|
|
.addSequence("dbtest_seq").schema()
|
|
|
|
|
.execute(db);
|
|
|
|
|
Date dbNow = db.toInsert("insert into dbtest (pk, d) values (:seq, :d)")
|
|
|
|
|
LocalDateTime dbNow = db.toInsert("insert into dbtest (pk, d) values (:seq, :d)")
|
|
|
|
|
.argPkSeq(":seq", "dbtest_seq")
|
|
|
|
|
.argDateNowPerDb(":d")
|
|
|
|
|
.insertReturning("dbtest", "pk", rs -> {
|
|
|
|
|
assertTrue(rs.next());
|
|
|
|
|
assertEquals(Long.valueOf(1L), rs.getLongOrNull(1));
|
|
|
|
|
Date dbDate = rs.getDateOrNull(2);
|
|
|
|
|
LocalDateTime dbDate = rs.getLocalDateTimeOrNull(2);
|
|
|
|
|
assertFalse(rs.next());
|
|
|
|
|
return dbDate;
|
|
|
|
|
}, "d");
|
|
|
|
@ -1583,11 +1592,11 @@ public abstract class CommonTest {
|
|
|
|
|
db.toInsert("insert into dbtest (d) values (?)")
|
|
|
|
|
.argDateNowPerDb()
|
|
|
|
|
.insert(1);
|
|
|
|
|
Date dbNow = db.toSelect("select d from dbtest").queryDateOrNull();
|
|
|
|
|
if (dbNow != null && dbNow.getTime() % 10 != 0) {
|
|
|
|
|
LocalDateTime dbNow = db.toSelect("select d from dbtest").queryDateOrNull();
|
|
|
|
|
if (dbNow != null && dbNow.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() % 10 != 0) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
System.out.println("Zero in least significant digit (attempt " + attempts + ")");
|
|
|
|
|
logger.info("Zero in least significant digit (attempt " + attempts + ")");
|
|
|
|
|
db.dropTableQuietly(TEST_TABLE_NAME);
|
|
|
|
|
}
|
|
|
|
|
fail("Timestamp had zero in the least significant digit");
|
|
|
|
@ -1605,7 +1614,7 @@ public abstract class CommonTest {
|
|
|
|
|
.argDateNowPerDb()
|
|
|
|
|
.insert(1);
|
|
|
|
|
// Now pull it out, put it back in, and verify it matches in the database
|
|
|
|
|
Date dbNow = db.toSelect("select d1 from dbtest").queryDateOrNull();
|
|
|
|
|
LocalDateTime dbNow = db.toSelect("select d1 from dbtest").queryDateOrNull();
|
|
|
|
|
db.toUpdate("update dbtest set d2=?")
|
|
|
|
|
.argDate(dbNow)
|
|
|
|
|
.update(1);
|
|
|
|
@ -1619,21 +1628,23 @@ public abstract class CommonTest {
|
|
|
|
|
.addTable("dbtest")
|
|
|
|
|
.addColumn("d").asDate().table().schema()
|
|
|
|
|
.execute(db);
|
|
|
|
|
Date date = new Date(166656789L);
|
|
|
|
|
Instant instant = Instant.ofEpochMilli(166656789L);
|
|
|
|
|
LocalDateTime dateMinus = LocalDateTime.ofInstant(instant, ZoneId.ofOffset("GMT", ZoneOffset.ofHours(-4)));
|
|
|
|
|
LocalDateTime datePlus = LocalDateTime.ofInstant(instant, ZoneId.ofOffset("GMT", ZoneOffset.ofHours(+4)));
|
|
|
|
|
TimeZone defaultTZ = TimeZone.getDefault();
|
|
|
|
|
try {
|
|
|
|
|
TimeZone.setDefault(TimeZone.getTimeZone("GMT-4:00"));
|
|
|
|
|
db.toInsert("insert into dbtest (d) values (?)").argDate(date).insert(1);
|
|
|
|
|
assertEquals(date, db.toSelect("select d from dbtest").queryDateOrNull());
|
|
|
|
|
assertEquals("1970-01-02 18:17:36.789000-0400", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS000Z").format(
|
|
|
|
|
db.toSelect("select d from dbtest").queryDateOrNull()));
|
|
|
|
|
db.toDelete("delete from dbtest where d=?").argDate(date).update(1);
|
|
|
|
|
db.toInsert("insert into dbtest (d) values (?)").argDate(dateMinus).insert(1);
|
|
|
|
|
LocalDateTime localDateTimeMinus = db.toSelect("select d from dbtest").queryDateOrNull();
|
|
|
|
|
assertEquals(dateMinus, localDateTimeMinus);
|
|
|
|
|
assertEquals("1970-01-02 18:17:36.789", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS").format(localDateTimeMinus));
|
|
|
|
|
db.toDelete("delete from dbtest where d=?").argDate(dateMinus).update(1);
|
|
|
|
|
TimeZone.setDefault(TimeZone.getTimeZone("GMT+4:00"));
|
|
|
|
|
db.toInsert("insert into dbtest (d) values (?)").argDate(date).insert(1);
|
|
|
|
|
assertEquals(date, db.toSelect("select d from dbtest").queryDateOrNull());
|
|
|
|
|
assertEquals("1970-01-03 02:17:36.789000+0400", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS000Z").format(
|
|
|
|
|
db.toSelect("select d from dbtest").queryDateOrNull()));
|
|
|
|
|
db.toDelete("delete from dbtest where d=?").argDate(date).update(1);
|
|
|
|
|
db.toInsert("insert into dbtest (d) values (?)").argDate(datePlus).insert(1);
|
|
|
|
|
LocalDateTime localDateTimePlus = db.toSelect("select d from dbtest").queryDateOrNull();
|
|
|
|
|
assertEquals(datePlus, localDateTimePlus);
|
|
|
|
|
assertEquals("1970-01-03 02:17:36.789", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS").format(localDateTimePlus));
|
|
|
|
|
db.toDelete("delete from dbtest where d=?").argDate(datePlus).update(1);
|
|
|
|
|
} finally {
|
|
|
|
|
TimeZone.setDefault(defaultTZ);
|
|
|
|
|
}
|
|
|
|
@ -1647,30 +1658,30 @@ public abstract class CommonTest {
|
|
|
|
|
*/
|
|
|
|
|
@Test
|
|
|
|
|
public void stringDateFunctions() {
|
|
|
|
|
Date date = new Date(166656789L);
|
|
|
|
|
System.out.println("Date: " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS000Z").format(date));
|
|
|
|
|
Instant instant = Instant.ofEpochMilli(166656789L);
|
|
|
|
|
LocalDateTime dateMinus = LocalDateTime.ofInstant(instant, ZoneId.ofOffset("GMT", ZoneOffset.ofHours(-4)));
|
|
|
|
|
LocalDateTime datePlus = LocalDateTime.ofInstant(instant, ZoneId.ofOffset("GMT", ZoneOffset.ofHours(+4)));
|
|
|
|
|
logger.info("LocalDateTime: " + dateMinus + " " + datePlus);
|
|
|
|
|
TimeZone defaultTZ = TimeZone.getDefault();
|
|
|
|
|
try {
|
|
|
|
|
TimeZone.setDefault(TimeZone.getTimeZone("GMT-4:00"));
|
|
|
|
|
new Schema()
|
|
|
|
|
.addTable("dbtest")
|
|
|
|
|
.addColumn("d").asDate().schema().execute(db);
|
|
|
|
|
new Schema().addTable("dbtest").addColumn("d").asDate().schema().execute(db);
|
|
|
|
|
db.toInsert("insert into dbtest (d) values ("
|
|
|
|
|
+ db.flavor().dateAsSqlFunction(date, db.options().calendarForTimestamps()).replace(":", "::") + ")")
|
|
|
|
|
+ db.flavor().dateAsSqlFunction(Timestamp.valueOf(dateMinus), db.options().calendarForTimestamps()).replace(":", "::") + ")")
|
|
|
|
|
.insert(1);
|
|
|
|
|
assertEquals("1970-01-02 18:17:36.789000-0400", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS000Z").format(
|
|
|
|
|
db.toSelect("select d from dbtest").queryDateOrNull()));
|
|
|
|
|
assertEquals("1970-01-02 18:17:36.789",
|
|
|
|
|
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS").format(db.toSelect("select d from dbtest").queryDateOrNull()));
|
|
|
|
|
// Now do some client operations in a different time zone
|
|
|
|
|
TimeZone.setDefault(TimeZone.getTimeZone("GMT+4:00"));
|
|
|
|
|
// Verify regular arg maps date the same way even though our TimeZone is now different
|
|
|
|
|
db.toDelete("delete from dbtest where d=?").argDate(date).update(1);
|
|
|
|
|
db.toDelete("delete from dbtest where d=?").argDate(datePlus).update(1);
|
|
|
|
|
db.toInsert("insert into dbtest (d) values ("
|
|
|
|
|
+ db.flavor().dateAsSqlFunction(date, db.options().calendarForTimestamps()).replace(":", "::") + ")")
|
|
|
|
|
+ db.flavor().dateAsSqlFunction(Timestamp.valueOf(datePlus), db.options().calendarForTimestamps()).replace(":", "::") + ")")
|
|
|
|
|
.insert(1);
|
|
|
|
|
assertEquals("1970-01-03 02:17:36.789000+0400", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS000Z").format(
|
|
|
|
|
db.toSelect("select d from dbtest").queryDateOrNull()));
|
|
|
|
|
assertEquals("1970-01-03 02:17:36.789",
|
|
|
|
|
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS").format(db.toSelect("select d from dbtest").queryDateOrNull()));
|
|
|
|
|
// Verify the function maps correctly for equals operations as well
|
|
|
|
|
db.toDelete("delete from dbtest where d=" + db.flavor().dateAsSqlFunction(date,
|
|
|
|
|
db.toDelete("delete from dbtest where d=" + db.flavor().dateAsSqlFunction(Timestamp.valueOf(datePlus),
|
|
|
|
|
db.options().calendarForTimestamps()).replace(":", "::")).update(1);
|
|
|
|
|
} finally {
|
|
|
|
|
TimeZone.setDefault(defaultTZ);
|
|
|
|
|