提交 d6b21dad 编写于 作者: J jyhou

Fix issue #270

上级 64840179
...@@ -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>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 { ...@@ -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; ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 @@ ...@@ -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>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册