sync jdbc from develop to master (#6394)
* change * remove test cases not available for master branch Co-authored-by: Ping Xiao <pxiao@taosdata.com>
This commit is contained in:
parent
c99a639c79
commit
3bf8a5dd7e
|
@ -84,10 +84,12 @@ public abstract class AbstractResultSet extends WrapperImpl implements ResultSet
|
|||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public InputStream getUnicodeStream(int columnIndex) throws SQLException {
|
||||
if (isClosed())
|
||||
if (isClosed()) {
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
|
||||
|
||||
}
|
||||
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
|
||||
}
|
||||
|
||||
|
@ -171,6 +173,7 @@ public abstract class AbstractResultSet extends WrapperImpl implements ResultSet
|
|||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public InputStream getUnicodeStream(String columnLabel) throws SQLException {
|
||||
return getUnicodeStream(findColumn(columnLabel));
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ public class TSDBConnection extends AbstractConnection {
|
|||
this.databaseMetaData.setConnection(this);
|
||||
}
|
||||
|
||||
public TSDBJNIConnector getConnection() {
|
||||
public TSDBJNIConnector getConnector() {
|
||||
return this.connector;
|
||||
}
|
||||
|
||||
|
@ -58,7 +58,7 @@ public class TSDBConnection extends AbstractConnection {
|
|||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
|
||||
}
|
||||
|
||||
return new TSDBStatement(this, this.connector);
|
||||
return new TSDBStatement(this);
|
||||
}
|
||||
|
||||
public TSDBSubscribe subscribe(String topic, String sql, boolean restart) throws SQLException {
|
||||
|
@ -74,14 +74,18 @@ public class TSDBConnection extends AbstractConnection {
|
|||
}
|
||||
|
||||
public PreparedStatement prepareStatement(String sql) throws SQLException {
|
||||
if (isClosed())
|
||||
if (isClosed()) {
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
|
||||
return new TSDBPreparedStatement(this, this.connector, sql);
|
||||
}
|
||||
|
||||
return new TSDBPreparedStatement(this, sql);
|
||||
}
|
||||
|
||||
public void close() throws SQLException {
|
||||
if (isClosed)
|
||||
if (isClosed) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.connector.closeConnection();
|
||||
this.isClosed = true;
|
||||
}
|
||||
|
|
|
@ -16,12 +16,13 @@
|
|||
*/
|
||||
package com.taosdata.jdbc;
|
||||
|
||||
import com.taosdata.jdbc.utils.TaosInfo;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.SQLWarning;
|
||||
import java.util.List;
|
||||
|
||||
import com.taosdata.jdbc.utils.TaosInfo;
|
||||
|
||||
/**
|
||||
* JNI connector
|
||||
*/
|
||||
|
@ -29,10 +30,13 @@ public class TSDBJNIConnector {
|
|||
private static volatile Boolean isInitialized = false;
|
||||
|
||||
private TaosInfo taosInfo = TaosInfo.getInstance();
|
||||
|
||||
// Connection pointer used in C
|
||||
private long taos = TSDBConstants.JNI_NULL_POINTER;
|
||||
|
||||
// result set status in current connection
|
||||
private boolean isResultsetClosed;
|
||||
|
||||
private int affectedRows = -1;
|
||||
|
||||
static {
|
||||
|
@ -75,7 +79,6 @@ public class TSDBJNIConnector {
|
|||
|
||||
public boolean connect(String host, int port, String dbName, String user, String password) throws SQLException {
|
||||
if (this.taos != TSDBConstants.JNI_NULL_POINTER) {
|
||||
// this.closeConnectionImp(this.taos);
|
||||
closeConnection();
|
||||
this.taos = TSDBConstants.JNI_NULL_POINTER;
|
||||
}
|
||||
|
@ -97,12 +100,6 @@ public class TSDBJNIConnector {
|
|||
* @throws SQLException
|
||||
*/
|
||||
public long executeQuery(String sql) throws SQLException {
|
||||
// close previous result set if the user forgets to invoke the
|
||||
// free method to close previous result set.
|
||||
// if (!this.isResultsetClosed) {
|
||||
// freeResultSet(taosResultSetPointer);
|
||||
// }
|
||||
|
||||
Long pSql = 0l;
|
||||
try {
|
||||
pSql = this.executeQueryImp(sql.getBytes(TaosGlobalConfig.getCharset()), this.taos);
|
||||
|
@ -170,7 +167,7 @@ public class TSDBJNIConnector {
|
|||
private native long isUpdateQueryImp(long connection, long pSql);
|
||||
|
||||
/**
|
||||
* Free resultset operation from C to release resultset pointer by JNI
|
||||
* Free result set operation from C to release result set pointer by JNI
|
||||
*/
|
||||
public int freeResultSet(long pSql) {
|
||||
int res = this.freeResultSetImp(this.taos, pSql);
|
||||
|
@ -178,19 +175,6 @@ public class TSDBJNIConnector {
|
|||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the open result set which is associated to the current connection. If the result set is already
|
||||
* closed, return 0 for success.
|
||||
*/
|
||||
// public int freeResultSet() {
|
||||
// int resCode = TSDBConstants.JNI_SUCCESS;
|
||||
// if (!isResultsetClosed) {
|
||||
// resCode = this.freeResultSetImp(this.taos, this.taosResultSetPointer);
|
||||
// taosResultSetPointer = TSDBConstants.JNI_NULL_POINTER;
|
||||
// isResultsetClosed = true;
|
||||
// }
|
||||
// return resCode;
|
||||
// }
|
||||
private native int freeResultSetImp(long connection, long result);
|
||||
|
||||
/**
|
||||
|
@ -237,6 +221,7 @@ public class TSDBJNIConnector {
|
|||
*/
|
||||
public void closeConnection() throws SQLException {
|
||||
int code = this.closeConnectionImp(this.taos);
|
||||
|
||||
if (code < 0) {
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL);
|
||||
} else if (code == 0) {
|
||||
|
@ -244,6 +229,7 @@ public class TSDBJNIConnector {
|
|||
} else {
|
||||
throw new SQLException("Undefined error code returned by TDengine when closing a connection");
|
||||
}
|
||||
|
||||
// invoke closeConnectionImpl only here
|
||||
taosInfo.connect_close_increment();
|
||||
}
|
||||
|
@ -280,7 +266,7 @@ public class TSDBJNIConnector {
|
|||
private native void unsubscribeImp(long subscription, boolean isKeep);
|
||||
|
||||
/**
|
||||
* Validate if a <I>create table</I> sql statement is correct without actually creating that table
|
||||
* Validate if a <I>create table</I> SQL statement is correct without actually creating that table
|
||||
*/
|
||||
public boolean validateCreateTableSql(String sql) {
|
||||
int res = validateCreateTableSqlImp(taos, sql.getBytes());
|
||||
|
@ -288,4 +274,67 @@ public class TSDBJNIConnector {
|
|||
}
|
||||
|
||||
private native int validateCreateTableSqlImp(long connection, byte[] sqlBytes);
|
||||
|
||||
public long prepareStmt(String sql) throws SQLException {
|
||||
Long stmt = prepareStmtImp(sql.getBytes(), this.taos);
|
||||
if (stmt == TSDBConstants.JNI_TDENGINE_ERROR) {
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_SQL);
|
||||
} else if (stmt == TSDBConstants.JNI_CONNECTION_NULL) {
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL);
|
||||
} else if (stmt == TSDBConstants.JNI_SQL_NULL) {
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_SQL_NULL);
|
||||
} else if (stmt == TSDBConstants.JNI_OUT_OF_MEMORY) {
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
return stmt;
|
||||
}
|
||||
|
||||
private native long prepareStmtImp(byte[] sql, long con);
|
||||
|
||||
public void setBindTableName(long stmt, String tableName) throws SQLException {
|
||||
int code = setBindTableNameImp(stmt, tableName, this.taos);
|
||||
if (code != TSDBConstants.JNI_SUCCESS) {
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "failed to set table name");
|
||||
}
|
||||
}
|
||||
|
||||
private native int setBindTableNameImp(long stmt, String name, long conn);
|
||||
|
||||
public void setBindTableNameAndTags(long stmt, String tableName, int numOfTags, ByteBuffer tags, ByteBuffer typeList, ByteBuffer lengthList, ByteBuffer nullList) throws SQLException {
|
||||
int code = setTableNameTagsImp(stmt, tableName, numOfTags, tags.array(), typeList.array(), lengthList.array(),
|
||||
nullList.array(), this.taos);
|
||||
if (code != TSDBConstants.JNI_SUCCESS) {
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "failed to bind table name and corresponding tags");
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
int code = bindColDataImp(stmt, colDataList.array(), lengthList.array(), isNullList.array(), type, bytes, numOfRows, columnIndex, this.taos);
|
||||
if (code != TSDBConstants.JNI_SUCCESS) {
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "failed to bind column data");
|
||||
}
|
||||
}
|
||||
|
||||
private native int bindColDataImp(long stmt, byte[] colDataList, byte[] lengthList, byte[] isNullList, int type, int bytes, int numOfRows, int columnIndex, long conn);
|
||||
|
||||
public void executeBatch(long stmt) throws SQLException {
|
||||
int code = executeBatchImp(stmt, this.taos);
|
||||
if (code != TSDBConstants.JNI_SUCCESS) {
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "failed to execute batch bind");
|
||||
}
|
||||
}
|
||||
|
||||
private native int executeBatchImp(long stmt, long con);
|
||||
|
||||
public void closeBatch(long stmt) throws SQLException {
|
||||
int code = closeStmt(stmt, this.taos);
|
||||
if (code != TSDBConstants.JNI_SUCCESS) {
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "failed to close batch bind");
|
||||
}
|
||||
}
|
||||
|
||||
private native int closeStmt(long stmt, long con);
|
||||
}
|
||||
|
|
|
@ -18,33 +18,43 @@ import com.taosdata.jdbc.utils.Utils;
|
|||
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.math.BigDecimal;
|
||||
import java.net.URL;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.sql.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/*
|
||||
* 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
|
||||
* compatibility needs.
|
||||
*/
|
||||
public class TSDBPreparedStatement extends TSDBStatement implements PreparedStatement {
|
||||
|
||||
private String rawSql;
|
||||
private Object[] parameters;
|
||||
private boolean isPrepared;
|
||||
|
||||
|
||||
private ArrayList<ColumnInfo> colData;
|
||||
private ArrayList<TableTagInfo> tableTags;
|
||||
private int tagValueLength;
|
||||
|
||||
private String tableName;
|
||||
private long nativeStmtHandle = 0;
|
||||
|
||||
private volatile TSDBParameterMetaData parameterMetaData;
|
||||
|
||||
TSDBPreparedStatement(TSDBConnection connection, TSDBJNIConnector connecter, String sql) {
|
||||
super(connection, connecter);
|
||||
TSDBPreparedStatement(TSDBConnection connection, String sql) {
|
||||
super(connection);
|
||||
init(sql);
|
||||
|
||||
int parameterCnt = 0;
|
||||
if (sql.contains("?")) {
|
||||
int parameterCnt = 0;
|
||||
for (int i = 0; i < sql.length(); i++) {
|
||||
if ('?' == sql.charAt(i)) {
|
||||
parameterCnt++;
|
||||
|
@ -53,6 +63,12 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
|
|||
parameters = new Object[parameterCnt];
|
||||
this.isPrepared = true;
|
||||
}
|
||||
|
||||
if (parameterCnt > 1) {
|
||||
// the table name is also a parameter, so ignore it.
|
||||
this.colData = new ArrayList<ColumnInfo>();
|
||||
this.tableTags = new ArrayList<TableTagInfo>();
|
||||
}
|
||||
}
|
||||
|
||||
private void init(String sql) {
|
||||
|
@ -260,10 +276,14 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
|
|||
|
||||
@Override
|
||||
public void setObject(int parameterIndex, Object x) throws SQLException {
|
||||
if (isClosed())
|
||||
if (isClosed()) {
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
||||
if (parameterIndex < 1 && parameterIndex >= parameters.length)
|
||||
}
|
||||
|
||||
if (parameterIndex < 1 && parameterIndex >= parameters.length) {
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE);
|
||||
}
|
||||
|
||||
parameters[parameterIndex - 1] = x;
|
||||
}
|
||||
|
||||
|
@ -300,9 +320,10 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
|
|||
|
||||
@Override
|
||||
public void setRef(int parameterIndex, Ref x) throws SQLException {
|
||||
if (isClosed())
|
||||
if (isClosed()) {
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
||||
|
||||
}
|
||||
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
|
||||
}
|
||||
|
||||
|
@ -515,4 +536,489 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
|
|||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// NOTE: the following APIs are not JDBC compatible
|
||||
// set the bind table name
|
||||
private static class ColumnInfo {
|
||||
@SuppressWarnings("rawtypes")
|
||||
private ArrayList data;
|
||||
private int type;
|
||||
private int bytes;
|
||||
private boolean typeIsSet;
|
||||
|
||||
public ColumnInfo() {
|
||||
this.typeIsSet = false;
|
||||
}
|
||||
|
||||
public void setType(int type) throws SQLException {
|
||||
if (this.isTypeSet()) {
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "column data type has been set");
|
||||
}
|
||||
|
||||
this.typeIsSet = true;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public boolean isTypeSet() {
|
||||
return this.typeIsSet;
|
||||
}
|
||||
};
|
||||
|
||||
private static class TableTagInfo {
|
||||
private boolean isNull;
|
||||
private Object value;
|
||||
private int type;
|
||||
public TableTagInfo(Object value, int type) {
|
||||
this.value = value;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public static TableTagInfo createNullTag(int type) {
|
||||
TableTagInfo info = new TableTagInfo(null, type);
|
||||
info.isNull = true;
|
||||
return info;
|
||||
}
|
||||
};
|
||||
|
||||
public void setTableName(String name) {
|
||||
this.tableName = name;
|
||||
}
|
||||
|
||||
private void ensureTagCapacity(int index) {
|
||||
if (this.tableTags.size() < index + 1) {
|
||||
int delta = index + 1 - this.tableTags.size();
|
||||
this.tableTags.addAll(Collections.nCopies(delta, null));
|
||||
}
|
||||
}
|
||||
|
||||
public void setTagNull(int index, int type) {
|
||||
ensureTagCapacity(index);
|
||||
this.tableTags.set(index, TableTagInfo.createNullTag(type));
|
||||
}
|
||||
|
||||
public void setTagBoolean(int index, boolean value) {
|
||||
ensureTagCapacity(index);
|
||||
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_BOOL));
|
||||
this.tagValueLength += Byte.BYTES;
|
||||
}
|
||||
|
||||
public void setTagInt(int index, int value) {
|
||||
ensureTagCapacity(index);
|
||||
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_INT));
|
||||
this.tagValueLength += Integer.BYTES;
|
||||
}
|
||||
|
||||
public void setTagByte(int index, byte value) {
|
||||
ensureTagCapacity(index);
|
||||
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_TINYINT));
|
||||
this.tagValueLength += Byte.BYTES;
|
||||
}
|
||||
|
||||
public void setTagShort(int index, short value) {
|
||||
ensureTagCapacity(index);
|
||||
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_SMALLINT));
|
||||
this.tagValueLength += Short.BYTES;
|
||||
}
|
||||
|
||||
public void setTagLong(int index, long value) {
|
||||
ensureTagCapacity(index);
|
||||
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_BIGINT));
|
||||
this.tagValueLength += Long.BYTES;
|
||||
}
|
||||
|
||||
public void setTagTimestamp(int index, long value) {
|
||||
ensureTagCapacity(index);
|
||||
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP));
|
||||
this.tagValueLength += Long.BYTES;
|
||||
}
|
||||
|
||||
public void setTagFloat(int index, float value) {
|
||||
ensureTagCapacity(index);
|
||||
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_FLOAT));
|
||||
this.tagValueLength += Float.BYTES;
|
||||
}
|
||||
|
||||
public void setTagDouble(int index, double value) {
|
||||
ensureTagCapacity(index);
|
||||
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_DOUBLE));
|
||||
this.tagValueLength += Double.BYTES;
|
||||
}
|
||||
|
||||
public void setTagString(int index, String value) {
|
||||
ensureTagCapacity(index);
|
||||
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_BINARY));
|
||||
this.tagValueLength += value.getBytes().length;
|
||||
}
|
||||
|
||||
public void setTagNString(int index, String value) {
|
||||
ensureTagCapacity(index);
|
||||
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_NCHAR));
|
||||
|
||||
String charset = TaosGlobalConfig.getCharset();
|
||||
try {
|
||||
this.tagValueLength += value.getBytes(charset).length;
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public <T> void setValueImpl(int columnIndex, ArrayList<T> list, int type, int bytes) throws SQLException {
|
||||
if (this.colData.size() == 0) {
|
||||
this.colData.addAll(Collections.nCopies(this.parameters.length - 1 - this.tableTags.size(), null));
|
||||
|
||||
}
|
||||
ColumnInfo col = (ColumnInfo) this.colData.get(columnIndex);
|
||||
if (col == null) {
|
||||
ColumnInfo p = new ColumnInfo();
|
||||
p.setType(type);
|
||||
p.bytes = bytes;
|
||||
p.data = (ArrayList<?>) list.clone();
|
||||
this.colData.set(columnIndex, p);
|
||||
} else {
|
||||
if (col.type != type) {
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "column data type mismatch");
|
||||
}
|
||||
col.data.addAll(list);
|
||||
}
|
||||
}
|
||||
|
||||
public void setInt(int columnIndex, ArrayList<Integer> list) throws SQLException {
|
||||
setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_INT, Integer.BYTES);
|
||||
}
|
||||
|
||||
public void setFloat(int columnIndex, ArrayList<Float> list) throws SQLException {
|
||||
setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_FLOAT, Float.BYTES);
|
||||
}
|
||||
|
||||
public void setTimestamp(int columnIndex, ArrayList<Long> list) throws SQLException {
|
||||
setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP, Long.BYTES);
|
||||
}
|
||||
|
||||
public void setLong(int columnIndex, ArrayList<Long> list) throws SQLException {
|
||||
setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_BIGINT, Long.BYTES);
|
||||
}
|
||||
|
||||
public void setDouble(int columnIndex, ArrayList<Double> list) throws SQLException {
|
||||
setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_DOUBLE, Double.BYTES);
|
||||
}
|
||||
|
||||
public void setBoolean(int columnIndex, ArrayList<Boolean> list) throws SQLException {
|
||||
setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_BOOL, Byte.BYTES);
|
||||
}
|
||||
|
||||
public void setByte(int columnIndex, ArrayList<Byte> list) throws SQLException {
|
||||
setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_TINYINT, Byte.BYTES);
|
||||
}
|
||||
|
||||
public void setShort(int columnIndex, ArrayList<Short> list) throws SQLException {
|
||||
setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_SMALLINT, Short.BYTES);
|
||||
}
|
||||
|
||||
public void setString(int columnIndex, ArrayList<String> list, int size) throws SQLException {
|
||||
setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_BINARY, size);
|
||||
}
|
||||
|
||||
// note: expand the required space for each NChar character
|
||||
public void setNString(int columnIndex, ArrayList<String> list, int size) throws SQLException {
|
||||
setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_NCHAR, size * Integer.BYTES);
|
||||
}
|
||||
|
||||
public void columnDataAddBatch() throws SQLException {
|
||||
// pass the data block to native code
|
||||
if (rawSql == null) {
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "sql statement not set yet");
|
||||
}
|
||||
|
||||
// table name is not set yet, abort
|
||||
if (this.tableName == null) {
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "table name not set yet");
|
||||
}
|
||||
|
||||
int numOfCols = this.colData.size();
|
||||
if (numOfCols == 0) {
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "column data not bind");
|
||||
}
|
||||
|
||||
TSDBJNIConnector connector = ((TSDBConnection) this.getConnection()).getConnector();
|
||||
this.nativeStmtHandle = connector.prepareStmt(rawSql);
|
||||
|
||||
if (this.tableTags == null) {
|
||||
connector.setBindTableName(this.nativeStmtHandle, this.tableName);
|
||||
} else {
|
||||
int num = this.tableTags.size();
|
||||
ByteBuffer tagDataList = ByteBuffer.allocate(this.tagValueLength);
|
||||
tagDataList.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
ByteBuffer typeList = ByteBuffer.allocate(num);
|
||||
typeList.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
ByteBuffer lengthList = ByteBuffer.allocate(num * Long.BYTES);
|
||||
lengthList.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
ByteBuffer isNullList = ByteBuffer.allocate(num * Integer.BYTES);
|
||||
isNullList.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
for (int i = 0; i < num; ++i) {
|
||||
TableTagInfo tag = this.tableTags.get(i);
|
||||
if (tag.isNull) {
|
||||
typeList.put((byte) tag.type);
|
||||
isNullList.putInt(1);
|
||||
lengthList.putLong(0);
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (tag.type) {
|
||||
case TSDBConstants.TSDB_DATA_TYPE_INT: {
|
||||
Integer val = (Integer) tag.value;
|
||||
tagDataList.putInt(val);
|
||||
lengthList.putLong(Integer.BYTES);
|
||||
break;
|
||||
}
|
||||
case TSDBConstants.TSDB_DATA_TYPE_TINYINT: {
|
||||
Byte val = (Byte) tag.value;
|
||||
tagDataList.put(val);
|
||||
lengthList.putLong(Byte.BYTES);
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDBConstants.TSDB_DATA_TYPE_BOOL: {
|
||||
Boolean val = (Boolean) tag.value;
|
||||
tagDataList.put((byte) (val ? 1 : 0));
|
||||
lengthList.putLong(Byte.BYTES);
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: {
|
||||
Short val = (Short) tag.value;
|
||||
tagDataList.putShort(val);
|
||||
lengthList.putLong(Short.BYTES);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
|
||||
case TSDBConstants.TSDB_DATA_TYPE_BIGINT: {
|
||||
Long val = (Long) tag.value;
|
||||
tagDataList.putLong(val == null ? 0 : val);
|
||||
lengthList.putLong(Long.BYTES);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDBConstants.TSDB_DATA_TYPE_FLOAT: {
|
||||
Float val = (Float) tag.value;
|
||||
tagDataList.putFloat(val == null ? 0 : val);
|
||||
lengthList.putLong(Float.BYTES);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: {
|
||||
Double val = (Double) tag.value;
|
||||
tagDataList.putDouble(val == null ? 0 : val);
|
||||
lengthList.putLong(Double.BYTES);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
|
||||
case TSDBConstants.TSDB_DATA_TYPE_BINARY: {
|
||||
String charset = TaosGlobalConfig.getCharset();
|
||||
String val = (String) tag.value;
|
||||
|
||||
byte[] b = null;
|
||||
try {
|
||||
if (tag.type == TSDBConstants.TSDB_DATA_TYPE_BINARY) {
|
||||
b = val.getBytes();
|
||||
} else {
|
||||
b = val.getBytes(charset);
|
||||
}
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
tagDataList.put(b);
|
||||
lengthList.putLong(b.length);
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDBConstants.TSDB_DATA_TYPE_UTINYINT:
|
||||
case TSDBConstants.TSDB_DATA_TYPE_USMALLINT:
|
||||
case TSDBConstants.TSDB_DATA_TYPE_UINT:
|
||||
case TSDBConstants.TSDB_DATA_TYPE_UBIGINT: {
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "not support data types");
|
||||
}
|
||||
}
|
||||
|
||||
typeList.put((byte) tag.type);
|
||||
isNullList.putInt(tag.isNull? 1 : 0);
|
||||
}
|
||||
|
||||
connector.setBindTableNameAndTags(this.nativeStmtHandle, this.tableName, this.tableTags.size(), tagDataList,
|
||||
typeList, lengthList, isNullList);
|
||||
}
|
||||
|
||||
ColumnInfo colInfo = (ColumnInfo) this.colData.get(0);
|
||||
if (colInfo == null) {
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "column data not bind");
|
||||
}
|
||||
|
||||
int rows = colInfo.data.size();
|
||||
for (int i = 0; i < numOfCols; ++i) {
|
||||
ColumnInfo col1 = this.colData.get(i);
|
||||
if (col1 == null || !col1.isTypeSet()) {
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "column data not bind");
|
||||
}
|
||||
|
||||
if (rows != col1.data.size()) {
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "the rows in column data not identical");
|
||||
}
|
||||
|
||||
ByteBuffer colDataList = ByteBuffer.allocate(rows * col1.bytes);
|
||||
colDataList.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
ByteBuffer lengthList = ByteBuffer.allocate(rows * Integer.BYTES);
|
||||
lengthList.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
ByteBuffer isNullList = ByteBuffer.allocate(rows * Byte.BYTES);
|
||||
isNullList.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
switch (col1.type) {
|
||||
case TSDBConstants.TSDB_DATA_TYPE_INT: {
|
||||
for (int j = 0; j < rows; ++j) {
|
||||
Integer val = (Integer) col1.data.get(j);
|
||||
colDataList.putInt(val == null? Integer.MIN_VALUE:val);
|
||||
isNullList.put((byte) (val == null? 1:0));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDBConstants.TSDB_DATA_TYPE_TINYINT: {
|
||||
for (int j = 0; j < rows; ++j) {
|
||||
Byte val = (Byte) col1.data.get(j);
|
||||
colDataList.put(val == null? 0:val);
|
||||
isNullList.put((byte) (val == null? 1:0));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDBConstants.TSDB_DATA_TYPE_BOOL: {
|
||||
for (int j = 0; j < rows; ++j) {
|
||||
Boolean val = (Boolean) col1.data.get(j);
|
||||
if (val == null) {
|
||||
colDataList.put((byte) 0);
|
||||
} else {
|
||||
colDataList.put((byte) (val? 1:0));
|
||||
}
|
||||
|
||||
isNullList.put((byte) (val == null? 1:0));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: {
|
||||
for (int j = 0; j < rows; ++j) {
|
||||
Short val = (Short) col1.data.get(j);
|
||||
colDataList.putShort(val == null? 0:val);
|
||||
isNullList.put((byte) (val == null? 1:0));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
|
||||
case TSDBConstants.TSDB_DATA_TYPE_BIGINT: {
|
||||
for (int j = 0; j < rows; ++j) {
|
||||
Long val = (Long) col1.data.get(j);
|
||||
colDataList.putLong(val == null? 0:val);
|
||||
isNullList.put((byte) (val == null? 1:0));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDBConstants.TSDB_DATA_TYPE_FLOAT: {
|
||||
for (int j = 0; j < rows; ++j) {
|
||||
Float val = (Float) col1.data.get(j);
|
||||
colDataList.putFloat(val == null? 0:val);
|
||||
isNullList.put((byte) (val == null? 1:0));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: {
|
||||
for (int j = 0; j < rows; ++j) {
|
||||
Double val = (Double) col1.data.get(j);
|
||||
colDataList.putDouble(val == null? 0:val);
|
||||
isNullList.put((byte) (val == null? 1:0));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
|
||||
case TSDBConstants.TSDB_DATA_TYPE_BINARY: {
|
||||
String charset = TaosGlobalConfig.getCharset();
|
||||
for (int j = 0; j < rows; ++j) {
|
||||
String val = (String) col1.data.get(j);
|
||||
|
||||
colDataList.position(j * col1.bytes); // seek to the correct position
|
||||
if (val != null) {
|
||||
byte[] b = null;
|
||||
try {
|
||||
if (col1.type == TSDBConstants.TSDB_DATA_TYPE_BINARY) {
|
||||
b = val.getBytes();
|
||||
} else {
|
||||
b = val.getBytes(charset);
|
||||
}
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (val.length() > col1.bytes) {
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "string data too long");
|
||||
}
|
||||
|
||||
colDataList.put(b);
|
||||
lengthList.putInt(b.length);
|
||||
isNullList.put((byte) 0);
|
||||
} else {
|
||||
lengthList.putInt(0);
|
||||
isNullList.put((byte) 1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDBConstants.TSDB_DATA_TYPE_UTINYINT:
|
||||
case TSDBConstants.TSDB_DATA_TYPE_USMALLINT:
|
||||
case TSDBConstants.TSDB_DATA_TYPE_UINT:
|
||||
case TSDBConstants.TSDB_DATA_TYPE_UBIGINT: {
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "not support data types");
|
||||
}
|
||||
};
|
||||
|
||||
connector.bindColumnDataArray(this.nativeStmtHandle, colDataList, lengthList, isNullList, col1.type, col1.bytes, rows, i);
|
||||
}
|
||||
}
|
||||
|
||||
public void columnDataExecuteBatch() throws SQLException {
|
||||
TSDBJNIConnector connector = ((TSDBConnection) this.getConnection()).getConnector();
|
||||
connector.executeBatch(this.nativeStmtHandle);
|
||||
this.columnDataClearBatch();
|
||||
}
|
||||
|
||||
public void columnDataClearBatch() {
|
||||
int size = this.colData.size();
|
||||
this.colData.clear();
|
||||
|
||||
this.colData.addAll(Collections.nCopies(size, null));
|
||||
this.tableName = null; // clear the table name
|
||||
}
|
||||
|
||||
public void columnDataCloseBatch() throws SQLException {
|
||||
TSDBJNIConnector connector = ((TSDBConnection) this.getConnection()).getConnector();
|
||||
connector.closeBatch(this.nativeStmtHandle);
|
||||
|
||||
this.nativeStmtHandle = 0L;
|
||||
this.tableName = null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,8 @@ import java.util.ArrayList;
|
|||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.taosdata.jdbc.utils.NullType;
|
||||
|
||||
public class TSDBResultSetBlockData {
|
||||
private int numOfRows = 0;
|
||||
private int rowIndex = 0;
|
||||
|
@ -164,59 +166,7 @@ public class TSDBResultSetBlockData {
|
|||
}
|
||||
}
|
||||
|
||||
private static class NullType {
|
||||
private static final byte NULL_BOOL_VAL = 0x2;
|
||||
private static final String NULL_STR = "null";
|
||||
|
||||
public String toString() {
|
||||
return NullType.NULL_STR;
|
||||
}
|
||||
|
||||
public static boolean isBooleanNull(byte val) {
|
||||
return val == NullType.NULL_BOOL_VAL;
|
||||
}
|
||||
|
||||
private static boolean isTinyIntNull(byte val) {
|
||||
return val == Byte.MIN_VALUE;
|
||||
}
|
||||
|
||||
private static boolean isSmallIntNull(short val) {
|
||||
return val == Short.MIN_VALUE;
|
||||
}
|
||||
|
||||
private static boolean isIntNull(int val) {
|
||||
return val == Integer.MIN_VALUE;
|
||||
}
|
||||
|
||||
private static boolean isBigIntNull(long val) {
|
||||
return val == Long.MIN_VALUE;
|
||||
}
|
||||
|
||||
private static boolean isFloatNull(float val) {
|
||||
return Float.isNaN(val);
|
||||
}
|
||||
|
||||
private static boolean isDoubleNull(double val) {
|
||||
return Double.isNaN(val);
|
||||
}
|
||||
|
||||
private static boolean isBinaryNull(byte[] val, int length) {
|
||||
if (length != Byte.BYTES) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return val[0] == 0xFF;
|
||||
}
|
||||
|
||||
private static boolean isNcharNull(byte[] val, int length) {
|
||||
if (length != Integer.BYTES) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (val[0] & val[1] & val[2] & val[3]) == 0xFF;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The original type may not be a string type, but will be converted to by
|
||||
|
@ -488,8 +438,8 @@ public class TSDBResultSetBlockData {
|
|||
}
|
||||
|
||||
try {
|
||||
String ss = TaosGlobalConfig.getCharset();
|
||||
return new String(dest, ss);
|
||||
String charset = TaosGlobalConfig.getCharset();
|
||||
return new String(dest, charset);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
|
|
@ -84,7 +84,8 @@ public class TSDBResultSetRowData {
|
|||
data.set(col, value);
|
||||
}
|
||||
|
||||
public int getInt(int col, int srcType) throws SQLException {
|
||||
@SuppressWarnings("deprecation")
|
||||
public int getInt(int col, int srcType) throws SQLException {
|
||||
Object obj = data.get(col);
|
||||
|
||||
switch (srcType) {
|
||||
|
@ -128,7 +129,7 @@ public class TSDBResultSetRowData {
|
|||
long value = (long) obj;
|
||||
if (value < 0)
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE);
|
||||
return new Long(value).intValue();
|
||||
return Long.valueOf(value).intValue();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,8 +19,6 @@ import java.sql.ResultSet;
|
|||
import java.sql.SQLException;
|
||||
|
||||
public class TSDBStatement extends AbstractStatement {
|
||||
|
||||
private TSDBJNIConnector connector;
|
||||
/**
|
||||
* Status of current statement
|
||||
*/
|
||||
|
@ -29,29 +27,26 @@ public class TSDBStatement extends AbstractStatement {
|
|||
private TSDBConnection connection;
|
||||
private TSDBResultSet resultSet;
|
||||
|
||||
public void setConnection(TSDBConnection connection) {
|
||||
TSDBStatement(TSDBConnection connection) {
|
||||
this.connection = connection;
|
||||
}
|
||||
|
||||
TSDBStatement(TSDBConnection connection, TSDBJNIConnector connector) {
|
||||
this.connection = connection;
|
||||
this.connector = connector;
|
||||
}
|
||||
|
||||
public ResultSet executeQuery(String sql) throws SQLException {
|
||||
// check if closed
|
||||
if (isClosed())
|
||||
if (isClosed()) {
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
||||
}
|
||||
|
||||
//TODO: 如果在executeQuery方法中执行insert语句,那么先执行了SQL,再通过pSql来检查是否为一个insert语句,但这个insert SQL已经执行成功了
|
||||
|
||||
// execute query
|
||||
long pSql = this.connector.executeQuery(sql);
|
||||
long pSql = this.connection.getConnector().executeQuery(sql);
|
||||
// if pSql is create/insert/update/delete/alter SQL
|
||||
if (this.connector.isUpdateQuery(pSql)) {
|
||||
this.connector.freeResultSet(pSql);
|
||||
if (this.connection.getConnector().isUpdateQuery(pSql)) {
|
||||
this.connection.getConnector().freeResultSet(pSql);
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_WITH_EXECUTEQUERY);
|
||||
}
|
||||
TSDBResultSet res = new TSDBResultSet(this, this.connector, pSql);
|
||||
TSDBResultSet res = new TSDBResultSet(this, this.connection.getConnector(), pSql);
|
||||
res.setBatchFetch(this.connection.getBatchFetch());
|
||||
return res;
|
||||
}
|
||||
|
@ -60,14 +55,14 @@ public class TSDBStatement extends AbstractStatement {
|
|||
if (isClosed())
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
||||
|
||||
long pSql = this.connector.executeQuery(sql);
|
||||
long pSql = this.connection.getConnector().executeQuery(sql);
|
||||
// if pSql is create/insert/update/delete/alter SQL
|
||||
if (!this.connector.isUpdateQuery(pSql)) {
|
||||
this.connector.freeResultSet(pSql);
|
||||
if (!this.connection.getConnector().isUpdateQuery(pSql)) {
|
||||
this.connection.getConnector().freeResultSet(pSql);
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_WITH_EXECUTEUPDATE);
|
||||
}
|
||||
int affectedRows = this.connector.getAffectedRows(pSql);
|
||||
this.connector.freeResultSet(pSql);
|
||||
int affectedRows = this.connection.getConnector().getAffectedRows(pSql);
|
||||
this.connection.getConnector().freeResultSet(pSql);
|
||||
return affectedRows;
|
||||
}
|
||||
|
||||
|
@ -81,30 +76,29 @@ public class TSDBStatement extends AbstractStatement {
|
|||
|
||||
public boolean execute(String sql) throws SQLException {
|
||||
// check if closed
|
||||
if (isClosed())
|
||||
if (isClosed()) {
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
||||
}
|
||||
|
||||
// execute query
|
||||
long pSql = this.connector.executeQuery(sql);
|
||||
long pSql = this.connection.getConnector().executeQuery(sql);
|
||||
// if pSql is create/insert/update/delete/alter SQL
|
||||
if (this.connector.isUpdateQuery(pSql)) {
|
||||
this.affectedRows = this.connector.getAffectedRows(pSql);
|
||||
this.connector.freeResultSet(pSql);
|
||||
if (this.connection.getConnector().isUpdateQuery(pSql)) {
|
||||
this.affectedRows = this.connection.getConnector().getAffectedRows(pSql);
|
||||
this.connection.getConnector().freeResultSet(pSql);
|
||||
return false;
|
||||
}
|
||||
|
||||
this.resultSet = new TSDBResultSet(this, this.connector, pSql);
|
||||
this.resultSet = new TSDBResultSet(this, this.connection.getConnector(), pSql);
|
||||
this.resultSet.setBatchFetch(this.connection.getBatchFetch());
|
||||
return true;
|
||||
}
|
||||
|
||||
public ResultSet getResultSet() throws SQLException {
|
||||
if (isClosed())
|
||||
if (isClosed()) {
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
||||
// long resultSetPointer = connector.getResultSet();
|
||||
// TSDBResultSet resSet = null;
|
||||
// if (resultSetPointer != TSDBConstants.JNI_NULL_POINTER) {
|
||||
// resSet = new TSDBResultSet(connector, resultSetPointer);
|
||||
// }
|
||||
}
|
||||
|
||||
return this.resultSet;
|
||||
}
|
||||
|
||||
|
@ -115,12 +109,20 @@ public class TSDBStatement extends AbstractStatement {
|
|||
}
|
||||
|
||||
public Connection getConnection() throws SQLException {
|
||||
if (isClosed())
|
||||
if (isClosed()) {
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
||||
if (this.connector == null)
|
||||
}
|
||||
|
||||
if (this.connection.getConnector() == null) {
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL);
|
||||
}
|
||||
|
||||
return this.connection;
|
||||
}
|
||||
|
||||
public void setConnection(TSDBConnection connection) {
|
||||
this.connection = connection;
|
||||
}
|
||||
|
||||
public boolean isClosed() throws SQLException {
|
||||
return isClosed;
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
package com.taosdata.jdbc.utils;
|
||||
|
||||
public class NullType {
|
||||
private static final byte NULL_BOOL_VAL = 0x2;
|
||||
private static final String NULL_STR = "null";
|
||||
|
||||
public String toString() {
|
||||
return NullType.NULL_STR;
|
||||
}
|
||||
|
||||
public static boolean isBooleanNull(byte val) {
|
||||
return val == NullType.NULL_BOOL_VAL;
|
||||
}
|
||||
|
||||
public static boolean isTinyIntNull(byte val) {
|
||||
return val == Byte.MIN_VALUE;
|
||||
}
|
||||
|
||||
public static boolean isSmallIntNull(short val) {
|
||||
return val == Short.MIN_VALUE;
|
||||
}
|
||||
|
||||
public static boolean isIntNull(int val) {
|
||||
return val == Integer.MIN_VALUE;
|
||||
}
|
||||
|
||||
public static boolean isBigIntNull(long val) {
|
||||
return val == Long.MIN_VALUE;
|
||||
}
|
||||
|
||||
public static boolean isFloatNull(float val) {
|
||||
return Float.isNaN(val);
|
||||
}
|
||||
|
||||
public static boolean isDoubleNull(double val) {
|
||||
return Double.isNaN(val);
|
||||
}
|
||||
|
||||
public static boolean isBinaryNull(byte[] val, int length) {
|
||||
if (length != Byte.BYTES) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return val[0] == 0xFF;
|
||||
}
|
||||
|
||||
public static boolean isNcharNull(byte[] val, int length) {
|
||||
if (length != Integer.BYTES) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (val[0] & val[1] & val[2] & val[3]) == 0xFF;
|
||||
}
|
||||
|
||||
public static byte getBooleanNull() {
|
||||
return NullType.NULL_BOOL_VAL;
|
||||
}
|
||||
|
||||
public static byte getTinyintNull() {
|
||||
return Byte.MIN_VALUE;
|
||||
}
|
||||
|
||||
public static int getIntNull() {
|
||||
return Integer.MIN_VALUE;
|
||||
}
|
||||
|
||||
public static short getSmallIntNull() {
|
||||
return Short.MIN_VALUE;
|
||||
}
|
||||
|
||||
public static long getBigIntNull() {
|
||||
return Long.MIN_VALUE;
|
||||
}
|
||||
|
||||
public static int getFloatNull() {
|
||||
return 0x7FF00000;
|
||||
}
|
||||
|
||||
public static long getDoubleNull() {
|
||||
return 0x7FFFFF0000000000L;
|
||||
}
|
||||
|
||||
public static byte getBinaryNull() {
|
||||
return (byte) 0xFF;
|
||||
}
|
||||
|
||||
public static byte[] getNcharNull() {
|
||||
return new byte[] {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF};
|
||||
}
|
||||
|
||||
}
|
|
@ -146,6 +146,7 @@ public class Utils {
|
|||
*/
|
||||
private static String transformSql(String rawSql, Object[] paramArr, Map<Integer, Integer> placeholderPosition, RangeSet<Integer> clauseRangeSet) {
|
||||
String[] sqlArr = rawSql.split("\\?");
|
||||
|
||||
return IntStream.range(0, sqlArr.length).mapToObj(index -> {
|
||||
if (index == paramArr.length)
|
||||
return sqlArr[index];
|
||||
|
|
|
@ -8,6 +8,8 @@ import org.junit.Test;
|
|||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.sql.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Random;
|
||||
|
||||
public class TSDBPreparedStatementTest {
|
||||
private static final String host = "127.0.0.1";
|
||||
|
@ -96,7 +98,7 @@ public class TSDBPreparedStatementTest {
|
|||
result = pstmt_insert.executeUpdate();
|
||||
Assert.assertEquals(1, result);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void setBoolean() throws SQLException {
|
||||
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
|
||||
|
|
|
@ -3,7 +3,6 @@ package com.taosdata.jdbc;
|
|||
import com.google.common.primitives.Ints;
|
||||
import com.google.common.primitives.Longs;
|
||||
import com.google.common.primitives.Shorts;
|
||||
import com.taosdata.jdbc.rs.RestfulResultSet;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
|
@ -177,7 +176,8 @@ public class TSDBResultSetTest {
|
|||
rs.getAsciiStream("f1");
|
||||
}
|
||||
|
||||
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||
@SuppressWarnings("deprecation")
|
||||
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||
public void getUnicodeStream() throws SQLException {
|
||||
rs.getUnicodeStream("f1");
|
||||
}
|
||||
|
@ -326,7 +326,7 @@ public class TSDBResultSetTest {
|
|||
|
||||
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||
public void getRow() throws SQLException {
|
||||
int row = rs.getRow();
|
||||
rs.getRow();
|
||||
}
|
||||
|
||||
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||
|
@ -405,12 +405,12 @@ public class TSDBResultSetTest {
|
|||
|
||||
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||
public void updateByte() throws SQLException {
|
||||
rs.updateByte(1, new Byte("0"));
|
||||
rs.updateByte(1, (byte) 0);
|
||||
}
|
||||
|
||||
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||
public void updateShort() throws SQLException {
|
||||
rs.updateShort(1, new Short("0"));
|
||||
rs.updateShort(1, (short) 0);
|
||||
}
|
||||
|
||||
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||
|
|
|
@ -345,6 +345,7 @@ public class InsertSpecialCharacterJniTest {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCase12() throws SQLException {
|
||||
final long now = System.currentTimeMillis();
|
||||
|
|
Loading…
Reference in New Issue