Fix issue #270
This commit is contained in:
parent
6484017932
commit
d6b21dadd0
|
@ -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>1.0.0</version>
|
<version>1.0.1</version>
|
||||||
<name>JDBCDriver</name>
|
<name>JDBCDriver</name>
|
||||||
<description>TDengine JDBC Driver</description>
|
<description>TDengine JDBC Driver</description>
|
||||||
<properties>
|
<properties>
|
||||||
|
|
|
@ -24,6 +24,8 @@ public abstract class TSDBConstants {
|
||||||
public static final String INVALID_VARIABLES = "invalid variables";
|
public static final String INVALID_VARIABLES = "invalid variables";
|
||||||
public static Map<Integer, String> DATATYPE_MAP = null;
|
public static Map<Integer, String> DATATYPE_MAP = null;
|
||||||
|
|
||||||
|
public static final long JNI_NULL_POINTER = 0L;
|
||||||
|
|
||||||
public static final int JNI_SUCCESS = 0;
|
public static final int JNI_SUCCESS = 0;
|
||||||
public static final int JNI_TDENGINE_ERROR = -1;
|
public static final int JNI_TDENGINE_ERROR = -1;
|
||||||
public static final int JNI_CONNECTION_NULL = -2;
|
public static final int JNI_CONNECTION_NULL = -2;
|
||||||
|
|
|
@ -19,7 +19,6 @@ import java.sql.SQLWarning;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class TSDBJNIConnector {
|
public class TSDBJNIConnector {
|
||||||
static final long INVALID_CONNECTION_POINTER_VALUE = 0l;
|
|
||||||
static volatile Boolean isInitialized = false;
|
static volatile Boolean isInitialized = false;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
|
@ -29,7 +28,12 @@ public class TSDBJNIConnector {
|
||||||
/**
|
/**
|
||||||
* Connection pointer used in C
|
* Connection pointer used in C
|
||||||
*/
|
*/
|
||||||
private long taos = INVALID_CONNECTION_POINTER_VALUE;
|
private long taos = TSDBConstants.JNI_NULL_POINTER;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Result set pointer for the current connection
|
||||||
|
*/
|
||||||
|
private long taosResultSetPointer = TSDBConstants.JNI_NULL_POINTER;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* result set status in current connection
|
* result set status in current connection
|
||||||
|
@ -41,7 +45,7 @@ public class TSDBJNIConnector {
|
||||||
* Whether the connection is closed
|
* Whether the connection is closed
|
||||||
*/
|
*/
|
||||||
public boolean isClosed() {
|
public boolean isClosed() {
|
||||||
return this.taos == INVALID_CONNECTION_POINTER_VALUE;
|
return this.taos == TSDBConstants.JNI_NULL_POINTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -86,13 +90,13 @@ public class TSDBJNIConnector {
|
||||||
* @throws SQLException
|
* @throws SQLException
|
||||||
*/
|
*/
|
||||||
public boolean connect(String host, int port, String dbName, String user, String password) throws SQLException {
|
public boolean connect(String host, int port, String dbName, String user, String password) throws SQLException {
|
||||||
if (this.taos != INVALID_CONNECTION_POINTER_VALUE) {
|
if (this.taos != TSDBConstants.JNI_NULL_POINTER) {
|
||||||
this.closeConnectionImp(this.taos);
|
this.closeConnectionImp(this.taos);
|
||||||
this.taos = INVALID_CONNECTION_POINTER_VALUE;
|
this.taos = TSDBConstants.JNI_NULL_POINTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.taos = this.connectImp(host, port, dbName, user, password);
|
this.taos = this.connectImp(host, port, dbName, user, password);
|
||||||
if (this.taos == INVALID_CONNECTION_POINTER_VALUE) {
|
if (this.taos == TSDBConstants.JNI_NULL_POINTER) {
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(this.getErrMsg()), "", this.getErrCode());
|
throw new SQLException(TSDBConstants.WrapErrMsg(this.getErrMsg()), "", this.getErrCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,13 +112,7 @@ public class TSDBJNIConnector {
|
||||||
*/
|
*/
|
||||||
public int executeQuery(String sql) throws SQLException {
|
public int executeQuery(String sql) throws SQLException {
|
||||||
if (!this.isResultsetClosed) {
|
if (!this.isResultsetClosed) {
|
||||||
//throw new RuntimeException(TSDBConstants.WrapErrMsg("Connection already has an open result set"));
|
freeResultSet(taosResultSetPointer);
|
||||||
long resultSetPointer = this.getResultSet();
|
|
||||||
if (resultSetPointer == TSDBConstants.JNI_CONNECTION_NULL) {
|
|
||||||
//do nothing
|
|
||||||
} else {
|
|
||||||
this.freeResultSet(resultSetPointer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int code;
|
int code;
|
||||||
|
@ -133,7 +131,14 @@ public class TSDBJNIConnector {
|
||||||
throw new SQLException(TSDBConstants.FixErrMsg(code), "", this.getErrCode());
|
throw new SQLException(TSDBConstants.FixErrMsg(code), "", this.getErrCode());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Try retrieving result set for the executed SQLusing the current connection pointer. If the executed
|
||||||
|
// SQL is a DML/DDL which doesn't return a result set, then taosResultSetPointer should be 0L. Otherwise,
|
||||||
|
// taosResultSetPointer should be a non-zero value.
|
||||||
|
taosResultSetPointer = this.getResultSetImp(this.taos);
|
||||||
|
if (taosResultSetPointer != TSDBConstants.JNI_NULL_POINTER) {
|
||||||
|
isResultsetClosed = false;
|
||||||
|
}
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,8 +167,7 @@ public class TSDBJNIConnector {
|
||||||
* Each connection should have a single open result set at a time
|
* Each connection should have a single open result set at a time
|
||||||
*/
|
*/
|
||||||
public long getResultSet() {
|
public long getResultSet() {
|
||||||
long res = this.getResultSetImp(this.taos);
|
return taosResultSetPointer;
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private native long getResultSetImp(long connection);
|
private native long getResultSetImp(long connection);
|
||||||
|
@ -172,11 +176,31 @@ public class TSDBJNIConnector {
|
||||||
* Free resultset operation from C to release resultset pointer by JNI
|
* Free resultset operation from C to release resultset pointer by JNI
|
||||||
*/
|
*/
|
||||||
public int freeResultSet(long result) {
|
public int freeResultSet(long result) {
|
||||||
int res = this.freeResultSetImp(this.taos, result);
|
int res = TSDBConstants.JNI_SUCCESS;
|
||||||
this.isResultsetClosed = true; // reset resultSetPointer to 0 after freeResultSetImp() return
|
if (result != taosResultSetPointer && taosResultSetPointer != TSDBConstants.JNI_NULL_POINTER) {
|
||||||
return res;
|
throw new RuntimeException("Invalid result set pointer");
|
||||||
|
} else if (taosResultSetPointer != TSDBConstants.JNI_NULL_POINTER){
|
||||||
|
res = this.freeResultSetImp(this.taos, result);
|
||||||
|
isResultsetClosed = true; // reset resultSetPointer to 0 after freeResultSetImp() return
|
||||||
|
taosResultSetPointer = TSDBConstants.JNI_NULL_POINTER;
|
||||||
|
}
|
||||||
|
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.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int freeResultSet() {
|
||||||
|
int resCode = TSDBConstants.JNI_SUCCESS;
|
||||||
|
if (!isResultsetClosed) {
|
||||||
|
resCode = this.freeResultSetImp(this.taos, this.taosResultSetPointer);
|
||||||
|
taosResultSetPointer = TSDBConstants.JNI_NULL_POINTER;
|
||||||
|
}
|
||||||
|
return resCode;
|
||||||
|
}
|
||||||
|
|
||||||
private native int freeResultSetImp(long connection, long result);
|
private native int freeResultSetImp(long connection, long result);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -220,7 +244,7 @@ public class TSDBJNIConnector {
|
||||||
if (code < 0) {
|
if (code < 0) {
|
||||||
throw new SQLException(TSDBConstants.FixErrMsg(code), "", this.getErrCode());
|
throw new SQLException(TSDBConstants.FixErrMsg(code), "", this.getErrCode());
|
||||||
} else if (code == 0){
|
} else if (code == 0){
|
||||||
this.taos = INVALID_CONNECTION_POINTER_VALUE;
|
this.taos = TSDBConstants.JNI_NULL_POINTER;
|
||||||
} else {
|
} else {
|
||||||
throw new SQLException("Undefined error code returned by TDengine when closing a connection");
|
throw new SQLException("Undefined error code returned by TDengine when closing a connection");
|
||||||
}
|
}
|
||||||
|
|
|
@ -244,7 +244,7 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean execute() throws SQLException {
|
public boolean execute() throws SQLException {
|
||||||
return executeUpdate(getNativeSql()) == 0;
|
return super.execute(getNativeSql());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -27,8 +27,14 @@ public class TSDBStatement implements Statement {
|
||||||
/** Timeout for a query */
|
/** Timeout for a query */
|
||||||
protected int queryTimeout = 0;
|
protected int queryTimeout = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Status of current statement
|
||||||
|
*/
|
||||||
|
private boolean isClosed = true;
|
||||||
|
|
||||||
TSDBStatement(TSDBJNIConnector connecter) {
|
TSDBStatement(TSDBJNIConnector connecter) {
|
||||||
this.connecter = connecter;
|
this.connecter = connecter;
|
||||||
|
this.isClosed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> T unwrap(Class<T> iface) throws SQLException {
|
public <T> T unwrap(Class<T> iface) throws SQLException {
|
||||||
|
@ -40,13 +46,16 @@ public class TSDBStatement implements Statement {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResultSet executeQuery(String sql) throws SQLException {
|
public ResultSet executeQuery(String sql) throws SQLException {
|
||||||
|
if (isClosed) {
|
||||||
|
throw new SQLException("Invalid method call on a closed statement.");
|
||||||
|
}
|
||||||
this.connecter.executeQuery(sql);
|
this.connecter.executeQuery(sql);
|
||||||
|
|
||||||
long resultSetPointer = this.connecter.getResultSet();
|
long resultSetPointer = this.connecter.getResultSet();
|
||||||
|
|
||||||
if (resultSetPointer == TSDBConstants.JNI_CONNECTION_NULL) {
|
if (resultSetPointer == TSDBConstants.JNI_CONNECTION_NULL) {
|
||||||
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL));
|
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL));
|
||||||
} else if (resultSetPointer == 0) {
|
} else if (resultSetPointer == TSDBConstants.JNI_NULL_POINTER) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
return new TSDBResultSet(this.connecter, resultSetPointer);
|
return new TSDBResultSet(this.connecter, resultSetPointer);
|
||||||
|
@ -54,7 +63,20 @@ public class TSDBStatement implements Statement {
|
||||||
}
|
}
|
||||||
|
|
||||||
public int executeUpdate(String sql) throws SQLException {
|
public int executeUpdate(String sql) throws SQLException {
|
||||||
return this.connecter.executeQuery(sql);
|
if (isClosed) {
|
||||||
|
throw new SQLException("Invalid method call on a closed statement.");
|
||||||
|
}
|
||||||
|
int res = this.connecter.executeQuery(sql);
|
||||||
|
long resultSetPointer = this.connecter.getResultSet();
|
||||||
|
|
||||||
|
if (resultSetPointer == TSDBConstants.JNI_CONNECTION_NULL) {
|
||||||
|
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL));
|
||||||
|
} else if (resultSetPointer != TSDBConstants.JNI_NULL_POINTER) {
|
||||||
|
this.connecter.freeResultSet();
|
||||||
|
throw new SQLException("The executed SQL is not a DML or a DDL");
|
||||||
|
} else {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getErrorMsg() {
|
public String getErrorMsg() {
|
||||||
|
@ -62,6 +84,12 @@ public class TSDBStatement implements Statement {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void close() throws SQLException {
|
public void close() throws SQLException {
|
||||||
|
if (!isClosed) {
|
||||||
|
if (!this.connecter.isResultsetClosed()) {
|
||||||
|
this.connecter.freeResultSet();
|
||||||
|
}
|
||||||
|
isClosed = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMaxFieldSize() throws SQLException {
|
public int getMaxFieldSize() throws SQLException {
|
||||||
|
@ -110,19 +138,38 @@ public class TSDBStatement implements Statement {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean execute(String sql) throws SQLException {
|
public boolean execute(String sql) throws SQLException {
|
||||||
return executeUpdate(sql) == 0;
|
if (isClosed) {
|
||||||
|
throw new SQLException("Invalid method call on a closed statement.");
|
||||||
|
}
|
||||||
|
boolean res = true;
|
||||||
|
this.connecter.executeQuery(sql);
|
||||||
|
long resultSetPointer = this.connecter.getResultSet();
|
||||||
|
|
||||||
|
if (resultSetPointer == TSDBConstants.JNI_CONNECTION_NULL) {
|
||||||
|
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL));
|
||||||
|
} else if (resultSetPointer == TSDBConstants.JNI_NULL_POINTER) {
|
||||||
|
// no result set is retrieved
|
||||||
|
res = false;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResultSet getResultSet() throws SQLException {
|
public ResultSet getResultSet() throws SQLException {
|
||||||
|
if (isClosed) {
|
||||||
|
throw new SQLException("Invalid method call on a closed statement.");
|
||||||
|
}
|
||||||
long resultSetPointer = connecter.getResultSet();
|
long resultSetPointer = connecter.getResultSet();
|
||||||
TSDBResultSet resSet = null;
|
TSDBResultSet resSet = null;
|
||||||
if (resultSetPointer != 0l) {
|
if (resultSetPointer != TSDBConstants.JNI_NULL_POINTER) {
|
||||||
resSet = new TSDBResultSet(connecter, resultSetPointer);
|
resSet = new TSDBResultSet(connecter, resultSetPointer);
|
||||||
}
|
}
|
||||||
return resSet;
|
return resSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getUpdateCount() throws SQLException {
|
public int getUpdateCount() throws SQLException {
|
||||||
|
if (isClosed) {
|
||||||
|
throw new SQLException("Invalid method call on a closed statement.");
|
||||||
|
}
|
||||||
return this.connecter.getAffectedRows();
|
return this.connecter.getAffectedRows();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,6 +218,9 @@ public class TSDBStatement implements Statement {
|
||||||
}
|
}
|
||||||
|
|
||||||
public int[] executeBatch() throws SQLException {
|
public int[] executeBatch() throws SQLException {
|
||||||
|
if (isClosed) {
|
||||||
|
throw new SQLException("Invalid method call on a closed statement.");
|
||||||
|
}
|
||||||
if (batchedArgs == null) {
|
if (batchedArgs == null) {
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg("Batch is empty!"));
|
throw new SQLException(TSDBConstants.WrapErrMsg("Batch is empty!"));
|
||||||
} else {
|
} else {
|
||||||
|
@ -223,7 +273,7 @@ public class TSDBStatement implements Statement {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isClosed() throws SQLException {
|
public boolean isClosed() throws SQLException {
|
||||||
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
return isClosed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPoolable(boolean poolable) throws SQLException {
|
public void setPoolable(boolean poolable) throws SQLException {
|
||||||
|
|
|
@ -63,7 +63,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.taosdata.jdbc</groupId>
|
<groupId>com.taosdata.jdbc</groupId>
|
||||||
<artifactId>taos-jdbcdriver</artifactId>
|
<artifactId>taos-jdbcdriver</artifactId>
|
||||||
<version>1.0.0</version>
|
<version>1.0.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
|
Loading…
Reference in New Issue