diff --git a/src/connector/jdbc/pom.xml b/src/connector/jdbc/pom.xml
index 05989178c7c47861722c9faa3f5efe83c8d63433..d29700fe8a4db855a40a9ac2cd747c4d5f5b371e 100755
--- a/src/connector/jdbc/pom.xml
+++ b/src/connector/jdbc/pom.xml
@@ -3,7 +3,7 @@
4.0.0
com.taosdata.jdbc
taos-jdbcdriver
- 1.0.0
+ 1.0.1
JDBCDriver
TDengine JDBC Driver
diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBConstants.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBConstants.java
index ba0c6d939e76fbcd7933ec634d13ec7215538e33..3940e809300b7d8e0b6c79038afaa6ff76f81bf0 100644
--- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBConstants.java
+++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBConstants.java
@@ -24,6 +24,8 @@ public abstract class TSDBConstants {
public static final String INVALID_VARIABLES = "invalid variables";
public static Map DATATYPE_MAP = null;
+ public static final long JNI_NULL_POINTER = 0L;
+
public static final int JNI_SUCCESS = 0;
public static final int JNI_TDENGINE_ERROR = -1;
public static final int JNI_CONNECTION_NULL = -2;
diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBJNIConnector.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBJNIConnector.java
index b1c38914241f29c7b797545ada366903a2b52df7..6f305cc2c7eecf036eb78d1478f98e3f35d7cfd2 100755
--- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBJNIConnector.java
+++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBJNIConnector.java
@@ -19,7 +19,6 @@ import java.sql.SQLWarning;
import java.util.List;
public class TSDBJNIConnector {
- static final long INVALID_CONNECTION_POINTER_VALUE = 0l;
static volatile Boolean isInitialized = false;
static {
@@ -29,7 +28,12 @@ public class TSDBJNIConnector {
/**
* 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
@@ -41,7 +45,7 @@ public class TSDBJNIConnector {
* Whether the connection is closed
*/
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
*/
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.taos = INVALID_CONNECTION_POINTER_VALUE;
+ this.taos = TSDBConstants.JNI_NULL_POINTER;
}
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());
}
@@ -108,13 +112,7 @@ public class TSDBJNIConnector {
*/
public int executeQuery(String sql) throws SQLException {
if (!this.isResultsetClosed) {
- //throw new RuntimeException(TSDBConstants.WrapErrMsg("Connection already has an open result set"));
- long resultSetPointer = this.getResultSet();
- if (resultSetPointer == TSDBConstants.JNI_CONNECTION_NULL) {
- //do nothing
- } else {
- this.freeResultSet(resultSetPointer);
- }
+ freeResultSet(taosResultSetPointer);
}
int code;
@@ -133,7 +131,14 @@ public class TSDBJNIConnector {
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;
}
@@ -162,8 +167,7 @@ public class TSDBJNIConnector {
* Each connection should have a single open result set at a time
*/
public long getResultSet() {
- long res = this.getResultSetImp(this.taos);
- return res;
+ return taosResultSetPointer;
}
private native long getResultSetImp(long connection);
@@ -172,11 +176,31 @@ public class TSDBJNIConnector {
* Free resultset operation from C to release resultset pointer by JNI
*/
public int freeResultSet(long result) {
- int res = this.freeResultSetImp(this.taos, result);
- this.isResultsetClosed = true; // reset resultSetPointer to 0 after freeResultSetImp() return
- return res;
+ int res = TSDBConstants.JNI_SUCCESS;
+ if (result != taosResultSetPointer && taosResultSetPointer != TSDBConstants.JNI_NULL_POINTER) {
+ 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);
/**
@@ -220,7 +244,7 @@ public class TSDBJNIConnector {
if (code < 0) {
throw new SQLException(TSDBConstants.FixErrMsg(code), "", this.getErrCode());
} else if (code == 0){
- this.taos = INVALID_CONNECTION_POINTER_VALUE;
+ this.taos = TSDBConstants.JNI_NULL_POINTER;
} else {
throw new SQLException("Undefined error code returned by TDengine when closing a connection");
}
diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBPreparedStatement.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBPreparedStatement.java
index d613c252f03a97c519e5814b4e5ea99d15ed3067..bd45fbfb7a25fadaf1e42da63ea1065518d3e53a 100644
--- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBPreparedStatement.java
+++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBPreparedStatement.java
@@ -244,7 +244,7 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
@Override
public boolean execute() throws SQLException {
- return executeUpdate(getNativeSql()) == 0;
+ return super.execute(getNativeSql());
}
@Override
diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBStatement.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBStatement.java
index 7d4f4c4691c732bb1475f6b9d6f751205234a3b4..455b73bb927b8253f967d975a9030482c097f00c 100644
--- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBStatement.java
+++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBStatement.java
@@ -27,8 +27,14 @@ public class TSDBStatement implements Statement {
/** Timeout for a query */
protected int queryTimeout = 0;
+ /**
+ * Status of current statement
+ */
+ private boolean isClosed = true;
+
TSDBStatement(TSDBJNIConnector connecter) {
this.connecter = connecter;
+ this.isClosed = false;
}
public T unwrap(Class iface) throws SQLException {
@@ -40,13 +46,16 @@ public class TSDBStatement implements Statement {
}
public ResultSet executeQuery(String sql) throws SQLException {
+ if (isClosed) {
+ throw new SQLException("Invalid method call on a closed statement.");
+ }
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 == 0) {
+ } else if (resultSetPointer == TSDBConstants.JNI_NULL_POINTER) {
return null;
} else {
return new TSDBResultSet(this.connecter, resultSetPointer);
@@ -54,7 +63,20 @@ public class TSDBStatement implements Statement {
}
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() {
@@ -62,6 +84,12 @@ public class TSDBStatement implements Statement {
}
public void close() throws SQLException {
+ if (!isClosed) {
+ if (!this.connecter.isResultsetClosed()) {
+ this.connecter.freeResultSet();
+ }
+ isClosed = true;
+ }
}
public int getMaxFieldSize() throws SQLException {
@@ -110,19 +138,38 @@ public class TSDBStatement implements Statement {
}
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 {
+ if (isClosed) {
+ throw new SQLException("Invalid method call on a closed statement.");
+ }
long resultSetPointer = connecter.getResultSet();
TSDBResultSet resSet = null;
- if (resultSetPointer != 0l) {
+ if (resultSetPointer != TSDBConstants.JNI_NULL_POINTER) {
resSet = new TSDBResultSet(connecter, resultSetPointer);
}
return resSet;
}
public int getUpdateCount() throws SQLException {
+ if (isClosed) {
+ throw new SQLException("Invalid method call on a closed statement.");
+ }
return this.connecter.getAffectedRows();
}
@@ -171,6 +218,9 @@ public class TSDBStatement implements Statement {
}
public int[] executeBatch() throws SQLException {
+ if (isClosed) {
+ throw new SQLException("Invalid method call on a closed statement.");
+ }
if (batchedArgs == null) {
throw new SQLException(TSDBConstants.WrapErrMsg("Batch is empty!"));
} else {
@@ -223,7 +273,7 @@ public class TSDBStatement implements Statement {
}
public boolean isClosed() throws SQLException {
- throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
+ return isClosed;
}
public void setPoolable(boolean poolable) throws SQLException {
diff --git a/tests/examples/JDBC/JDBCDemo/pom.xml b/tests/examples/JDBC/JDBCDemo/pom.xml
index 1c62379af9ea0234993f827e23bd42a91609a722..d015c62772d615fb6afb275856da5a81c339644c 100644
--- a/tests/examples/JDBC/JDBCDemo/pom.xml
+++ b/tests/examples/JDBC/JDBCDemo/pom.xml
@@ -63,7 +63,7 @@
com.taosdata.jdbc
taos-jdbcdriver
- 1.0.0
+ 1.0.1