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

[TD-13785]<fix>: change method for jdbc judge update or query (#10538)

* [TD-13785]<fix>: change method for jdbc judge update or query

* [TD-13785]<fix>: add desc test case
上级 df194dbd
...@@ -20,6 +20,7 @@ public class RestfulStatement extends AbstractStatement { ...@@ -20,6 +20,7 @@ public class RestfulStatement extends AbstractStatement {
private boolean closed; private boolean closed;
private String database; private String database;
private final RestfulConnection conn; private final RestfulConnection conn;
private static final String ROW_NAME = "affected_rows";
private volatile RestfulResultSet resultSet; private volatile RestfulResultSet resultSet;
...@@ -32,20 +33,18 @@ public class RestfulStatement extends AbstractStatement { ...@@ -32,20 +33,18 @@ public class RestfulStatement extends AbstractStatement {
public ResultSet executeQuery(String sql) throws SQLException { public ResultSet executeQuery(String sql) throws SQLException {
if (isClosed()) if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
if (!SqlSyntaxValidator.isValidForExecuteQuery(sql))
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_FOR_EXECUTE_QUERY, "not a valid sql for executeQuery: " + sql);
return executeOneQuery(sql); execute(sql);
return resultSet;
} }
@Override @Override
public int executeUpdate(String sql) throws SQLException { public int executeUpdate(String sql) throws SQLException {
if (isClosed()) if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
if (!SqlSyntaxValidator.isValidForExecuteUpdate(sql))
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_FOR_EXECUTE_UPDATE, "not a valid sql for executeUpdate: " + sql);
return executeOneUpdate(sql); execute(sql);
return affectedRows;
} }
@Override @Override
...@@ -64,33 +63,36 @@ public class RestfulStatement extends AbstractStatement { ...@@ -64,33 +63,36 @@ public class RestfulStatement extends AbstractStatement {
//如果执行了use操作应该将当前Statement的catalog设置为新的database //如果执行了use操作应该将当前Statement的catalog设置为新的database
boolean result = true; boolean result = true;
String response = HttpClientPoolUtil.execute(getUrl(), sql, this.conn.getToken());
JSONObject jsonObject = JSON.parseObject(response);
if (null == jsonObject) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "sql: " + sql);
}
if (jsonObject.getString("status").equals("error")) {
throw TSDBError.createSQLException(jsonObject.getInteger("code"), "sql: " + sql + ", desc: " + jsonObject.getString("desc"));
}
if (SqlSyntaxValidator.isUseSql(sql)) { if (SqlSyntaxValidator.isUseSql(sql)) {
String ret = HttpClientPoolUtil.execute(getUrl(), sql, this.conn.getToken());
JSONObject resultJson = JSON.parseObject(ret);
if (resultJson.getString("status").equals("error")) {
throw TSDBError.createSQLException(resultJson.getInteger("code"), "sql: " + sql + ", desc: " + resultJson.getString("desc"));
}
this.database = sql.trim().replace("use", "").trim(); this.database = sql.trim().replace("use", "").trim();
this.conn.setCatalog(this.database); this.conn.setCatalog(this.database);
this.conn.setClientInfo(TSDBDriver.PROPERTY_KEY_DBNAME, this.database); this.conn.setClientInfo(TSDBDriver.PROPERTY_KEY_DBNAME, this.database);
result = false; result = false;
} else if (SqlSyntaxValidator.isDatabaseUnspecifiedQuery(sql)) {
executeOneQuery(sql);
} else if (SqlSyntaxValidator.isDatabaseUnspecifiedUpdate(sql)) {
executeOneUpdate(sql);
result = false;
} else { } else {
if (SqlSyntaxValidator.isValidForExecuteQuery(sql)) { JSONArray head = jsonObject.getJSONArray("head");
executeOneQuery(sql); Integer rows = jsonObject.getInteger("rows");
if (head.size() == 1 && ROW_NAME.equals(head.getString(0)) && rows == 1) {
this.resultSet = null;
this.affectedRows = getAffectedRows(jsonObject);
return false;
} else { } else {
executeOneUpdate(sql); this.resultSet = new RestfulResultSet(database, this, jsonObject);
result = false; this.affectedRows = -1;
} }
} }
return result; return result;
} }
private String getUrl() throws SQLException { private String getUrl() throws SQLException {
String dbname = conn.getClientInfo(TSDBDriver.PROPERTY_KEY_DBNAME); String dbname = conn.getClientInfo(TSDBDriver.PROPERTY_KEY_DBNAME);
if (dbname == null || dbname.trim().isEmpty()) { if (dbname == null || dbname.trim().isEmpty()) {
...@@ -114,29 +116,6 @@ public class RestfulStatement extends AbstractStatement { ...@@ -114,29 +116,6 @@ public class RestfulStatement extends AbstractStatement {
return url; return url;
} }
private ResultSet executeOneQuery(String sql) throws SQLException {
// row data
String result = HttpClientPoolUtil.execute(getUrl(), sql, this.conn.getToken());
JSONObject resultJson = JSON.parseObject(result);
if (resultJson.getString("status").equals("error")) {
throw TSDBError.createSQLException(resultJson.getInteger("code"), "sql: " + sql + ", desc: " + resultJson.getString("desc"));
}
this.resultSet = new RestfulResultSet(database, this, resultJson);
this.affectedRows = -1;
return resultSet;
}
private int executeOneUpdate(String sql) throws SQLException {
String result = HttpClientPoolUtil.execute(getUrl(), sql, this.conn.getToken());
JSONObject jsonObject = JSON.parseObject(result);
if (jsonObject.getString("status").equals("error")) {
throw TSDBError.createSQLException(jsonObject.getInteger("code"), "sql: " + sql + ", desc: " + jsonObject.getString("desc"));
}
this.resultSet = null;
this.affectedRows = getAffectedRows(jsonObject);
return this.affectedRows;
}
private int getAffectedRows(JSONObject jsonObject) throws SQLException { private int getAffectedRows(JSONObject jsonObject) throws SQLException {
JSONArray head = jsonObject.getJSONArray("head"); JSONArray head = jsonObject.getJSONArray("head");
if (head.size() != 1 || !"affected_rows".equals(head.getString(0))) if (head.size() != 1 || !"affected_rows".equals(head.getString(0)))
......
...@@ -16,43 +16,7 @@ package com.taosdata.jdbc.utils; ...@@ -16,43 +16,7 @@ package com.taosdata.jdbc.utils;
public class SqlSyntaxValidator { public class SqlSyntaxValidator {
private static final String[] updateSQL = {"insert", "import", "create", "use", "alter", "drop", "set", "reset"};
private static final String[] querySQL = {"select", "show", "describe"};
private static final String[] databaseUnspecifiedShow = {"databases", "dnodes", "mnodes", "variables"};
public static boolean isValidForExecuteUpdate(String sql) {
for (String prefix : updateSQL) {
if (sql.trim().toLowerCase().startsWith(prefix))
return true;
}
return false;
}
public static boolean isValidForExecuteQuery(String sql) {
for (String prefix : querySQL) {
if (sql.trim().toLowerCase().startsWith(prefix))
return true;
}
return false;
}
public static boolean isDatabaseUnspecifiedQuery(String sql) {
for (String databaseObj : databaseUnspecifiedShow) {
if (sql.trim().toLowerCase().matches("show\\s+" + databaseObj + ".*"))
return true;
}
return false;
}
public static boolean isDatabaseUnspecifiedUpdate(String sql) {
sql = sql.trim().toLowerCase();
return sql.matches("create\\s+database.*") || sql.startsWith("set") || sql.matches("drop\\s+database.*");
}
public static boolean isUseSql(String sql) { public static boolean isUseSql(String sql) {
return sql.trim().toLowerCase().startsWith("use"); return sql.trim().toLowerCase().startsWith("use");
} }
} }
...@@ -33,8 +33,6 @@ public class WSStatement extends AbstractStatement { ...@@ -33,8 +33,6 @@ public class WSStatement extends AbstractStatement {
public ResultSet executeQuery(String sql) throws SQLException { public ResultSet executeQuery(String sql) throws SQLException {
if (isClosed()) if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
if (!SqlSyntaxValidator.isValidForExecuteQuery(sql))
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_FOR_EXECUTE_QUERY, "not a valid sql for executeQuery: " + sql);
this.execute(sql); this.execute(sql);
return this.resultSet; return this.resultSet;
...@@ -44,8 +42,6 @@ public class WSStatement extends AbstractStatement { ...@@ -44,8 +42,6 @@ public class WSStatement extends AbstractStatement {
public int executeUpdate(String sql) throws SQLException { public int executeUpdate(String sql) throws SQLException {
if (isClosed()) if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
if (!SqlSyntaxValidator.isValidForExecuteUpdate(sql))
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_FOR_EXECUTE_UPDATE, "not a valid sql for executeUpdate: " + sql);
this.execute(sql); this.execute(sql);
return affectedRows; return affectedRows;
......
...@@ -37,6 +37,12 @@ public class RestfulStatementTest { ...@@ -37,6 +37,12 @@ public class RestfulStatementTest {
Assert.assertEquals(0, affectRows); Assert.assertEquals(0, affectRows);
affectRows = stmt.executeUpdate("create table " + dbName + ".weather(ts timestamp, temperature float) tags(loc nchar(64))"); affectRows = stmt.executeUpdate("create table " + dbName + ".weather(ts timestamp, temperature float) tags(loc nchar(64))");
Assert.assertEquals(0, affectRows); Assert.assertEquals(0, affectRows);
try (ResultSet resultSet = stmt.executeQuery("desc " + dbName + ".weather")){
ResultSetMetaData metaData = resultSet.getMetaData();
Assert.assertEquals(4, metaData.getColumnCount());
}
affectRows = stmt.executeUpdate("insert into " + dbName + ".t1 using " + dbName + ".weather tags('北京') values(now, 22.33)"); affectRows = stmt.executeUpdate("insert into " + dbName + ".t1 using " + dbName + ".weather tags('北京') values(now, 22.33)");
Assert.assertEquals(1, affectRows); Assert.assertEquals(1, affectRows);
affectRows = stmt.executeUpdate("drop database " + dbName); affectRows = stmt.executeUpdate("drop database " + dbName);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册