提交 d6b21dad 编写于 作者: J jyhou

Fix issue #270

上级 64840179
......@@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.taosdata.jdbc</groupId>
<artifactId>taos-jdbcdriver</artifactId>
<version>1.0.0</version>
<version>1.0.1</version>
<name>JDBCDriver</name>
<description>TDengine JDBC Driver</description>
<properties>
......
......@@ -24,6 +24,8 @@ public abstract class TSDBConstants {
public static final String INVALID_VARIABLES = "invalid variables";
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_TDENGINE_ERROR = -1;
public static final int JNI_CONNECTION_NULL = -2;
......
......@@ -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;
......@@ -134,6 +132,13 @@ public class TSDBJNIConnector {
}
}
// 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
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");
}
......
......@@ -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
......
......@@ -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> T unwrap(Class<T> 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 {
......
......@@ -63,7 +63,7 @@
<dependency>
<groupId>com.taosdata.jdbc</groupId>
<artifactId>taos-jdbcdriver</artifactId>
<version>1.0.0</version>
<version>1.0.1</version>
</dependency>
</dependencies>
</project>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册