[TD-3762]<feature>: support us and ms percision for timestamp in JDBC (#5818)
* [TD-3762]<feature>: support us and ms percision for timestamp in JDBC * change * change * change * change
This commit is contained in:
parent
9f5301a318
commit
bcebfbe844
|
@ -4,13 +4,23 @@ import java.sql.*;
|
|||
import java.util.Enumeration;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.*;
|
||||
|
||||
public abstract class AbstractConnection extends WrapperImpl implements Connection {
|
||||
|
||||
protected volatile boolean isClosed;
|
||||
protected volatile String catalog;
|
||||
protected volatile Properties clientInfoProps = new Properties();
|
||||
protected final Properties clientInfoProps = new Properties();
|
||||
|
||||
protected AbstractConnection(Properties properties) {
|
||||
Set<String> propNames = properties.stringPropertyNames();
|
||||
for (String propName : propNames) {
|
||||
clientInfoProps.setProperty(propName, properties.getProperty(propName));
|
||||
}
|
||||
String timestampFormat = properties.getProperty(TSDBDriver.PROPERTY_KEY_TIMESTAMP_FORMAT, "STRING");
|
||||
clientInfoProps.setProperty(TSDBDriver.PROPERTY_KEY_TIMESTAMP_FORMAT, timestampFormat);
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract Statement createStatement() throws SQLException;
|
||||
|
@ -35,7 +45,6 @@ public abstract class AbstractConnection extends WrapperImpl implements Connecti
|
|||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void setAutoCommit(boolean autoCommit) throws SQLException {
|
||||
if (isClosed())
|
||||
|
@ -441,9 +450,8 @@ public abstract class AbstractConnection extends WrapperImpl implements Connecti
|
|||
if (isClosed)
|
||||
throw (SQLClientInfoException) TSDBError.createSQLException(TSDBErrorNumbers.ERROR_SQLCLIENT_EXCEPTION_ON_CONNECTION_CLOSED);
|
||||
|
||||
if (clientInfoProps == null)
|
||||
clientInfoProps = new Properties();
|
||||
clientInfoProps.setProperty(name, value);
|
||||
if (clientInfoProps != null)
|
||||
clientInfoProps.setProperty(name, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -28,6 +28,7 @@ public class TSDBConnection extends AbstractConnection {
|
|||
}
|
||||
|
||||
public TSDBConnection(Properties info, TSDBDatabaseMetaData meta) throws SQLException {
|
||||
super(info);
|
||||
this.databaseMetaData = meta;
|
||||
connect(info.getProperty(TSDBDriver.PROPERTY_KEY_HOST),
|
||||
Integer.parseInt(info.getProperty(TSDBDriver.PROPERTY_KEY_PORT, "0")),
|
||||
|
|
|
@ -95,6 +95,11 @@ public class TSDBDriver extends AbstractDriver {
|
|||
*/
|
||||
public static final String PROPERTY_KEY_BATCH_LOAD = "batchfetch";
|
||||
|
||||
/**
|
||||
* timestamp format for JDBC-RESTful,should one of the options: string or timestamp or utc
|
||||
*/
|
||||
public static final String PROPERTY_KEY_TIMESTAMP_FORMAT = "timestampFormat";
|
||||
|
||||
private TSDBDatabaseMetaData dbMetaData = null;
|
||||
|
||||
static {
|
||||
|
|
|
@ -203,7 +203,11 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
|
|||
|
||||
this.lastWasNull = this.rowData.wasNull(columnIndex - 1);
|
||||
if (!lastWasNull) {
|
||||
res = this.rowData.getLong(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType());
|
||||
Object value = this.rowData.get(columnIndex - 1);
|
||||
if (value instanceof Timestamp)
|
||||
res = ((Timestamp) value).getTime();
|
||||
else
|
||||
res = this.rowData.getLong(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType());
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
@ -273,7 +277,6 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
|
|||
checkAvailability(columnIndex, this.columnMetaDataList.size());
|
||||
|
||||
Timestamp res = null;
|
||||
|
||||
if (this.getBatchFetch())
|
||||
return this.blockData.getTimestamp(columnIndex - 1);
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ package com.taosdata.jdbc;
|
|||
import java.math.BigDecimal;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Timestamp;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
||||
|
@ -299,7 +300,19 @@ public class TSDBResultSetRowData {
|
|||
}
|
||||
|
||||
public void setTimestamp(int col, long ts) {
|
||||
data.set(col, new Timestamp(ts));
|
||||
//TODO: this implementation contains logical error
|
||||
// when precision is us the (long ts) is 16 digital number
|
||||
// when precision is ms, the (long ts) is 13 digital number
|
||||
// we need a JNI function like this:
|
||||
// public void setTimestamp(int col, long epochSecond, long nanoAdjustment)
|
||||
if (ts < 1_0000_0000_0000_0L) {
|
||||
data.set(col, new Timestamp(ts));
|
||||
} else {
|
||||
long epochSec = ts / 1000_000l;
|
||||
long nanoAdjustment = ts % 1000_000l * 1000l;
|
||||
Timestamp timestamp = Timestamp.from(Instant.ofEpochSecond(epochSec, nanoAdjustment));
|
||||
data.set(col, timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
public Timestamp getTimestamp(int col) {
|
||||
|
|
|
@ -22,6 +22,7 @@ public class RestfulConnection extends AbstractConnection {
|
|||
private final DatabaseMetaData metadata;
|
||||
|
||||
public RestfulConnection(String host, String port, Properties props, String database, String url) {
|
||||
super(props);
|
||||
this.host = host;
|
||||
this.port = Integer.parseInt(port);
|
||||
this.database = database;
|
||||
|
|
|
@ -5,13 +5,14 @@ import com.alibaba.fastjson.JSONObject;
|
|||
import com.google.common.primitives.Ints;
|
||||
import com.google.common.primitives.Longs;
|
||||
import com.google.common.primitives.Shorts;
|
||||
import com.taosdata.jdbc.AbstractResultSet;
|
||||
import com.taosdata.jdbc.TSDBConstants;
|
||||
import com.taosdata.jdbc.TSDBError;
|
||||
import com.taosdata.jdbc.TSDBErrorNumbers;
|
||||
import com.taosdata.jdbc.*;
|
||||
import com.taosdata.jdbc.utils.UtcTimestampUtil;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.*;
|
||||
import java.time.Instant;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
|
||||
|
@ -19,6 +20,7 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
|
|||
private volatile boolean isClosed;
|
||||
private int pos = -1;
|
||||
|
||||
|
||||
private final String database;
|
||||
private final Statement statement;
|
||||
// data
|
||||
|
@ -65,7 +67,7 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
|
|||
}
|
||||
}
|
||||
|
||||
private Object parseColumnData(JSONArray row, int colIndex, int taosType) {
|
||||
private Object parseColumnData(JSONArray row, int colIndex, int taosType) throws SQLException {
|
||||
switch (taosType) {
|
||||
case TSDBConstants.TSDB_DATA_TYPE_BOOL:
|
||||
return row.getBoolean(colIndex);
|
||||
|
@ -81,8 +83,44 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
|
|||
return row.getFloat(colIndex);
|
||||
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE:
|
||||
return row.getDouble(colIndex);
|
||||
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
|
||||
return new Timestamp(row.getDate(colIndex).getTime());
|
||||
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: {
|
||||
if (row.get(colIndex) == null)
|
||||
return null;
|
||||
String timestampFormat = this.statement.getConnection().getClientInfo(TSDBDriver.PROPERTY_KEY_TIMESTAMP_FORMAT);
|
||||
if ("TIMESTAMP".equalsIgnoreCase(timestampFormat)) {
|
||||
Long value = row.getLong(colIndex);
|
||||
//TODO:
|
||||
if (value < 1_0000_0000_0000_0L)
|
||||
return new Timestamp(value);
|
||||
long epochSec = value / 1000_000l;
|
||||
long nanoAdjustment = value % 1000_000l * 1000l;
|
||||
return Timestamp.from(Instant.ofEpochSecond(epochSec, nanoAdjustment));
|
||||
}
|
||||
if ("UTC".equalsIgnoreCase(timestampFormat)) {
|
||||
String value = row.getString(colIndex);
|
||||
long epochSec = Timestamp.valueOf(value.substring(0, 19).replace("T", " ")).getTime() / 1000;
|
||||
int fractionalSec = Integer.parseInt(value.substring(20, value.length() - 5));
|
||||
long nanoAdjustment = 0;
|
||||
if (value.length() > 28) {
|
||||
// ms timestamp: yyyy-MM-ddTHH:mm:ss.SSSSSS+0x00
|
||||
nanoAdjustment = fractionalSec * 1000l;
|
||||
} else {
|
||||
// ms timestamp: yyyy-MM-ddTHH:mm:ss.SSS+0x00
|
||||
nanoAdjustment = fractionalSec * 1000_000l;
|
||||
}
|
||||
ZoneOffset zoneOffset = ZoneOffset.of(value.substring(value.length() - 5));
|
||||
Instant instant = Instant.ofEpochSecond(epochSec, nanoAdjustment).atOffset(zoneOffset).toInstant();
|
||||
return Timestamp.from(instant);
|
||||
}
|
||||
String value = row.getString(colIndex);
|
||||
if (value.length() <= 23) // ms timestamp: yyyy-MM-dd HH:mm:ss.SSS
|
||||
return row.getTimestamp(colIndex);
|
||||
// us timestamp: yyyy-MM-dd HH:mm:ss.SSSSSS
|
||||
long epochSec = Timestamp.valueOf(value.substring(0, 19)).getTime() / 1000;
|
||||
long nanoAdjustment = Integer.parseInt(value.substring(20)) * 1000l;
|
||||
Timestamp timestamp = Timestamp.from(Instant.ofEpochSecond(epochSec, nanoAdjustment));
|
||||
return timestamp;
|
||||
}
|
||||
case TSDBConstants.TSDB_DATA_TYPE_BINARY:
|
||||
return row.getString(colIndex) == null ? null : row.getString(colIndex).getBytes();
|
||||
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
|
||||
|
@ -215,6 +253,9 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
|
|||
Object value = resultSet.get(pos).get(columnIndex - 1);
|
||||
if (value == null)
|
||||
return 0;
|
||||
if (value instanceof Timestamp) {
|
||||
return ((Timestamp) value).getTime();
|
||||
}
|
||||
|
||||
long valueAsLong = 0;
|
||||
try {
|
||||
|
@ -307,6 +348,13 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
|
|||
return null;
|
||||
if (value instanceof Timestamp)
|
||||
return (Timestamp) value;
|
||||
// if (value instanceof Long) {
|
||||
// if (1_0000_0000_0000_0L > (long) value)
|
||||
// return Timestamp.from(Instant.ofEpochMilli((long) value));
|
||||
// long epochSec = (long) value / 1000_000L;
|
||||
// long nanoAdjustment = (long) ((long) value % 1000_000L * 1000);
|
||||
// return Timestamp.from(Instant.ofEpochSecond(epochSec, nanoAdjustment));
|
||||
// }
|
||||
return Timestamp.valueOf(value.toString());
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSON;
|
|||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.taosdata.jdbc.AbstractStatement;
|
||||
import com.taosdata.jdbc.TSDBDriver;
|
||||
import com.taosdata.jdbc.TSDBError;
|
||||
import com.taosdata.jdbc.TSDBErrorNumbers;
|
||||
import com.taosdata.jdbc.utils.HttpClientPoolUtil;
|
||||
|
@ -34,14 +35,11 @@ public class RestfulStatement extends AbstractStatement {
|
|||
if (!SqlSyntaxValidator.isValidForExecuteQuery(sql))
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_FOR_EXECUTE_QUERY, "not a valid sql for executeQuery: " + sql);
|
||||
|
||||
final String url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sql";
|
||||
if (SqlSyntaxValidator.isDatabaseUnspecifiedQuery(sql)) {
|
||||
return executeOneQuery(url, sql);
|
||||
return executeOneQuery(sql);
|
||||
}
|
||||
|
||||
// if (this.database != null && !this.database.trim().replaceAll("\\s","").isEmpty())
|
||||
// HttpClientPoolUtil.execute(url, "use " + this.database);
|
||||
return executeOneQuery(url, sql);
|
||||
return executeOneQuery(sql);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -56,8 +54,6 @@ public class RestfulStatement extends AbstractStatement {
|
|||
return executeOneUpdate(url, sql);
|
||||
}
|
||||
|
||||
// if (this.database != null && !this.database.trim().replaceAll("\\s", "").isEmpty())
|
||||
// HttpClientPoolUtil.execute(url, "use " + this.database);
|
||||
return executeOneUpdate(url, sql);
|
||||
}
|
||||
|
||||
|
@ -78,14 +74,21 @@ public class RestfulStatement extends AbstractStatement {
|
|||
|
||||
//如果执行了use操作应该将当前Statement的catalog设置为新的database
|
||||
boolean result = true;
|
||||
final String url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sql";
|
||||
String url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sql";
|
||||
if (conn.getClientInfo(TSDBDriver.PROPERTY_KEY_TIMESTAMP_FORMAT).equals("TIMESTAMP")) {
|
||||
url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sqlt";
|
||||
}
|
||||
if (conn.getClientInfo(TSDBDriver.PROPERTY_KEY_TIMESTAMP_FORMAT).equals("UTC")) {
|
||||
url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sqlutc";
|
||||
}
|
||||
|
||||
if (SqlSyntaxValidator.isUseSql(sql)) {
|
||||
HttpClientPoolUtil.execute(url, sql);
|
||||
this.database = sql.trim().replace("use", "").trim();
|
||||
this.conn.setCatalog(this.database);
|
||||
result = false;
|
||||
} else if (SqlSyntaxValidator.isDatabaseUnspecifiedQuery(sql)) {
|
||||
executeOneQuery(url, sql);
|
||||
executeOneQuery(sql);
|
||||
} else if (SqlSyntaxValidator.isDatabaseUnspecifiedUpdate(sql)) {
|
||||
executeOneUpdate(url, sql);
|
||||
result = false;
|
||||
|
@ -101,11 +104,18 @@ public class RestfulStatement extends AbstractStatement {
|
|||
return result;
|
||||
}
|
||||
|
||||
private ResultSet executeOneQuery(String url, String sql) throws SQLException {
|
||||
private ResultSet executeOneQuery(String sql) throws SQLException {
|
||||
if (!SqlSyntaxValidator.isValidForExecuteQuery(sql))
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_FOR_EXECUTE_QUERY, "not a valid sql for executeQuery: " + sql);
|
||||
|
||||
// row data
|
||||
String url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sql";
|
||||
String timestampFormat = conn.getClientInfo(TSDBDriver.PROPERTY_KEY_TIMESTAMP_FORMAT);
|
||||
if ("TIMESTAMP".equalsIgnoreCase(timestampFormat))
|
||||
url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sqlt";
|
||||
if ("UTC".equalsIgnoreCase(timestampFormat))
|
||||
url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sqlutc";
|
||||
|
||||
String result = HttpClientPoolUtil.execute(url, sql);
|
||||
JSONObject resultJson = JSON.parseObject(result);
|
||||
if (resultJson.getString("status").equals("error")) {
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
package com.taosdata.jdbc.utils;
|
||||
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeFormatterBuilder;
|
||||
|
||||
public class UtcTimestampUtil {
|
||||
public static final DateTimeFormatter formatter = new DateTimeFormatterBuilder()
|
||||
.appendPattern("yyyy-MM-ddTHH:mm:ss.SSS+")
|
||||
// .appendFraction(ChronoField.NANO_OF_SECOND, 0, 9, true)
|
||||
.toFormatter();
|
||||
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
package com.taosdata.jdbc.cases;
|
||||
|
||||
|
||||
import com.taosdata.jdbc.TSDBDriver;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.Properties;
|
||||
|
||||
public class TwoTypeTimestampPercisionInJniTest {
|
||||
|
||||
private static final String host = "127.0.0.1";
|
||||
private static final String ms_timestamp_db = "ms_precision_test";
|
||||
private static final String us_timestamp_db = "us_precision_test";
|
||||
private static final long timestamp1 = System.currentTimeMillis();
|
||||
private static final long timestamp2 = timestamp1 * 1000 + 123;
|
||||
|
||||
private static Connection conn;
|
||||
|
||||
@Test
|
||||
public void testCase1() {
|
||||
try (Statement stmt = conn.createStatement()) {
|
||||
ResultSet rs = stmt.executeQuery("select last_row(ts) from " + ms_timestamp_db + ".weather");
|
||||
rs.next();
|
||||
long ts = rs.getTimestamp(1).getTime();
|
||||
Assert.assertEquals(timestamp1, ts);
|
||||
ts = rs.getLong(1);
|
||||
Assert.assertEquals(timestamp1, ts);
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase2() {
|
||||
try (Statement stmt = conn.createStatement()) {
|
||||
ResultSet rs = stmt.executeQuery("select last_row(ts) from " + us_timestamp_db + ".weather");
|
||||
rs.next();
|
||||
|
||||
Timestamp timestamp = rs.getTimestamp(1);
|
||||
System.out.println(timestamp);
|
||||
long ts = timestamp.getTime();
|
||||
Assert.assertEquals(timestamp1, ts);
|
||||
int nanos = timestamp.getNanos();
|
||||
Assert.assertEquals(timestamp2 % 1000_000l * 1000, nanos);
|
||||
|
||||
ts = rs.getLong(1);
|
||||
Assert.assertEquals(timestamp1, ts);
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws SQLException {
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
||||
|
||||
String url = "jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata";
|
||||
conn = DriverManager.getConnection(url, properties);
|
||||
|
||||
Statement stmt = conn.createStatement();
|
||||
stmt.execute("drop database if exists " + ms_timestamp_db);
|
||||
stmt.execute("create database if not exists " + ms_timestamp_db + " precision 'ms'");
|
||||
stmt.execute("create table " + ms_timestamp_db + ".weather(ts timestamp, f1 int)");
|
||||
stmt.executeUpdate("insert into " + ms_timestamp_db + ".weather(ts,f1) values(" + timestamp1 + ", 127)");
|
||||
|
||||
stmt.execute("drop database if exists " + us_timestamp_db);
|
||||
stmt.execute("create database if not exists " + us_timestamp_db + " precision 'us'");
|
||||
stmt.execute("create table " + us_timestamp_db + ".weather(ts timestamp, f1 int)");
|
||||
stmt.executeUpdate("insert into " + us_timestamp_db + ".weather(ts,f1) values(" + timestamp2 + ", 127)");
|
||||
stmt.close();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void afterClass() {
|
||||
try {
|
||||
if (conn != null)
|
||||
conn.close();
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,168 @@
|
|||
package com.taosdata.jdbc.cases;
|
||||
|
||||
|
||||
import com.taosdata.jdbc.TSDBDriver;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.Properties;
|
||||
|
||||
public class TwoTypeTimestampPercisionInRestfulTest {
|
||||
|
||||
private static final String host = "127.0.0.1";
|
||||
private static final String ms_timestamp_db = "ms_precision_test";
|
||||
private static final String us_timestamp_db = "us_precision_test";
|
||||
private static final long timestamp1 = System.currentTimeMillis();
|
||||
private static final long timestamp2 = timestamp1 * 1000 + 123;
|
||||
|
||||
private static Connection conn1;
|
||||
private static Connection conn2;
|
||||
private static Connection conn3;
|
||||
|
||||
@Test
|
||||
public void testCase1() {
|
||||
try (Statement stmt = conn1.createStatement()) {
|
||||
ResultSet rs = stmt.executeQuery("select last_row(ts) from " + ms_timestamp_db + ".weather");
|
||||
rs.next();
|
||||
long ts = rs.getTimestamp(1).getTime();
|
||||
Assert.assertEquals(timestamp1, ts);
|
||||
ts = rs.getLong(1);
|
||||
Assert.assertEquals(timestamp1, ts);
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase2() {
|
||||
try (Statement stmt = conn1.createStatement()) {
|
||||
ResultSet rs = stmt.executeQuery("select last_row(ts) from " + us_timestamp_db + ".weather");
|
||||
rs.next();
|
||||
|
||||
Timestamp timestamp = rs.getTimestamp(1);
|
||||
long ts = timestamp.getTime();
|
||||
Assert.assertEquals(timestamp1, ts);
|
||||
int nanos = timestamp.getNanos();
|
||||
Assert.assertEquals(timestamp2 % 1000_000l * 1000, nanos);
|
||||
|
||||
ts = rs.getLong(1);
|
||||
Assert.assertEquals(timestamp1, ts);
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase3() {
|
||||
try (Statement stmt = conn2.createStatement()) {
|
||||
ResultSet rs = stmt.executeQuery("select last_row(ts) from " + ms_timestamp_db + ".weather");
|
||||
rs.next();
|
||||
Timestamp rsTimestamp = rs.getTimestamp(1);
|
||||
long ts = rsTimestamp.getTime();
|
||||
Assert.assertEquals(timestamp1, ts);
|
||||
ts = rs.getLong(1);
|
||||
Assert.assertEquals(timestamp1, ts);
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase4() {
|
||||
try (Statement stmt = conn2.createStatement()) {
|
||||
ResultSet rs = stmt.executeQuery("select last_row(ts) from " + us_timestamp_db + ".weather");
|
||||
rs.next();
|
||||
|
||||
Timestamp timestamp = rs.getTimestamp(1);
|
||||
long ts = timestamp.getTime();
|
||||
Assert.assertEquals(timestamp1, ts);
|
||||
int nanos = timestamp.getNanos();
|
||||
Assert.assertEquals(timestamp2 % 1000_000l * 1000, nanos);
|
||||
|
||||
ts = rs.getLong(1);
|
||||
Assert.assertEquals(timestamp1, ts);
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase5() {
|
||||
try (Statement stmt = conn3.createStatement()) {
|
||||
ResultSet rs = stmt.executeQuery("select last_row(ts) from " + ms_timestamp_db + ".weather");
|
||||
rs.next();
|
||||
long ts = rs.getTimestamp(1).getTime();
|
||||
Assert.assertEquals(timestamp1, ts);
|
||||
ts = rs.getLong(1);
|
||||
Assert.assertEquals(timestamp1, ts);
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase6() {
|
||||
try (Statement stmt = conn3.createStatement()) {
|
||||
ResultSet rs = stmt.executeQuery("select last_row(ts) from " + us_timestamp_db + ".weather");
|
||||
rs.next();
|
||||
|
||||
Timestamp timestamp = rs.getTimestamp(1);
|
||||
long ts = timestamp.getTime();
|
||||
Assert.assertEquals(timestamp1, ts);
|
||||
int nanos = timestamp.getNanos();
|
||||
Assert.assertEquals(timestamp2 % 1000_000l * 1000, nanos);
|
||||
|
||||
ts = rs.getLong(1);
|
||||
Assert.assertEquals(timestamp1, ts);
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws SQLException {
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
||||
// properties.setProperty(TSDBDriver.PROPERTY_KEY_TIMESTAMP_FORMAT, "TIMESTAMP");
|
||||
|
||||
String url = "jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata";
|
||||
conn1 = DriverManager.getConnection(url, properties);
|
||||
|
||||
url = "jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata×tampFormat=timestamp";
|
||||
conn2 = DriverManager.getConnection(url, properties);
|
||||
|
||||
url = "jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata×tampFormat=utc";
|
||||
conn3 = DriverManager.getConnection(url, properties);
|
||||
|
||||
Statement stmt = conn1.createStatement();
|
||||
stmt.execute("drop database if exists " + ms_timestamp_db);
|
||||
stmt.execute("create database if not exists " + ms_timestamp_db + " precision 'ms'");
|
||||
stmt.execute("create table " + ms_timestamp_db + ".weather(ts timestamp, f1 int)");
|
||||
stmt.executeUpdate("insert into " + ms_timestamp_db + ".weather(ts,f1) values(" + timestamp1 + ", 127)");
|
||||
|
||||
stmt.execute("drop database if exists " + us_timestamp_db);
|
||||
stmt.execute("create database if not exists " + us_timestamp_db + " precision 'us'");
|
||||
stmt.execute("create table " + us_timestamp_db + ".weather(ts timestamp, f1 int)");
|
||||
stmt.executeUpdate("insert into " + us_timestamp_db + ".weather(ts,f1) values(" + timestamp2 + ", 127)");
|
||||
stmt.close();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void afterClass() {
|
||||
try {
|
||||
if (conn1 != null)
|
||||
conn1.close();
|
||||
if (conn2 != null)
|
||||
conn2.close();
|
||||
if (conn3 != null)
|
||||
conn3.close();
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue