未验证 提交 05acc9b2 编写于 作者: H huolibo 提交者: GitHub

[TD-14038]<fix>: bind result when statement is closed release the res… (#10774)

* [TD-14038]<fix>: bind result when statement is closed release the resource

* [TD-14038]<fix>: bind result fix test case

* [TD-14038]<fix>: release related resource when connection or statement close
上级 b8c8514a
package com.taosdata.jdbc;
import java.sql.*;
import java.util.Properties;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
public class TSDBConnection extends AbstractConnection {
private TSDBJNIConnector connector;
private final TSDBDatabaseMetaData databaseMetaData;
private boolean batchFetch;
private CopyOnWriteArrayList<Statement> statements = new CopyOnWriteArrayList<>();
public Boolean getBatchFetch() {
return this.batchFetch;
......@@ -67,12 +69,26 @@ public class TSDBConnection extends AbstractConnection {
}
public void close() throws SQLException {
if (isClosed)
return;
synchronized (this) {
if (isClosed) {
return;
}
for (Statement statement : statements) {
statement.close();
}
this.connector.closeConnection();
this.isClosed = true;
}
}
public void unregisterStatement(Statement stmt) {
this.statements.remove(stmt);
}
public void registerStatement(Statement stmt) {
this.statements.addIfAbsent(stmt);
}
public boolean isClosed() throws SQLException {
return this.connector != null && this.connector.isClosed();
......
......@@ -28,12 +28,16 @@ public class TSDBStatement extends AbstractStatement {
TSDBStatement(TSDBConnection connection) {
this.connection = connection;
connection.registerStatement(this);
}
public ResultSet executeQuery(String sql) throws SQLException {
synchronized (this) {
if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
}
if (this.resultSet != null && !this.resultSet.isClosed())
this.resultSet.close();
//TODO:
// this is an unreasonable implementation, if the paratemer is a insert statement,
// the JNI connector will execute the sql at first and return a pointer: pSql,
......@@ -47,14 +51,18 @@ public class TSDBStatement extends AbstractStatement {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_WITH_EXECUTEQUERY);
}
int timestampPrecision = this.connection.getConnector().getResultTimePrecision(pSql);
TSDBResultSet res = new TSDBResultSet(this, this.connection.getConnector(), pSql, timestampPrecision);
res.setBatchFetch(this.connection.getBatchFetch());
return res;
resultSet = new TSDBResultSet(this, this.connection.getConnector(), pSql, timestampPrecision);
resultSet.setBatchFetch(this.connection.getBatchFetch());
return resultSet;
}
}
public int executeUpdate(String sql) throws SQLException {
synchronized (this) {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
if (this.resultSet != null && !this.resultSet.isClosed())
this.resultSet.close();
long pSql = this.connection.getConnector().executeQuery(sql);
// if pSql is create/insert/update/delete/alter SQL
......@@ -66,20 +74,25 @@ public class TSDBStatement extends AbstractStatement {
this.connection.getConnector().freeResultSet(pSql);
return affectedRows;
}
}
public void close() throws SQLException {
if (isClosed)
return;
connection.unregisterStatement(this);
if (this.resultSet != null && !this.resultSet.isClosed())
this.resultSet.close();
isClosed = true;
}
public boolean execute(String sql) throws SQLException {
synchronized (this) {
// check if closed
if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
}
if (this.resultSet != null && !this.resultSet.isClosed())
this.resultSet.close();
// execute query
long pSql = this.connection.getConnector().executeQuery(sql);
......@@ -95,6 +108,7 @@ public class TSDBStatement extends AbstractStatement {
this.resultSet.setBatchFetch(this.connection.getBatchFetch());
return true;
}
}
public ResultSet getResultSet() throws SQLException {
if (isClosed()) {
......
......@@ -71,19 +71,17 @@ public class NanoSecondTimestampJNITest {
long ns = ms * 1000_000L + random.nextInt(1000_000);
// when
ResultSet rs = null;
try (Statement stmt = conn.createStatement()) {
stmt.executeUpdate("insert into weather(ts, temperature, humidity) values(" + ns + ", 12.3, 4)");
rs = stmt.executeQuery("select * from weather");
ResultSet rs = stmt.executeQuery("select * from weather");
rs.next();
}
// then
long actual = rs.getLong(1);
Assert.assertEquals(ns, actual);
actual = rs.getLong("ts");
Assert.assertEquals(ns, actual);
}
}
@Test
public void selectUsingStringValue() throws SQLException {
......@@ -91,19 +89,17 @@ public class NanoSecondTimestampJNITest {
String timestampStr = "2021-01-01 12:00:00.123456789";
// when
ResultSet rs;
try (Statement stmt = conn.createStatement()) {
stmt.executeUpdate("insert into weather(ts, temperature, humidity) values('" + timestampStr + "', 12.3, 4)");
rs = stmt.executeQuery("select * from weather");
ResultSet rs = stmt.executeQuery("select * from weather");
rs.next();
}
// then
String actual = rs.getString(1);
Assert.assertEquals(timestampStr, actual);
actual = rs.getString("ts");
Assert.assertEquals(timestampStr, actual);
}
}
@Test
public void selectUsingTimestampValue() throws SQLException {
......@@ -123,12 +119,9 @@ public class NanoSecondTimestampJNITest {
}
// when
ResultSet rs = null;
try (Statement stmt = conn.createStatement()) {
rs = stmt.executeQuery("select * from weather");
ResultSet rs = stmt.executeQuery("select * from weather");
rs.next();
}
// then
Timestamp actual = rs.getTimestamp(1);
Assert.assertEquals(ts, actual);
......@@ -137,6 +130,7 @@ public class NanoSecondTimestampJNITest {
Assert.assertEquals(timeMillis, actual.getTime());
Assert.assertEquals(nanoAdjustment, actual.getNanos());
}
}
@Before
public void before() throws SQLException {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册