Fix issue #270
This commit is contained in:
parent
6484017932
commit
d6b21dadd0
|
@ -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;
|
||||
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in New Issue