提交 1a816408 编写于 作者: H Haojun Liao

[td-225] merge develop.

上级 74bc74d6
...@@ -8,10 +8,8 @@ IF (TD_MVN_INSTALLED) ...@@ -8,10 +8,8 @@ IF (TD_MVN_INSTALLED)
ADD_CUSTOM_COMMAND(OUTPUT ${JDBC_CMD_NAME} ADD_CUSTOM_COMMAND(OUTPUT ${JDBC_CMD_NAME}
POST_BUILD POST_BUILD
COMMAND mvn -Dmaven.test.skip=true install -f ${CMAKE_CURRENT_SOURCE_DIR}/pom.xml COMMAND mvn -Dmaven.test.skip=true install -f ${CMAKE_CURRENT_SOURCE_DIR}/pom.xml
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/target/taos-jdbcdriver-2.0.29.jar ${LIBRARY_OUTPUT_PATH} COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/target/taos-jdbcdriver-2.0.32-dist.jar ${LIBRARY_OUTPUT_PATH}
COMMAND mvn -Dmaven.test.skip=true clean -f ${CMAKE_CURRENT_SOURCE_DIR}/pom.xml COMMAND mvn -Dmaven.test.skip=true clean -f ${CMAKE_CURRENT_SOURCE_DIR}/pom.xml
COMMENT "build jdbc driver") COMMENT "build jdbc driver")
ADD_CUSTOM_TARGET(${JDBC_TARGET_NAME} ALL WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH} DEPENDS ${JDBC_CMD_NAME}) ADD_CUSTOM_TARGET(${JDBC_TARGET_NAME} ALL WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH} DEPENDS ${JDBC_CMD_NAME})
ENDIF () ENDIF ()
\ No newline at end of file
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
<groupId>com.taosdata.jdbc</groupId> <groupId>com.taosdata.jdbc</groupId>
<artifactId>taos-jdbcdriver</artifactId> <artifactId>taos-jdbcdriver</artifactId>
<version>2.0.29</version> <version>2.0.32</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>JDBCDriver</name> <name>JDBCDriver</name>
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>com.taosdata.jdbc</groupId> <groupId>com.taosdata.jdbc</groupId>
<artifactId>taos-jdbcdriver</artifactId> <artifactId>taos-jdbcdriver</artifactId>
<version>2.0.29</version> <version>2.0.32</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>JDBCDriver</name> <name>JDBCDriver</name>
<url>https://github.com/taosdata/TDengine/tree/master/src/connector/jdbc</url> <url>https://github.com/taosdata/TDengine/tree/master/src/connector/jdbc</url>
...@@ -47,7 +47,7 @@ ...@@ -47,7 +47,7 @@
<dependency> <dependency>
<groupId>org.apache.httpcomponents</groupId> <groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId> <artifactId>httpclient</artifactId>
<version>4.5.8</version> <version>4.5.13</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.alibaba</groupId> <groupId>com.alibaba</groupId>
...@@ -113,16 +113,16 @@ ...@@ -113,16 +113,16 @@
<include>**/*Test.java</include> <include>**/*Test.java</include>
</includes> </includes>
<excludes> <excludes>
<exclude>**/TSDBJNIConnectorTest.java</exclude>
<exclude>**/UnsignedNumberJniTest.java</exclude>
<exclude>**/DatetimeBefore1970Test.java</exclude>
<exclude>**/AppMemoryLeakTest.java</exclude> <exclude>**/AppMemoryLeakTest.java</exclude>
<exclude>**/AuthenticationTest.java</exclude> <exclude>**/AuthenticationTest.java</exclude>
<exclude>**/TaosInfoMonitorTest.java</exclude> <exclude>**/ConnectMultiTaosdByRestfulWithDifferentTokenTest.java</exclude>
<exclude>**/DatetimeBefore1970Test.java</exclude>
<exclude>**/FailOverTest.java</exclude> <exclude>**/FailOverTest.java</exclude>
<exclude>**/InvalidResultSetPointerTest.java</exclude> <exclude>**/InvalidResultSetPointerTest.java</exclude>
<exclude>**/RestfulConnectionTest.java</exclude> <exclude>**/RestfulConnectionTest.java</exclude>
<exclude>**/TD4144Test.java</exclude> <exclude>**/TSDBJNIConnectorTest.java</exclude>
<exclude>**/TaosInfoMonitorTest.java</exclude>
<exclude>**/UnsignedNumberJniTest.java</exclude>
</excludes> </excludes>
<testFailureIgnore>true</testFailureIgnore> <testFailureIgnore>true</testFailureIgnore>
</configuration> </configuration>
......
package com.taosdata.jdbc; package com.taosdata.jdbc;
import com.taosdata.jdbc.enums.TimestampFormat;
import java.sql.*; import java.sql.*;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.Map; import java.util.Map;
...@@ -18,7 +20,7 @@ public abstract class AbstractConnection extends WrapperImpl implements Connecti ...@@ -18,7 +20,7 @@ public abstract class AbstractConnection extends WrapperImpl implements Connecti
for (String propName : propNames) { for (String propName : propNames) {
clientInfoProps.setProperty(propName, properties.getProperty(propName)); clientInfoProps.setProperty(propName, properties.getProperty(propName));
} }
String timestampFormat = properties.getProperty(TSDBDriver.PROPERTY_KEY_TIMESTAMP_FORMAT, "STRING"); String timestampFormat = properties.getProperty(TSDBDriver.PROPERTY_KEY_TIMESTAMP_FORMAT, String.valueOf(TimestampFormat.STRING));
clientInfoProps.setProperty(TSDBDriver.PROPERTY_KEY_TIMESTAMP_FORMAT, timestampFormat); clientInfoProps.setProperty(TSDBDriver.PROPERTY_KEY_TIMESTAMP_FORMAT, timestampFormat);
} }
...@@ -304,9 +306,6 @@ public abstract class AbstractConnection extends WrapperImpl implements Connecti ...@@ -304,9 +306,6 @@ public abstract class AbstractConnection extends WrapperImpl implements Connecti
@Override @Override
public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
switch (resultSetHoldability) { switch (resultSetHoldability) {
case ResultSet.HOLD_CURSORS_OVER_COMMIT: case ResultSet.HOLD_CURSORS_OVER_COMMIT:
break; break;
...@@ -320,11 +319,7 @@ public abstract class AbstractConnection extends WrapperImpl implements Connecti ...@@ -320,11 +319,7 @@ public abstract class AbstractConnection extends WrapperImpl implements Connecti
} }
@Override @Override
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
switch (resultSetHoldability) { switch (resultSetHoldability) {
case ResultSet.HOLD_CURSORS_OVER_COMMIT: case ResultSet.HOLD_CURSORS_OVER_COMMIT:
break; break;
...@@ -423,7 +418,7 @@ public abstract class AbstractConnection extends WrapperImpl implements Connecti ...@@ -423,7 +418,7 @@ public abstract class AbstractConnection extends WrapperImpl implements Connecti
status = resultSet.getInt("server_status()"); status = resultSet.getInt("server_status()");
resultSet.close(); resultSet.close();
} }
return status == 1 ? true : false; return status == 1;
}); });
boolean status = false; boolean status = false;
...@@ -432,9 +427,7 @@ public abstract class AbstractConnection extends WrapperImpl implements Connecti ...@@ -432,9 +427,7 @@ public abstract class AbstractConnection extends WrapperImpl implements Connecti
status = future.get(); status = future.get();
else else
status = future.get(timeout, TimeUnit.SECONDS); status = future.get(timeout, TimeUnit.SECONDS);
} catch (InterruptedException e) { } catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace(); e.printStackTrace();
} catch (TimeoutException e) { } catch (TimeoutException e) {
future.cancel(true); future.cancel(true);
...@@ -450,7 +443,6 @@ public abstract class AbstractConnection extends WrapperImpl implements Connecti ...@@ -450,7 +443,6 @@ public abstract class AbstractConnection extends WrapperImpl implements Connecti
if (isClosed) if (isClosed)
throw (SQLClientInfoException) TSDBError.createSQLException(TSDBErrorNumbers.ERROR_SQLCLIENT_EXCEPTION_ON_CONNECTION_CLOSED); throw (SQLClientInfoException) TSDBError.createSQLException(TSDBErrorNumbers.ERROR_SQLCLIENT_EXCEPTION_ON_CONNECTION_CLOSED);
if (clientInfoProps != null)
clientInfoProps.setProperty(name, value); clientInfoProps.setProperty(name, value);
} }
...@@ -459,8 +451,8 @@ public abstract class AbstractConnection extends WrapperImpl implements Connecti ...@@ -459,8 +451,8 @@ public abstract class AbstractConnection extends WrapperImpl implements Connecti
if (isClosed) if (isClosed)
throw (SQLClientInfoException) TSDBError.createSQLException(TSDBErrorNumbers.ERROR_SQLCLIENT_EXCEPTION_ON_CONNECTION_CLOSED); throw (SQLClientInfoException) TSDBError.createSQLException(TSDBErrorNumbers.ERROR_SQLCLIENT_EXCEPTION_ON_CONNECTION_CLOSED);
for (Enumeration<Object> enumer = properties.keys(); enumer.hasMoreElements(); ) { for (Enumeration<Object> enumeration = properties.keys(); enumeration.hasMoreElements(); ) {
String name = (String) enumer.nextElement(); String name = (String) enumeration.nextElement();
clientInfoProps.put(name, properties.getProperty(name)); clientInfoProps.put(name, properties.getProperty(name));
} }
} }
...@@ -516,7 +508,6 @@ public abstract class AbstractConnection extends WrapperImpl implements Connecti ...@@ -516,7 +508,6 @@ public abstract class AbstractConnection extends WrapperImpl implements Connecti
public void abort(Executor executor) throws SQLException { public void abort(Executor executor) throws SQLException {
if (isClosed()) if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
// do nothing // do nothing
} }
...@@ -527,14 +518,13 @@ public abstract class AbstractConnection extends WrapperImpl implements Connecti ...@@ -527,14 +518,13 @@ public abstract class AbstractConnection extends WrapperImpl implements Connecti
if (milliseconds < 0) if (milliseconds < 0)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_VARIABLE); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_VARIABLE);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); // do nothing
} }
@Override @Override
public int getNetworkTimeout() throws SQLException { public int getNetworkTimeout() throws SQLException {
if (isClosed()) if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
return 0;
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
} }
} }
...@@ -58,7 +58,7 @@ public abstract class AbstractDriver implements Driver { ...@@ -58,7 +58,7 @@ public abstract class AbstractDriver implements Driver {
value = parameterValuePair.substring(indexOfEqual + 1); value = parameterValuePair.substring(indexOfEqual + 1);
} }
} }
if ((value != null && value.length() > 0) && (parameter != null && parameter.length() > 0)) { if (value != null && value.length() > 0 && parameter.length() > 0) {
urlProps.setProperty(parameter, value); urlProps.setProperty(parameter, value);
} }
} }
...@@ -87,7 +87,7 @@ public abstract class AbstractDriver implements Driver { ...@@ -87,7 +87,7 @@ public abstract class AbstractDriver implements Driver {
url = url.substring(0, indexOfColon); url = url.substring(0, indexOfColon);
} }
// parse host // parse host
if (url != null && url.length() > 0 && url.trim().length() > 0) { if (url.length() > 0 && url.trim().length() > 0) {
urlProps.setProperty(TSDBDriver.PROPERTY_KEY_HOST, url); urlProps.setProperty(TSDBDriver.PROPERTY_KEY_HOST, url);
} }
return urlProps; return urlProps;
......
...@@ -49,6 +49,22 @@ public abstract class AbstractParameterMetaData extends WrapperImpl implements P ...@@ -49,6 +49,22 @@ public abstract class AbstractParameterMetaData extends WrapperImpl implements P
if (param < 1 && param >= parameters.length) if (param < 1 && param >= parameters.length)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE);
if (parameters[param - 1] instanceof Boolean)
return TSDBConstants.BOOLEAN_PRECISION;
if (parameters[param - 1] instanceof Byte)
return TSDBConstants.TINYINT_PRECISION;
if (parameters[param - 1] instanceof Short)
return TSDBConstants.SMALLINT_PRECISION;
if (parameters[param - 1] instanceof Integer)
return TSDBConstants.INT_PRECISION;
if (parameters[param - 1] instanceof Long)
return TSDBConstants.BIGINT_PRECISION;
if (parameters[param - 1] instanceof Timestamp)
return TSDBConstants.TIMESTAMP_MS_PRECISION;
if (parameters[param - 1] instanceof Float)
return TSDBConstants.FLOAT_PRECISION;
if (parameters[param - 1] instanceof Double)
return TSDBConstants.DOUBLE_PRECISION;
if (parameters[param - 1] instanceof String) if (parameters[param - 1] instanceof String)
return ((String) parameters[param - 1]).length(); return ((String) parameters[param - 1]).length();
if (parameters[param - 1] instanceof byte[]) if (parameters[param - 1] instanceof byte[])
...@@ -60,6 +76,11 @@ public abstract class AbstractParameterMetaData extends WrapperImpl implements P ...@@ -60,6 +76,11 @@ public abstract class AbstractParameterMetaData extends WrapperImpl implements P
public int getScale(int param) throws SQLException { public int getScale(int param) throws SQLException {
if (param < 1 && param >= parameters.length) if (param < 1 && param >= parameters.length)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE);
if (parameters[param - 1] instanceof Float)
return TSDBConstants.FLOAT_SCALE;
if (parameters[param - 1] instanceof Double)
return TSDBConstants.DOUBLE_SCALE;
return 0; return 0;
} }
......
...@@ -66,10 +66,16 @@ public abstract class AbstractResultSet extends WrapperImpl implements ResultSet ...@@ -66,10 +66,16 @@ public abstract class AbstractResultSet extends WrapperImpl implements ResultSet
public abstract byte[] getBytes(int columnIndex) throws SQLException; public abstract byte[] getBytes(int columnIndex) throws SQLException;
@Override @Override
public abstract Date getDate(int columnIndex) throws SQLException; public Date getDate(int columnIndex) throws SQLException {
Timestamp timestamp = getTimestamp(columnIndex);
return timestamp == null ? null : new Date(timestamp.getTime());
}
@Override @Override
public abstract Time getTime(int columnIndex) throws SQLException; public Time getTime(int columnIndex) throws SQLException {
Timestamp timestamp = getTimestamp(columnIndex);
return timestamp == null ? null : new Time(timestamp.getTime());
}
@Override @Override
public abstract Timestamp getTimestamp(int columnIndex) throws SQLException; public abstract Timestamp getTimestamp(int columnIndex) throws SQLException;
......
...@@ -9,8 +9,6 @@ public abstract class AbstractStatement extends WrapperImpl implements Statement ...@@ -9,8 +9,6 @@ public abstract class AbstractStatement extends WrapperImpl implements Statement
protected List<String> batchedArgs; protected List<String> batchedArgs;
private int fetchSize; private int fetchSize;
@Override @Override
public abstract ResultSet executeQuery(String sql) throws SQLException; public abstract ResultSet executeQuery(String sql) throws SQLException;
......
...@@ -23,7 +23,7 @@ import java.util.Calendar; ...@@ -23,7 +23,7 @@ import java.util.Calendar;
import java.util.Map; import java.util.Map;
/* /*
* TDengine only supports a subset of the standard SQL, thus this implemetation of the * TDengine only supports a subset of the standard SQL, thus this implementation of the
* standard JDBC API contains more or less some adjustments customized for certain * standard JDBC API contains more or less some adjustments customized for certain
* compatibility needs. * compatibility needs.
*/ */
......
...@@ -20,7 +20,7 @@ import java.util.Properties; ...@@ -20,7 +20,7 @@ import java.util.Properties;
public class TSDBConnection extends AbstractConnection { public class TSDBConnection extends AbstractConnection {
private TSDBJNIConnector connector; private TSDBJNIConnector connector;
private TSDBDatabaseMetaData databaseMetaData; private final TSDBDatabaseMetaData databaseMetaData;
private boolean batchFetch; private boolean batchFetch;
public Boolean getBatchFetch() { public Boolean getBatchFetch() {
......
...@@ -41,22 +41,66 @@ public abstract class TSDBConstants { ...@@ -41,22 +41,66 @@ public abstract class TSDBConstants {
public static final int TSDB_DATA_TYPE_BINARY = 8; public static final int TSDB_DATA_TYPE_BINARY = 8;
public static final int TSDB_DATA_TYPE_TIMESTAMP = 9; public static final int TSDB_DATA_TYPE_TIMESTAMP = 9;
public static final int TSDB_DATA_TYPE_NCHAR = 10; public static final int TSDB_DATA_TYPE_NCHAR = 10;
/* /**
系统增加新的无符号数据类型,分别是: * 系统增加新的无符号数据类型,分别是:
unsigned tinyint, 数值范围:0-254, NULL 为255 * unsigned tinyint, 数值范围:0-254, NULL 为255
unsigned smallint,数值范围: 0-65534, NULL 为65535 * unsigned smallint,数值范围: 0-65534, NULL 为65535
unsigned int,数值范围:0-4294967294,NULL 为4294967295u * unsigned int,数值范围:0-4294967294,NULL 为4294967295u
unsigned bigint,数值范围:0-18446744073709551614u,NULL 为18446744073709551615u。 * unsigned bigint,数值范围:0-18446744073709551614u,NULL 为18446744073709551615u。
example: * example:
create table tb(ts timestamp, a tinyint unsigned, b smallint unsigned, c int unsigned, d bigint unsigned); * create table tb(ts timestamp, a tinyint unsigned, b smallint unsigned, c int unsigned, d bigint unsigned);
*/ */
public static final int TSDB_DATA_TYPE_UTINYINT = 11; //unsigned tinyint public static final int TSDB_DATA_TYPE_UTINYINT = 11; //unsigned tinyint
public static final int TSDB_DATA_TYPE_USMALLINT = 12; //unsigned smallint public static final int TSDB_DATA_TYPE_USMALLINT = 12; //unsigned smallint
public static final int TSDB_DATA_TYPE_UINT = 13; //unsigned int public static final int TSDB_DATA_TYPE_UINT = 13; //unsigned int
public static final int TSDB_DATA_TYPE_UBIGINT = 14; //unsigned bigint public static final int TSDB_DATA_TYPE_UBIGINT = 14; //unsigned bigint
// nchar column max length // nchar column max length
public static final int maxFieldSize = 16 * 1024; public static final int maxFieldSize = 16 * 1024;
// precision for data types, this is used for metadata
public static final int BOOLEAN_PRECISION = 1;
public static final int TINYINT_PRECISION = 4;
public static final int SMALLINT_PRECISION = 6;
public static final int INT_PRECISION = 11;
public static final int BIGINT_PRECISION = 20;
public static final int FLOAT_PRECISION = 12;
public static final int DOUBLE_PRECISION = 22;
public static final int TIMESTAMP_MS_PRECISION = 23;
public static final int TIMESTAMP_US_PRECISION = 26;
// scale for data types, this is used for metadata
public static final int FLOAT_SCALE = 31;
public static final int DOUBLE_SCALE = 31;
public static final String DEFAULT_PRECISION = "ms";
public static int typeName2JdbcType(String type) {
switch (type.toUpperCase()) {
case "TIMESTAMP":
return Types.TIMESTAMP;
case "INT":
return Types.INTEGER;
case "BIGINT":
return Types.BIGINT;
case "FLOAT":
return Types.FLOAT;
case "DOUBLE":
return Types.DOUBLE;
case "BINARY":
return Types.BINARY;
case "SMALLINT":
return Types.SMALLINT;
case "TINYINT":
return Types.TINYINT;
case "BOOL":
return Types.BOOLEAN;
case "NCHAR":
return Types.NCHAR;
default:
return Types.NULL;
}
}
public static int taosType2JdbcType(int taosType) throws SQLException { public static int taosType2JdbcType(int taosType) throws SQLException {
switch (taosType) { switch (taosType) {
case TSDBConstants.TSDB_DATA_TYPE_BOOL: case TSDBConstants.TSDB_DATA_TYPE_BOOL:
...@@ -88,7 +132,7 @@ public abstract class TSDBConstants { ...@@ -88,7 +132,7 @@ public abstract class TSDBConstants {
} }
public static String taosType2JdbcTypeName(int taosType) throws SQLException { public static String taosType2JdbcTypeName(int taosType) throws SQLException {
switch (taosType){ switch (taosType) {
case TSDBConstants.TSDB_DATA_TYPE_BOOL: case TSDBConstants.TSDB_DATA_TYPE_BOOL:
return "BOOL"; return "BOOL";
case TSDBConstants.TSDB_DATA_TYPE_UTINYINT: case TSDBConstants.TSDB_DATA_TYPE_UTINYINT:
...@@ -119,7 +163,7 @@ public abstract class TSDBConstants { ...@@ -119,7 +163,7 @@ public abstract class TSDBConstants {
} }
public static int jdbcType2TaosType(int jdbcType) throws SQLException { public static int jdbcType2TaosType(int jdbcType) throws SQLException {
switch (jdbcType){ switch (jdbcType) {
case Types.BOOLEAN: case Types.BOOLEAN:
return TSDBConstants.TSDB_DATA_TYPE_BOOL; return TSDBConstants.TSDB_DATA_TYPE_BOOL;
case Types.TINYINT: case Types.TINYINT:
...@@ -145,7 +189,7 @@ public abstract class TSDBConstants { ...@@ -145,7 +189,7 @@ public abstract class TSDBConstants {
} }
public static String jdbcType2TaosTypeName(int jdbcType) throws SQLException { public static String jdbcType2TaosTypeName(int jdbcType) throws SQLException {
switch (jdbcType){ switch (jdbcType) {
case Types.BOOLEAN: case Types.BOOLEAN:
return "BOOL"; return "BOOL";
case Types.TINYINT: case Types.TINYINT:
......
...@@ -20,8 +20,8 @@ import java.sql.SQLException; ...@@ -20,8 +20,8 @@ import java.sql.SQLException;
public class TSDBDatabaseMetaData extends AbstractDatabaseMetaData { public class TSDBDatabaseMetaData extends AbstractDatabaseMetaData {
private String url; private final String url;
private String userName; private final String userName;
private Connection conn; private Connection conn;
public TSDBDatabaseMetaData(String url, String userName) { public TSDBDatabaseMetaData(String url, String userName) {
......
...@@ -176,7 +176,7 @@ public class TSDBDriver extends AbstractDriver { ...@@ -176,7 +176,7 @@ public class TSDBDriver extends AbstractDriver {
int beginningOfSlashes = url.indexOf("//"); int beginningOfSlashes = url.indexOf("//");
int index = url.indexOf("?"); int index = url.indexOf("?");
if (index != -1) { if (index != -1) {
String paramString = url.substring(index + 1, url.length()); String paramString = url.substring(index + 1);
url = url.substring(0, index); url = url.substring(0, index);
StringTokenizer queryParams = new StringTokenizer(paramString, "&"); StringTokenizer queryParams = new StringTokenizer(paramString, "&");
while (queryParams.hasMoreElements()) { while (queryParams.hasMoreElements()) {
...@@ -213,7 +213,7 @@ public class TSDBDriver extends AbstractDriver { ...@@ -213,7 +213,7 @@ public class TSDBDriver extends AbstractDriver {
url = url.substring(0, indexOfColon); url = url.substring(0, indexOfColon);
} }
if (url != null && url.length() > 0 && url.trim().length() > 0) { if (url.length() > 0 && url.trim().length() > 0) {
urlProps.setProperty(TSDBDriver.PROPERTY_KEY_HOST, url); urlProps.setProperty(TSDBDriver.PROPERTY_KEY_HOST, url);
} }
...@@ -233,7 +233,7 @@ public class TSDBDriver extends AbstractDriver { ...@@ -233,7 +233,7 @@ public class TSDBDriver extends AbstractDriver {
return false; return false;
} }
public Logger getParentLogger() throws SQLFeatureNotSupportedException { public Logger getParentLogger() {
return null; return null;
} }
......
...@@ -8,7 +8,7 @@ import java.util.HashMap; ...@@ -8,7 +8,7 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
public class TSDBError { public class TSDBError {
private static Map<Integer, String> TSDBErrorMap = new HashMap<>(); private static final Map<Integer, String> TSDBErrorMap = new HashMap<>();
static { static {
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED, "connection already closed"); TSDBErrorMap.put(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED, "connection already closed");
...@@ -32,10 +32,10 @@ public class TSDBError { ...@@ -32,10 +32,10 @@ public class TSDBError {
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_INVALID_SQL, "invalid sql"); TSDBErrorMap.put(TSDBErrorNumbers.ERROR_INVALID_SQL, "invalid sql");
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE, "numeric value out of range"); TSDBErrorMap.put(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE, "numeric value out of range");
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_UNKNOWN_TAOS_TYPE_IN_TDENGINE, "unknown taos type in tdengine"); TSDBErrorMap.put(TSDBErrorNumbers.ERROR_UNKNOWN_TAOS_TYPE_IN_TDENGINE, "unknown taos type in tdengine");
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_UNKNOWN_TIMESTAMP_PERCISION, "unknown timestamp precision");
/**************************************************/
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_UNKNOWN, "unknown error"); TSDBErrorMap.put(TSDBErrorNumbers.ERROR_UNKNOWN, "unknown error");
/**************************************************/
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_SUBSCRIBE_FAILED, "failed to create subscription"); TSDBErrorMap.put(TSDBErrorNumbers.ERROR_SUBSCRIBE_FAILED, "failed to create subscription");
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_UNSUPPORTED_ENCODING, "Unsupported encoding"); TSDBErrorMap.put(TSDBErrorNumbers.ERROR_UNSUPPORTED_ENCODING, "Unsupported encoding");
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_JNI_TDENGINE_ERROR, "internal error of database"); TSDBErrorMap.put(TSDBErrorNumbers.ERROR_JNI_TDENGINE_ERROR, "internal error of database");
......
package com.taosdata.jdbc; package com.taosdata.jdbc;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set;
public class TSDBErrorNumbers { public class TSDBErrorNumbers {
...@@ -25,6 +26,7 @@ public class TSDBErrorNumbers { ...@@ -25,6 +26,7 @@ public class TSDBErrorNumbers {
public static final int ERROR_INVALID_SQL = 0x2313; // invalid sql public static final int ERROR_INVALID_SQL = 0x2313; // invalid sql
public static final int ERROR_NUMERIC_VALUE_OUT_OF_RANGE = 0x2314; // numeric value out of range public static final int ERROR_NUMERIC_VALUE_OUT_OF_RANGE = 0x2314; // numeric value out of range
public static final int ERROR_UNKNOWN_TAOS_TYPE_IN_TDENGINE = 0x2315; //unknown taos type in tdengine public static final int ERROR_UNKNOWN_TAOS_TYPE_IN_TDENGINE = 0x2315; //unknown taos type in tdengine
public static final int ERROR_UNKNOWN_TIMESTAMP_PERCISION = 0x2316; // unknown timestamp precision
public static final int ERROR_UNKNOWN = 0x2350; //unknown error public static final int ERROR_UNKNOWN = 0x2350; //unknown error
...@@ -38,10 +40,9 @@ public class TSDBErrorNumbers { ...@@ -38,10 +40,9 @@ public class TSDBErrorNumbers {
public static final int ERROR_JNI_FETCH_END = 0x2358; // fetch to the end of resultSet public static final int ERROR_JNI_FETCH_END = 0x2358; // fetch to the end of resultSet
public static final int ERROR_JNI_OUT_OF_MEMORY = 0x2359; // JNI alloc memory failed public static final int ERROR_JNI_OUT_OF_MEMORY = 0x2359; // JNI alloc memory failed
private static final HashSet<Integer> errorNumbers; private static final Set<Integer> errorNumbers = new HashSet();
static { static {
errorNumbers = new HashSet();
errorNumbers.add(ERROR_CONNECTION_CLOSED); errorNumbers.add(ERROR_CONNECTION_CLOSED);
errorNumbers.add(ERROR_UNSUPPORTED_METHOD); errorNumbers.add(ERROR_UNSUPPORTED_METHOD);
errorNumbers.add(ERROR_INVALID_VARIABLE); errorNumbers.add(ERROR_INVALID_VARIABLE);
...@@ -62,8 +63,8 @@ public class TSDBErrorNumbers { ...@@ -62,8 +63,8 @@ public class TSDBErrorNumbers {
errorNumbers.add(ERROR_INVALID_SQL); errorNumbers.add(ERROR_INVALID_SQL);
errorNumbers.add(ERROR_NUMERIC_VALUE_OUT_OF_RANGE); errorNumbers.add(ERROR_NUMERIC_VALUE_OUT_OF_RANGE);
errorNumbers.add(ERROR_UNKNOWN_TAOS_TYPE_IN_TDENGINE); errorNumbers.add(ERROR_UNKNOWN_TAOS_TYPE_IN_TDENGINE);
errorNumbers.add(ERROR_UNKNOWN_TIMESTAMP_PERCISION);
/*****************************************************/
errorNumbers.add(ERROR_SUBSCRIBE_FAILED); errorNumbers.add(ERROR_SUBSCRIBE_FAILED);
errorNumbers.add(ERROR_UNSUPPORTED_ENCODING); errorNumbers.add(ERROR_UNSUPPORTED_ENCODING);
errorNumbers.add(ERROR_JNI_TDENGINE_ERROR); errorNumbers.add(ERROR_JNI_TDENGINE_ERROR);
......
...@@ -16,27 +16,22 @@ ...@@ -16,27 +16,22 @@
*/ */
package com.taosdata.jdbc; package com.taosdata.jdbc;
import com.taosdata.jdbc.utils.TaosInfo;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.SQLWarning; import java.sql.SQLWarning;
import java.util.List; import java.util.List;
import com.taosdata.jdbc.utils.TaosInfo;
/** /**
* JNI connector * JNI connector
*/ */
public class TSDBJNIConnector { public class TSDBJNIConnector {
private static volatile Boolean isInitialized = false; private static volatile Boolean isInitialized = false;
private TaosInfo taosInfo = TaosInfo.getInstance(); private final TaosInfo taosInfo = TaosInfo.getInstance();
private long taos = TSDBConstants.JNI_NULL_POINTER; // Connection pointer used in C
// Connection pointer used in C private boolean isResultsetClosed; // result set status in current connection
private long taos = TSDBConstants.JNI_NULL_POINTER;
// result set status in current connection
private boolean isResultsetClosed;
private int affectedRows = -1; private int affectedRows = -1;
static { static {
...@@ -96,11 +91,9 @@ public class TSDBJNIConnector { ...@@ -96,11 +91,9 @@ public class TSDBJNIConnector {
/** /**
* Execute DML/DDL operation * Execute DML/DDL operation
*
* @throws SQLException
*/ */
public long executeQuery(String sql) throws SQLException { public long executeQuery(String sql) throws SQLException {
Long pSql = 0l; long pSql = 0L;
try { try {
pSql = this.executeQueryImp(sql.getBytes(TaosGlobalConfig.getCharset()), this.taos); pSql = this.executeQueryImp(sql.getBytes(TaosGlobalConfig.getCharset()), this.taos);
taosInfo.stmt_count_increment(); taosInfo.stmt_count_increment();
...@@ -161,7 +154,7 @@ public class TSDBJNIConnector { ...@@ -161,7 +154,7 @@ public class TSDBJNIConnector {
private native long getResultSetImp(long connection, long pSql); private native long getResultSetImp(long connection, long pSql);
public boolean isUpdateQuery(long pSql) { public boolean isUpdateQuery(long pSql) {
return isUpdateQueryImp(this.taos, pSql) == 1 ? true : false; return isUpdateQueryImp(this.taos, pSql) == 1;
} }
private native long isUpdateQueryImp(long connection, long pSql); private native long isUpdateQueryImp(long connection, long pSql);
...@@ -194,7 +187,9 @@ public class TSDBJNIConnector { ...@@ -194,7 +187,9 @@ public class TSDBJNIConnector {
* Get schema metadata * Get schema metadata
*/ */
public int getSchemaMetaData(long resultSet, List<ColumnMetaData> columnMetaData) { public int getSchemaMetaData(long resultSet, List<ColumnMetaData> columnMetaData) {
return this.getSchemaMetaDataImp(this.taos, resultSet, columnMetaData); int ret = this.getSchemaMetaDataImp(this.taos, resultSet, columnMetaData);
columnMetaData.forEach(column -> column.setColIndex(column.getColIndex() + 1));
return ret;
} }
private native int getSchemaMetaDataImp(long connection, long resultSet, List<ColumnMetaData> columnMetaData); private native int getSchemaMetaDataImp(long connection, long resultSet, List<ColumnMetaData> columnMetaData);
...@@ -215,9 +210,18 @@ public class TSDBJNIConnector { ...@@ -215,9 +210,18 @@ public class TSDBJNIConnector {
private native int fetchBlockImp(long connection, long resultSet, TSDBResultSetBlockData blockData); private native int fetchBlockImp(long connection, long resultSet, TSDBResultSetBlockData blockData);
/** /**
* Execute close operation from C to release connection pointer by JNI * Get Result Time Precision.
* *
* @throws SQLException * @return 0: ms, 1: us, 2: ns
*/
public int getResultTimePrecision(long sqlObj) {
return this.getResultTimePrecisionImp(this.taos, sqlObj);
}
private native int getResultTimePrecisionImp(long connection, long result);
/**
* Execute close operation from C to release connection pointer by JNI
*/ */
public void closeConnection() throws SQLException { public void closeConnection() throws SQLException {
int code = this.closeConnectionImp(this.taos); int code = this.closeConnectionImp(this.taos);
...@@ -256,8 +260,6 @@ public class TSDBJNIConnector { ...@@ -256,8 +260,6 @@ public class TSDBJNIConnector {
/** /**
* Unsubscribe, close a subscription * Unsubscribe, close a subscription
*
* @param subscription
*/ */
void unsubscribe(long subscription, boolean isKeep) { void unsubscribe(long subscription, boolean isKeep) {
unsubscribeImp(subscription, isKeep); unsubscribeImp(subscription, isKeep);
...@@ -270,20 +272,29 @@ public class TSDBJNIConnector { ...@@ -270,20 +272,29 @@ public class TSDBJNIConnector {
*/ */
public boolean validateCreateTableSql(String sql) { public boolean validateCreateTableSql(String sql) {
int res = validateCreateTableSqlImp(taos, sql.getBytes()); int res = validateCreateTableSqlImp(taos, sql.getBytes());
return res != 0 ? false : true; return res == 0;
} }
private native int validateCreateTableSqlImp(long connection, byte[] sqlBytes); private native int validateCreateTableSqlImp(long connection, byte[] sqlBytes);
public long prepareStmt(String sql) throws SQLException { public long prepareStmt(String sql) throws SQLException {
Long stmt = prepareStmtImp(sql.getBytes(), this.taos); long stmt;
if (stmt == TSDBConstants.JNI_TDENGINE_ERROR) { try {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_SQL); stmt = prepareStmtImp(sql.getBytes(), this.taos);
} else if (stmt == TSDBConstants.JNI_CONNECTION_NULL) { } catch (Exception e) {
e.printStackTrace();
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_ENCODING);
}
if (stmt == TSDBConstants.JNI_CONNECTION_NULL) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL);
} else if (stmt == TSDBConstants.JNI_SQL_NULL) { }
if (stmt == TSDBConstants.JNI_SQL_NULL) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_SQL_NULL); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_SQL_NULL);
} else if (stmt == TSDBConstants.JNI_OUT_OF_MEMORY) { }
if (stmt == TSDBConstants.JNI_OUT_OF_MEMORY) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_OUT_OF_MEMORY); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_OUT_OF_MEMORY);
} }
...@@ -311,7 +322,7 @@ public class TSDBJNIConnector { ...@@ -311,7 +322,7 @@ public class TSDBJNIConnector {
private native int setTableNameTagsImp(long stmt, String name, int numOfTags, byte[] tags, byte[] typeList, byte[] lengthList, byte[] nullList, long conn); private native int setTableNameTagsImp(long stmt, String name, int numOfTags, byte[] tags, byte[] typeList, byte[] lengthList, byte[] nullList, long conn);
public void bindColumnDataArray(long stmt, ByteBuffer colDataList, ByteBuffer lengthList, ByteBuffer isNullList, int type, int bytes, int numOfRows,int columnIndex) throws SQLException { public void bindColumnDataArray(long stmt, ByteBuffer colDataList, ByteBuffer lengthList, ByteBuffer isNullList, int type, int bytes, int numOfRows, int columnIndex) throws SQLException {
int code = bindColDataImp(stmt, colDataList.array(), lengthList.array(), isNullList.array(), type, bytes, numOfRows, columnIndex, this.taos); int code = bindColDataImp(stmt, colDataList.array(), lengthList.array(), isNullList.array(), type, bytes, numOfRows, columnIndex, this.taos);
if (code != TSDBConstants.JNI_SUCCESS) { if (code != TSDBConstants.JNI_SUCCESS) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "failed to bind column data"); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "failed to bind column data");
......
...@@ -38,7 +38,6 @@ import java.util.regex.Pattern; ...@@ -38,7 +38,6 @@ import java.util.regex.Pattern;
public class TSDBPreparedStatement extends TSDBStatement implements PreparedStatement { public class TSDBPreparedStatement extends TSDBStatement implements PreparedStatement {
private String rawSql; private String rawSql;
private Object[] parameters; private Object[] parameters;
private boolean isPrepared;
private ArrayList<ColumnInfo> colData; private ArrayList<ColumnInfo> colData;
private ArrayList<TableTagInfo> tableTags; private ArrayList<TableTagInfo> tableTags;
...@@ -47,8 +46,6 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat ...@@ -47,8 +46,6 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
private String tableName; private String tableName;
private long nativeStmtHandle = 0; private long nativeStmtHandle = 0;
private volatile TSDBParameterMetaData parameterMetaData;
TSDBPreparedStatement(TSDBConnection connection, String sql) { TSDBPreparedStatement(TSDBConnection connection, String sql) {
super(connection); super(connection);
init(sql); init(sql);
...@@ -61,13 +58,12 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat ...@@ -61,13 +58,12 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
} }
} }
parameters = new Object[parameterCnt]; parameters = new Object[parameterCnt];
this.isPrepared = true;
} }
if (parameterCnt > 1) { if (parameterCnt > 1) {
// the table name is also a parameter, so ignore it. // the table name is also a parameter, so ignore it.
this.colData = new ArrayList<ColumnInfo>(); this.colData = new ArrayList<>();
this.tableTags = new ArrayList<TableTagInfo>(); this.tableTags = new ArrayList<>();
} }
} }
...@@ -76,18 +72,17 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat ...@@ -76,18 +72,17 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
preprocessSql(); preprocessSql();
} }
@Override
public int[] executeBatch() throws SQLException {
return super.executeBatch();
}
/* /*
*
*/
/**
* Some of the SQLs sent by other popular frameworks or tools like Spark, contains syntax that cannot be parsed by * Some of the SQLs sent by other popular frameworks or tools like Spark, contains syntax that cannot be parsed by
* the TDengine client. Thus, some simple parsers/filters are intentionally added in this JDBC implementation in * the TDengine client. Thus, some simple parsers/filters are intentionally added in this JDBC implementation in
* order to process those supported SQLs. * order to process those supported SQLs.
*/ */
private void preprocessSql() { private void preprocessSql() {
/***** For processing some of Spark SQLs*****/ /***For processing some of Spark SQLs*/
// should replace it first // should replace it first
this.rawSql = this.rawSql.replaceAll("or (.*) is null", ""); this.rawSql = this.rawSql.replaceAll("or (.*) is null", "");
this.rawSql = this.rawSql.replaceAll(" where ", " WHERE "); this.rawSql = this.rawSql.replaceAll(" where ", " WHERE ");
...@@ -134,32 +129,17 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat ...@@ -134,32 +129,17 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
} }
rawSql = rawSql.replace(matcher.group(1), tableFullName); rawSql = rawSql.replace(matcher.group(1), tableFullName);
} }
/***** for inner queries *****/
}
/**
* Populate parameters into prepared sql statements
*
* @return a string of the native sql statement for TSDB
*/
private String getNativeSql(String rawSql) throws SQLException {
return Utils.getNativeSql(rawSql, this.parameters);
} }
@Override @Override
public ResultSet executeQuery() throws SQLException { public ResultSet executeQuery() throws SQLException {
if (!isPrepared) final String sql = Utils.getNativeSql(this.rawSql, this.parameters);
return executeQuery(this.rawSql);
final String sql = getNativeSql(this.rawSql);
return executeQuery(sql); return executeQuery(sql);
} }
@Override @Override
public int executeUpdate() throws SQLException { public int executeUpdate() throws SQLException {
if (!isPrepared) String sql = Utils.getNativeSql(this.rawSql, this.parameters);
return executeUpdate(this.rawSql);
String sql = getNativeSql(this.rawSql);
return executeUpdate(sql); return executeUpdate(sql);
} }
...@@ -205,9 +185,7 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat ...@@ -205,9 +185,7 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
@Override @Override
public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException { public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException {
if (isClosed()) setObject(parameterIndex, x.doubleValue());
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
} }
@Override @Override
...@@ -222,16 +200,12 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat ...@@ -222,16 +200,12 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
@Override @Override
public void setDate(int parameterIndex, Date x) throws SQLException { public void setDate(int parameterIndex, Date x) throws SQLException {
if (isClosed()) setObject(parameterIndex, new Timestamp(x.getTime()));
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
} }
@Override @Override
public void setTime(int parameterIndex, Time x) throws SQLException { public void setTime(int parameterIndex, Time x) throws SQLException {
if (isClosed()) setObject(parameterIndex, new Timestamp(x.getTime()));
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
} }
@Override @Override
...@@ -283,32 +257,20 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat ...@@ -283,32 +257,20 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
if (parameterIndex < 1 && parameterIndex >= parameters.length) { if (parameterIndex < 1 && parameterIndex >= parameters.length) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE);
} }
parameters[parameterIndex - 1] = x; parameters[parameterIndex - 1] = x;
} }
@Override @Override
public boolean execute() throws SQLException { public boolean execute() throws SQLException {
if (!isPrepared) final String sql = Utils.getNativeSql(this.rawSql, this.parameters);
return execute(this.rawSql);
final String sql = getNativeSql(this.rawSql);
return execute(sql); return execute(sql);
} }
@Override @Override
public void addBatch() throws SQLException { public void addBatch() throws SQLException {
if (this.batchedArgs == null) { String sql = Utils.getNativeSql(this.rawSql, this.parameters);
batchedArgs = new ArrayList<>();
}
if (!isPrepared) {
addBatch(this.rawSql);
} else {
String sql = this.getConnection().nativeSQL(this.rawSql);
addBatch(sql); addBatch(sql);
} }
}
@Override @Override
public void setCharacterStream(int parameterIndex, Reader reader, int length) throws SQLException { public void setCharacterStream(int parameterIndex, Reader reader, int length) throws SQLException {
...@@ -350,9 +312,9 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat ...@@ -350,9 +312,9 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
@Override @Override
public ResultSetMetaData getMetaData() throws SQLException { public ResultSetMetaData getMetaData() throws SQLException {
if (isClosed()) if (this.getResultSet() == null)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); return null;
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); return getResultSet().getMetaData();
} }
@Override @Override
...@@ -396,10 +358,7 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat ...@@ -396,10 +358,7 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
if (isClosed()) if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
if (parameterMetaData == null) { return new TSDBParameterMetaData(parameters);
this.parameterMetaData = new TSDBParameterMetaData(parameters);
}
return this.parameterMetaData;
} }
@Override @Override
...@@ -411,9 +370,7 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat ...@@ -411,9 +370,7 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
@Override @Override
public void setNString(int parameterIndex, String value) throws SQLException { public void setNString(int parameterIndex, String value) throws SQLException {
if (isClosed()) setString(parameterIndex, value);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
} }
@Override @Override
...@@ -563,12 +520,13 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat ...@@ -563,12 +520,13 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
public boolean isTypeSet() { public boolean isTypeSet() {
return this.typeIsSet; return this.typeIsSet;
} }
}; }
private static class TableTagInfo { private static class TableTagInfo {
private boolean isNull; private boolean isNull;
private Object value; private final Object value;
private int type; private final int type;
public TableTagInfo(Object value, int type) { public TableTagInfo(Object value, int type) {
this.value = value; this.value = value;
this.type = type; this.type = type;
...@@ -579,7 +537,7 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat ...@@ -579,7 +537,7 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
info.isNull = true; info.isNull = true;
return info; return info;
} }
}; }
public void setTableName(String name) { public void setTableName(String name) {
this.tableName = name; this.tableName = name;
...@@ -666,9 +624,9 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat ...@@ -666,9 +624,9 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
public <T> void setValueImpl(int columnIndex, ArrayList<T> list, int type, int bytes) throws SQLException { public <T> void setValueImpl(int columnIndex, ArrayList<T> list, int type, int bytes) throws SQLException {
if (this.colData.size() == 0) { if (this.colData.size() == 0) {
this.colData.addAll(Collections.nCopies(this.parameters.length - 1 - this.tableTags.size(), null)); this.colData.addAll(Collections.nCopies(this.parameters.length - 1 - this.tableTags.size(), null));
} }
ColumnInfo col = (ColumnInfo) this.colData.get(columnIndex);
ColumnInfo col = this.colData.get(columnIndex);
if (col == null) { if (col == null) {
ColumnInfo p = new ColumnInfo(); ColumnInfo p = new ColumnInfo();
p.setType(type); p.setType(type);
...@@ -759,8 +717,7 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat ...@@ -759,8 +717,7 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
ByteBuffer isNullList = ByteBuffer.allocate(num * Integer.BYTES); ByteBuffer isNullList = ByteBuffer.allocate(num * Integer.BYTES);
isNullList.order(ByteOrder.LITTLE_ENDIAN); isNullList.order(ByteOrder.LITTLE_ENDIAN);
for (int i = 0; i < num; ++i) { for (TableTagInfo tag : this.tableTags) {
TableTagInfo tag = this.tableTags.get(i);
if (tag.isNull) { if (tag.isNull) {
typeList.put((byte) tag.type); typeList.put((byte) tag.type);
isNullList.putInt(1); isNullList.putInt(1);
...@@ -852,14 +809,14 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat ...@@ -852,14 +809,14 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
} }
typeList.put((byte) tag.type); typeList.put((byte) tag.type);
isNullList.putInt(tag.isNull? 1 : 0); isNullList.putInt(tag.isNull ? 1 : 0);
} }
connector.setBindTableNameAndTags(this.nativeStmtHandle, this.tableName, this.tableTags.size(), tagDataList, connector.setBindTableNameAndTags(this.nativeStmtHandle, this.tableName, this.tableTags.size(), tagDataList,
typeList, lengthList, isNullList); typeList, lengthList, isNullList);
} }
ColumnInfo colInfo = (ColumnInfo) this.colData.get(0); ColumnInfo colInfo = this.colData.get(0);
if (colInfo == null) { if (colInfo == null) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "column data not bind"); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "column data not bind");
} }
...@@ -888,8 +845,8 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat ...@@ -888,8 +845,8 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
case TSDBConstants.TSDB_DATA_TYPE_INT: { case TSDBConstants.TSDB_DATA_TYPE_INT: {
for (int j = 0; j < rows; ++j) { for (int j = 0; j < rows; ++j) {
Integer val = (Integer) col1.data.get(j); Integer val = (Integer) col1.data.get(j);
colDataList.putInt(val == null? Integer.MIN_VALUE:val); colDataList.putInt(val == null ? Integer.MIN_VALUE : val);
isNullList.put((byte) (val == null? 1:0)); isNullList.put((byte) (val == null ? 1 : 0));
} }
break; break;
} }
...@@ -897,8 +854,8 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat ...@@ -897,8 +854,8 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
case TSDBConstants.TSDB_DATA_TYPE_TINYINT: { case TSDBConstants.TSDB_DATA_TYPE_TINYINT: {
for (int j = 0; j < rows; ++j) { for (int j = 0; j < rows; ++j) {
Byte val = (Byte) col1.data.get(j); Byte val = (Byte) col1.data.get(j);
colDataList.put(val == null? 0:val); colDataList.put(val == null ? 0 : val);
isNullList.put((byte) (val == null? 1:0)); isNullList.put((byte) (val == null ? 1 : 0));
} }
break; break;
} }
...@@ -909,10 +866,10 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat ...@@ -909,10 +866,10 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
if (val == null) { if (val == null) {
colDataList.put((byte) 0); colDataList.put((byte) 0);
} else { } else {
colDataList.put((byte) (val? 1:0)); colDataList.put((byte) (val ? 1 : 0));
} }
isNullList.put((byte) (val == null? 1:0)); isNullList.put((byte) (val == null ? 1 : 0));
} }
break; break;
} }
...@@ -920,8 +877,8 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat ...@@ -920,8 +877,8 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: { case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: {
for (int j = 0; j < rows; ++j) { for (int j = 0; j < rows; ++j) {
Short val = (Short) col1.data.get(j); Short val = (Short) col1.data.get(j);
colDataList.putShort(val == null? 0:val); colDataList.putShort(val == null ? 0 : val);
isNullList.put((byte) (val == null? 1:0)); isNullList.put((byte) (val == null ? 1 : 0));
} }
break; break;
} }
...@@ -930,8 +887,8 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat ...@@ -930,8 +887,8 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
case TSDBConstants.TSDB_DATA_TYPE_BIGINT: { case TSDBConstants.TSDB_DATA_TYPE_BIGINT: {
for (int j = 0; j < rows; ++j) { for (int j = 0; j < rows; ++j) {
Long val = (Long) col1.data.get(j); Long val = (Long) col1.data.get(j);
colDataList.putLong(val == null? 0:val); colDataList.putLong(val == null ? 0 : val);
isNullList.put((byte) (val == null? 1:0)); isNullList.put((byte) (val == null ? 1 : 0));
} }
break; break;
} }
...@@ -939,8 +896,8 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat ...@@ -939,8 +896,8 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
case TSDBConstants.TSDB_DATA_TYPE_FLOAT: { case TSDBConstants.TSDB_DATA_TYPE_FLOAT: {
for (int j = 0; j < rows; ++j) { for (int j = 0; j < rows; ++j) {
Float val = (Float) col1.data.get(j); Float val = (Float) col1.data.get(j);
colDataList.putFloat(val == null? 0:val); colDataList.putFloat(val == null ? 0 : val);
isNullList.put((byte) (val == null? 1:0)); isNullList.put((byte) (val == null ? 1 : 0));
} }
break; break;
} }
...@@ -948,8 +905,8 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat ...@@ -948,8 +905,8 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: { case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: {
for (int j = 0; j < rows; ++j) { for (int j = 0; j < rows; ++j) {
Double val = (Double) col1.data.get(j); Double val = (Double) col1.data.get(j);
colDataList.putDouble(val == null? 0:val); colDataList.putDouble(val == null ? 0 : val);
isNullList.put((byte) (val == null? 1:0)); isNullList.put((byte) (val == null ? 1 : 0));
} }
break; break;
} }
...@@ -994,7 +951,7 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat ...@@ -994,7 +951,7 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
case TSDBConstants.TSDB_DATA_TYPE_UBIGINT: { case TSDBConstants.TSDB_DATA_TYPE_UBIGINT: {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "not support data types"); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "not support data types");
} }
}; }
connector.bindColumnDataArray(this.nativeStmtHandle, colDataList, lengthList, isNullList, col1.type, col1.bytes, rows, i); connector.bindColumnDataArray(this.nativeStmtHandle, colDataList, lengthList, isNullList, col1.type, col1.bytes, rows, i);
} }
......
...@@ -133,9 +133,10 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { ...@@ -133,9 +133,10 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
if (this.getBatchFetch()) if (this.getBatchFetch())
return this.blockData.getString(columnIndex - 1); return this.blockData.getString(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(columnIndex - 1); this.lastWasNull = this.rowData.wasNull(columnIndex);
if (!lastWasNull) { if (!lastWasNull) {
res = this.rowData.getString(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType()); int nativeType = this.columnMetaDataList.get(columnIndex - 1).getColType();
res = this.rowData.getString(columnIndex, nativeType);
} }
return res; return res;
} }
...@@ -147,9 +148,10 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { ...@@ -147,9 +148,10 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
if (this.getBatchFetch()) if (this.getBatchFetch())
return this.blockData.getBoolean(columnIndex - 1); return this.blockData.getBoolean(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(columnIndex - 1); this.lastWasNull = this.rowData.wasNull(columnIndex);
if (!lastWasNull) { if (!lastWasNull) {
res = this.rowData.getBoolean(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType()); int nativeType = this.columnMetaDataList.get(columnIndex - 1).getColType();
res = this.rowData.getBoolean(columnIndex, nativeType);
} }
return res; return res;
} }
...@@ -161,9 +163,10 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { ...@@ -161,9 +163,10 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
if (this.getBatchFetch()) if (this.getBatchFetch())
return (byte) this.blockData.getInt(columnIndex - 1); return (byte) this.blockData.getInt(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(columnIndex - 1); this.lastWasNull = this.rowData.wasNull(columnIndex);
if (!lastWasNull) { if (!lastWasNull) {
res = (byte) this.rowData.getInt(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType()); int nativeType = this.columnMetaDataList.get(columnIndex - 1).getColType();
res = (byte) this.rowData.getInt(columnIndex, nativeType);
} }
return res; return res;
} }
...@@ -175,9 +178,10 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { ...@@ -175,9 +178,10 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
if (this.getBatchFetch()) if (this.getBatchFetch())
return (short) this.blockData.getInt(columnIndex - 1); return (short) this.blockData.getInt(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(columnIndex - 1); this.lastWasNull = this.rowData.wasNull(columnIndex);
if (!lastWasNull) { if (!lastWasNull) {
res = (short) this.rowData.getInt(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType()); int nativeType = this.columnMetaDataList.get(columnIndex - 1).getColType();
res = (short) this.rowData.getInt(columnIndex, nativeType);
} }
return res; return res;
} }
...@@ -189,9 +193,11 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { ...@@ -189,9 +193,11 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
if (this.getBatchFetch()) if (this.getBatchFetch())
return this.blockData.getInt(columnIndex - 1); return this.blockData.getInt(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(columnIndex);
if (!lastWasNull) { if (!lastWasNull) {
res = this.rowData.getInt(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType()); int nativeType = this.columnMetaDataList.get(columnIndex - 1).getColType();
res = this.rowData.getInt(columnIndex, nativeType);
} }
return res; return res;
} }
...@@ -203,13 +209,15 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { ...@@ -203,13 +209,15 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
if (this.getBatchFetch()) if (this.getBatchFetch())
return this.blockData.getLong(columnIndex - 1); return this.blockData.getLong(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(columnIndex - 1); this.lastWasNull = this.rowData.wasNull(columnIndex);
if (!lastWasNull) { if (!lastWasNull) {
Object value = this.rowData.get(columnIndex - 1); Object value = this.rowData.getObject(columnIndex);
if (value instanceof Timestamp) if (value instanceof Timestamp) {
res = ((Timestamp) value).getTime(); res = ((Timestamp) value).getTime();
else } else {
res = this.rowData.getLong(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType()); int nativeType = this.columnMetaDataList.get(columnIndex - 1).getColType();
res = this.rowData.getLong(columnIndex, nativeType);
}
} }
return res; return res;
} }
...@@ -221,9 +229,11 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { ...@@ -221,9 +229,11 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
if (this.getBatchFetch()) if (this.getBatchFetch())
return (float) this.blockData.getDouble(columnIndex - 1); return (float) this.blockData.getDouble(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(columnIndex - 1); this.lastWasNull = this.rowData.wasNull(columnIndex);
if (!lastWasNull) if (!lastWasNull) {
res = this.rowData.getFloat(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType()); int nativeType = this.columnMetaDataList.get(columnIndex - 1).getColType();
res = this.rowData.getFloat(columnIndex, nativeType);
}
return res; return res;
} }
...@@ -235,9 +245,10 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { ...@@ -235,9 +245,10 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
if (this.getBatchFetch()) if (this.getBatchFetch())
return this.blockData.getDouble(columnIndex - 1); return this.blockData.getDouble(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(columnIndex - 1); this.lastWasNull = this.rowData.wasNull(columnIndex);
if (!lastWasNull) { if (!lastWasNull) {
res = this.rowData.getDouble(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType()); int nativeType = this.columnMetaDataList.get(columnIndex - 1).getColType();
res = this.rowData.getDouble(columnIndex, nativeType);
} }
return res; return res;
} }
...@@ -245,34 +256,27 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { ...@@ -245,34 +256,27 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
public byte[] getBytes(int columnIndex) throws SQLException { public byte[] getBytes(int columnIndex) throws SQLException {
checkAvailability(columnIndex, this.columnMetaDataList.size()); checkAvailability(columnIndex, this.columnMetaDataList.size());
Object value = this.rowData.get(columnIndex - 1); Object value = this.rowData.getObject(columnIndex);
if (value == null) if (value == null)
return null; return null;
int colType = this.columnMetaDataList.get(columnIndex - 1).getColType(); int nativeType = this.columnMetaDataList.get(columnIndex - 1).getColType();
switch (colType) { switch (nativeType) {
case TSDBConstants.TSDB_DATA_TYPE_BIGINT: case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
return Longs.toByteArray((Long) value); return Longs.toByteArray((long) value);
case TSDBConstants.TSDB_DATA_TYPE_INT: case TSDBConstants.TSDB_DATA_TYPE_INT:
return Ints.toByteArray((int) value); return Ints.toByteArray((int) value);
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: case TSDBConstants.TSDB_DATA_TYPE_SMALLINT:
return Shorts.toByteArray((Short) value); return Shorts.toByteArray((short) value);
case TSDBConstants.TSDB_DATA_TYPE_TINYINT: case TSDBConstants.TSDB_DATA_TYPE_TINYINT:
return new byte[]{(byte) value}; return new byte[]{(byte) value};
} case TSDBConstants.TSDB_DATA_TYPE_BINARY:
return (byte[]) value;
case TSDBConstants.TSDB_DATA_TYPE_BOOL:
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
default:
return value.toString().getBytes(); return value.toString().getBytes();
} }
@Override
public Date getDate(int columnIndex) throws SQLException {
Timestamp timestamp = getTimestamp(columnIndex);
return timestamp == null ? null : new Date(timestamp.getTime());
}
@Override
public Time getTime(int columnIndex) throws SQLException {
Timestamp timestamp = getTimestamp(columnIndex);
return timestamp == null ? null : new Time(timestamp.getTime());
} }
public Timestamp getTimestamp(int columnIndex) throws SQLException { public Timestamp getTimestamp(int columnIndex) throws SQLException {
...@@ -282,9 +286,10 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { ...@@ -282,9 +286,10 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
if (this.getBatchFetch()) if (this.getBatchFetch())
return this.blockData.getTimestamp(columnIndex - 1); return this.blockData.getTimestamp(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(columnIndex - 1); this.lastWasNull = this.rowData.wasNull(columnIndex);
if (!lastWasNull) { if (!lastWasNull) {
res = this.rowData.getTimestamp(columnIndex - 1); int nativeType = this.columnMetaDataList.get(columnIndex - 1).getColType();
res = this.rowData.getTimestamp(columnIndex, nativeType);
} }
return res; return res;
} }
...@@ -304,13 +309,9 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { ...@@ -304,13 +309,9 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
if (this.getBatchFetch()) if (this.getBatchFetch())
return this.blockData.get(columnIndex - 1); return this.blockData.get(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(columnIndex - 1); this.lastWasNull = this.rowData.wasNull(columnIndex);
if (!lastWasNull) { if (!lastWasNull) {
int colType = this.columnMetaDataList.get(columnIndex - 1).getColType(); res = this.rowData.getObject(columnIndex);
if (colType == TSDBConstants.TSDB_DATA_TYPE_BINARY)
res = ((String) this.rowData.get(columnIndex - 1)).getBytes();
else
res = this.rowData.get(columnIndex - 1);
} }
return res; return res;
} }
...@@ -318,7 +319,7 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { ...@@ -318,7 +319,7 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
public int findColumn(String columnLabel) throws SQLException { public int findColumn(String columnLabel) throws SQLException {
for (ColumnMetaData colMetaData : this.columnMetaDataList) { for (ColumnMetaData colMetaData : this.columnMetaDataList) {
if (colMetaData.getColName() != null && colMetaData.getColName().equalsIgnoreCase(columnLabel)) { if (colMetaData.getColName() != null && colMetaData.getColName().equalsIgnoreCase(columnLabel)) {
return colMetaData.getColIndex() + 1; return colMetaData.getColIndex();
} }
} }
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_VARIABLE); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_VARIABLE);
...@@ -329,25 +330,25 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { ...@@ -329,25 +330,25 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
if (this.getBatchFetch()) if (this.getBatchFetch())
return new BigDecimal(this.blockData.getLong(columnIndex - 1)); return new BigDecimal(this.blockData.getLong(columnIndex - 1));
this.lastWasNull = this.rowData.wasNull(columnIndex - 1); this.lastWasNull = this.rowData.wasNull(columnIndex);
BigDecimal res = null; BigDecimal res = null;
if (!lastWasNull) { if (!lastWasNull) {
int colType = this.columnMetaDataList.get(columnIndex - 1).getColType(); int nativeType = this.columnMetaDataList.get(columnIndex - 1).getColType();
switch (colType) { switch (nativeType) {
case TSDBConstants.TSDB_DATA_TYPE_TINYINT: case TSDBConstants.TSDB_DATA_TYPE_TINYINT:
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: case TSDBConstants.TSDB_DATA_TYPE_SMALLINT:
case TSDBConstants.TSDB_DATA_TYPE_INT: case TSDBConstants.TSDB_DATA_TYPE_INT:
case TSDBConstants.TSDB_DATA_TYPE_BIGINT: case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
res = new BigDecimal(Long.valueOf(this.rowData.get(columnIndex - 1).toString())); res = new BigDecimal(Long.parseLong(this.rowData.getObject(columnIndex).toString()));
break; break;
case TSDBConstants.TSDB_DATA_TYPE_FLOAT: case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: case TSDBConstants.TSDB_DATA_TYPE_DOUBLE:
res = new BigDecimal(Double.valueOf(this.rowData.get(columnIndex - 1).toString())); res = BigDecimal.valueOf(Double.parseDouble(this.rowData.getObject(columnIndex).toString()));
break; break;
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
return new BigDecimal(((Timestamp) this.rowData.get(columnIndex - 1)).getTime()); return new BigDecimal(((Timestamp) this.rowData.getObject(columnIndex)).getTime());
default: default:
res = new BigDecimal(this.rowData.get(columnIndex - 1).toString()); res = new BigDecimal(this.rowData.getObject(columnIndex).toString());
} }
} }
return res; return res;
......
...@@ -36,23 +36,20 @@ public class TSDBResultSetBlockData { ...@@ -36,23 +36,20 @@ public class TSDBResultSetBlockData {
private int rowIndex = 0; private int rowIndex = 0;
private List<ColumnMetaData> columnMetaDataList; private List<ColumnMetaData> columnMetaDataList;
private ArrayList<Object> colData = null; private ArrayList<Object> colData;
public TSDBResultSetBlockData(List<ColumnMetaData> colMeta, int numOfCols) { public TSDBResultSetBlockData(List<ColumnMetaData> colMeta, int numOfCols) {
this.columnMetaDataList = colMeta; this.columnMetaDataList = colMeta;
this.colData = new ArrayList<Object>(numOfCols); this.colData = new ArrayList<>(numOfCols);
} }
public TSDBResultSetBlockData() { public TSDBResultSetBlockData() {
this.colData = new ArrayList<Object>(); this.colData = new ArrayList<>();
} }
public void clear() { public void clear() {
int size = this.colData.size(); int size = this.colData.size();
if (this.colData != null) {
this.colData.clear(); this.colData.clear();
}
setNumOfCols(size); setNumOfCols(size);
} }
...@@ -69,7 +66,7 @@ public class TSDBResultSetBlockData { ...@@ -69,7 +66,7 @@ public class TSDBResultSetBlockData {
} }
public void setNumOfCols(int numOfCols) { public void setNumOfCols(int numOfCols) {
this.colData = new ArrayList<Object>(numOfCols); this.colData = new ArrayList<>(numOfCols);
this.colData.addAll(Collections.nCopies(numOfCols, null)); this.colData.addAll(Collections.nCopies(numOfCols, null));
} }
...@@ -167,14 +164,9 @@ public class TSDBResultSetBlockData { ...@@ -167,14 +164,9 @@ public class TSDBResultSetBlockData {
} }
/** /**
* The original type may not be a string type, but will be converted to by * The original type may not be a string type, but will be converted to by
* calling this method * calling this method
*
* @param col column index
* @return
* @throws SQLException
*/ */
public String getString(int col) throws SQLException { public String getString(int col) throws SQLException {
Object obj = get(col); Object obj = get(col);
...@@ -387,7 +379,7 @@ public class TSDBResultSetBlockData { ...@@ -387,7 +379,7 @@ public class TSDBResultSetBlockData {
return null; return null;
} }
return (long) val; return val;
} }
case TSDBConstants.TSDB_DATA_TYPE_FLOAT: { case TSDBConstants.TSDB_DATA_TYPE_FLOAT: {
......
...@@ -41,10 +41,7 @@ public class TSDBResultSetMetaData extends WrapperImpl implements ResultSetMetaD ...@@ -41,10 +41,7 @@ public class TSDBResultSetMetaData extends WrapperImpl implements ResultSetMetaD
} }
public boolean isSearchable(int column) throws SQLException { public boolean isSearchable(int column) throws SQLException {
if (column == 1) { return column == 1;
return true;
}
return false;
} }
public boolean isCurrency(int column) throws SQLException { public boolean isCurrency(int column) throws SQLException {
...@@ -113,6 +110,7 @@ public class TSDBResultSetMetaData extends WrapperImpl implements ResultSetMetaD ...@@ -113,6 +110,7 @@ public class TSDBResultSetMetaData extends WrapperImpl implements ResultSetMetaD
ColumnMetaData columnMetaData = this.colMetaDataList.get(column - 1); ColumnMetaData columnMetaData = this.colMetaDataList.get(column - 1);
switch (columnMetaData.getColType()) { switch (columnMetaData.getColType()) {
case TSDBConstants.TSDB_DATA_TYPE_FLOAT: case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
return 5; return 5;
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: case TSDBConstants.TSDB_DATA_TYPE_DOUBLE:
......
...@@ -14,19 +14,22 @@ ...@@ -14,19 +14,22 @@
*****************************************************************************/ *****************************************************************************/
package com.taosdata.jdbc; package com.taosdata.jdbc;
import com.taosdata.jdbc.utils.NullType;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.time.Instant;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
public class TSDBResultSetRowData { public class TSDBResultSetRowData {
private ArrayList<Object> data; private ArrayList<Object> data;
private int colSize = 0; private final int colSize;
public TSDBResultSetRowData(int colSize) { public TSDBResultSetRowData(int colSize) {
this.setColSize(colSize); this.colSize = colSize;
this.clear();
} }
public void clear() { public void clear() {
...@@ -41,129 +44,191 @@ public class TSDBResultSetRowData { ...@@ -41,129 +44,191 @@ public class TSDBResultSetRowData {
} }
public boolean wasNull(int col) { public boolean wasNull(int col) {
return data.get(col) == null; return data.get(col - 1) == null;
}
/**
* $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api
*/
public void setBooleanValue(int col, boolean value) {
setBoolean(col - 1, value);
} }
/**
* !!! this method is invoked by JNI method and the index start from 0 in C implementations
*/
public void setBoolean(int col, boolean value) { public void setBoolean(int col, boolean value) {
data.set(col, value); data.set(col, value);
} }
public boolean getBoolean(int col, int srcType) throws SQLException { public boolean getBoolean(int col, int nativeType) throws SQLException {
Object obj = data.get(col); Object obj = data.get(col - 1);
switch (srcType) { switch (nativeType) {
case TSDBConstants.TSDB_DATA_TYPE_BOOL: case TSDBConstants.TSDB_DATA_TYPE_BOOL:
return (Boolean) obj; return (Boolean) obj;
case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
return ((Float) obj) == 1.0 ? Boolean.TRUE : Boolean.FALSE;
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE:
return ((Double) obj) == 1.0 ? Boolean.TRUE : Boolean.FALSE;
case TSDBConstants.TSDB_DATA_TYPE_TINYINT: case TSDBConstants.TSDB_DATA_TYPE_TINYINT:
return ((Byte) obj) == 1 ? Boolean.TRUE : Boolean.FALSE; return ((Byte) obj) == 1 ? Boolean.TRUE : Boolean.FALSE;
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: case TSDBConstants.TSDB_DATA_TYPE_SMALLINT:
return ((Short) obj) == 1 ? Boolean.TRUE : Boolean.FALSE; return ((Short) obj) == 1 ? Boolean.TRUE : Boolean.FALSE;
case TSDBConstants.TSDB_DATA_TYPE_INT: case TSDBConstants.TSDB_DATA_TYPE_INT:
return ((Integer) obj) == 1 ? Boolean.TRUE : Boolean.FALSE; return ((Integer) obj) == 1 ? Boolean.TRUE : Boolean.FALSE;
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
case TSDBConstants.TSDB_DATA_TYPE_BIGINT: case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
return ((Long) obj) == 1L ? Boolean.TRUE : Boolean.FALSE; return ((Long) obj) == 1L ? Boolean.TRUE : Boolean.FALSE;
case TSDBConstants.TSDB_DATA_TYPE_BINARY:
case TSDBConstants.TSDB_DATA_TYPE_NCHAR: {
return obj.toString().contains("1");
}
default: default:
return false; return false;
} }
} }
/**
* $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api
*/
public void setByteValue(int colIndex, byte value) {
setByte(colIndex - 1, value);
}
/**
* !!! this method is invoked by JNI method and the index start from 0 in C implementations
*/
public void setByte(int col, byte value) { public void setByte(int col, byte value) {
data.set(col, value); data.set(col, value);
} }
/**
* $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api
*/
public void setShortValue(int colIndex, short value) {
setShort(colIndex - 1, value);
}
/**
* !!! this method is invoked by JNI method and the index start from 0 in C implementations
*/
public void setShort(int col, short value) { public void setShort(int col, short value) {
data.set(col, value); data.set(col, value);
} }
/**
* $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api
*/
public void setIntValue(int colIndex, int value) {
setInt(colIndex - 1, value);
}
/**
* !!! this method is invoked by JNI method and the index start from 0 in C implementations
*/
public void setInt(int col, int value) { public void setInt(int col, int value) {
data.set(col, value); data.set(col, value);
} }
@SuppressWarnings("deprecation") public int getInt(int col, int nativeType) throws SQLException {
public int getInt(int col, int srcType) throws SQLException { Object obj = data.get(col - 1);
Object obj = data.get(col); if (obj == null)
return NullType.getIntNull();
switch (srcType) { switch (nativeType) {
case TSDBConstants.TSDB_DATA_TYPE_BOOL: case TSDBConstants.TSDB_DATA_TYPE_BOOL:
return Boolean.TRUE.equals(obj) ? 1 : 0; return Boolean.TRUE.equals(obj) ? 1 : 0;
case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
return ((Float) obj).intValue();
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE:
return ((Double) obj).intValue();
case TSDBConstants.TSDB_DATA_TYPE_TINYINT: case TSDBConstants.TSDB_DATA_TYPE_TINYINT:
return (Byte) obj; return (Byte) obj;
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: case TSDBConstants.TSDB_DATA_TYPE_SMALLINT:
return (Short) obj; return (Short) obj;
case TSDBConstants.TSDB_DATA_TYPE_INT: case TSDBConstants.TSDB_DATA_TYPE_INT:
return (Integer) obj; return (Integer) obj;
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
case TSDBConstants.TSDB_DATA_TYPE_BIGINT: case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
return ((Long) obj).intValue(); return ((Long) obj).intValue();
case TSDBConstants.TSDB_DATA_TYPE_NCHAR: case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
case TSDBConstants.TSDB_DATA_TYPE_BINARY: case TSDBConstants.TSDB_DATA_TYPE_BINARY:
return Integer.parseInt((String) obj); return Integer.parseInt((String) obj);
case TSDBConstants.TSDB_DATA_TYPE_UTINYINT: { case TSDBConstants.TSDB_DATA_TYPE_UTINYINT:
Byte value = (byte) obj; return parseUnsignedTinyIntToInt(obj);
case TSDBConstants.TSDB_DATA_TYPE_USMALLINT:
return parseUnsignedSmallIntToInt(obj);
case TSDBConstants.TSDB_DATA_TYPE_UINT:
return parseUnsignedIntegerToInt(obj);
case TSDBConstants.TSDB_DATA_TYPE_UBIGINT:
return parseUnsignedBigIntToInt(obj);
case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
return ((Float) obj).intValue();
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE:
return ((Double) obj).intValue();
default:
return 0;
}
}
private byte parseUnsignedTinyIntToInt(Object obj) throws SQLException {
byte value = (byte) obj;
if (value < 0) if (value < 0)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE);
return value; return value;
} }
case TSDBConstants.TSDB_DATA_TYPE_USMALLINT: {
private short parseUnsignedSmallIntToInt(Object obj) throws SQLException {
short value = (short) obj; short value = (short) obj;
if (value < 0) if (value < 0)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE);
return value; return value;
} }
case TSDBConstants.TSDB_DATA_TYPE_UINT: {
private int parseUnsignedIntegerToInt(Object obj) throws SQLException {
int value = (int) obj; int value = (int) obj;
if (value < 0) if (value < 0)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE);
return value; return value;
} }
case TSDBConstants.TSDB_DATA_TYPE_UBIGINT: {
private int parseUnsignedBigIntToInt(Object obj) throws SQLException {
long value = (long) obj; long value = (long) obj;
if (value < 0) if (value < 0)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE);
return Long.valueOf(value).intValue(); return Long.valueOf(value).intValue();
} }
}
return 0;
/**
* $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api
*/
public void setLongValue(int colIndex, long value) {
setLong(colIndex - 1, value);
} }
/**
* !!! this method is invoked by JNI method and the index start from 0 in C implementations
*/
public void setLong(int col, long value) { public void setLong(int col, long value) {
data.set(col, value); data.set(col, value);
} }
public long getLong(int col, int srcType) throws SQLException { public long getLong(int col, int nativeType) throws SQLException {
Object obj = data.get(col); Object obj = data.get(col - 1);
if (obj == null) {
return NullType.getBigIntNull();
}
switch (srcType) { switch (nativeType) {
case TSDBConstants.TSDB_DATA_TYPE_BOOL: case TSDBConstants.TSDB_DATA_TYPE_BOOL:
return Boolean.TRUE.equals(obj) ? 1 : 0; return Boolean.TRUE.equals(obj) ? 1 : 0;
case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
return ((Float) obj).longValue();
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE:
return ((Double) obj).longValue();
case TSDBConstants.TSDB_DATA_TYPE_TINYINT: case TSDBConstants.TSDB_DATA_TYPE_TINYINT:
return (Byte) obj; return (Byte) obj;
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: case TSDBConstants.TSDB_DATA_TYPE_SMALLINT:
return (Short) obj; return (Short) obj;
case TSDBConstants.TSDB_DATA_TYPE_INT: case TSDBConstants.TSDB_DATA_TYPE_INT:
return (Integer) obj; return (Integer) obj;
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
case TSDBConstants.TSDB_DATA_TYPE_BIGINT: case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
return (Long) obj; return (Long) obj;
case TSDBConstants.TSDB_DATA_TYPE_NCHAR: case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
case TSDBConstants.TSDB_DATA_TYPE_BINARY: case TSDBConstants.TSDB_DATA_TYPE_BINARY:
return Long.parseLong((String) obj); return Long.parseLong((String) obj);
case TSDBConstants.TSDB_DATA_TYPE_UTINYINT: { case TSDBConstants.TSDB_DATA_TYPE_UTINYINT: {
Byte value = (byte) obj; byte value = (byte) obj;
if (value < 0) if (value < 0)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE);
return value; return value;
...@@ -186,19 +251,35 @@ public class TSDBResultSetRowData { ...@@ -186,19 +251,35 @@ public class TSDBResultSetRowData {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE);
return value; return value;
} }
case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
return ((Float) obj).longValue();
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE:
return ((Double) obj).longValue();
default:
return 0;
}
} }
return 0; /**
* $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api
*/
public void setFloatValue(int colIndex, float value) {
setFloat(colIndex - 1, value);
} }
/**
* !!! this method is invoked by JNI method and the index start from 0 in C implementations
*/
public void setFloat(int col, float value) { public void setFloat(int col, float value) {
data.set(col, value); data.set(col, value);
} }
public float getFloat(int col, int srcType) { public float getFloat(int col, int nativeType) {
Object obj = data.get(col); Object obj = data.get(col - 1);
if (obj == null)
return NullType.getFloatNull();
switch (srcType) { switch (nativeType) {
case TSDBConstants.TSDB_DATA_TYPE_BOOL: case TSDBConstants.TSDB_DATA_TYPE_BOOL:
return Boolean.TRUE.equals(obj) ? 1 : 0; return Boolean.TRUE.equals(obj) ? 1 : 0;
case TSDBConstants.TSDB_DATA_TYPE_FLOAT: case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
...@@ -214,19 +295,31 @@ public class TSDBResultSetRowData { ...@@ -214,19 +295,31 @@ public class TSDBResultSetRowData {
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
case TSDBConstants.TSDB_DATA_TYPE_BIGINT: case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
return (Long) obj; return (Long) obj;
default:
return NullType.getFloatNull();
}
} }
return 0; /**
* $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api
*/
public void setDoubleValue(int colIndex, double value) {
setDouble(colIndex - 1, value);
} }
/**
* !!! this method is invoked by JNI method and the index start from 0 in C implementations
*/
public void setDouble(int col, double value) { public void setDouble(int col, double value) {
data.set(col, value); data.set(col, value);
} }
public double getDouble(int col, int srcType) { public double getDouble(int col, int nativeType) {
Object obj = data.get(col); Object obj = data.get(col - 1);
if (obj == null)
return NullType.getDoubleNull();
switch (srcType) { switch (nativeType) {
case TSDBConstants.TSDB_DATA_TYPE_BOOL: case TSDBConstants.TSDB_DATA_TYPE_BOOL:
return Boolean.TRUE.equals(obj) ? 1 : 0; return Boolean.TRUE.equals(obj) ? 1 : 0;
case TSDBConstants.TSDB_DATA_TYPE_FLOAT: case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
...@@ -242,16 +335,46 @@ public class TSDBResultSetRowData { ...@@ -242,16 +335,46 @@ public class TSDBResultSetRowData {
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
case TSDBConstants.TSDB_DATA_TYPE_BIGINT: case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
return (Long) obj; return (Long) obj;
default:
return NullType.getDoubleNull();
}
} }
return 0; /**
* $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api
*/
public void setStringValue(int colIndex, String value) {
data.set(colIndex - 1, value);
} }
/**
* !!! this method is invoked by JNI method and the index start from 0 in C implementations
*/
public void setString(int col, String value) { public void setString(int col, String value) {
data.set(col, value); // TODO:
// !!!NOTE!!!
// this is very confusing problem which related to JNI-method implementation,
// the JNI method return a String(encoded in UTF) for BINARY value, which means the JNI method will invoke
// this setString(int, String) to handle BINARY value, we need to build a byte[] with default charsetEncoding
data.set(col, value == null ? null : value.getBytes());
}
/**
* $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api
*/
public void setByteArrayValue(int colIndex, byte[] value) {
setByteArray(colIndex - 1, value);
} }
/**
* !!! this method is invoked by JNI method and the index start from 0 in C implementations
*/
public void setByteArray(int col, byte[] value) { public void setByteArray(int col, byte[] value) {
// TODO:
// !!!NOTE!!!
// this is very confusing problem which related to JNI-method implementation,
// the JNI method return a byte[] for NCHAR value, which means the JNI method will invoke
// this setByteArr(int, byte[]) to handle NCHAR value, we need to build a String with charsetEncoding by TaosGlobalConfig
try { try {
data.set(col, new String(value, TaosGlobalConfig.getCharset())); data.set(col, new String(value, TaosGlobalConfig.getCharset()));
} catch (Exception e) { } catch (Exception e) {
...@@ -259,85 +382,99 @@ public class TSDBResultSetRowData { ...@@ -259,85 +382,99 @@ public class TSDBResultSetRowData {
} }
} }
/** public String getString(int col, int nativeType) {
* The original type may not be a string type, but will be converted to by calling this method Object obj = data.get(col - 1);
* if (obj == null)
* @param col column index return null;
* @return
*/ switch (nativeType) {
public String getString(int col, int srcType) {
switch (srcType) {
case TSDBConstants.TSDB_DATA_TYPE_BINARY:
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
return (String) data.get(col);
case TSDBConstants.TSDB_DATA_TYPE_UTINYINT: { case TSDBConstants.TSDB_DATA_TYPE_UTINYINT: {
Byte value = new Byte(String.valueOf(data.get(col))); byte value = new Byte(String.valueOf(obj));
if (value >= 0) if (value >= 0)
return value.toString(); return Byte.toString(value);
return Integer.toString(value & 0xff); return Integer.toString(value & 0xff);
} }
case TSDBConstants.TSDB_DATA_TYPE_USMALLINT: { case TSDBConstants.TSDB_DATA_TYPE_USMALLINT: {
Short value = new Short(String.valueOf(data.get(col))); short value = new Short(String.valueOf(obj));
if (value >= 0) if (value >= 0)
return value.toString(); return Short.toString(value);
return Integer.toString(value & 0xffff); return Integer.toString(value & 0xffff);
} }
case TSDBConstants.TSDB_DATA_TYPE_UINT: { case TSDBConstants.TSDB_DATA_TYPE_UINT: {
Integer value = new Integer(String.valueOf(data.get(col))); int value = new Integer(String.valueOf(obj));
if (value >= 0) if (value >= 0)
return value.toString(); return Integer.toString(value);
return Long.toString(value & 0xffffffffl); return Long.toString(value & 0xffffffffL);
} }
case TSDBConstants.TSDB_DATA_TYPE_UBIGINT: { case TSDBConstants.TSDB_DATA_TYPE_UBIGINT: {
Long value = new Long(String.valueOf(data.get(col))); long value = new Long(String.valueOf(obj));
if (value >= 0) if (value >= 0)
return value.toString(); return Long.toString(value);
long lowValue = value & 0x7fffffffffffffffL; long lowValue = value & 0x7fffffffffffffffL;
return BigDecimal.valueOf(lowValue).add(BigDecimal.valueOf(Long.MAX_VALUE)).add(BigDecimal.valueOf(1)).toString(); return BigDecimal.valueOf(lowValue).add(BigDecimal.valueOf(Long.MAX_VALUE)).add(BigDecimal.valueOf(1)).toString();
} }
case TSDBConstants.TSDB_DATA_TYPE_BINARY:
return new String((byte[]) obj);
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
return (String) obj;
default: default:
return String.valueOf(data.get(col)); return String.valueOf(obj);
} }
} }
public void setTimestamp(int col, long ts) { /**
//TODO: this implementation contains logical error * $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api
// when precision is us the (long ts) is 16 digital number */
// when precision is ms, the (long ts) is 13 digital number public void setTimestampValue(int colIndex, long value) {
// we need a JNI function like this: setTimestamp(colIndex - 1, value, 0);
// 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) { /**
return (Timestamp) data.get(col); * !!! this method is invoked by JNI method and the index start from 0 in C implementations
*
* @param precision 0 : ms, 1 : us, 2 : ns
*/
public void setTimestamp(int col, long ts, int precision) {
long milliseconds;
int fracNanoseconds;
switch (precision) {
case 0: {
milliseconds = ts;
fracNanoseconds = (int) (ts * 1_000_000 % 1_000_000_000);
break;
} }
case 1: {
public Object get(int col) { milliseconds = ts / 1_000;
return data.get(col); fracNanoseconds = (int) (ts * 1_000 % 1_000_000_000);
break;
}
case 2: {
milliseconds = ts / 1_000_000;
fracNanoseconds = (int) (ts % 1_000_000_000);
break;
}
default: {
throw new IllegalArgumentException("precision is not valid. precision: " + precision);
} }
public int getColSize() {
return colSize;
} }
private void setColSize(int colSize) { Timestamp tsObj = new Timestamp(milliseconds);
this.colSize = colSize; tsObj.setNanos(fracNanoseconds);
this.clear(); data.set(col, tsObj);
} }
public ArrayList<Object> getData() { public Timestamp getTimestamp(int col, int nativeType) {
return data; Object obj = data.get(col - 1);
if (obj == null)
return null;
if (nativeType == TSDBConstants.TSDB_DATA_TYPE_BIGINT) {
return new Timestamp((Long) obj);
}
return (Timestamp) obj;
} }
public void setData(ArrayList<Object> data) { public Object getObject(int col) {
this.data = (ArrayList<Object>) data.clone(); return data.get(col - 1);
} }
} }
...@@ -32,14 +32,15 @@ public class TSDBStatement extends AbstractStatement { ...@@ -32,14 +32,15 @@ public class TSDBStatement extends AbstractStatement {
} }
public ResultSet executeQuery(String sql) throws SQLException { public ResultSet executeQuery(String sql) throws SQLException {
// check if closed
if (isClosed()) { if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
} }
//TODO:
//TODO: 如果在executeQuery方法中执行insert语句,那么先执行了SQL,再通过pSql来检查是否为一个insert语句,但这个insert SQL已经执行成功了 // this is an unreasonable implementation, if the paratemer is a insert statement,
// the JNI connector will execute the sql at first and return a pointer: pSql,
// execute query // we use this pSql and invoke the isUpdateQuery(long pSql) method to decide .
// but the insert sql is already executed in database.
//execute query
long pSql = this.connection.getConnector().executeQuery(sql); long pSql = this.connection.getConnector().executeQuery(sql);
// if pSql is create/insert/update/delete/alter SQL // if pSql is create/insert/update/delete/alter SQL
if (this.connection.getConnector().isUpdateQuery(pSql)) { if (this.connection.getConnector().isUpdateQuery(pSql)) {
......
...@@ -47,9 +47,6 @@ public class TSDBSubscribe { ...@@ -47,9 +47,6 @@ public class TSDBSubscribe {
/** /**
* close subscription * close subscription
*
* @param keepProgress
* @throws SQLException
*/ */
public void close(boolean keepProgress) throws SQLException { public void close(boolean keepProgress) throws SQLException {
if (this.connecter.isClosed()) if (this.connecter.isClosed())
......
package com.taosdata.jdbc.enums;
public enum TimestampFormat {
STRING,
TIMESTAMP,
UTC
}
package com.taosdata.jdbc.enums;
public enum TimestampPrecision {
MS,
US,
NS,
UNKNOWN
}
...@@ -16,17 +16,19 @@ public class RestfulConnection extends AbstractConnection { ...@@ -16,17 +16,19 @@ public class RestfulConnection extends AbstractConnection {
private final String host; private final String host;
private final int port; private final int port;
private final String url; private final String url;
private volatile String database; private final String database;
private final String token;
/******************************************************/ /******************************************************/
private boolean isClosed; private boolean isClosed;
private final DatabaseMetaData metadata; private final DatabaseMetaData metadata;
public RestfulConnection(String host, String port, Properties props, String database, String url) { public RestfulConnection(String host, String port, Properties props, String database, String url, String token) {
super(props); super(props);
this.host = host; this.host = host;
this.port = Integer.parseInt(port); this.port = Integer.parseInt(port);
this.database = database; this.database = database;
this.url = url; this.url = url;
this.token = token;
this.metadata = new RestfulDatabaseMetaData(url, props.getProperty(TSDBDriver.PROPERTY_KEY_USER), this); this.metadata = new RestfulDatabaseMetaData(url, props.getProperty(TSDBDriver.PROPERTY_KEY_USER), this);
} }
...@@ -66,6 +68,7 @@ public class RestfulConnection extends AbstractConnection { ...@@ -66,6 +68,7 @@ public class RestfulConnection extends AbstractConnection {
return this.metadata; return this.metadata;
} }
// getters
public String getHost() { public String getHost() {
return host; return host;
} }
...@@ -81,4 +84,8 @@ public class RestfulConnection extends AbstractConnection { ...@@ -81,4 +84,8 @@ public class RestfulConnection extends AbstractConnection {
public String getUrl() { public String getUrl() {
return url; return url;
} }
public String getToken() {
return token;
}
} }
\ No newline at end of file
...@@ -38,15 +38,11 @@ public class RestfulDriver extends AbstractDriver { ...@@ -38,15 +38,11 @@ public class RestfulDriver extends AbstractDriver {
String port = props.getProperty(TSDBDriver.PROPERTY_KEY_PORT, "6041"); String port = props.getProperty(TSDBDriver.PROPERTY_KEY_PORT, "6041");
String database = props.containsKey(TSDBDriver.PROPERTY_KEY_DBNAME) ? props.getProperty(TSDBDriver.PROPERTY_KEY_DBNAME) : null; String database = props.containsKey(TSDBDriver.PROPERTY_KEY_DBNAME) ? props.getProperty(TSDBDriver.PROPERTY_KEY_DBNAME) : null;
String loginUrl = "http://" + props.getProperty(TSDBDriver.PROPERTY_KEY_HOST) + ":" String loginUrl = "http://" + host + ":" + port + "/rest/login/" + props.getProperty(TSDBDriver.PROPERTY_KEY_USER) + "/" + props.getProperty(TSDBDriver.PROPERTY_KEY_PASSWORD) + "";
+ props.getProperty(TSDBDriver.PROPERTY_KEY_PORT) + "/rest/login/"
+ props.getProperty(TSDBDriver.PROPERTY_KEY_USER) + "/"
+ props.getProperty(TSDBDriver.PROPERTY_KEY_PASSWORD) + "";
try { try {
String user = URLEncoder.encode(props.getProperty(TSDBDriver.PROPERTY_KEY_USER), "UTF-8"); String user = URLEncoder.encode(props.getProperty(TSDBDriver.PROPERTY_KEY_USER), "UTF-8");
String password = URLEncoder.encode(props.getProperty(TSDBDriver.PROPERTY_KEY_PASSWORD), "UTF-8"); String password = URLEncoder.encode(props.getProperty(TSDBDriver.PROPERTY_KEY_PASSWORD), "UTF-8");
loginUrl = "http://" + props.getProperty(TSDBDriver.PROPERTY_KEY_HOST) + ":" loginUrl = "http://" + props.getProperty(TSDBDriver.PROPERTY_KEY_HOST) + ":" + props.getProperty(TSDBDriver.PROPERTY_KEY_PORT) + "/rest/login/" + user + "/" + password + "";
+ props.getProperty(TSDBDriver.PROPERTY_KEY_PORT) + "/rest/login/" + user + "/" + password + "";
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
e.printStackTrace(); e.printStackTrace();
} }
...@@ -55,12 +51,12 @@ public class RestfulDriver extends AbstractDriver { ...@@ -55,12 +51,12 @@ public class RestfulDriver extends AbstractDriver {
JSONObject jsonResult = JSON.parseObject(result); JSONObject jsonResult = JSON.parseObject(result);
String status = jsonResult.getString("status"); String status = jsonResult.getString("status");
String token = jsonResult.getString("desc"); String token = jsonResult.getString("desc");
HttpClientPoolUtil.token = token;
if (!status.equals("succ")) { if (!status.equals("succ")) {
throw new SQLException(jsonResult.getString("desc")); throw new SQLException(jsonResult.getString("desc"));
} }
RestfulConnection conn = new RestfulConnection(host, port, props, database, url); RestfulConnection conn = new RestfulConnection(host, port, props, database, url, token);
if (database != null && !database.trim().replaceAll("\\s", "").isEmpty()) { if (database != null && !database.trim().replaceAll("\\s", "").isEmpty()) {
Statement stmt = conn.createStatement(); Statement stmt = conn.createStatement();
stmt.execute("use " + database); stmt.execute("use " + database);
......
...@@ -13,7 +13,7 @@ import java.util.Calendar; ...@@ -13,7 +13,7 @@ import java.util.Calendar;
public class RestfulPreparedStatement extends RestfulStatement implements PreparedStatement { public class RestfulPreparedStatement extends RestfulStatement implements PreparedStatement {
private ParameterMetaData parameterMetaData; private final ParameterMetaData parameterMetaData;
private final String rawSql; private final String rawSql;
private Object[] parameters; private Object[] parameters;
private boolean isPrepared; private boolean isPrepared;
...@@ -44,7 +44,7 @@ public class RestfulPreparedStatement extends RestfulStatement implements Prepar ...@@ -44,7 +44,7 @@ public class RestfulPreparedStatement extends RestfulStatement implements Prepar
if (!isPrepared) if (!isPrepared)
return executeQuery(this.rawSql); return executeQuery(this.rawSql);
final String sql = getNativeSql(this.rawSql); final String sql = Utils.getNativeSql(this.rawSql, this.parameters);
return executeQuery(sql); return executeQuery(sql);
} }
...@@ -55,20 +55,10 @@ public class RestfulPreparedStatement extends RestfulStatement implements Prepar ...@@ -55,20 +55,10 @@ public class RestfulPreparedStatement extends RestfulStatement implements Prepar
if (!isPrepared) if (!isPrepared)
return executeUpdate(this.rawSql); return executeUpdate(this.rawSql);
final String sql = getNativeSql(this.rawSql); final String sql = Utils.getNativeSql(rawSql, this.parameters);
return executeUpdate(sql); return executeUpdate(sql);
} }
/****
* 将rawSql转换成一条可执行的sql语句,使用属性parameters中的变脸进行替换
* 对于insert into ?.? (?,?,?) using ?.? (?,?,?) tags(?, ?, ?) values(?, ?, ?)
* @param rawSql,可能是insert、select或其他,使用?做占位符
* @return
*/
private String getNativeSql(String rawSql) {
return Utils.getNativeSql(rawSql, this.parameters);
}
@Override @Override
public void setNull(int parameterIndex, int sqlType) throws SQLException { public void setNull(int parameterIndex, int sqlType) throws SQLException {
if (isClosed()) if (isClosed())
...@@ -224,16 +214,13 @@ public class RestfulPreparedStatement extends RestfulStatement implements Prepar ...@@ -224,16 +214,13 @@ public class RestfulPreparedStatement extends RestfulStatement implements Prepar
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
if (!isPrepared) if (!isPrepared)
return execute(this.rawSql); return execute(this.rawSql);
final String sql = getNativeSql(rawSql); final String sql = Utils.getNativeSql(rawSql, this.parameters);
return execute(sql); return execute(sql);
} }
@Override @Override
public void addBatch() throws SQLException { public void addBatch() throws SQLException {
if (isClosed()) final String sql = Utils.getNativeSql(rawSql, this.parameters);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
final String sql = getNativeSql(this.rawSql);
addBatch(sql); addBatch(sql);
} }
......
...@@ -6,6 +6,8 @@ import com.google.common.primitives.Ints; ...@@ -6,6 +6,8 @@ import com.google.common.primitives.Ints;
import com.google.common.primitives.Longs; import com.google.common.primitives.Longs;
import com.google.common.primitives.Shorts; import com.google.common.primitives.Shorts;
import com.taosdata.jdbc.*; import com.taosdata.jdbc.*;
import com.taosdata.jdbc.enums.TimestampPrecision;
import com.taosdata.jdbc.enums.TimestampFormat;
import com.taosdata.jdbc.utils.Utils; import com.taosdata.jdbc.utils.Utils;
import java.math.BigDecimal; import java.math.BigDecimal;
...@@ -15,19 +17,20 @@ import java.time.ZoneOffset; ...@@ -15,19 +17,20 @@ import java.time.ZoneOffset;
import java.time.format.DateTimeParseException; import java.time.format.DateTimeParseException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.List;
public class RestfulResultSet extends AbstractResultSet implements ResultSet { public class RestfulResultSet extends AbstractResultSet implements ResultSet {
private volatile boolean isClosed;
private int pos = -1;
private final String database;
private final Statement statement; private final Statement statement;
// data // data
private final ArrayList<ArrayList<Object>> resultSet = new ArrayList<>(); private final List<List<Object>> resultSet = new ArrayList<>();
// meta // meta
private ArrayList<String> columnNames = new ArrayList<>(); private final List<String> columnNames = new ArrayList<>();
private ArrayList<Field> columns = new ArrayList<>(); private final List<Field> columns = new ArrayList<>();
private RestfulResultSetMetaData metaData; private final RestfulResultSetMetaData metaData;
private volatile boolean isClosed;
private int pos = -1;
/** /**
* 由一个result的Json构造结果集,对应执行show databases, show tables等这些语句,返回结果集,但无法获取结果集对应的meta,统一当成String处理 * 由一个result的Json构造结果集,对应执行show databases, show tables等这些语句,返回结果集,但无法获取结果集对应的meta,统一当成String处理
...@@ -35,34 +38,30 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { ...@@ -35,34 +38,30 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
* @param resultJson: 包含data信息的结果集,有sql返回的结果集 * @param resultJson: 包含data信息的结果集,有sql返回的结果集
***/ ***/
public RestfulResultSet(String database, Statement statement, JSONObject resultJson) throws SQLException { public RestfulResultSet(String database, Statement statement, JSONObject resultJson) throws SQLException {
this.database = database;
this.statement = statement; this.statement = statement;
// get head
JSONArray head = resultJson.getJSONArray("head");
// get column metadata // get column metadata
JSONArray columnMeta = resultJson.getJSONArray("column_meta"); JSONArray columnMeta = resultJson.getJSONArray("column_meta");
// get row data // get row data
JSONArray data = resultJson.getJSONArray("data"); JSONArray data = resultJson.getJSONArray("data");
if (data == null || data.isEmpty()) {
columnNames.clear();
columns.clear();
this.resultSet.clear();
return;
}
// get head
JSONArray head = resultJson.getJSONArray("head");
// get rows // get rows
Integer rows = resultJson.getInteger("rows"); Integer rows = resultJson.getInteger("rows");
// parse column_meta // parse column_meta
if (columnMeta != null) { if (columnMeta != null) {
parseColumnMeta_new(columnMeta); parseColumnMeta_new(columnMeta);
} else { } else {
parseColumnMeta_old(head, data, rows); parseColumnMeta_old(head, data, rows);
} }
this.metaData = new RestfulResultSetMetaData(this.database, columns, this); this.metaData = new RestfulResultSetMetaData(database, columns, this);
if (data == null || data.isEmpty())
return;
// parse row data // parse row data
resultSet.clear();
for (int rowIndex = 0; rowIndex < data.size(); rowIndex++) { for (int rowIndex = 0; rowIndex < data.size(); rowIndex++) {
ArrayList row = new ArrayList(); List<Object> row = new ArrayList();
JSONArray jsonRow = data.getJSONArray(rowIndex); JSONArray jsonRow = data.getJSONArray(rowIndex);
for (int colIndex = 0; colIndex < this.metaData.getColumnCount(); colIndex++) { for (int colIndex = 0; colIndex < this.metaData.getColumnCount(); colIndex++) {
row.add(parseColumnData(jsonRow, colIndex, columns.get(colIndex).taos_type)); row.add(parseColumnData(jsonRow, colIndex, columns.get(colIndex).taos_type));
...@@ -131,7 +130,6 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { ...@@ -131,7 +130,6 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
} }
} }
private Object parseColumnData(JSONArray row, int colIndex, int taosType) throws SQLException { private Object parseColumnData(JSONArray row, int colIndex, int taosType) throws SQLException {
switch (taosType) { switch (taosType) {
case TSDBConstants.TSDB_DATA_TYPE_NULL: case TSDBConstants.TSDB_DATA_TYPE_NULL:
...@@ -150,54 +148,77 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { ...@@ -150,54 +148,77 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
return row.getFloat(colIndex); return row.getFloat(colIndex);
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: case TSDBConstants.TSDB_DATA_TYPE_DOUBLE:
return row.getDouble(colIndex); return row.getDouble(colIndex);
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: { case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
return parseTimestampColumnData(row, colIndex);
case TSDBConstants.TSDB_DATA_TYPE_BINARY:
return row.getString(colIndex) == null ? null : row.getString(colIndex).getBytes();
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
return row.getString(colIndex) == null ? null : row.getString(colIndex);
default:
return row.get(colIndex);
}
}
private Timestamp parseTimestampColumnData(JSONArray row, int colIndex) throws SQLException {
if (row.get(colIndex) == null) if (row.get(colIndex) == null)
return null; return null;
String timestampFormat = this.statement.getConnection().getClientInfo(TSDBDriver.PROPERTY_KEY_TIMESTAMP_FORMAT); String tsFormatUpperCase = this.statement.getConnection().getClientInfo(TSDBDriver.PROPERTY_KEY_TIMESTAMP_FORMAT).toUpperCase();
if ("TIMESTAMP".equalsIgnoreCase(timestampFormat)) { TimestampFormat timestampFormat = TimestampFormat.valueOf(tsFormatUpperCase);
switch (timestampFormat) {
case TIMESTAMP: {
Long value = row.getLong(colIndex); Long value = row.getLong(colIndex);
//TODO: this implementation has bug if the timestamp bigger than 9999_9999_9999_9 //TODO: this implementation has bug if the timestamp bigger than 9999_9999_9999_9
if (value < 1_0000_0000_0000_0L) if (value < 1_0000_0000_0000_0L)
return new Timestamp(value); return new Timestamp(value);
long epochSec = value / 1000_000l; long epochSec = value / 1000_000L;
long nanoAdjustment = value % 1000_000l * 1000l; long nanoAdjustment = value % 1000_000L * 1000L;
return Timestamp.from(Instant.ofEpochSecond(epochSec, nanoAdjustment)); return Timestamp.from(Instant.ofEpochSecond(epochSec, nanoAdjustment));
} }
if ("UTC".equalsIgnoreCase(timestampFormat)) { case UTC: {
String value = row.getString(colIndex); String value = row.getString(colIndex);
long epochSec = Timestamp.valueOf(value.substring(0, 19).replace("T", " ")).getTime() / 1000; long epochSec = Timestamp.valueOf(value.substring(0, 19).replace("T", " ")).getTime() / 1000;
int fractionalSec = Integer.parseInt(value.substring(20, value.length() - 5)); int fractionalSec = Integer.parseInt(value.substring(20, value.length() - 5));
long nanoAdjustment = 0; long nanoAdjustment;
if (value.length() > 28) { if (value.length() > 31) {
// ns timestamp: yyyy-MM-ddTHH:mm:ss.SSSSSSSSS+0x00
nanoAdjustment = fractionalSec;
} else if (value.length() > 28) {
// ms timestamp: yyyy-MM-ddTHH:mm:ss.SSSSSS+0x00 // ms timestamp: yyyy-MM-ddTHH:mm:ss.SSSSSS+0x00
nanoAdjustment = fractionalSec * 1000l; nanoAdjustment = fractionalSec * 1000L;
} else { } else {
// ms timestamp: yyyy-MM-ddTHH:mm:ss.SSS+0x00 // ms timestamp: yyyy-MM-ddTHH:mm:ss.SSS+0x00
nanoAdjustment = fractionalSec * 1000_000l; nanoAdjustment = fractionalSec * 1000_000L;
} }
ZoneOffset zoneOffset = ZoneOffset.of(value.substring(value.length() - 5)); ZoneOffset zoneOffset = ZoneOffset.of(value.substring(value.length() - 5));
Instant instant = Instant.ofEpochSecond(epochSec, nanoAdjustment).atOffset(zoneOffset).toInstant(); Instant instant = Instant.ofEpochSecond(epochSec, nanoAdjustment).atOffset(zoneOffset).toInstant();
return Timestamp.from(instant); return Timestamp.from(instant);
} }
case STRING:
default: {
String value = row.getString(colIndex); String value = row.getString(colIndex);
if (value.length() <= 23) // ms timestamp: yyyy-MM-dd HH:mm:ss.SSS TimestampPrecision precision = Utils.guessTimestampPrecision(value);
if (precision == TimestampPrecision.MS) {
// ms timestamp: yyyy-MM-dd HH:mm:ss.SSS
return row.getTimestamp(colIndex); return row.getTimestamp(colIndex);
}
if (precision == TimestampPrecision.US) {
// us timestamp: yyyy-MM-dd HH:mm:ss.SSSSSS // us timestamp: yyyy-MM-dd HH:mm:ss.SSSSSS
long epochSec = Timestamp.valueOf(value.substring(0, 19)).getTime() / 1000; long epochSec = Timestamp.valueOf(value.substring(0, 19)).getTime() / 1000;
long nanoAdjustment = Integer.parseInt(value.substring(20)) * 1000l; long nanoAdjustment = Integer.parseInt(value.substring(20)) * 1000L;
Timestamp timestamp = Timestamp.from(Instant.ofEpochSecond(epochSec, nanoAdjustment)); return Timestamp.from(Instant.ofEpochSecond(epochSec, nanoAdjustment));
return timestamp; }
if (precision == TimestampPrecision.NS) {
// ms timestamp: yyyy-MM-dd HH:mm:ss.SSSSSSSSS
long epochSec = Timestamp.valueOf(value.substring(0, 19)).getTime() / 1000;
long nanoAdjustment = Integer.parseInt(value.substring(20));
return Timestamp.from(Instant.ofEpochSecond(epochSec, nanoAdjustment));
}
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN_TIMESTAMP_PERCISION);
} }
case TSDBConstants.TSDB_DATA_TYPE_BINARY:
return row.getString(colIndex) == null ? null : row.getString(colIndex).getBytes();
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
return row.getString(colIndex) == null ? null : row.getString(colIndex);
default:
return row.get(colIndex);
} }
} }
public class Field { public static class Field {
String name; String name;
int type; int type;
int length; int length;
...@@ -211,6 +232,7 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { ...@@ -211,6 +232,7 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
this.note = note; this.note = note;
this.taos_type = taos_type; this.taos_type = taos_type;
} }
} }
@Override @Override
...@@ -218,10 +240,7 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { ...@@ -218,10 +240,7 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
if (isClosed()) if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
pos++; pos++;
if (pos <= resultSet.size() - 1) { return pos <= resultSet.size() - 1;
return true;
}
return false;
} }
@Override @Override
...@@ -231,13 +250,6 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { ...@@ -231,13 +250,6 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
} }
} }
// @Override
// public boolean wasNull() throws SQLException {
// if (isClosed())
// throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
// return resultSet.isEmpty();
// }
@Override @Override
public String getString(int columnIndex) throws SQLException { public String getString(int columnIndex) throws SQLException {
checkAvailability(columnIndex, resultSet.get(pos).size()); checkAvailability(columnIndex, resultSet.get(pos).size());
...@@ -262,7 +274,7 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { ...@@ -262,7 +274,7 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
wasNull = false; wasNull = false;
if (value instanceof Boolean) if (value instanceof Boolean)
return (boolean) value; return (boolean) value;
return Boolean.valueOf(value.toString()); return Boolean.parseBoolean(value.toString());
} }
@Override @Override
...@@ -334,6 +346,7 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { ...@@ -334,6 +346,7 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
wasNull = true; wasNull = true;
return 0; return 0;
} }
wasNull = false; wasNull = false;
if (value instanceof Timestamp) { if (value instanceof Timestamp) {
return ((Timestamp) value).getTime(); return ((Timestamp) value).getTime();
...@@ -416,9 +429,7 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { ...@@ -416,9 +429,7 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
return null; return null;
if (value instanceof Timestamp) if (value instanceof Timestamp)
return new Date(((Timestamp) value).getTime()); return new Date(((Timestamp) value).getTime());
Date date = null; return Utils.parseDate(value.toString());
date = Utils.parseDate(value.toString());
return date;
} }
@Override @Override
...@@ -433,8 +444,7 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { ...@@ -433,8 +444,7 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
Time time = null; Time time = null;
try { try {
time = Utils.parseTime(value.toString()); time = Utils.parseTime(value.toString());
} catch (DateTimeParseException e) { } catch (DateTimeParseException ignored) {
time = null;
} }
return time; return time;
} }
...@@ -498,9 +508,9 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { ...@@ -498,9 +508,9 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
return null; return null;
if (value instanceof Long || value instanceof Integer || value instanceof Short || value instanceof Byte) if (value instanceof Long || value instanceof Integer || value instanceof Short || value instanceof Byte)
return new BigDecimal(Long.valueOf(value.toString())); return new BigDecimal(Long.parseLong(value.toString()));
if (value instanceof Double || value instanceof Float) if (value instanceof Double || value instanceof Float)
return new BigDecimal(Double.valueOf(value.toString())); return BigDecimal.valueOf(Double.parseDouble(value.toString()));
if (value instanceof Timestamp) if (value instanceof Timestamp)
return new BigDecimal(((Timestamp) value).getTime()); return new BigDecimal(((Timestamp) value).getTime());
BigDecimal ret; BigDecimal ret;
...@@ -610,36 +620,6 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { ...@@ -610,36 +620,6 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
if (isClosed()) if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
// if (this.resultSet.size() == 0)
// return false;
//
// if (row == 0) {
// beforeFirst();
// return false;
// } else if (row == 1) {
// return first();
// } else if (row == -1) {
// return last();
// } else if (row > this.resultSet.size()) {
// afterLast();
// return false;
// } else {
// if (row < 0) {
// // adjust to reflect after end of result set
// int newRowPosition = this.resultSet.size() + row + 1;
// if (newRowPosition <= 0) {
// beforeFirst();
// return false;
// } else {
// return absolute(newRowPosition);
// }
// } else {
// row--; // adjust for index difference
// this.pos = row;
// return true;
// }
// }
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
} }
...@@ -683,5 +663,4 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { ...@@ -683,5 +663,4 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
return isClosed; return isClosed;
} }
} }
\ No newline at end of file
...@@ -7,21 +7,20 @@ import java.sql.ResultSetMetaData; ...@@ -7,21 +7,20 @@ import java.sql.ResultSetMetaData;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.sql.Types; import java.sql.Types;
import java.util.ArrayList; import java.util.Collections;
import java.util.List;
public class RestfulResultSetMetaData extends WrapperImpl implements ResultSetMetaData { public class RestfulResultSetMetaData extends WrapperImpl implements ResultSetMetaData {
private final String database; private final String database;
private ArrayList<RestfulResultSet.Field> fields; private final List<RestfulResultSet.Field> fields;
private final RestfulResultSet resultSet;
public RestfulResultSetMetaData(String database, ArrayList<RestfulResultSet.Field> fields, RestfulResultSet resultSet) { public RestfulResultSetMetaData(String database, List<RestfulResultSet.Field> fields, RestfulResultSet resultSet) {
this.database = database; this.database = database;
this.fields = fields; this.fields = fields == null ? Collections.emptyList() : fields;
this.resultSet = resultSet;
} }
public ArrayList<RestfulResultSet.Field> getFields() { public List<RestfulResultSet.Field> getFields() {
return fields; return fields;
} }
...@@ -139,8 +138,8 @@ public class RestfulResultSetMetaData extends WrapperImpl implements ResultSetMe ...@@ -139,8 +138,8 @@ public class RestfulResultSetMetaData extends WrapperImpl implements ResultSetMe
@Override @Override
public String getColumnTypeName(int column) throws SQLException { public String getColumnTypeName(int column) throws SQLException {
int taos_type = fields.get(column - 1).taos_type; int taosType = fields.get(column - 1).taos_type;
return TSDBConstants.taosType2JdbcTypeName(taos_type); return TSDBConstants.taosType2JdbcTypeName(taosType);
} }
@Override @Override
......
...@@ -35,10 +35,6 @@ public class RestfulStatement extends AbstractStatement { ...@@ -35,10 +35,6 @@ public class RestfulStatement extends AbstractStatement {
if (!SqlSyntaxValidator.isValidForExecuteQuery(sql)) if (!SqlSyntaxValidator.isValidForExecuteQuery(sql))
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_FOR_EXECUTE_QUERY, "not a valid sql for executeQuery: " + sql); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_FOR_EXECUTE_QUERY, "not a valid sql for executeQuery: " + sql);
if (SqlSyntaxValidator.isDatabaseUnspecifiedQuery(sql)) {
return executeOneQuery(sql);
}
return executeOneQuery(sql); return executeOneQuery(sql);
} }
...@@ -50,9 +46,6 @@ public class RestfulStatement extends AbstractStatement { ...@@ -50,9 +46,6 @@ public class RestfulStatement extends AbstractStatement {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_FOR_EXECUTE_UPDATE, "not a valid sql for executeUpdate: " + sql); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_FOR_EXECUTE_UPDATE, "not a valid sql for executeUpdate: " + sql);
final String url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sql"; final String url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sql";
if (SqlSyntaxValidator.isDatabaseUnspecifiedUpdate(sql)) {
return executeOneUpdate(url, sql);
}
return executeOneUpdate(url, sql); return executeOneUpdate(url, sql);
} }
...@@ -83,7 +76,7 @@ public class RestfulStatement extends AbstractStatement { ...@@ -83,7 +76,7 @@ public class RestfulStatement extends AbstractStatement {
} }
if (SqlSyntaxValidator.isUseSql(sql)) { if (SqlSyntaxValidator.isUseSql(sql)) {
HttpClientPoolUtil.execute(url, sql); HttpClientPoolUtil.execute(url, sql, this.conn.getToken());
this.database = sql.trim().replace("use", "").trim(); this.database = sql.trim().replace("use", "").trim();
this.conn.setCatalog(this.database); this.conn.setCatalog(this.database);
result = false; result = false;
...@@ -116,7 +109,7 @@ public class RestfulStatement extends AbstractStatement { ...@@ -116,7 +109,7 @@ public class RestfulStatement extends AbstractStatement {
if ("UTC".equalsIgnoreCase(timestampFormat)) if ("UTC".equalsIgnoreCase(timestampFormat))
url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sqlutc"; url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sqlutc";
String result = HttpClientPoolUtil.execute(url, sql); String result = HttpClientPoolUtil.execute(url, sql, this.conn.getToken());
JSONObject resultJson = JSON.parseObject(result); JSONObject resultJson = JSON.parseObject(result);
if (resultJson.getString("status").equals("error")) { if (resultJson.getString("status").equals("error")) {
throw TSDBError.createSQLException(resultJson.getInteger("code"), resultJson.getString("desc")); throw TSDBError.createSQLException(resultJson.getInteger("code"), resultJson.getString("desc"));
...@@ -130,7 +123,7 @@ public class RestfulStatement extends AbstractStatement { ...@@ -130,7 +123,7 @@ public class RestfulStatement extends AbstractStatement {
if (!SqlSyntaxValidator.isValidForExecuteUpdate(sql)) if (!SqlSyntaxValidator.isValidForExecuteUpdate(sql))
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_FOR_EXECUTE_UPDATE, "not a valid sql for executeUpdate: " + sql); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_FOR_EXECUTE_UPDATE, "not a valid sql for executeUpdate: " + sql);
String result = HttpClientPoolUtil.execute(url, sql); String result = HttpClientPoolUtil.execute(url, sql, this.conn.getToken());
JSONObject jsonObject = JSON.parseObject(result); JSONObject jsonObject = JSON.parseObject(result);
if (jsonObject.getString("status").equals("error")) { if (jsonObject.getString("status").equals("error")) {
throw TSDBError.createSQLException(jsonObject.getInteger("code"), jsonObject.getString("desc")); throw TSDBError.createSQLException(jsonObject.getInteger("code"), jsonObject.getString("desc"));
......
...@@ -16,43 +16,31 @@ import org.apache.http.protocol.HTTP; ...@@ -16,43 +16,31 @@ import org.apache.http.protocol.HTTP;
import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils; import org.apache.http.util.EntityUtils;
import java.nio.charset.Charset; import java.nio.charset.StandardCharsets;
public class HttpClientPoolUtil { public class HttpClientPoolUtil {
public static PoolingHttpClientConnectionManager cm = null;
public static CloseableHttpClient httpClient = null;
public static String token = "cm9vdDp0YW9zZGF0YQ==";
/**
* 默认content 类型
*/
private static final String DEFAULT_CONTENT_TYPE = "application/json"; private static final String DEFAULT_CONTENT_TYPE = "application/json";
/**
* 默认请求超时时间30s
*/
private static final int DEFAULT_TIME_OUT = 15000; private static final int DEFAULT_TIME_OUT = 15000;
private static final int count = 32; private static final int DEFAULT_MAX_PER_ROUTE = 32;
private static final int totalCount = 1000; private static final int DEFAULT_MAX_TOTAL = 1000;
private static final int Http_Default_Keep_Time = 15000; private static final int DEFAULT_HTTP_KEEP_TIME = 15000;
private static CloseableHttpClient httpClient;
/**
* 初始化连接池
*/
private static synchronized void initPools() { private static synchronized void initPools() {
if (httpClient == null) { if (httpClient == null) {
cm = new PoolingHttpClientConnectionManager(); PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
cm.setDefaultMaxPerRoute(count); connectionManager.setDefaultMaxPerRoute(DEFAULT_MAX_PER_ROUTE);
cm.setMaxTotal(totalCount); connectionManager.setMaxTotal(DEFAULT_MAX_TOTAL);
httpClient = HttpClients.custom().setKeepAliveStrategy(defaultStrategy).setConnectionManager(cm).build(); httpClient = HttpClients.custom().setKeepAliveStrategy(DEFAULT_KEEP_ALIVE_STRATEGY).setConnectionManager(connectionManager).build();
} }
} }
/** private static final ConnectionKeepAliveStrategy DEFAULT_KEEP_ALIVE_STRATEGY = (response, context) -> {
* Http connection keepAlive 设置
*/
private static ConnectionKeepAliveStrategy defaultStrategy = (response, context) -> {
HeaderElementIterator it = new BasicHeaderElementIterator(response.headerIterator(HTTP.CONN_KEEP_ALIVE)); HeaderElementIterator it = new BasicHeaderElementIterator(response.headerIterator(HTTP.CONN_KEEP_ALIVE));
int keepTime = Http_Default_Keep_Time * 1000; int keepTime = DEFAULT_HTTP_KEEP_TIME * 1000;
while (it.hasNext()) { while (it.hasNext()) {
HeaderElement headerElement = it.nextElement(); HeaderElement headerElement = it.nextElement();
String param = headerElement.getName(); String param = headerElement.getName();
...@@ -76,7 +64,7 @@ public class HttpClientPoolUtil { ...@@ -76,7 +64,7 @@ public class HttpClientPoolUtil {
* @param data 请求数据 * @param data 请求数据
* @return responseBody * @return responseBody
*/ */
public static String execute(String uri, String data) { public static String execute(String uri, String data, String token) {
long startTime = System.currentTimeMillis(); long startTime = System.currentTimeMillis();
HttpEntity httpEntity = null; HttpEntity httpEntity = null;
HttpEntityEnclosingRequestBase method = null; HttpEntityEnclosingRequestBase method = null;
...@@ -90,7 +78,7 @@ public class HttpClientPoolUtil { ...@@ -90,7 +78,7 @@ public class HttpClientPoolUtil {
method.setHeader("Connection", "keep-alive"); method.setHeader("Connection", "keep-alive");
method.setHeader("Authorization", "Taosd " + token); method.setHeader("Authorization", "Taosd " + token);
method.setEntity(new StringEntity(data, Charset.forName("UTF-8"))); method.setEntity(new StringEntity(data, StandardCharsets.UTF_8));
HttpContext context = HttpClientContext.create(); HttpContext context = HttpClientContext.create();
CloseableHttpResponse httpResponse = httpClient.execute(method, context); CloseableHttpResponse httpResponse = httpClient.execute(method, context);
httpEntity = httpResponse.getEntity(); httpEntity = httpResponse.getEntity();
...@@ -175,28 +163,18 @@ public class HttpClientPoolUtil { ...@@ -175,28 +163,18 @@ public class HttpClientPoolUtil {
httpEntity = httpResponse.getEntity(); httpEntity = httpResponse.getEntity();
if (httpEntity != null) { if (httpEntity != null) {
responseBody = EntityUtils.toString(httpEntity, "UTF-8"); responseBody = EntityUtils.toString(httpEntity, "UTF-8");
// logger.info("请求URL: " + uri + "+ 返回状态码:" + httpResponse.getStatusLine().getStatusCode());
} }
} catch (Exception e) { } catch (Exception e) {
if (method != null) { if (method != null) {
method.abort(); method.abort();
} }
e.printStackTrace(); e.printStackTrace();
// logger.error("execute get request exception, url:" + uri + ", exception:" + e.toString() + ",cost time(ms):"
// + (System.currentTimeMillis() - startTime));
System.out.println("log:调用 HttpClientPoolUtil execute get request exception, url:" + uri + ", exception:" + e.toString() + ",cost time(ms):"
+ (System.currentTimeMillis() - startTime));
} finally { } finally {
if (httpEntity != null) { if (httpEntity != null) {
try { try {
EntityUtils.consumeQuietly(httpEntity); EntityUtils.consumeQuietly(httpEntity);
} catch (Exception e) { } catch (Exception e) {
// e.printStackTrace(); new Exception("close response exception, url:" + uri + ", exception:" + e.toString() + ",cost time(ms):" + (System.currentTimeMillis() - startTime)).printStackTrace();
// logger.error("close response exception, url:" + uri + ", exception:" + e.toString()
// + ",cost time(ms):" + (System.currentTimeMillis() - startTime));
new Exception("close response exception, url:" + uri + ", exception:" + e.toString()
+ ",cost time(ms):" + (System.currentTimeMillis() - startTime))
.printStackTrace();
} }
} }
} }
......
...@@ -14,10 +14,6 @@ ...@@ -14,10 +14,6 @@
*****************************************************************************/ *****************************************************************************/
package com.taosdata.jdbc.utils; package com.taosdata.jdbc.utils;
import com.taosdata.jdbc.TSDBConnection;
import java.sql.Connection;
public class SqlSyntaxValidator { public class SqlSyntaxValidator {
private static final String[] SQL = {"select", "insert", "import", "create", "use", "alter", "drop", "set", "show", "describe"}; private static final String[] SQL = {"select", "insert", "import", "create", "use", "alter", "drop", "set", "show", "describe"};
...@@ -26,12 +22,6 @@ public class SqlSyntaxValidator { ...@@ -26,12 +22,6 @@ public class SqlSyntaxValidator {
private static final String[] databaseUnspecifiedShow = {"databases", "dnodes", "mnodes", "variables"}; private static final String[] databaseUnspecifiedShow = {"databases", "dnodes", "mnodes", "variables"};
private TSDBConnection tsdbConnection;
public SqlSyntaxValidator(Connection connection) {
this.tsdbConnection = (TSDBConnection) connection;
}
public static boolean isValidForExecuteUpdate(String sql) { public static boolean isValidForExecuteUpdate(String sql) {
for (String prefix : updateSQL) { for (String prefix : updateSQL) {
if (sql.trim().toLowerCase().startsWith(prefix)) if (sql.trim().toLowerCase().startsWith(prefix))
......
...@@ -3,14 +3,14 @@ package com.taosdata.jdbc.utils; ...@@ -3,14 +3,14 @@ package com.taosdata.jdbc.utils;
import com.google.common.collect.Range; import com.google.common.collect.Range;
import com.google.common.collect.RangeSet; import com.google.common.collect.RangeSet;
import com.google.common.collect.TreeRangeSet; import com.google.common.collect.TreeRangeSet;
import com.taosdata.jdbc.enums.TimestampPrecision;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.sql.Date; import java.sql.Date;
import java.sql.Time; import java.sql.Time;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder; import java.time.format.DateTimeFormatterBuilder;
import java.time.format.DateTimeParseException; import java.time.format.DateTimeParseException;
...@@ -25,39 +25,52 @@ public class Utils { ...@@ -25,39 +25,52 @@ public class Utils {
private static Pattern ptn = Pattern.compile(".*?'"); private static Pattern ptn = Pattern.compile(".*?'");
private static final DateTimeFormatter formatter = new DateTimeFormatterBuilder() private static final DateTimeFormatter milliSecFormatter = new DateTimeFormatterBuilder().appendPattern("yyyy-MM-dd HH:mm:ss.SSS").toFormatter();
.appendPattern("yyyy-MM-dd HH:mm:ss.SSS").toFormatter(); private static final DateTimeFormatter microSecFormatter = new DateTimeFormatterBuilder().appendPattern("yyyy-MM-dd HH:mm:ss.SSSSSS").toFormatter();
private static final DateTimeFormatter formatter2 = new DateTimeFormatterBuilder() private static final DateTimeFormatter nanoSecFormatter = new DateTimeFormatterBuilder().appendPattern("yyyy-MM-dd HH:mm:ss.SSSSSSSSS").toFormatter();
.appendPattern("yyyy-MM-dd HH:mm:ss.SSSSSS").toFormatter();
public static Time parseTime(String timestampStr) throws DateTimeParseException { public static Time parseTime(String timestampStr) throws DateTimeParseException {
LocalTime time; LocalDateTime dateTime = parseLocalDateTime(timestampStr);
try { return dateTime != null ? Time.valueOf(dateTime.toLocalTime()) : null;
time = LocalTime.parse(timestampStr, formatter);
} catch (DateTimeParseException e) {
time = LocalTime.parse(timestampStr, formatter2);
} }
return Time.valueOf(time);
public static Date parseDate(String timestampStr) {
LocalDateTime dateTime = parseLocalDateTime(timestampStr);
return dateTime != null ? Date.valueOf(String.valueOf(dateTime)) : null;
} }
public static Date parseDate(String timestampStr) throws DateTimeParseException { public static Timestamp parseTimestamp(String timeStampStr) {
LocalDate date; LocalDateTime dateTime = parseLocalDateTime(timeStampStr);
return dateTime != null ? Timestamp.valueOf(dateTime) : null;
}
private static LocalDateTime parseLocalDateTime(String timeStampStr) {
try { try {
date = LocalDate.parse(timestampStr, formatter); return parseMilliSecTimestamp(timeStampStr);
} catch (DateTimeParseException e) { } catch (DateTimeParseException e) {
date = LocalDate.parse(timestampStr, formatter2); try {
return parseMicroSecTimestamp(timeStampStr);
} catch (DateTimeParseException ee) {
try {
return parseNanoSecTimestamp(timeStampStr);
} catch (DateTimeParseException eee) {
eee.printStackTrace();
}
} }
return Date.valueOf(date); }
return null;
} }
public static Timestamp parseTimestamp(String timeStampStr) { private static LocalDateTime parseMilliSecTimestamp(String timeStampStr) throws DateTimeParseException {
LocalDateTime dateTime; return LocalDateTime.parse(timeStampStr, milliSecFormatter);
try {
dateTime = LocalDateTime.parse(timeStampStr, formatter);
} catch (DateTimeParseException e) {
dateTime = LocalDateTime.parse(timeStampStr, formatter2);
} }
return Timestamp.valueOf(dateTime);
private static LocalDateTime parseMicroSecTimestamp(String timeStampStr) throws DateTimeParseException {
return LocalDateTime.parse(timeStampStr, microSecFormatter);
}
private static LocalDateTime parseNanoSecTimestamp(String timeStampStr) throws DateTimeParseException {
return LocalDateTime.parse(timeStampStr, nanoSecFormatter);
} }
public static String escapeSingleQuota(String origin) { public static String escapeSingleQuota(String origin) {
...@@ -93,18 +106,11 @@ public class Utils { ...@@ -93,18 +106,11 @@ public class Utils {
} }
public static String getNativeSql(String rawSql, Object[] parameters) { public static String getNativeSql(String rawSql, Object[] parameters) {
if (parameters == null || !rawSql.contains("?"))
return rawSql;
// toLowerCase // toLowerCase
String preparedSql = rawSql.trim().toLowerCase(); String preparedSql = rawSql.trim().toLowerCase();
String[] clause = new String[]{"values\\s*\\(.*?\\)", "tags\\s*\\(.*?\\)", "where\\s*.*"};
String[] clause = new String[0];
if (SqlSyntaxValidator.isInsertSql(preparedSql)) {
// insert or import
clause = new String[]{"values\\s*\\(.*?\\)", "tags\\s*\\(.*?\\)"};
}
if (SqlSyntaxValidator.isSelectSql(preparedSql)) {
// select
clause = new String[]{"where\\s*.*"};
}
Map<Integer, Integer> placeholderPositions = new HashMap<>(); Map<Integer, Integer> placeholderPositions = new HashMap<>();
RangeSet<Integer> clauseRangeSet = TreeRangeSet.create(); RangeSet<Integer> clauseRangeSet = TreeRangeSet.create();
findPlaceholderPosition(preparedSql, placeholderPositions); findPlaceholderPosition(preparedSql, placeholderPositions);
...@@ -155,7 +161,7 @@ public class Utils { ...@@ -155,7 +161,7 @@ public class Utils {
String paraStr; String paraStr;
if (para != null) { if (para != null) {
if (para instanceof byte[]) { if (para instanceof byte[]) {
paraStr = new String((byte[]) para, Charset.forName("UTF-8")); paraStr = new String((byte[]) para, StandardCharsets.UTF_8);
} else { } else {
paraStr = para.toString(); paraStr = para.toString();
} }
...@@ -176,13 +182,47 @@ public class Utils { ...@@ -176,13 +182,47 @@ public class Utils {
}).collect(Collectors.joining()); }).collect(Collectors.joining());
} }
public static String formatTimestamp(Timestamp timestamp) { public static String formatTimestamp(Timestamp timestamp) {
int nanos = timestamp.getNanos(); int nanos = timestamp.getNanos();
if (nanos % 1000000l != 0) if (nanos % 1000000l != 0)
return timestamp.toLocalDateTime().format(formatter2); return timestamp.toLocalDateTime().format(microSecFormatter);
return timestamp.toLocalDateTime().format(formatter); return timestamp.toLocalDateTime().format(milliSecFormatter);
} }
public static TimestampPrecision guessTimestampPrecision(String value) {
if (isMilliSecFormat(value))
return TimestampPrecision.MS;
if (isMicroSecFormat(value))
return TimestampPrecision.US;
if (isNanoSecFormat(value))
return TimestampPrecision.NS;
return TimestampPrecision.UNKNOWN;
}
private static boolean isMilliSecFormat(String timestampStr) {
try {
milliSecFormatter.parse(timestampStr);
} catch (DateTimeParseException e) {
return false;
}
return true;
}
private static boolean isMicroSecFormat(String timestampStr) {
try {
microSecFormatter.parse(timestampStr);
} catch (DateTimeParseException e) {
return false;
}
return true;
}
private static boolean isNanoSecFormat(String timestampStr) {
try {
nanoSecFormatter.parse(timestampStr);
} catch (DateTimeParseException e) {
return false;
}
return true;
}
} }
package com.taosdata.jdbc;
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 StatementTest {
static Connection connection = null;
static Statement statement = null;
static String dbName = "test";
static String tName = "t0";
static String host = "localhost";
@BeforeClass
public static void createConnection() throws SQLException {
try {
Class.forName("com.taosdata.jdbc.TSDBDriver");
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");
connection = DriverManager.getConnection("jdbc:TAOS://" + host + ":0/?user=root&password=taosdata", properties);
statement = connection.createStatement();
statement.executeUpdate("drop database if exists " + dbName);
} catch (ClassNotFoundException e) {
return;
}
}
@Test
public void testCase() {
try {
ResultSet rs = statement.executeQuery("show databases");
ResultSetMetaData metaData = rs.getMetaData();
while (rs.next()) {
for (int i = 1; i <= metaData.getColumnCount(); i++) {
System.out.print(metaData.getColumnLabel(i) + ":" + rs.getString(i) + "\t");
}
System.out.println();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
@Test
public void createTableAndQuery() throws SQLException {
long ts = System.currentTimeMillis();
statement.executeUpdate("create database if not exists " + dbName);
statement.executeUpdate("create table if not exists " + dbName + "." + tName + "(ts timestamp, k1 int)");
statement.executeUpdate("insert into " + dbName + "." + tName + " values (" + ts + ", 1)");
statement.execute("select * from " + dbName + "." + tName);
ResultSet resultSet = statement.getResultSet();
Assert.assertNotNull(resultSet);
boolean isClosed = statement.isClosed();
Assert.assertEquals(false, isClosed);
}
@Test(expected = SQLException.class)
public void testUnsupport() throws SQLException {
Assert.assertNotNull(statement.unwrap(TSDBStatement.class));
Assert.assertTrue(statement.isWrapperFor(TSDBStatement.class));
statement.getMaxFieldSize();
statement.setMaxFieldSize(0);
statement.setEscapeProcessing(true);
statement.cancel();
statement.getWarnings();
statement.clearWarnings();
statement.setCursorName(null);
statement.getMoreResults();
statement.setFetchDirection(0);
statement.getFetchDirection();
statement.getResultSetConcurrency();
statement.getResultSetType();
statement.getConnection();
statement.getMoreResults();
statement.getGeneratedKeys();
statement.executeUpdate(null, 0);
statement.executeUpdate(null, new int[]{0});
statement.executeUpdate(null, new String[]{"str1", "str2"});
statement.getResultSetHoldability();
statement.setPoolable(true);
statement.isPoolable();
statement.closeOnCompletion();
statement.isCloseOnCompletion();
}
@AfterClass
public static void close() {
try {
statement.execute("drop database if exists " + dbName);
if (statement != null)
statement.close();
if (connection != null)
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
...@@ -32,20 +32,34 @@ public class TSDBConnectionTest { ...@@ -32,20 +32,34 @@ public class TSDBConnectionTest {
} }
@Test @Test
public void subscribe() { public void runSubscribe() {
try { try {
// given
TSDBConnection unwrap = conn.unwrap(TSDBConnection.class); TSDBConnection unwrap = conn.unwrap(TSDBConnection.class);
TSDBSubscribe subscribe = unwrap.subscribe("topic1", "select * from log.log", false); TSDBSubscribe subscribe = unwrap.subscribe("topic1", "select * from log.log", false);
// when
TSDBResultSet rs = subscribe.consume(); TSDBResultSet rs = subscribe.consume();
ResultSetMetaData metaData = rs.getMetaData(); ResultSetMetaData metaData = rs.getMetaData();
for (int count = 0; count < 10 && rs.next(); count++) {
for (int i = 1; i <= metaData.getColumnCount(); i++) { // then
String value = rs.getString(i);
System.out.print(metaData.getColumnLabel(i) + ":" + value + "\t");
}
System.out.println();
}
Assert.assertNotNull(rs); Assert.assertNotNull(rs);
Assert.assertEquals(4, metaData.getColumnCount());
Assert.assertEquals("ts", metaData.getColumnLabel(1));
Assert.assertEquals("level", metaData.getColumnLabel(2));
Assert.assertEquals("content", metaData.getColumnLabel(3));
Assert.assertEquals("ipaddr", metaData.getColumnLabel(4));
rs.next();
// row 1
{
Assert.assertNotNull(rs.getTimestamp(1));
Assert.assertNotNull(rs.getTimestamp("ts"));
Assert.assertNotNull(rs.getByte(2));
Assert.assertNotNull(rs.getByte("level"));
Assert.assertNotNull(rs.getString(3));
Assert.assertNotNull(rs.getString("content"));
Assert.assertNotNull(rs.getString(4));
Assert.assertNotNull(rs.getString("ipaddr"));
}
subscribe.close(false); subscribe.close(false);
} catch (SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();
...@@ -366,14 +380,15 @@ public class TSDBConnectionTest { ...@@ -366,14 +380,15 @@ public class TSDBConnectionTest {
conn.abort(null); conn.abort(null);
} }
@Test(expected = SQLFeatureNotSupportedException.class) @Test
public void setNetworkTimeout() throws SQLException { public void setNetworkTimeout() throws SQLException {
conn.setNetworkTimeout(null, 1000); conn.setNetworkTimeout(null, 1000);
} }
@Test(expected = SQLFeatureNotSupportedException.class) @Test
public void getNetworkTimeout() throws SQLException { public void getNetworkTimeout() throws SQLException {
conn.getNetworkTimeout(); int networkTimeout = conn.getNetworkTimeout();
Assert.assertEquals(0, networkTimeout);
} }
@Test @Test
......
package com.taosdata.jdbc; package com.taosdata.jdbc;
import org.junit.Test; import org.junit.Test;
import static org.junit.Assert.*;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.SQLWarning; import java.sql.SQLWarning;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.lang.management.ThreadMXBean;
public class TSDBJNIConnectorTest { public class TSDBJNIConnectorTest {
private static TSDBResultSetRowData rowData; private static TSDBResultSetRowData rowData;
...@@ -14,17 +19,68 @@ public class TSDBJNIConnectorTest { ...@@ -14,17 +19,68 @@ public class TSDBJNIConnectorTest {
@Test @Test
public void test() { public void test() {
try { try {
try {
//change sleepSeconds when debugging with attach to process to find PID
int sleepSeconds = -1;
if (sleepSeconds>0) {
RuntimeMXBean runtimeBean = ManagementFactory.getRuntimeMXBean();
String jvmName = runtimeBean.getName();
long pid = Long.valueOf(jvmName.split("@")[0]);
System.out.println("JVM PID = " + pid);
Thread.sleep(sleepSeconds*1000);
}
}
catch (Exception e) {
e.printStackTrace();
}
// init // init
TSDBJNIConnector.init("/etc/taos/taos.cfg", null, null, null); TSDBJNIConnector.init("/etc/taos", null, null, null);
// connect // connect
TSDBJNIConnector connector = new TSDBJNIConnector(); TSDBJNIConnector connector = new TSDBJNIConnector();
connector.connect("127.0.0.1", 6030, "unsign_jni", "root", "taosdata"); connector.connect("127.0.0.1", 6030, null, "root", "taosdata");
// setup
String setupSqlStrs[] = {"create database if not exists d precision \"us\"",
"create table if not exists d.t(ts timestamp, f int)",
"create database if not exists d2",
"create table if not exists d2.t2(ts timestamp, f int)",
"insert into d.t values(now+100s, 100)",
"insert into d2.t2 values(now+200s, 200)"
};
for (String setupSqlStr : setupSqlStrs) {
long setupSql = connector.executeQuery(setupSqlStr);
assertEquals(0, connector.getResultTimePrecision(setupSql));
if (connector.isUpdateQuery(setupSql)) {
connector.freeResultSet(setupSql);
}
}
{
long sqlObj1 = connector.executeQuery("select * from d2.t2");
assertEquals(0, connector.getResultTimePrecision(sqlObj1));
List<ColumnMetaData> columnMetaDataList = new ArrayList<>();
int code = connector.getSchemaMetaData(sqlObj1, columnMetaDataList);
rowData = new TSDBResultSetRowData(columnMetaDataList.size());
assertTrue(next(connector, sqlObj1));
assertEquals(0, connector.getResultTimePrecision(sqlObj1));
connector.freeResultSet(sqlObj1);
}
// executeQuery // executeQuery
long pSql = connector.executeQuery("select * from unsign_jni.us_table"); long pSql = connector.executeQuery("select * from d.t");
if (connector.isUpdateQuery(pSql)) { if (connector.isUpdateQuery(pSql)) {
connector.freeResultSet(pSql); connector.freeResultSet(pSql);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_WITH_EXECUTEQUERY); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_WITH_EXECUTEQUERY);
} }
assertEquals(1, connector.getResultTimePrecision(pSql));
// get schema // get schema
List<ColumnMetaData> columnMetaDataList = new ArrayList<>(); List<ColumnMetaData> columnMetaDataList = new ArrayList<>();
int code = connector.getSchemaMetaData(pSql, columnMetaDataList); int code = connector.getSchemaMetaData(pSql, columnMetaDataList);
...@@ -37,6 +93,8 @@ public class TSDBJNIConnectorTest { ...@@ -37,6 +93,8 @@ public class TSDBJNIConnectorTest {
if (code == TSDBConstants.JNI_NUM_OF_FIELDS_0) { if (code == TSDBConstants.JNI_NUM_OF_FIELDS_0) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_NUM_OF_FIELDS_0); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_NUM_OF_FIELDS_0);
} }
assertEquals(1, connector.getResultTimePrecision(pSql));
int columnSize = columnMetaDataList.size(); int columnSize = columnMetaDataList.size();
// print metadata // print metadata
for (int i = 0; i < columnSize; i++) { for (int i = 0; i < columnSize; i++) {
...@@ -45,8 +103,7 @@ public class TSDBJNIConnectorTest { ...@@ -45,8 +103,7 @@ public class TSDBJNIConnectorTest {
rowData = new TSDBResultSetRowData(columnSize); rowData = new TSDBResultSetRowData(columnSize);
// iterate resultSet // iterate resultSet
for (int i = 0; next(connector, pSql); i++) { for (int i = 0; next(connector, pSql); i++) {
System.out.println("col[" + i + "] size: " + rowData.getColSize()); assertEquals(1, connector.getResultTimePrecision(pSql));
rowData.getData().stream().forEach(col -> System.out.print(col + "\t"));
System.out.println(); System.out.println();
} }
// close resultSet // close resultSet
......
...@@ -54,16 +54,17 @@ public class TSDBParameterMetaDataTest { ...@@ -54,16 +54,17 @@ public class TSDBParameterMetaDataTest {
@Test @Test
public void getPrecision() throws SQLException { public void getPrecision() throws SQLException {
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(1)); //create table weather(ts timestamp, f1 int, f2 bigint, f3 float, f4 double, f5 smallint, f6 tinyint, f7 bool, f8 binary(64), f9 nchar(64))
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(2)); Assert.assertEquals(TSDBConstants.TIMESTAMP_MS_PRECISION, parameterMetaData_insert.getPrecision(1));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(3)); Assert.assertEquals(TSDBConstants.INT_PRECISION, parameterMetaData_insert.getPrecision(2));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(4)); Assert.assertEquals(TSDBConstants.BIGINT_PRECISION, parameterMetaData_insert.getPrecision(3));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(5)); Assert.assertEquals(TSDBConstants.FLOAT_PRECISION, parameterMetaData_insert.getPrecision(4));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(6)); Assert.assertEquals(TSDBConstants.DOUBLE_PRECISION, parameterMetaData_insert.getPrecision(5));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(7)); Assert.assertEquals(TSDBConstants.SMALLINT_PRECISION, parameterMetaData_insert.getPrecision(6));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(8)); Assert.assertEquals(TSDBConstants.TINYINT_PRECISION, parameterMetaData_insert.getPrecision(7));
Assert.assertEquals(5, parameterMetaData_insert.getPrecision(9)); Assert.assertEquals(TSDBConstants.BOOLEAN_PRECISION, parameterMetaData_insert.getPrecision(8));
Assert.assertEquals(5, parameterMetaData_insert.getPrecision(10)); Assert.assertEquals("hello".getBytes().length, parameterMetaData_insert.getPrecision(9));
Assert.assertEquals("涛思数据".length(), parameterMetaData_insert.getPrecision(10));
} }
@Test @Test
...@@ -71,8 +72,8 @@ public class TSDBParameterMetaDataTest { ...@@ -71,8 +72,8 @@ public class TSDBParameterMetaDataTest {
Assert.assertEquals(0, parameterMetaData_insert.getScale(1)); Assert.assertEquals(0, parameterMetaData_insert.getScale(1));
Assert.assertEquals(0, parameterMetaData_insert.getScale(2)); Assert.assertEquals(0, parameterMetaData_insert.getScale(2));
Assert.assertEquals(0, parameterMetaData_insert.getScale(3)); Assert.assertEquals(0, parameterMetaData_insert.getScale(3));
Assert.assertEquals(0, parameterMetaData_insert.getScale(4)); Assert.assertEquals(31, parameterMetaData_insert.getScale(4));
Assert.assertEquals(0, parameterMetaData_insert.getScale(5)); Assert.assertEquals(31, parameterMetaData_insert.getScale(5));
Assert.assertEquals(0, parameterMetaData_insert.getScale(6)); Assert.assertEquals(0, parameterMetaData_insert.getScale(6));
Assert.assertEquals(0, parameterMetaData_insert.getScale(7)); Assert.assertEquals(0, parameterMetaData_insert.getScale(7));
Assert.assertEquals(0, parameterMetaData_insert.getScale(8)); Assert.assertEquals(0, parameterMetaData_insert.getScale(8));
...@@ -124,10 +125,16 @@ public class TSDBParameterMetaDataTest { ...@@ -124,10 +125,16 @@ public class TSDBParameterMetaDataTest {
@Test @Test
public void getParameterMode() throws SQLException { public void getParameterMode() throws SQLException {
for (int i = 1; i <= parameterMetaData_insert.getParameterCount(); i++) { Assert.assertEquals(ParameterMetaData.parameterModeUnknown, parameterMetaData_insert.getParameterMode(1));
int parameterMode = parameterMetaData_insert.getParameterMode(i); Assert.assertEquals(ParameterMetaData.parameterModeUnknown, parameterMetaData_insert.getParameterMode(2));
Assert.assertEquals(ParameterMetaData.parameterModeUnknown, parameterMode); Assert.assertEquals(ParameterMetaData.parameterModeUnknown, parameterMetaData_insert.getParameterMode(3));
} Assert.assertEquals(ParameterMetaData.parameterModeUnknown, parameterMetaData_insert.getParameterMode(4));
Assert.assertEquals(ParameterMetaData.parameterModeUnknown, parameterMetaData_insert.getParameterMode(5));
Assert.assertEquals(ParameterMetaData.parameterModeUnknown, parameterMetaData_insert.getParameterMode(6));
Assert.assertEquals(ParameterMetaData.parameterModeUnknown, parameterMetaData_insert.getParameterMode(7));
Assert.assertEquals(ParameterMetaData.parameterModeUnknown, parameterMetaData_insert.getParameterMode(8));
Assert.assertEquals(ParameterMetaData.parameterModeUnknown, parameterMetaData_insert.getParameterMode(9));
Assert.assertEquals(ParameterMetaData.parameterModeUnknown, parameterMetaData_insert.getParameterMode(10));
} }
@Test @Test
...@@ -144,7 +151,6 @@ public class TSDBParameterMetaDataTest { ...@@ -144,7 +151,6 @@ public class TSDBParameterMetaDataTest {
@BeforeClass @BeforeClass
public static void beforeClass() { public static void beforeClass() {
try { try {
Class.forName("com.taosdata.jdbc.TSDBDriver");
conn = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata"); conn = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata");
try (Statement stmt = conn.createStatement()) { try (Statement stmt = conn.createStatement()) {
stmt.execute("drop database if exists test_pstmt"); stmt.execute("drop database if exists test_pstmt");
...@@ -164,7 +170,7 @@ public class TSDBParameterMetaDataTest { ...@@ -164,7 +170,7 @@ public class TSDBParameterMetaDataTest {
pstmt_insert.setObject(7, Byte.MAX_VALUE); pstmt_insert.setObject(7, Byte.MAX_VALUE);
pstmt_insert.setObject(8, true); pstmt_insert.setObject(8, true);
pstmt_insert.setObject(9, "hello".getBytes()); pstmt_insert.setObject(9, "hello".getBytes());
pstmt_insert.setObject(10, "Hello"); pstmt_insert.setObject(10, "涛思数据");
parameterMetaData_insert = pstmt_insert.getParameterMetaData(); parameterMetaData_insert = pstmt_insert.getParameterMetaData();
pstmt_select = conn.prepareStatement(sql_select); pstmt_select = conn.prepareStatement(sql_select);
...@@ -173,7 +179,7 @@ public class TSDBParameterMetaDataTest { ...@@ -173,7 +179,7 @@ public class TSDBParameterMetaDataTest {
pstmt_select.setInt(3, 0); pstmt_select.setInt(3, 0);
parameterMetaData_select = pstmt_select.getParameterMetaData(); parameterMetaData_select = pstmt_select.getParameterMetaData();
} catch (ClassNotFoundException | SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
......
package com.taosdata.jdbc.rs; package com.taosdata.jdbc.cases;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
......
...@@ -7,7 +7,7 @@ import org.junit.*; ...@@ -7,7 +7,7 @@ import org.junit.*;
import java.sql.*; import java.sql.*;
import java.util.Properties; import java.util.Properties;
public class TD3841Test { public class NullValueInResultSetTest {
private static final String host = "127.0.0.1"; private static final String host = "127.0.0.1";
private static Properties properties; private static Properties properties;
private static Connection conn_restful; private static Connection conn_restful;
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册