提交 3b4f730f 编写于 作者: L liuyq-617

Merge branch 'develop' into test/jenkins

...@@ -43,7 +43,7 @@ CREATE STABLE meters (ts timestamp, current float, voltage int, phase float) TAG ...@@ -43,7 +43,7 @@ CREATE STABLE meters (ts timestamp, current float, voltage int, phase float) TAG
## <a class="anchor" id="create-table"></a>创建表 ## <a class="anchor" id="create-table"></a>创建表
TDengine对每个数据采集点需要独立建表。与标准的关系型数据一样,一张表有表名,Schema,但除此之外,还可以带有一到多个标签。创建时,需要使用超级表做模板,同时指定标签的具体值。以表一中的智能电表为例,可以使用如下的SQL命令建表: TDengine对每个数据采集点需要独立建表。与标准的关系型数据一样,一张表有表名,Schema,但除此之外,还可以带有一到多个标签。创建时,需要使用超级表做模板,同时指定标签的具体值。以表一中的智能电表为例,可以使用如下的SQL命令建表:
```cmd ```mysql
CREATE TABLE d1001 USING meters TAGS ("Beijing.Chaoyang", 2); CREATE TABLE d1001 USING meters TAGS ("Beijing.Chaoyang", 2);
``` ```
其中d1001是表名,meters是超级表的表名,后面紧跟标签Location的具体标签值”Beijing.Chaoyang",标签groupId的具体标签值2。虽然在创建表时,需要指定标签值,但可以事后修改。详细细则请见 [TAOS SQL 的表管理](https://www.taosdata.com/cn/documentation/taos-sql#table) 章节。 其中d1001是表名,meters是超级表的表名,后面紧跟标签Location的具体标签值”Beijing.Chaoyang",标签groupId的具体标签值2。虽然在创建表时,需要指定标签值,但可以事后修改。详细细则请见 [TAOS SQL 的表管理](https://www.taosdata.com/cn/documentation/taos-sql#table) 章节。
...@@ -54,10 +54,12 @@ TDengine建议将数据采集点的全局唯一ID作为表名(比如设备序列 ...@@ -54,10 +54,12 @@ TDengine建议将数据采集点的全局唯一ID作为表名(比如设备序列
**自动建表**:在某些特殊场景中,用户在写数据时并不确定某个数据采集点的表是否存在,此时可在写入数据时使用自动建表语法来创建不存在的表,若该表已存在则不会建立新表。比如: **自动建表**:在某些特殊场景中,用户在写数据时并不确定某个数据采集点的表是否存在,此时可在写入数据时使用自动建表语法来创建不存在的表,若该表已存在则不会建立新表。比如:
```cmd ```mysql
INSERT INTO d1001 USING METERS TAGS ("Beijng.Chaoyang", 2) VALUES (now, 10.2, 219, 0.32); INSERT INTO d1001 USING METERS TAGS ("Beijng.Chaoyang", 2) VALUES (now, 10.2, 219, 0.32);
``` ```
上述SQL语句将记录(now, 10.2, 219, 0.32) 插入进表d1001。如果表d1001还未创建,则使用超级表meters做模板自动创建,同时打上标签值“Beijing.Chaoyang", 2。 上述SQL语句将记录 (now, 10.2, 219, 0.32) 插入表d1001。如果表d1001还未创建,则使用超级表meters做模板自动创建,同时打上标签值“Beijing.Chaoyang", 2。
关于自动建表的详细语法请参见 [插入记录时自动建表](https://www.taosdata.com/cn/documentation/taos-sql#auto_create_table) 章节。
## 多列模型 vs 单列模型 ## 多列模型 vs 单列模型
......
...@@ -152,6 +152,14 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic ...@@ -152,6 +152,14 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic
``` ```
以指定的超级表为模板,指定 tags 的值来创建数据表。 以指定的超级表为模板,指定 tags 的值来创建数据表。
- **以超级表为模板创建数据表,并指定具体的 tags 列**
```mysql
CREATE TABLE [IF NOT EXISTS] tb_name USING stb_name (tag_name1, ...) TAGS (tag_value1, ...);
```
以指定的超级表为模板,指定一部分 tags 列的值来创建数据表。(没被指定的 tags 列会设为空值。)
说明:从 2.0.17 版本开始支持这种方式。在之前的版本中,不允许指定 tags 列,而必须显式给出所有 tags 列的取值。
- **批量创建数据表** - **批量创建数据表**
```mysql ```mysql
...@@ -306,7 +314,7 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic ...@@ -306,7 +314,7 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic
- **插入一条记录,数据对应到指定的列** - **插入一条记录,数据对应到指定的列**
```mysql ```mysql
INSERT INTO tb_name (field1_name, ...) VALUES (field1_value, ...) INSERT INTO tb_name (field1_name, ...) VALUES (field1_value1, ...);
``` ```
向表tb_name中插入一条记录,数据对应到指定的列。SQL语句中没有出现的列,数据库将自动填充为NULL。主键(时间戳)不能为NULL。 向表tb_name中插入一条记录,数据对应到指定的列。SQL语句中没有出现的列,数据库将自动填充为NULL。主键(时间戳)不能为NULL。
...@@ -340,6 +348,18 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic ...@@ -340,6 +348,18 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic
1) 如果时间戳为0,系统将自动使用服务器当前时间作为该记录的时间戳; 1) 如果时间戳为0,系统将自动使用服务器当前时间作为该记录的时间戳;
2) 允许插入的最老记录的时间戳,是相对于当前服务器时间,减去配置的keep值(数据保留的天数),允许插入的最新记录的时间戳,是相对于当前服务器时间,加上配置的days值(数据文件存储数据的时间跨度,单位为天)。keep和days都是可以在创建数据库时指定的,缺省值分别是3650天和10天。 2) 允许插入的最老记录的时间戳,是相对于当前服务器时间,减去配置的keep值(数据保留的天数),允许插入的最新记录的时间戳,是相对于当前服务器时间,加上配置的days值(数据文件存储数据的时间跨度,单位为天)。keep和days都是可以在创建数据库时指定的,缺省值分别是3650天和10天。
- <a class="anchor" id="auto_create_table"></a>**插入记录时自动建表**
```mysql
INSERT INTO tb_name USING stb_name TAGS (tag_value1, ...) VALUES (field_value1, ...);
```
如果用户在写数据时并不确定某个表是否存在,此时可以在写入数据时使用自动建表语法来创建不存在的表,若该表已存在则不会建立新表。自动建表时,要求必须以超级表为模板,并写明数据表的 tags 取值。
- **插入记录时自动建表,并指定具体的 tags 列**
```mysql
INSERT INTO tb_name USING stb_name (tag_name1, ...) TAGS (tag_value1, ...) VALUES (field_value1, ...);
```
在自动建表时,可以只是指定部分 tags 列的取值,未被指定的 tags 列将取为空值。
**历史记录写入**:可使用IMPORT或者INSERT命令,IMPORT的语法,功能与INSERT完全一样。 **历史记录写入**:可使用IMPORT或者INSERT命令,IMPORT的语法,功能与INSERT完全一样。
说明:针对 insert 类型的 SQL 语句,我们采用的流式解析策略,在发现后面的错误之前,前面正确的部分SQL仍会执行。下面的sql中,insert语句是无效的,但是d1001仍会被创建。 说明:针对 insert 类型的 SQL 语句,我们采用的流式解析策略,在发现后面的错误之前,前面正确的部分SQL仍会执行。下面的sql中,insert语句是无效的,但是d1001仍会被创建。
...@@ -383,7 +403,7 @@ SELECT select_expr [, select_expr ...] ...@@ -383,7 +403,7 @@ SELECT select_expr [, select_expr ...]
[ORDER BY col_list { DESC | ASC }] [ORDER BY col_list { DESC | ASC }]
[SLIMIT limit_val [, SOFFSET offset_val]] [SLIMIT limit_val [, SOFFSET offset_val]]
[LIMIT limit_val [, OFFSET offset_val]] [LIMIT limit_val [, OFFSET offset_val]]
[>> export_file] [>> export_file];
``` ```
#### SELECT子句 #### SELECT子句
......
...@@ -128,6 +128,7 @@ ...@@ -128,6 +128,7 @@
</includes> </includes>
<excludes> <excludes>
<exclude>**/AppMemoryLeakTest.java</exclude> <exclude>**/AppMemoryLeakTest.java</exclude>
<exclude>**/AuthenticationTest.java</exclude>
<exclude>**/TaosInfoMonitorTest.java</exclude> <exclude>**/TaosInfoMonitorTest.java</exclude>
<exclude>**/FailOverTest.java</exclude> <exclude>**/FailOverTest.java</exclude>
<exclude>**/InvalidResultSetPointerTest.java</exclude> <exclude>**/InvalidResultSetPointerTest.java</exclude>
......
package com.taosdata.jdbc;
import java.sql.*;
import java.util.Enumeration;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.*;
public abstract class AbstractConnection extends WrapperImpl implements Connection {
protected volatile boolean isClosed;
protected volatile String catalog;
protected volatile Properties clientInfoProps = new Properties();
@Override
public abstract Statement createStatement() throws SQLException;
@Override
public abstract PreparedStatement prepareStatement(String sql) throws SQLException;
@Override
public CallableStatement prepareCall(String sql) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public String nativeSQL(String sql) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
// do nothing
return sql;
}
@Override
public void setAutoCommit(boolean autoCommit) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
//do nothing
}
@Override
public boolean getAutoCommit() throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
return true;
}
@Override
public void commit() throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
// do nothing
}
@Override
public void rollback() throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
// do nothing
}
@Override
public abstract void close() throws SQLException;
@Override
public abstract boolean isClosed() throws SQLException;
@Override
public abstract DatabaseMetaData getMetaData() throws SQLException;
@Override
public void setReadOnly(boolean readOnly) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
//do nothing
}
@Override
public boolean isReadOnly() throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
return true;
}
@Override
public void setCatalog(String catalog) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
/*
try (Statement stmt = createStatement()) {
boolean execute = stmt.execute("use " + catalog);
if (execute)
this.catalog = catalog;
} catch (SQLException e) {
// do nothing
}
*/
this.catalog = catalog;
}
@Override
public String getCatalog() throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
return this.catalog;
}
@Override
public void setTransactionIsolation(int level) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
switch (level) {
case Connection.TRANSACTION_NONE:
break;
case Connection.TRANSACTION_READ_UNCOMMITTED:
case Connection.TRANSACTION_READ_COMMITTED:
case Connection.TRANSACTION_REPEATABLE_READ:
case Connection.TRANSACTION_SERIALIZABLE:
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORTED_METHOD_EXCEPTION_MSG);
default:
throw new SQLException(TSDBConstants.INVALID_VARIABLES);
}
//do nothing
}
@Override
public int getTransactionIsolation() throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
return Connection.TRANSACTION_NONE;
}
@Override
public SQLWarning getWarnings() throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
return null;
}
@Override
public void clearWarnings() throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
// do nothing
}
@Override
public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
switch (resultSetType) {
case ResultSet.TYPE_FORWARD_ONLY:
break;
case ResultSet.TYPE_SCROLL_INSENSITIVE:
case ResultSet.TYPE_SCROLL_SENSITIVE:
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
default:
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_VARIABLE);
}
switch (resultSetConcurrency) {
case ResultSet.CONCUR_READ_ONLY:
break;
case ResultSet.CONCUR_UPDATABLE:
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
default:
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_VARIABLE);
}
return createStatement();
}
@Override
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
switch (resultSetType) {
case ResultSet.TYPE_FORWARD_ONLY:
break;
case ResultSet.TYPE_SCROLL_INSENSITIVE:
case ResultSet.TYPE_SCROLL_SENSITIVE:
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
default:
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_VARIABLE);
}
switch (resultSetConcurrency) {
case ResultSet.CONCUR_READ_ONLY:
break;
case ResultSet.CONCUR_UPDATABLE:
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
default:
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_VARIABLE);
}
return prepareStatement(sql);
}
@Override
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public Map<String, Class<?>> getTypeMap() throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public void setHoldability(int holdability) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
switch (holdability) {
case ResultSet.HOLD_CURSORS_OVER_COMMIT:
break;
case ResultSet.CLOSE_CURSORS_AT_COMMIT:
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
default:
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_VARIABLE);
}
//do nothing
}
@Override
public int getHoldability() throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
return ResultSet.HOLD_CURSORS_OVER_COMMIT;
}
@Override
public Savepoint setSavepoint() throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public Savepoint setSavepoint(String name) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public void rollback(Savepoint savepoint) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public void releaseSavepoint(Savepoint savepoint) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
switch (resultSetHoldability) {
case ResultSet.HOLD_CURSORS_OVER_COMMIT:
break;
case ResultSet.CLOSE_CURSORS_AT_COMMIT:
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
default:
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_VARIABLE);
}
return createStatement(resultSetType, resultSetConcurrency);
}
@Override
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability)
throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
switch (resultSetHoldability) {
case ResultSet.HOLD_CURSORS_OVER_COMMIT:
break;
case ResultSet.CLOSE_CURSORS_AT_COMMIT:
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
default:
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_VARIABLE);
}
return prepareStatement(sql, resultSetType, resultSetConcurrency);
}
@Override
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
switch (autoGeneratedKeys) {
case Statement.RETURN_GENERATED_KEYS:
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
case Statement.NO_GENERATED_KEYS:
break;
}
return prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT);
}
@Override
public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public Clob createClob() throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public Blob createBlob() throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public NClob createNClob() throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public SQLXML createSQLXML() throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public boolean isValid(int timeout) throws SQLException {
//true if the connection is valid, false otherwise
if (isClosed())
return false;
if (timeout < 0) //SQLException - if the value supplied for timeout is less then 0
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_VARIABLE);
ExecutorService executor = Executors.newCachedThreadPool();
Future<Boolean> future = executor.submit(() -> {
int status;
try (Statement stmt = createStatement()) {
ResultSet resultSet = stmt.executeQuery("select server_status()");
resultSet.next();
status = resultSet.getInt("server_status()");
resultSet.close();
}
return status == 1 ? true : false;
});
boolean status = false;
try {
if (timeout == 0)
status = future.get();
else
status = future.get(timeout, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
future.cancel(true);
status = false;
} finally {
executor.shutdownNow();
}
return status;
}
@Override
public void setClientInfo(String name, String value) throws SQLClientInfoException {
if (isClosed)
throw TSDBError.createSQLClientInfoException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
if (clientInfoProps == null)
clientInfoProps = new Properties();
clientInfoProps.setProperty(name, value);
}
@Override
public void setClientInfo(Properties properties) throws SQLClientInfoException {
if (isClosed)
throw TSDBError.createSQLClientInfoException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
for (Enumeration<Object> enumer = properties.keys(); enumer.hasMoreElements(); ) {
String name = (String) enumer.nextElement();
clientInfoProps.put(name, properties.getProperty(name));
}
}
@Override
public String getClientInfo(String name) throws SQLException {
if (isClosed)
throw TSDBError.createSQLClientInfoException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
return clientInfoProps.getProperty(name);
}
@Override
public Properties getClientInfo() throws SQLException {
if (isClosed)
throw TSDBError.createSQLClientInfoException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
return clientInfoProps;
}
@Override
public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public void setSchema(String schema) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
//do nothing
}
@Override
public String getSchema() throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
return null;
}
@Override
public void abort(Executor executor) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
// do nothing
}
@Override
public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
if (milliseconds < 0)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_VARIABLE);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public int getNetworkTimeout() throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
}
...@@ -4,7 +4,7 @@ import java.sql.*; ...@@ -4,7 +4,7 @@ import java.sql.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public abstract class AbstractDatabaseMetaData implements DatabaseMetaData, Wrapper { public abstract class AbstractDatabaseMetaData extends WrapperImpl implements DatabaseMetaData {
private final static String PRODUCT_NAME = "TDengine"; private final static String PRODUCT_NAME = "TDengine";
private final static String PRODUCT_VESION = "2.0.x.x"; private final static String PRODUCT_VESION = "2.0.x.x";
...@@ -981,9 +981,7 @@ public abstract class AbstractDatabaseMetaData implements DatabaseMetaData, Wrap ...@@ -981,9 +981,7 @@ public abstract class AbstractDatabaseMetaData implements DatabaseMetaData, Wrap
return getEmptyResultSet(); return getEmptyResultSet();
} }
public Connection getConnection() throws SQLException { public abstract Connection getConnection() throws SQLException;
return null;
}
public boolean supportsSavepoints() throws SQLException { public boolean supportsSavepoints() throws SQLException {
return false; return false;
...@@ -1067,6 +1065,7 @@ public abstract class AbstractDatabaseMetaData implements DatabaseMetaData, Wrap ...@@ -1067,6 +1065,7 @@ public abstract class AbstractDatabaseMetaData implements DatabaseMetaData, Wrap
} }
public ResultSet getClientInfoProperties() throws SQLException { public ResultSet getClientInfoProperties() throws SQLException {
//TODO: see https://docs.oracle.com/javase/8/docs/api/java/sql/Connection.html#setClientInfo-java.lang.String-java.lang.String-
return getEmptyResultSet(); return getEmptyResultSet();
} }
...@@ -1093,20 +1092,6 @@ public abstract class AbstractDatabaseMetaData implements DatabaseMetaData, Wrap ...@@ -1093,20 +1092,6 @@ public abstract class AbstractDatabaseMetaData implements DatabaseMetaData, Wrap
return new EmptyResultSet(); return new EmptyResultSet();
} }
@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
try {
return iface.cast(this);
} catch (ClassCastException cce) {
throw new SQLException("Unable to unwrap to " + iface.toString());
}
}
@Override
public boolean isWrapperFor(Class<?> iface) throws SQLException {
return iface.isInstance(this);
}
protected ResultSet getCatalogs(Connection conn) throws SQLException { protected ResultSet getCatalogs(Connection conn) throws SQLException {
try (Statement stmt = conn.createStatement()) { try (Statement stmt = conn.createStatement()) {
DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet(); DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet();
......
...@@ -14,41 +14,25 @@ ...@@ -14,41 +14,25 @@
*****************************************************************************/ *****************************************************************************/
package com.taosdata.jdbc; package com.taosdata.jdbc;
import java.sql.Array; import java.sql.*;
import java.sql.Blob; import java.util.Properties;
import java.sql.CallableStatement;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.NClob;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLClientInfoException;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.SQLXML;
import java.sql.Savepoint;
import java.sql.Statement;
import java.sql.Struct;
import java.util.*;
import java.util.concurrent.Executor;
public class TSDBConnection implements Connection { public class TSDBConnection extends AbstractConnection {
private TSDBJNIConnector connector = null; private TSDBJNIConnector connector;
private TSDBDatabaseMetaData databaseMetaData;
private boolean batchFetch;
private String catalog = null; public Boolean getBatchFetch() {
return this.batchFetch;
private TSDBDatabaseMetaData dbMetaData; }
private Properties clientInfoProps = new Properties();
private int timeoutMilliseconds = 0;
private boolean batchFetch = false; public void setBatchFetch(Boolean batchFetch) {
this.batchFetch = batchFetch;
}
public TSDBConnection(Properties info, TSDBDatabaseMetaData meta) throws SQLException { public TSDBConnection(Properties info, TSDBDatabaseMetaData meta) throws SQLException {
this.dbMetaData = meta; this.databaseMetaData = meta;
connect(info.getProperty(TSDBDriver.PROPERTY_KEY_HOST), connect(info.getProperty(TSDBDriver.PROPERTY_KEY_HOST),
Integer.parseInt(info.getProperty(TSDBDriver.PROPERTY_KEY_PORT, "0")), Integer.parseInt(info.getProperty(TSDBDriver.PROPERTY_KEY_PORT, "0")),
info.getProperty(TSDBDriver.PROPERTY_KEY_DBNAME), info.getProperty(TSDBDriver.PROPERTY_KEY_DBNAME),
...@@ -64,8 +48,8 @@ public class TSDBConnection implements Connection { ...@@ -64,8 +48,8 @@ public class TSDBConnection implements Connection {
private void connect(String host, int port, String dbName, String user, String password) throws SQLException { private void connect(String host, int port, String dbName, String user, String password) throws SQLException {
this.connector = new TSDBJNIConnector(); this.connector = new TSDBJNIConnector();
this.connector.connect(host, port, dbName, user, password); this.connector.connect(host, port, dbName, user, password);
this.setCatalog(dbName); this.catalog = dbName;
this.dbMetaData.setConnection(this); this.databaseMetaData.setConnection(this);
} }
public TSDBJNIConnector getConnection() { public TSDBJNIConnector getConnection() {
...@@ -102,52 +86,11 @@ public class TSDBConnection implements Connection { ...@@ -102,52 +86,11 @@ public class TSDBConnection implements Connection {
return new TSDBPreparedStatement(this, this.connector, sql); return new TSDBPreparedStatement(this, this.connector, sql);
} }
public CallableStatement prepareCall(String sql) throws SQLException {
if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public String nativeSQL(String sql) throws SQLException {
if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public void setAutoCommit(boolean autoCommit) throws SQLException {
if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
}
public boolean getAutoCommit() throws SQLException {
if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
return true;
}
public void commit() throws SQLException {
if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
}
public void rollback() throws SQLException {
if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public void close() throws SQLException { public void close() throws SQLException {
if (isClosed()) { if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
} }
this.isClosed = true;
this.connector.closeConnection(); this.connector.closeConnection();
} }
...@@ -155,105 +98,11 @@ public class TSDBConnection implements Connection { ...@@ -155,105 +98,11 @@ public class TSDBConnection implements Connection {
return this.connector != null && this.connector.isClosed(); return this.connector != null && this.connector.isClosed();
} }
/**
* A connection's database is able to provide information describing its tables,
* its supported SQL grammar, its stored procedures, the capabilities of this
* connection, etc. This information is made available through a
* DatabaseMetaData object.
*
* @return a DatabaseMetaData object for this connection
* @throws SQLException if a database access error occurs
*/
public DatabaseMetaData getMetaData() throws SQLException { public DatabaseMetaData getMetaData() throws SQLException {
if (isClosed()) { if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
} }
return this.dbMetaData; return this.databaseMetaData;
}
/**
* This readOnly option is not supported by TDengine. However, the method is intentionally left blank here to
* support HikariCP connection.
*
* @param readOnly
* @throws SQLException
*/
public void setReadOnly(boolean readOnly) throws SQLException {
if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
}
public boolean isReadOnly() throws SQLException {
if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
return true;
}
public void setCatalog(String catalog) throws SQLException {
if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
this.catalog = catalog;
}
public String getCatalog() throws SQLException {
if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
return this.catalog;
}
/**
* The transaction isolation level option is not supported by TDengine.
* This method is intentionally left empty to support HikariCP connection.
*
* @param level
* @throws SQLException
*/
public void setTransactionIsolation(int level) throws SQLException {
if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
switch (level) {
case Connection.TRANSACTION_NONE:
case Connection.TRANSACTION_READ_COMMITTED:
case Connection.TRANSACTION_READ_UNCOMMITTED:
case Connection.TRANSACTION_REPEATABLE_READ:
case Connection.TRANSACTION_SERIALIZABLE:
break;
default:
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_VARIABLE);
}
}
/**
* The transaction isolation level option is not supported by TDengine.
*
* @return
* @throws SQLException
*/
public int getTransactionIsolation() throws SQLException {
if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
return Connection.TRANSACTION_NONE;
}
public SQLWarning getWarnings() throws SQLException {
if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
//todo: implement getWarnings according to the warning messages returned from TDengine
return null;
}
public void clearWarnings() throws SQLException {
if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
//todo: implement clearWarnings according to the warning messages returned from TDengine
} }
public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException { public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
...@@ -263,253 +112,4 @@ public class TSDBConnection implements Connection { ...@@ -263,253 +112,4 @@ public class TSDBConnection implements Connection {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
} }
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency)
throws SQLException {
// This method is implemented in the current way to support Spark
if (resultSetType != ResultSet.TYPE_FORWARD_ONLY) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_VARIABLE);
}
if (resultSetConcurrency != ResultSet.CONCUR_READ_ONLY) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_VARIABLE);
}
return this.prepareStatement(sql);
}
public Boolean getBatchFetch() {
return this.batchFetch;
}
public void setBatchFetch(Boolean batchFetch) {
this.batchFetch = batchFetch;
}
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public Map<String, Class<?>> getTypeMap() throws SQLException {
if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public void setHoldability(int holdability) throws SQLException {
if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
}
/**
* the transaction is not supported by TDengine, so the opened ResultSet Objects will remain open
*
* @return
* @throws SQLException
*/
public int getHoldability() throws SQLException {
if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
return ResultSet.HOLD_CURSORS_OVER_COMMIT;
}
public Savepoint setSavepoint() throws SQLException {
if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public Savepoint setSavepoint(String name) throws SQLException {
if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public void rollback(Savepoint savepoint) throws SQLException {
if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public void releaseSavepoint(Savepoint savepoint) throws SQLException {
if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability)
throws SQLException {
if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency,
int resultSetHoldability) throws SQLException {
if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency,
int resultSetHoldability) throws SQLException {
if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public Clob createClob() throws SQLException {
if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public Blob createBlob() throws SQLException {
if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public NClob createNClob() throws SQLException {
if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public SQLXML createSQLXML() throws SQLException {
if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public boolean isValid(int timeout) throws SQLException {
return !this.isClosed();
}
public void setClientInfo(String name, String value) throws SQLClientInfoException {
clientInfoProps.setProperty(name, value);
}
public void setClientInfo(Properties properties) throws SQLClientInfoException {
for (Enumeration<Object> enumer = properties.keys(); enumer.hasMoreElements(); ) {
String name = (String) enumer.nextElement();
clientInfoProps.put(name, properties.getProperty(name));
}
}
public String getClientInfo(String name) throws SQLException {
if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
return clientInfoProps.getProperty(name);
}
public Properties getClientInfo() throws SQLException {
if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
return clientInfoProps;
}
public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public void setSchema(String schema) throws SQLException {
if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public String getSchema() throws SQLException {
if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public void abort(Executor executor) throws SQLException {
if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {
this.timeoutMilliseconds = milliseconds;
}
public int getNetworkTimeout() throws SQLException {
if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
return this.timeoutMilliseconds;
}
public <T> T unwrap(Class<T> iface) throws SQLException {
try {
return iface.cast(this);
} catch (ClassCastException cce) {
throw new SQLException("Unable to unwrap to " + iface.toString());
}
}
public boolean isWrapperFor(Class<?> iface) throws SQLException {
return iface.isInstance(this);
}
} }
...@@ -57,39 +57,38 @@ public class TSDBDatabaseMetaData extends AbstractDatabaseMetaData { ...@@ -57,39 +57,38 @@ public class TSDBDatabaseMetaData extends AbstractDatabaseMetaData {
*/ */
public ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String[] types) throws SQLException { public ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String[] types) throws SQLException {
if (conn == null || conn.isClosed()) { if (conn == null || conn.isClosed()) {
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL)); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
} }
return super.getTables(catalog, schemaPattern, tableNamePattern, types, conn); return super.getTables(catalog, schemaPattern, tableNamePattern, types, conn);
} }
public ResultSet getCatalogs() throws SQLException { public ResultSet getCatalogs() throws SQLException {
if (conn == null || conn.isClosed()) if (conn == null || conn.isClosed())
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL)); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
return super.getCatalogs(conn); return super.getCatalogs(conn);
} }
public ResultSet getTableTypes() throws SQLException { public ResultSet getTableTypes() throws SQLException {
if (conn == null || conn.isClosed()) if (conn == null || conn.isClosed())
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL)); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
return super.getTableTypes(); return super.getTableTypes();
} }
public ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) throws SQLException { public ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) throws SQLException {
if (conn == null || conn.isClosed()) if (conn == null || conn.isClosed())
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL)); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
return super.getColumns(catalog, schemaPattern, tableNamePattern, columnNamePattern, conn); return super.getColumns(catalog, schemaPattern, tableNamePattern, columnNamePattern, conn);
} }
public ResultSet getPrimaryKeys(String catalog, String schema, String table) throws SQLException { public ResultSet getPrimaryKeys(String catalog, String schema, String table) throws SQLException {
if (conn == null || conn.isClosed()) if (conn == null || conn.isClosed())
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL)); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
return super.getPrimaryKeys(catalog, schema, table, conn); return super.getPrimaryKeys(catalog, schema, table, conn);
} }
public ResultSet getSuperTables(String catalog, String schemaPattern, String tableNamePattern) throws SQLException { public ResultSet getSuperTables(String catalog, String schemaPattern, String tableNamePattern) throws SQLException {
if (conn == null || conn.isClosed()) if (conn == null || conn.isClosed())
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL)); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
return super.getSuperTables(catalog, schemaPattern, tableNamePattern, conn); return super.getSuperTables(catalog, schemaPattern, tableNamePattern, conn);
} }
......
package com.taosdata.jdbc; package com.taosdata.jdbc;
import java.sql.SQLClientInfoException;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException; import java.sql.SQLFeatureNotSupportedException;
import java.util.HashMap; import java.util.HashMap;
...@@ -17,6 +18,10 @@ public class TSDBError { ...@@ -17,6 +18,10 @@ public class TSDBError {
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_BATCH_IS_EMPTY, "Batch is empty!"); TSDBErrorMap.put(TSDBErrorNumbers.ERROR_BATCH_IS_EMPTY, "Batch is empty!");
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_INVALID_WITH_EXECUTEQUERY, "Can not issue data manipulation statements with executeQuery()"); TSDBErrorMap.put(TSDBErrorNumbers.ERROR_INVALID_WITH_EXECUTEQUERY, "Can not issue data manipulation statements with executeQuery()");
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_INVALID_WITH_EXECUTEUPDATE, "Can not issue SELECT via executeUpdate()"); TSDBErrorMap.put(TSDBErrorNumbers.ERROR_INVALID_WITH_EXECUTEUPDATE, "Can not issue SELECT via executeUpdate()");
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_INVALID_FOR_EXECUTE_QUERY, "not a valid sql for executeQuery: (?)");
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_DATABASE_NOT_SPECIFIED_OR_AVAILABLE, "Database not specified or available");
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_INVALID_FOR_EXECUTE_UPDATE, "not a valid sql for executeUpdate: (?)");
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_INVALID_FOR_EXECUTE, "not a valid sql for execute: (?)");
/**************************************************/ /**************************************************/
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_UNKNOWN, "unknown error"); TSDBErrorMap.put(TSDBErrorNumbers.ERROR_UNKNOWN, "unknown error");
...@@ -58,4 +63,8 @@ public class TSDBError { ...@@ -58,4 +63,8 @@ public class TSDBError {
// JNI exception's error number is large than 0x2350 // JNI exception's error number is large than 0x2350
return new SQLException("TDengine ERROR (" + Integer.toHexString(errorNumber) + "): " + message); return new SQLException("TDengine ERROR (" + Integer.toHexString(errorNumber) + "): " + message);
} }
public static SQLClientInfoException createSQLClientInfoException(int errorNumber) {
return new SQLClientInfoException();
}
} }
...@@ -12,6 +12,10 @@ public class TSDBErrorNumbers { ...@@ -12,6 +12,10 @@ public class TSDBErrorNumbers {
public static final int ERROR_BATCH_IS_EMPTY = 0x2306; //Batch is empty! public static final int ERROR_BATCH_IS_EMPTY = 0x2306; //Batch is empty!
public static final int ERROR_INVALID_WITH_EXECUTEQUERY = 0x2307; //Can not issue data manipulation statements with executeQuery() public static final int ERROR_INVALID_WITH_EXECUTEQUERY = 0x2307; //Can not issue data manipulation statements with executeQuery()
public static final int ERROR_INVALID_WITH_EXECUTEUPDATE = 0x2308; //Can not issue SELECT via executeUpdate() public static final int ERROR_INVALID_WITH_EXECUTEUPDATE = 0x2308; //Can not issue SELECT via executeUpdate()
public static final int ERROR_INVALID_FOR_EXECUTE_QUERY = 0x2309; //not a valid sql for executeQuery: (SQL)
public static final int ERROR_DATABASE_NOT_SPECIFIED_OR_AVAILABLE = 0x2310; //Database not specified or available
public static final int ERROR_INVALID_FOR_EXECUTE_UPDATE = 0x2311; //not a valid sql for executeUpdate: (SQL)
public static final int ERROR_INVALID_FOR_EXECUTE = 0x2312; //not a valid sql for execute: (SQL)
public static final int ERROR_UNKNOWN = 0x2350; //unknown error public static final int ERROR_UNKNOWN = 0x2350; //unknown error
...@@ -37,6 +41,11 @@ public class TSDBErrorNumbers { ...@@ -37,6 +41,11 @@ public class TSDBErrorNumbers {
errorNumbers.add(ERROR_RESULTSET_CLOSED); errorNumbers.add(ERROR_RESULTSET_CLOSED);
errorNumbers.add(ERROR_INVALID_WITH_EXECUTEQUERY); errorNumbers.add(ERROR_INVALID_WITH_EXECUTEQUERY);
errorNumbers.add(ERROR_INVALID_WITH_EXECUTEUPDATE); errorNumbers.add(ERROR_INVALID_WITH_EXECUTEUPDATE);
errorNumbers.add(ERROR_INVALID_FOR_EXECUTE_QUERY);
errorNumbers.add(ERROR_DATABASE_NOT_SPECIFIED_OR_AVAILABLE);
errorNumbers.add(ERROR_INVALID_FOR_EXECUTE_UPDATE);
errorNumbers.add(ERROR_INVALID_FOR_EXECUTE);
/*****************************************************/ /*****************************************************/
errorNumbers.add(ERROR_SUBSCRIBE_FAILED); errorNumbers.add(ERROR_SUBSCRIBE_FAILED);
errorNumbers.add(ERROR_UNSUPPORTED_ENCODING); errorNumbers.add(ERROR_UNSUPPORTED_ENCODING);
......
...@@ -16,9 +16,6 @@ package com.taosdata.jdbc; ...@@ -16,9 +16,6 @@ package com.taosdata.jdbc;
import javax.management.OperationsException; import javax.management.OperationsException;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.Map;
import java.util.TimerTask;
import java.util.concurrent.*;
public class TSDBSubscribe { public class TSDBSubscribe {
private TSDBJNIConnector connecter = null; private TSDBJNIConnector connecter = null;
...@@ -36,9 +33,8 @@ public class TSDBSubscribe { ...@@ -36,9 +33,8 @@ public class TSDBSubscribe {
/** /**
* consume * consume
* *
* @throws OperationsException, SQLException
*/ */
public TSDBResultSet consume() throws OperationsException, SQLException { public TSDBResultSet consume() throws SQLException {
if (this.connecter.isClosed()) { if (this.connecter.isClosed()) {
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL)); throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL));
} }
......
package com.taosdata.jdbc.rs; package com.taosdata.jdbc.rs;
import com.taosdata.jdbc.TSDBConstants; import com.taosdata.jdbc.*;
import com.taosdata.jdbc.TSDBDriver;
import java.sql.*; import java.sql.*;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.concurrent.Executor;
public class RestfulConnection implements Connection { public class RestfulConnection extends AbstractConnection {
private static final String CONNECTION_IS_CLOSED = "connection is closed.";
private static final String AUTO_COMMIT_IS_TRUE = "auto commit is true";
private final String host; private final String host;
private final int port; private final int port;
private final Properties props;
private volatile String database;
private final String url; private final String url;
private volatile String database;
/******************************************************/ /******************************************************/
private boolean isClosed; private boolean isClosed;
private DatabaseMetaData metadata; private final DatabaseMetaData metadata;
private Map<String, Class<?>> typeMap;
private Properties clientInfoProps = new Properties();
public RestfulConnection(String host, String port, Properties props, String database, String url) { public RestfulConnection(String host, String port, Properties props, String database, String url) {
this.host = host; this.host = host;
this.port = Integer.parseInt(port); this.port = Integer.parseInt(port);
this.props = props;
this.database = database; this.database = database;
this.url = url; this.url = url;
this.metadata = new RestfulDatabaseMetaData(url, props.getProperty(TSDBDriver.PROPERTY_KEY_USER), this); this.metadata = new RestfulDatabaseMetaData(url, props.getProperty(TSDBDriver.PROPERTY_KEY_USER), this);
...@@ -37,7 +26,7 @@ public class RestfulConnection implements Connection { ...@@ -37,7 +26,7 @@ public class RestfulConnection implements Connection {
@Override @Override
public Statement createStatement() throws SQLException { public Statement createStatement() throws SQLException {
if (isClosed()) if (isClosed())
throw new SQLException(CONNECTION_IS_CLOSED); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);;
return new RestfulStatement(this, database); return new RestfulStatement(this, database);
} }
...@@ -45,61 +34,11 @@ public class RestfulConnection implements Connection { ...@@ -45,61 +34,11 @@ public class RestfulConnection implements Connection {
@Override @Override
public PreparedStatement prepareStatement(String sql) throws SQLException { public PreparedStatement prepareStatement(String sql) throws SQLException {
if (isClosed()) if (isClosed())
throw new SQLException(CONNECTION_IS_CLOSED); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);;
//TODO: prepareStatement //TODO: prepareStatement
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORTED_METHOD_EXCEPTION_MSG); throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORTED_METHOD_EXCEPTION_MSG);
} }
@Override
public CallableStatement prepareCall(String sql) throws SQLException {
if (isClosed())
throw new SQLException(CONNECTION_IS_CLOSED);
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORTED_METHOD_EXCEPTION_MSG);
}
@Override
public String nativeSQL(String sql) throws SQLException {
if (isClosed())
throw new SQLException(CONNECTION_IS_CLOSED);
//nothing did
return sql;
}
@Override
public void setAutoCommit(boolean autoCommit) throws SQLException {
if (isClosed())
throw new SQLException(CONNECTION_IS_CLOSED);
if (!autoCommit)
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORTED_METHOD_EXCEPTION_MSG);
}
@Override
public boolean getAutoCommit() throws SQLException {
if (isClosed())
throw new SQLException(CONNECTION_IS_CLOSED);
return true;
}
@Override
public void commit() throws SQLException {
if (isClosed())
throw new SQLException(CONNECTION_IS_CLOSED);
if (getAutoCommit())
throw new SQLException(AUTO_COMMIT_IS_TRUE);
//nothing to do
}
@Override
public void rollback() throws SQLException {
if (isClosed())
throw new SQLException(CONNECTION_IS_CLOSED);
if (getAutoCommit())
throw new SQLException(AUTO_COMMIT_IS_TRUE);
//nothing to do
}
@Override @Override
public void close() throws SQLException { public void close() throws SQLException {
if (isClosed) if (isClosed)
...@@ -116,356 +55,11 @@ public class RestfulConnection implements Connection { ...@@ -116,356 +55,11 @@ public class RestfulConnection implements Connection {
@Override @Override
public DatabaseMetaData getMetaData() throws SQLException { public DatabaseMetaData getMetaData() throws SQLException {
if (isClosed()) if (isClosed())
throw new SQLException(CONNECTION_IS_CLOSED); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);;
return this.metadata; return this.metadata;
} }
@Override
public void setReadOnly(boolean readOnly) throws SQLException {
if (isClosed())
throw new SQLException(CONNECTION_IS_CLOSED);
// nothing to do
}
@Override
public boolean isReadOnly() throws SQLException {
if (isClosed())
throw new SQLException(CONNECTION_IS_CLOSED);
return true;
}
@Override
public void setCatalog(String catalog) throws SQLException {
if (isClosed())
throw new SQLException(CONNECTION_IS_CLOSED);
synchronized (RestfulConnection.class) {
this.database = catalog;
}
}
@Override
public String getCatalog() throws SQLException {
if (isClosed())
throw new SQLException(CONNECTION_IS_CLOSED);
return this.database;
}
@Override
public void setTransactionIsolation(int level) throws SQLException {
if (isClosed())
throw new SQLException(CONNECTION_IS_CLOSED);
switch (level) {
case Connection.TRANSACTION_NONE:
break;
case Connection.TRANSACTION_READ_UNCOMMITTED:
case Connection.TRANSACTION_READ_COMMITTED:
case Connection.TRANSACTION_REPEATABLE_READ:
case Connection.TRANSACTION_SERIALIZABLE:
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORTED_METHOD_EXCEPTION_MSG);
default:
throw new SQLException(TSDBConstants.INVALID_VARIABLES);
}
}
@Override
public int getTransactionIsolation() throws SQLException {
if (isClosed())
throw new SQLException(CONNECTION_IS_CLOSED);
//Connection.TRANSACTION_NONE specifies that transactions are not supported.
return Connection.TRANSACTION_NONE;
}
@Override
public SQLWarning getWarnings() throws SQLException {
if (isClosed())
throw new SQLException(CONNECTION_IS_CLOSED);
return null;
}
@Override
public void clearWarnings() throws SQLException {
if (isClosed())
throw new SQLException(CONNECTION_IS_CLOSED);
//nothing to do
}
@Override
public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
if (isClosed())
throw new SQLException(CONNECTION_IS_CLOSED);
if (resultSetType != ResultSet.TYPE_FORWARD_ONLY) {
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORTED_METHOD_EXCEPTION_MSG);
}
if (resultSetConcurrency != ResultSet.CONCUR_READ_ONLY)
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORTED_METHOD_EXCEPTION_MSG);
return createStatement();
}
@Override
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
if (isClosed())
throw new SQLException(CONNECTION_IS_CLOSED);
if (resultSetType != ResultSet.TYPE_FORWARD_ONLY || resultSetConcurrency != ResultSet.CONCUR_READ_ONLY)
throw new SQLFeatureNotSupportedException(TSDBConstants.INVALID_VARIABLES);
return this.prepareStatement(sql);
}
@Override
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
if (isClosed())
throw new SQLException(CONNECTION_IS_CLOSED);
if (resultSetType != ResultSet.TYPE_FORWARD_ONLY || resultSetConcurrency != ResultSet.CONCUR_READ_ONLY)
throw new SQLFeatureNotSupportedException(TSDBConstants.INVALID_VARIABLES);
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORTED_METHOD_EXCEPTION_MSG);
}
@Override
public Map<String, Class<?>> getTypeMap() throws SQLException {
if (isClosed())
throw new SQLException(CONNECTION_IS_CLOSED);
synchronized (RestfulConnection.class) {
if (this.typeMap == null) {
this.typeMap = new HashMap<>();
}
return this.typeMap;
}
}
@Override
public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
if (isClosed())
throw new SQLException(CONNECTION_IS_CLOSED);
synchronized (RestfulConnection.class) {
this.typeMap = map;
}
}
@Override
public void setHoldability(int holdability) throws SQLException {
if (isClosed())
throw new SQLException(CONNECTION_IS_CLOSED);
if (holdability != ResultSet.HOLD_CURSORS_OVER_COMMIT)
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORTED_METHOD_EXCEPTION_MSG);
}
@Override
public int getHoldability() throws SQLException {
if (isClosed())
throw new SQLException(CONNECTION_IS_CLOSED);
return ResultSet.HOLD_CURSORS_OVER_COMMIT;
}
@Override
public Savepoint setSavepoint() throws SQLException {
if (isClosed())
throw new SQLException(CONNECTION_IS_CLOSED);
if (getAutoCommit())
throw new SQLException(TSDBConstants.INVALID_VARIABLES);
//nothing to do
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORTED_METHOD_EXCEPTION_MSG);
}
@Override
public Savepoint setSavepoint(String name) throws SQLException {
if (isClosed())
throw new SQLException(CONNECTION_IS_CLOSED);
if (getAutoCommit())
throw new SQLException(TSDBConstants.INVALID_VARIABLES);
//nothing to do
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORTED_METHOD_EXCEPTION_MSG);
}
@Override
public void rollback(Savepoint savepoint) throws SQLException {
if (isClosed())
throw new SQLException(CONNECTION_IS_CLOSED);
if (getAutoCommit())
throw new SQLException(TSDBConstants.INVALID_VARIABLES);
//nothing to do
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORTED_METHOD_EXCEPTION_MSG);
}
@Override
public void releaseSavepoint(Savepoint savepoint) throws SQLException {
if (isClosed())
throw new SQLException(CONNECTION_IS_CLOSED);
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORTED_METHOD_EXCEPTION_MSG);
}
@Override
public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
if (resultSetHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT)
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORTED_METHOD_EXCEPTION_MSG);
return createStatement(resultSetType, resultSetConcurrency);
}
@Override
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
if (resultSetHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT)
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORTED_METHOD_EXCEPTION_MSG);
return prepareStatement(sql, resultSetType, resultSetConcurrency);
}
@Override
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORTED_METHOD_EXCEPTION_MSG);
}
@Override
public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORTED_METHOD_EXCEPTION_MSG);
}
@Override
public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORTED_METHOD_EXCEPTION_MSG);
}
@Override
public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORTED_METHOD_EXCEPTION_MSG);
}
@Override
public Clob createClob() throws SQLException {
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORTED_METHOD_EXCEPTION_MSG);
}
@Override
public Blob createBlob() throws SQLException {
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORTED_METHOD_EXCEPTION_MSG);
}
@Override
public NClob createNClob() throws SQLException {
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORTED_METHOD_EXCEPTION_MSG);
}
@Override
public SQLXML createSQLXML() throws SQLException {
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORTED_METHOD_EXCEPTION_MSG);
}
@Override
public boolean isValid(int timeout) throws SQLException {
if (timeout < 0)
throw new SQLException(TSDBConstants.INVALID_VARIABLES);
// TODO:
/* The driver shall submit a query on the connection or use some other mechanism that positively verifies
the connection is still valid when this method is called.*/
return !isClosed();
}
@Override
public void setClientInfo(String name, String value) throws SQLClientInfoException {
if (isClosed)
throw new SQLClientInfoException();
clientInfoProps.setProperty(name, value);
}
@Override
public void setClientInfo(Properties properties) throws SQLClientInfoException {
if (isClosed)
throw new SQLClientInfoException();
for (Enumeration<Object> enumer = properties.keys(); enumer.hasMoreElements(); ) {
String name = (String) enumer.nextElement();
clientInfoProps.put(name, properties.getProperty(name));
}
}
@Override
public String getClientInfo(String name) throws SQLException {
if (isClosed)
throw new SQLClientInfoException();
return clientInfoProps.getProperty(name);
}
@Override
public Properties getClientInfo() throws SQLException {
if (isClosed)
throw new SQLClientInfoException();
return clientInfoProps;
}
@Override
public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORTED_METHOD_EXCEPTION_MSG);
}
@Override
public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORTED_METHOD_EXCEPTION_MSG);
}
@Override
public void setSchema(String schema) throws SQLException {
if (isClosed())
throw new SQLException(CONNECTION_IS_CLOSED);
synchronized (RestfulConnection.class) {
this.database = schema;
}
}
@Override
public String getSchema() throws SQLException {
if (isClosed())
throw new SQLException(CONNECTION_IS_CLOSED);
return this.database;
}
@Override
public void abort(Executor executor) throws SQLException {
if (executor == null) {
throw new SQLException("Executor can not be null");
}
executor.execute(() -> {
try {
close();
} catch (SQLException e) {
e.printStackTrace();
}
});
}
@Override
public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {
if (isClosed())
throw new SQLException(CONNECTION_IS_CLOSED);
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORTED_METHOD_EXCEPTION_MSG);
}
@Override
public int getNetworkTimeout() throws SQLException {
if (isClosed())
throw new SQLException(CONNECTION_IS_CLOSED);
return 0;
}
@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
try {
return iface.cast(this);
} catch (ClassCastException cce) {
throw new SQLException("Unable to unwrap to " + iface.toString());
}
}
@Override
public boolean isWrapperFor(Class<?> iface) throws SQLException {
return iface.isInstance(this);
}
public String getHost() { public String getHost() {
return host; return host;
} }
...@@ -474,10 +68,6 @@ public class RestfulConnection implements Connection { ...@@ -474,10 +68,6 @@ public class RestfulConnection implements Connection {
return port; return port;
} }
public Properties getProps() {
return props;
}
public String getDatabase() { public String getDatabase() {
return database; return database;
} }
......
package com.taosdata.jdbc.rs; package com.taosdata.jdbc.rs;
import com.taosdata.jdbc.*; import com.taosdata.jdbc.AbstractDatabaseMetaData;
import com.taosdata.jdbc.TSDBError;
import com.taosdata.jdbc.TSDBErrorNumbers;
import java.sql.*; import java.sql.Connection;
import java.util.ArrayList; import java.sql.ResultSet;
import java.util.List; import java.sql.SQLException;
public class RestfulDatabaseMetaData extends AbstractDatabaseMetaData { public class RestfulDatabaseMetaData extends AbstractDatabaseMetaData {
...@@ -33,11 +35,10 @@ public class RestfulDatabaseMetaData extends AbstractDatabaseMetaData { ...@@ -33,11 +35,10 @@ public class RestfulDatabaseMetaData extends AbstractDatabaseMetaData {
return RestfulDriver.class.getName(); return RestfulDriver.class.getName();
} }
@Override @Override
public ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String[] types) throws SQLException { public ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String[] types) throws SQLException {
if (connection == null || connection.isClosed()) { if (connection == null || connection.isClosed()) {
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL)); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
} }
return super.getTables(catalog, schemaPattern, tableNamePattern, types, connection); return super.getTables(catalog, schemaPattern, tableNamePattern, types, connection);
} }
...@@ -45,14 +46,14 @@ public class RestfulDatabaseMetaData extends AbstractDatabaseMetaData { ...@@ -45,14 +46,14 @@ public class RestfulDatabaseMetaData extends AbstractDatabaseMetaData {
@Override @Override
public ResultSet getCatalogs() throws SQLException { public ResultSet getCatalogs() throws SQLException {
if (connection == null || connection.isClosed()) if (connection == null || connection.isClosed())
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL)); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
return super.getCatalogs(connection); return super.getCatalogs(connection);
} }
@Override @Override
public ResultSet getTableTypes() throws SQLException { public ResultSet getTableTypes() throws SQLException {
if (connection == null || connection.isClosed()) { if (connection == null || connection.isClosed()) {
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL)); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
} }
return super.getTableTypes(); return super.getTableTypes();
} }
...@@ -60,21 +61,26 @@ public class RestfulDatabaseMetaData extends AbstractDatabaseMetaData { ...@@ -60,21 +61,26 @@ public class RestfulDatabaseMetaData extends AbstractDatabaseMetaData {
@Override @Override
public ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) throws SQLException { public ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) throws SQLException {
if (connection == null || connection.isClosed()) if (connection == null || connection.isClosed())
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL)); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
return super.getColumns(catalog, schemaPattern, tableNamePattern, columnNamePattern, connection); return super.getColumns(catalog, schemaPattern, tableNamePattern, columnNamePattern, connection);
} }
@Override @Override
public ResultSet getPrimaryKeys(String catalog, String schema, String table) throws SQLException { public ResultSet getPrimaryKeys(String catalog, String schema, String table) throws SQLException {
if (connection == null || connection.isClosed()) if (connection == null || connection.isClosed())
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL)); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
return super.getPrimaryKeys(catalog, schema, table, connection); return super.getPrimaryKeys(catalog, schema, table, connection);
} }
@Override
public Connection getConnection() throws SQLException {
return this.connection;
}
@Override @Override
public ResultSet getSuperTables(String catalog, String schemaPattern, String tableNamePattern) throws SQLException { public ResultSet getSuperTables(String catalog, String schemaPattern, String tableNamePattern) throws SQLException {
if (connection == null || connection.isClosed()) if (connection == null || connection.isClosed())
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL)); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
return super.getSuperTables(catalog, schemaPattern, tableNamePattern, connection); return super.getSuperTables(catalog, schemaPattern, tableNamePattern, connection);
} }
......
...@@ -4,6 +4,8 @@ import com.alibaba.fastjson.JSON; ...@@ -4,6 +4,8 @@ import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.taosdata.jdbc.AbstractStatement; import com.taosdata.jdbc.AbstractStatement;
import com.taosdata.jdbc.TSDBConstants; import com.taosdata.jdbc.TSDBConstants;
import com.taosdata.jdbc.TSDBError;
import com.taosdata.jdbc.TSDBErrorNumbers;
import com.taosdata.jdbc.rs.util.HttpClientPoolUtil; import com.taosdata.jdbc.rs.util.HttpClientPoolUtil;
import com.taosdata.jdbc.utils.SqlSyntaxValidator; import com.taosdata.jdbc.utils.SqlSyntaxValidator;
...@@ -63,9 +65,9 @@ public class RestfulStatement extends AbstractStatement { ...@@ -63,9 +65,9 @@ public class RestfulStatement extends AbstractStatement {
@Override @Override
public ResultSet executeQuery(String sql) throws SQLException { public ResultSet executeQuery(String sql) throws SQLException {
if (isClosed()) if (isClosed())
throw new SQLException("statement already closed"); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
if (!SqlSyntaxValidator.isValidForExecuteQuery(sql)) if (!SqlSyntaxValidator.isValidForExecuteQuery(sql))
throw new SQLException("not a valid sql for executeQuery: " + sql); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_FOR_EXECUTE_QUERY, "not a valid sql for executeQuery: " + sql);
final String url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sql"; final String url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sql";
if (SqlSyntaxValidator.isDatabaseUnspecifiedQuery(sql)) { if (SqlSyntaxValidator.isDatabaseUnspecifiedQuery(sql)) {
...@@ -73,7 +75,7 @@ public class RestfulStatement extends AbstractStatement { ...@@ -73,7 +75,7 @@ public class RestfulStatement extends AbstractStatement {
} }
if (this.database == null || this.database.isEmpty()) if (this.database == null || this.database.isEmpty())
throw new SQLException("Database not specified or available"); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_DATABASE_NOT_SPECIFIED_OR_AVAILABLE);
HttpClientPoolUtil.execute(url, "use " + this.database); HttpClientPoolUtil.execute(url, "use " + this.database);
return executeOneQuery(url, sql); return executeOneQuery(url, sql);
} }
...@@ -81,9 +83,9 @@ public class RestfulStatement extends AbstractStatement { ...@@ -81,9 +83,9 @@ public class RestfulStatement extends AbstractStatement {
@Override @Override
public int executeUpdate(String sql) throws SQLException { public int executeUpdate(String sql) throws SQLException {
if (isClosed()) if (isClosed())
throw new SQLException("statement already closed"); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
if (!SqlSyntaxValidator.isValidForExecuteUpdate(sql)) if (!SqlSyntaxValidator.isValidForExecuteUpdate(sql))
throw new SQLException("not a valid sql for executeUpdate: " + sql); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_FOR_EXECUTE_UPDATE, "not a valid sql for executeUpdate: " + sql);
final String url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sql"; final String url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sql";
if (SqlSyntaxValidator.isDatabaseUnspecifiedUpdate(sql)) { if (SqlSyntaxValidator.isDatabaseUnspecifiedUpdate(sql)) {
...@@ -91,7 +93,8 @@ public class RestfulStatement extends AbstractStatement { ...@@ -91,7 +93,8 @@ public class RestfulStatement extends AbstractStatement {
} }
if (this.database == null || this.database.isEmpty()) if (this.database == null || this.database.isEmpty())
throw new SQLException("Database not specified or available"); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_DATABASE_NOT_SPECIFIED_OR_AVAILABLE);
HttpClientPoolUtil.execute(url, "use " + this.database); HttpClientPoolUtil.execute(url, "use " + this.database);
return executeOneUpdate(url, sql); return executeOneUpdate(url, sql);
} }
...@@ -107,9 +110,9 @@ public class RestfulStatement extends AbstractStatement { ...@@ -107,9 +110,9 @@ public class RestfulStatement extends AbstractStatement {
@Override @Override
public boolean execute(String sql) throws SQLException { public boolean execute(String sql) throws SQLException {
if (isClosed()) if (isClosed())
throw new SQLException("Invalid method call on a closed statement."); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
if (!SqlSyntaxValidator.isValidForExecute(sql)) if (!SqlSyntaxValidator.isValidForExecute(sql))
throw new SQLException("not a valid sql for execute: " + sql); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_FOR_EXECUTE, "not a valid sql for execute: " + sql);
//如果执行了use操作应该将当前Statement的catalog设置为新的database //如果执行了use操作应该将当前Statement的catalog设置为新的database
final String url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sql"; final String url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sql";
...@@ -134,7 +137,7 @@ public class RestfulStatement extends AbstractStatement { ...@@ -134,7 +137,7 @@ public class RestfulStatement extends AbstractStatement {
private ResultSet executeOneQuery(String url, String sql) throws SQLException { private ResultSet executeOneQuery(String url, String sql) throws SQLException {
if (!SqlSyntaxValidator.isValidForExecuteQuery(sql)) if (!SqlSyntaxValidator.isValidForExecuteQuery(sql))
throw new SQLException("not a select sql for executeQuery: " + sql); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_FOR_EXECUTE_QUERY, "not a valid sql for executeQuery: " + sql);
// row data // row data
String result = HttpClientPoolUtil.execute(url, sql); String result = HttpClientPoolUtil.execute(url, sql);
...@@ -165,7 +168,7 @@ public class RestfulStatement extends AbstractStatement { ...@@ -165,7 +168,7 @@ public class RestfulStatement extends AbstractStatement {
private int executeOneUpdate(String url, String sql) throws SQLException { private int executeOneUpdate(String url, String sql) throws SQLException {
if (!SqlSyntaxValidator.isValidForExecuteUpdate(sql)) if (!SqlSyntaxValidator.isValidForExecuteUpdate(sql))
throw new SQLException("not a valid sql for executeUpdate: " + sql); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_FOR_EXECUTE_UPDATE, "not a valid sql for executeUpdate: " + sql);
String result = HttpClientPoolUtil.execute(url, sql); String result = HttpClientPoolUtil.execute(url, sql);
JSONObject jsonObject = JSON.parseObject(result); JSONObject jsonObject = JSON.parseObject(result);
...@@ -186,16 +189,16 @@ public class RestfulStatement extends AbstractStatement { ...@@ -186,16 +189,16 @@ public class RestfulStatement extends AbstractStatement {
@Override @Override
public int getUpdateCount() throws SQLException { public int getUpdateCount() throws SQLException {
if (isClosed()) { if (isClosed())
throw new SQLException("Invalid method call on a closed statement."); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
}
return this.affectedRows; return this.affectedRows;
} }
@Override @Override
public void addBatch(String sql) throws SQLException { public void addBatch(String sql) throws SQLException {
if (isClosed()) if (isClosed())
throw new SQLException(TSDBConstants.STATEMENT_CLOSED); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
//TODO: //TODO:
} }
...@@ -213,7 +216,7 @@ public class RestfulStatement extends AbstractStatement { ...@@ -213,7 +216,7 @@ public class RestfulStatement extends AbstractStatement {
@Override @Override
public Connection getConnection() throws SQLException { public Connection getConnection() throws SQLException {
if (isClosed()) if (isClosed())
throw new SQLException(TSDBConstants.STATEMENT_CLOSED); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
return this.conn; return this.conn;
} }
......
package com.taosdata.jdbc;
import org.junit.Assert;
import org.junit.Test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
public class ConnectionTest {
private Connection connection;
private Statement statement;
private static String host = "127.0.0.1";
@Test
public void testConnection() {
Properties properties = new Properties();
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
try {
Class.forName("com.taosdata.jdbc.TSDBDriver");
connection = DriverManager.getConnection("jdbc:TAOS://" + host + ":0/", properties);
Assert.assertTrue(null != connection);
statement = connection.createStatement();
Assert.assertTrue(null != statement);
statement.close();
connection.close();
} catch (ClassNotFoundException e) {
return;
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package com.taosdata.jdbc;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import javax.management.OperationsException;
import java.sql.*;
import java.util.Properties;
public class TSDBConnectionTest {
private static final String host = "127.0.0.1";
private static Connection conn;
@Test
public void getConnection() {
// already test in beforeClass method
}
@Test
public void createStatement() {
try (Statement stmt = conn.createStatement()) {
ResultSet rs = stmt.executeQuery("select server_status()");
rs.next();
int status = rs.getInt("server_status()");
Assert.assertEquals(1, status);
} catch (SQLException e) {
e.printStackTrace();
}
}
@Test
public void subscribe() {
try {
TSDBConnection unwrap = conn.unwrap(TSDBConnection.class);
TSDBSubscribe subscribe = unwrap.subscribe("topic1", "select * from log.log", false);
TSDBResultSet rs = subscribe.consume();
ResultSetMetaData metaData = rs.getMetaData();
for (int count = 0; count < 10 && rs.next(); count++) {
for (int i = 1; i <= metaData.getColumnCount(); i++) {
String value = rs.getString(i);
System.out.print(metaData.getColumnLabel(i) + ":" + value + "\t");
}
System.out.println();
}
Assert.assertNotNull(rs);
subscribe.close(false);
} catch (SQLException e) {
e.printStackTrace();
}
}
@Test
public void prepareStatement() throws SQLException {
PreparedStatement pstmt = conn.prepareStatement("select server_status()");
ResultSet rs = pstmt.executeQuery();
rs.next();
int status = rs.getInt("server_status()");
Assert.assertEquals(1, status);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void prepareCall() throws SQLException {
conn.prepareCall("select server_status()");
}
@Test
public void nativeSQL() throws SQLException {
String nativeSQL = conn.nativeSQL("select * from log.log");
Assert.assertEquals("select * from log.log", nativeSQL);
}
@Test
public void setAutoCommit() throws SQLException {
conn.setAutoCommit(true);
conn.setAutoCommit(false);
}
@Test
public void getAutoCommit() throws SQLException {
Assert.assertTrue(conn.getAutoCommit());
}
@Test
public void commit() throws SQLException {
conn.commit();
}
@Test
public void rollback() throws SQLException {
conn.rollback();
}
@Test
public void close() {
// connection will close in afterClass method
}
@Test
public void isClosed() throws SQLException {
Assert.assertFalse(conn.isClosed());
}
@Test
public void getMetaData() throws SQLException {
DatabaseMetaData meta = conn.getMetaData();
Assert.assertNotNull(meta);
Assert.assertEquals("com.taosdata.jdbc.TSDBDriver", meta.getDriverName());
}
@Test
public void setReadOnly() throws SQLException {
conn.setReadOnly(true);
}
@Test
public void isReadOnly() throws SQLException {
Assert.assertTrue(conn.isReadOnly());
}
@Test
public void setCatalog() throws SQLException {
conn.setCatalog("test");
Assert.assertEquals("test", conn.getCatalog());
}
@Test
public void getCatalog() throws SQLException {
conn.setCatalog("log");
Assert.assertEquals("log", conn.getCatalog());
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void setTransactionIsolation() throws SQLException {
conn.setTransactionIsolation(Connection.TRANSACTION_NONE);
Assert.assertEquals(Connection.TRANSACTION_NONE, conn.getTransactionIsolation());
conn.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
}
@Test
public void getTransactionIsolation() throws SQLException {
Assert.assertEquals(Connection.TRANSACTION_NONE, conn.getTransactionIsolation());
}
@Test
public void getWarnings() throws SQLException {
Assert.assertNull(conn.getWarnings());
}
@Test
public void clearWarnings() throws SQLException {
conn.clearWarnings();
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void testCreateStatement() throws SQLException {
Statement stmt = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
ResultSet rs = stmt.executeQuery("select server_status()");
rs.next();
int status = rs.getInt("server_status()");
Assert.assertEquals(1, status);
conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void testPrepareStatement() throws SQLException {
PreparedStatement pstmt = conn.prepareStatement("select server_status()",
ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
ResultSet rs = pstmt.executeQuery();
rs.next();
int status = rs.getInt("server_status()");
Assert.assertEquals(1, status);
conn.prepareStatement("select server_status", ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void testPrepareCall() throws SQLException {
conn.prepareCall("", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void getTypeMap() throws SQLException {
conn.getTypeMap();
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void setTypeMap() throws SQLException {
conn.setTypeMap(null);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void setHoldability() throws SQLException {
conn.setHoldability(ResultSet.HOLD_CURSORS_OVER_COMMIT);
Assert.assertEquals(ResultSet.HOLD_CURSORS_OVER_COMMIT, conn.getHoldability());
conn.setHoldability(ResultSet.CLOSE_CURSORS_AT_COMMIT);
}
@Test
public void getHoldability() throws SQLException {
Assert.assertEquals(ResultSet.HOLD_CURSORS_OVER_COMMIT, conn.getHoldability());
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void setSavepoint() throws SQLException {
conn.setSavepoint();
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void testSetSavepoint() throws SQLException {
conn.setSavepoint(null);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void testRollback() throws SQLException {
conn.rollback(null);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void releaseSavepoint() throws SQLException {
conn.releaseSavepoint(null);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void testCreateStatement1() throws SQLException {
Statement stmt = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT);
ResultSet rs = stmt.executeQuery("select server_status()");
rs.next();
int status = rs.getInt("server_status()");
Assert.assertEquals(1, status);
conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void testPrepareStatement1() throws SQLException {
PreparedStatement pstmt = conn.prepareStatement("select server_status()",
ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT);
ResultSet rs = pstmt.executeQuery();
rs.next();
int status = rs.getInt("server_status()");
Assert.assertEquals(1, status);
conn.prepareStatement("select server_status", ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void testPrepareCall1() throws SQLException {
conn.prepareCall("", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void testPrepareStatement2() throws SQLException {
Assert.assertNotNull("", Statement.NO_GENERATED_KEYS);
conn.prepareStatement("", Statement.RETURN_GENERATED_KEYS);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void testPrepareStatement3() throws SQLException {
conn.prepareStatement("", new int[]{});
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void testPrepareStatement4() throws SQLException {
conn.prepareStatement("", new String[]{});
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void createClob() throws SQLException {
conn.createClob();
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void createBlob() throws SQLException {
conn.createBlob();
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void createNClob() throws SQLException {
conn.createNClob();
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void createSQLXML() throws SQLException {
conn.createSQLXML();
}
@Test(expected = SQLException.class)
public void isValid() throws SQLException {
Assert.assertTrue(conn.isValid(10));
Assert.assertTrue(conn.isValid(0));
conn.isValid(-1);
}
@Test
public void setClientInfo() throws SQLClientInfoException {
conn.setClientInfo(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
conn.setClientInfo(TSDBDriver.PROPERTY_KEY_CHARSET, "en_US.UTF-8");
conn.setClientInfo(TSDBDriver.PROPERTY_KEY_CHARSET, "UTC-8");
}
@Test
public void testSetClientInfo() throws SQLClientInfoException {
Properties properties = new Properties();
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
conn.setClientInfo(properties);
}
@Test
public void getClientInfo() throws SQLException {
conn.setClientInfo(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
conn.setClientInfo(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
conn.setClientInfo(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
Properties info = conn.getClientInfo();
String charset = info.getProperty(TSDBDriver.PROPERTY_KEY_CHARSET);
Assert.assertEquals("UTF-8", charset);
String locale = info.getProperty(TSDBDriver.PROPERTY_KEY_LOCALE);
Assert.assertEquals("en_US.UTF-8", locale);
String timezone = info.getProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE);
Assert.assertEquals("UTC-8", timezone);
}
@Test
public void testGetClientInfo() throws SQLException {
conn.setClientInfo(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
conn.setClientInfo(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
conn.setClientInfo(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
String charset = conn.getClientInfo(TSDBDriver.PROPERTY_KEY_CHARSET);
Assert.assertEquals("UTF-8", charset);
String locale = conn.getClientInfo(TSDBDriver.PROPERTY_KEY_LOCALE);
Assert.assertEquals("en_US.UTF-8", locale);
String timezone = conn.getClientInfo(TSDBDriver.PROPERTY_KEY_TIME_ZONE);
Assert.assertEquals("UTC-8", timezone);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void createArrayOf() throws SQLException {
conn.createArrayOf("", null);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void createStruct() throws SQLException {
conn.createStruct("", null);
}
@Test
public void setSchema() throws SQLException {
conn.setSchema("test");
}
@Test
public void getSchema() throws SQLException {
Assert.assertNull(conn.getSchema());
}
@Test
public void abort() throws SQLException {
conn.abort(null);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void setNetworkTimeout() throws SQLException {
conn.setNetworkTimeout(null, 1000);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void getNetworkTimeout() throws SQLException {
conn.getNetworkTimeout();
}
@Test
public void unwrap() {
try {
TSDBConnection tsdbConnection = conn.unwrap(TSDBConnection.class);
Assert.assertNotNull(tsdbConnection);
} catch (SQLException e) {
e.printStackTrace();
}
}
@Test
public void isWrapperFor() throws SQLException {
Assert.assertTrue(conn.isWrapperFor(TSDBConnection.class));
}
@BeforeClass
public static void beforeClass() {
try {
Class.forName("com.taosdata.jdbc.TSDBDriver");
Properties properties = new Properties();
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
conn = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/log?user=root&password=taosdata", properties);
// create test database for test cases
try (Statement stmt = conn.createStatement()) {
stmt.execute("create database if not exists test");
}
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
}
@AfterClass
public static void afterClass() {
try {
if (conn != null)
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
\ No newline at end of file
...@@ -24,11 +24,10 @@ public class TSDBDriverTest { ...@@ -24,11 +24,10 @@ public class TSDBDriverTest {
"jdbc:TAOS://:/test", "jdbc:TAOS://:/test",
"jdbc:TAOS://localhost:0/?user=root&password=taosdata" "jdbc:TAOS://localhost:0/?user=root&password=taosdata"
}; };
private Connection conn; private Connection conn;
@Test @Test
public void testConnectWithJdbcURL() { public void connectWithJdbcURL() {
final String url = "jdbc:TAOS://localhost:6030/log?user=root&password=taosdata"; final String url = "jdbc:TAOS://localhost:6030/log?user=root&password=taosdata";
try { try {
conn = DriverManager.getConnection(url); conn = DriverManager.getConnection(url);
...@@ -40,7 +39,7 @@ public class TSDBDriverTest { ...@@ -40,7 +39,7 @@ public class TSDBDriverTest {
} }
@Test @Test
public void testConnectWithProperties() { public void connectWithProperties() {
final String jdbcUrl = "jdbc:TAOS://localhost:6030/log?user=root&password=taosdata"; final String jdbcUrl = "jdbc:TAOS://localhost:6030/log?user=root&password=taosdata";
Properties connProps = new Properties(); Properties connProps = new Properties();
connProps.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8"); connProps.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
...@@ -56,7 +55,7 @@ public class TSDBDriverTest { ...@@ -56,7 +55,7 @@ public class TSDBDriverTest {
} }
@Test @Test
public void testConnectWithConfigFile() { public void connectWithConfigFile() {
String jdbcUrl = "jdbc:TAOS://:/log?user=root&password=taosdata"; String jdbcUrl = "jdbc:TAOS://:/log?user=root&password=taosdata";
Properties connProps = new Properties(); Properties connProps = new Properties();
connProps.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8"); connProps.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
...@@ -71,16 +70,6 @@ public class TSDBDriverTest { ...@@ -71,16 +70,6 @@ public class TSDBDriverTest {
} }
} }
@Test(expected = SQLException.class)
public void testAcceptsURL() throws SQLException {
Driver driver = new TSDBDriver();
for (String url : validURLs) {
assertTrue("failure - acceptsURL(\" " + url + " \") should be true", driver.acceptsURL(url));
}
driver.acceptsURL(null);
fail("acceptsURL throws exception when parameter is null");
}
@Test @Test
public void testParseURL() { public void testParseURL() {
TSDBDriver driver = new TSDBDriver(); TSDBDriver driver = new TSDBDriver();
...@@ -121,8 +110,19 @@ public class TSDBDriverTest { ...@@ -121,8 +110,19 @@ public class TSDBDriverTest {
assertNull("failure - dbname should be null", actual.getProperty("dbname")); assertNull("failure - dbname should be null", actual.getProperty("dbname"));
} }
@Test(expected = SQLException.class)
public void acceptsURL() throws SQLException {
Driver driver = new TSDBDriver();
for (String url : validURLs) {
assertTrue("failure - acceptsURL(\" " + url + " \") should be true", driver.acceptsURL(url));
}
driver.acceptsURL(null);
fail("acceptsURL throws exception when parameter is null");
}
@Test @Test
public void testGetPropertyInfo() throws SQLException { public void getPropertyInfo() throws SQLException {
Driver driver = new TSDBDriver(); Driver driver = new TSDBDriver();
final String url = "jdbc:TAOS://localhost:6030/log?user=root&password=taosdata"; final String url = "jdbc:TAOS://localhost:6030/log?user=root&password=taosdata";
Properties connProps = new Properties(); Properties connProps = new Properties();
...@@ -142,23 +142,23 @@ public class TSDBDriverTest { ...@@ -142,23 +142,23 @@ public class TSDBDriverTest {
} }
@Test @Test
public void testGetMajorVersion() { public void getMajorVersion() {
assertEquals("failure - getMajorVersion should be 2", 2, new TSDBDriver().getMajorVersion()); assertEquals(2, new TSDBDriver().getMajorVersion());
} }
@Test @Test
public void testGetMinorVersion() { public void getMinorVersion() {
assertEquals("failure - getMinorVersion should be 0", 0, new TSDBDriver().getMinorVersion()); assertEquals(0, new TSDBDriver().getMinorVersion());
} }
@Test @Test
public void testJdbcCompliant() { public void jdbcCompliant() {
assertFalse("failure - jdbcCompliant should be false", new TSDBDriver().jdbcCompliant()); assertFalse(new TSDBDriver().jdbcCompliant());
} }
@Test @Test
public void testGetParentLogger() throws SQLFeatureNotSupportedException { public void getParentLogger() throws SQLFeatureNotSupportedException {
assertNull("failure - getParentLogger should be be null", new TSDBDriver().getParentLogger()); assertNull(new TSDBDriver().getParentLogger());
} }
@BeforeClass @BeforeClass
...@@ -169,6 +169,4 @@ public class TSDBDriverTest { ...@@ -169,6 +169,4 @@ public class TSDBDriverTest {
e.printStackTrace(); e.printStackTrace();
} }
} }
} }
\ No newline at end of file
package com.taosdata.jdbc; package com.taosdata.jdbc.cases;
import com.taosdata.jdbc.TSDBDriver;
import org.junit.*; import org.junit.*;
import org.junit.runners.MethodSorters; import org.junit.runners.MethodSorters;
......
package com.taosdata.jdbc; package com.taosdata.jdbc.cases;
import com.taosdata.jdbc.TSDBDriver;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
......
package com.taosdata.jdbc; package com.taosdata.jdbc.cases;
import com.taosdata.jdbc.TSDBDriver;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
......
package com.taosdata.jdbc; package com.taosdata.jdbc.cases;
import com.taosdata.jdbc.TSDBDriver;
import org.junit.AfterClass; import org.junit.AfterClass;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.FixMethodOrder; import org.junit.FixMethodOrder;
......
package com.taosdata.jdbc.rs;
import com.taosdata.jdbc.TSDBConnection;
import com.taosdata.jdbc.TSDBDriver;
import com.taosdata.jdbc.TSDBResultSet;
import com.taosdata.jdbc.TSDBSubscribe;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import javax.management.OperationsException;
import java.sql.*;
import java.util.Properties;
public class RestfulConnectionTest {
// private static final String host = "127.0.0.1";
private static final String host = "master";
private static Connection conn;
@Test
public void getConnection() {
// already test in beforeClass method
}
@Test
public void createStatement() {
try (Statement stmt = conn.createStatement()) {
ResultSet rs = stmt.executeQuery("select server_status()");
rs.next();
int status = rs.getInt("server_status()");
Assert.assertEquals(1, status);
} catch (SQLException e) {
e.printStackTrace();
}
}
@Test
public void prepareStatement() throws SQLException {
PreparedStatement pstmt = conn.prepareStatement("select server_status()");
ResultSet rs = pstmt.executeQuery();
rs.next();
int status = rs.getInt("server_status()");
Assert.assertEquals(1, status);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void prepareCall() throws SQLException {
conn.prepareCall("select server_status()");
}
@Test
public void nativeSQL() throws SQLException {
String nativeSQL = conn.nativeSQL("select * from log.log");
Assert.assertEquals("select * from log.log", nativeSQL);
}
@Test
public void setAutoCommit() throws SQLException {
conn.setAutoCommit(true);
conn.setAutoCommit(false);
}
@Test
public void getAutoCommit() throws SQLException {
Assert.assertTrue(conn.getAutoCommit());
}
@Test
public void commit() throws SQLException {
conn.commit();
}
@Test
public void rollback() throws SQLException {
conn.rollback();
}
@Test
public void close() {
// connection will close in afterClass method
}
@Test
public void isClosed() throws SQLException {
Assert.assertFalse(conn.isClosed());
}
@Test
public void getMetaData() throws SQLException {
DatabaseMetaData meta = conn.getMetaData();
Assert.assertNotNull(meta);
Assert.assertEquals("com.taosdata.jdbc.rs.RestfulDriver", meta.getDriverName());
}
@Test
public void setReadOnly() throws SQLException {
conn.setReadOnly(true);
}
@Test
public void isReadOnly() throws SQLException {
Assert.assertTrue(conn.isReadOnly());
}
@Test
public void setCatalog() throws SQLException {
conn.setCatalog("test");
Assert.assertEquals("test", conn.getCatalog());
}
@Test
public void getCatalog() throws SQLException {
conn.setCatalog("log");
Assert.assertEquals("log", conn.getCatalog());
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void setTransactionIsolation() throws SQLException {
conn.setTransactionIsolation(Connection.TRANSACTION_NONE);
Assert.assertEquals(Connection.TRANSACTION_NONE, conn.getTransactionIsolation());
conn.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
}
@Test
public void getTransactionIsolation() throws SQLException {
Assert.assertEquals(Connection.TRANSACTION_NONE, conn.getTransactionIsolation());
}
@Test
public void getWarnings() throws SQLException {
Assert.assertNull(conn.getWarnings());
}
@Test
public void clearWarnings() throws SQLException {
conn.clearWarnings();
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void testCreateStatement() throws SQLException {
Statement stmt = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
ResultSet rs = stmt.executeQuery("select server_status()");
rs.next();
int status = rs.getInt("server_status()");
Assert.assertEquals(1, status);
conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void testPrepareStatement() throws SQLException {
PreparedStatement pstmt = conn.prepareStatement("select server_status()",
ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
ResultSet rs = pstmt.executeQuery();
rs.next();
int status = rs.getInt("server_status()");
Assert.assertEquals(1, status);
conn.prepareStatement("select server_status", ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void testPrepareCall() throws SQLException {
conn.prepareCall("", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void getTypeMap() throws SQLException {
conn.getTypeMap();
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void setTypeMap() throws SQLException {
conn.setTypeMap(null);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void setHoldability() throws SQLException {
conn.setHoldability(ResultSet.HOLD_CURSORS_OVER_COMMIT);
Assert.assertEquals(ResultSet.HOLD_CURSORS_OVER_COMMIT, conn.getHoldability());
conn.setHoldability(ResultSet.CLOSE_CURSORS_AT_COMMIT);
}
@Test
public void getHoldability() throws SQLException {
Assert.assertEquals(ResultSet.HOLD_CURSORS_OVER_COMMIT, conn.getHoldability());
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void setSavepoint() throws SQLException {
conn.setSavepoint();
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void testSetSavepoint() throws SQLException {
conn.setSavepoint(null);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void testRollback() throws SQLException {
conn.rollback(null);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void releaseSavepoint() throws SQLException {
conn.releaseSavepoint(null);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void testCreateStatement1() throws SQLException {
Statement stmt = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT);
ResultSet rs = stmt.executeQuery("select server_status()");
rs.next();
int status = rs.getInt("server_status()");
Assert.assertEquals(1, status);
conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void testPrepareStatement1() throws SQLException {
PreparedStatement pstmt = conn.prepareStatement("select server_status()",
ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT);
ResultSet rs = pstmt.executeQuery();
rs.next();
int status = rs.getInt("server_status()");
Assert.assertEquals(1, status);
conn.prepareStatement("select server_status", ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void testPrepareCall1() throws SQLException {
conn.prepareCall("", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void testPrepareStatement2() throws SQLException {
Assert.assertNotNull("", Statement.NO_GENERATED_KEYS);
conn.prepareStatement("", Statement.RETURN_GENERATED_KEYS);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void testPrepareStatement3() throws SQLException {
conn.prepareStatement("", new int[]{});
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void testPrepareStatement4() throws SQLException {
conn.prepareStatement("", new String[]{});
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void createClob() throws SQLException {
conn.createClob();
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void createBlob() throws SQLException {
conn.createBlob();
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void createNClob() throws SQLException {
conn.createNClob();
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void createSQLXML() throws SQLException {
conn.createSQLXML();
}
@Test(expected = SQLException.class)
public void isValid() throws SQLException {
Assert.assertTrue(conn.isValid(10));
Assert.assertTrue(conn.isValid(0));
conn.isValid(-1);
}
@Test
public void setClientInfo() throws SQLClientInfoException {
conn.setClientInfo(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
conn.setClientInfo(TSDBDriver.PROPERTY_KEY_CHARSET, "en_US.UTF-8");
conn.setClientInfo(TSDBDriver.PROPERTY_KEY_CHARSET, "UTC-8");
}
@Test
public void testSetClientInfo() throws SQLClientInfoException {
Properties properties = new Properties();
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
conn.setClientInfo(properties);
}
@Test
public void getClientInfo() throws SQLException {
conn.setClientInfo(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
conn.setClientInfo(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
conn.setClientInfo(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
Properties info = conn.getClientInfo();
String charset = info.getProperty(TSDBDriver.PROPERTY_KEY_CHARSET);
Assert.assertEquals("UTF-8", charset);
String locale = info.getProperty(TSDBDriver.PROPERTY_KEY_LOCALE);
Assert.assertEquals("en_US.UTF-8", locale);
String timezone = info.getProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE);
Assert.assertEquals("UTC-8", timezone);
}
@Test
public void testGetClientInfo() throws SQLException {
conn.setClientInfo(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
conn.setClientInfo(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
conn.setClientInfo(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
String charset = conn.getClientInfo(TSDBDriver.PROPERTY_KEY_CHARSET);
Assert.assertEquals("UTF-8", charset);
String locale = conn.getClientInfo(TSDBDriver.PROPERTY_KEY_LOCALE);
Assert.assertEquals("en_US.UTF-8", locale);
String timezone = conn.getClientInfo(TSDBDriver.PROPERTY_KEY_TIME_ZONE);
Assert.assertEquals("UTC-8", timezone);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void createArrayOf() throws SQLException {
conn.createArrayOf("", null);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void createStruct() throws SQLException {
conn.createStruct("", null);
}
@Test
public void setSchema() throws SQLException {
conn.setSchema("test");
}
@Test
public void getSchema() throws SQLException {
Assert.assertNull(conn.getSchema());
}
@Test
public void abort() throws SQLException {
conn.abort(null);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void setNetworkTimeout() throws SQLException {
conn.setNetworkTimeout(null, 1000);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void getNetworkTimeout() throws SQLException {
conn.getNetworkTimeout();
}
@Test
public void unwrap() {
try {
RestfulConnection restfulConnection = conn.unwrap(RestfulConnection.class);
Assert.assertNotNull(restfulConnection);
} catch (SQLException e) {
e.printStackTrace();
}
}
@Test
public void isWrapperFor() throws SQLException {
Assert.assertTrue(conn.isWrapperFor(RestfulConnection.class));
}
@BeforeClass
public static void beforeClass() {
try {
Class.forName("com.taosdata.jdbc.rs.RestfulDriver");
Properties properties = new Properties();
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
conn = DriverManager.getConnection("jdbc:TAOS-RS://" + host + ":6041/log?user=root&password=taosdata", properties);
// create test database for test cases
try (Statement stmt = conn.createStatement()) {
stmt.execute("create database if not exists test");
}
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
}
@AfterClass
public static void afterClass() {
try {
if (conn != null)
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
\ No newline at end of file
...@@ -67,13 +67,13 @@ def _crow_tinyint_unsigned_to_python( ...@@ -67,13 +67,13 @@ def _crow_tinyint_unsigned_to_python(
return [ return [
None if ele == FieldType.C_TINYINT_UNSIGNED_NULL else ele for ele in ctypes.cast( None if ele == FieldType.C_TINYINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER( data, ctypes.POINTER(
ctypes.c_byte))[ ctypes.c_ubyte))[
:abs(num_of_rows)]] :abs(num_of_rows)]]
else: else:
return [ return [
None if ele == FieldType.C_TINYINT_UNSIGNED_NULL else ele for ele in ctypes.cast( None if ele == FieldType.C_TINYINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER( data, ctypes.POINTER(
ctypes.c_byte))[ ctypes.c_ubyte))[
:abs(num_of_rows)]] :abs(num_of_rows)]]
...@@ -102,13 +102,13 @@ def _crow_smallint_unsigned_to_python( ...@@ -102,13 +102,13 @@ def _crow_smallint_unsigned_to_python(
return [ return [
None if ele == FieldType.C_SMALLINT_UNSIGNED_NULL else ele for ele in ctypes.cast( None if ele == FieldType.C_SMALLINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER( data, ctypes.POINTER(
ctypes.c_short))[ ctypes.c_ushort))[
:abs(num_of_rows)]] :abs(num_of_rows)]]
else: else:
return [ return [
None if ele == FieldType.C_SMALLINT_UNSIGNED_NULL else ele for ele in ctypes.cast( None if ele == FieldType.C_SMALLINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER( data, ctypes.POINTER(
ctypes.c_short))[ ctypes.c_ushort))[
:abs(num_of_rows)]] :abs(num_of_rows)]]
...@@ -130,13 +130,13 @@ def _crow_int_unsigned_to_python(data, num_of_rows, nbytes=None, micro=False): ...@@ -130,13 +130,13 @@ def _crow_int_unsigned_to_python(data, num_of_rows, nbytes=None, micro=False):
return [ return [
None if ele == FieldType.C_INT_UNSIGNED_NULL else ele for ele in ctypes.cast( None if ele == FieldType.C_INT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER( data, ctypes.POINTER(
ctypes.c_int))[ ctypes.c_uint))[
:abs(num_of_rows)]] :abs(num_of_rows)]]
else: else:
return [ return [
None if ele == FieldType.C_INT_UNSIGNED_NULL else ele for ele in ctypes.cast( None if ele == FieldType.C_INT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER( data, ctypes.POINTER(
ctypes.c_int))[ ctypes.c_uint))[
:abs(num_of_rows)]] :abs(num_of_rows)]]
...@@ -162,13 +162,13 @@ def _crow_bigint_unsigned_to_python( ...@@ -162,13 +162,13 @@ def _crow_bigint_unsigned_to_python(
return [ return [
None if ele == FieldType.C_BIGINT_UNSIGNED_NULL else ele for ele in ctypes.cast( None if ele == FieldType.C_BIGINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER( data, ctypes.POINTER(
ctypes.c_long))[ ctypes.c_ulong))[
:abs(num_of_rows)]] :abs(num_of_rows)]]
else: else:
return [ return [
None if ele == FieldType.C_BIGINT_UNSIGNED_NULL else ele for ele in ctypes.cast( None if ele == FieldType.C_BIGINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER( data, ctypes.POINTER(
ctypes.c_long))[ ctypes.c_ulong))[
:abs(num_of_rows)]] :abs(num_of_rows)]]
......
...@@ -19,10 +19,10 @@ class FieldType(object): ...@@ -19,10 +19,10 @@ class FieldType(object):
C_BINARY = 8 C_BINARY = 8
C_TIMESTAMP = 9 C_TIMESTAMP = 9
C_NCHAR = 10 C_NCHAR = 10
C_TINYINT_UNSIGNED = 12 C_TINYINT_UNSIGNED = 11
C_SMALLINT_UNSIGNED = 13 C_SMALLINT_UNSIGNED = 12
C_INT_UNSIGNED = 14 C_INT_UNSIGNED = 13
C_BIGINT_UNSIGNED = 15 C_BIGINT_UNSIGNED = 14
# NULL value definition # NULL value definition
# NOTE: These values should change according to C definition in tsdb.h # NOTE: These values should change according to C definition in tsdb.h
C_BOOL_NULL = 0x02 C_BOOL_NULL = 0x02
......
...@@ -67,13 +67,13 @@ def _crow_tinyint_unsigned_to_python( ...@@ -67,13 +67,13 @@ def _crow_tinyint_unsigned_to_python(
return [ return [
None if ele == FieldType.C_TINYINT_UNSIGNED_NULL else ele for ele in ctypes.cast( None if ele == FieldType.C_TINYINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER( data, ctypes.POINTER(
ctypes.c_byte))[ ctypes.c_ubyte))[
:abs(num_of_rows)]] :abs(num_of_rows)]]
else: else:
return [ return [
None if ele == FieldType.C_TINYINT_UNSIGNED_NULL else ele for ele in ctypes.cast( None if ele == FieldType.C_TINYINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER( data, ctypes.POINTER(
ctypes.c_byte))[ ctypes.c_ubyte))[
:abs(num_of_rows)]] :abs(num_of_rows)]]
...@@ -102,13 +102,13 @@ def _crow_smallint_unsigned_to_python( ...@@ -102,13 +102,13 @@ def _crow_smallint_unsigned_to_python(
return [ return [
None if ele == FieldType.C_SMALLINT_UNSIGNED_NULL else ele for ele in ctypes.cast( None if ele == FieldType.C_SMALLINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER( data, ctypes.POINTER(
ctypes.c_short))[ ctypes.c_ushort))[
:abs(num_of_rows)]] :abs(num_of_rows)]]
else: else:
return [ return [
None if ele == FieldType.C_SMALLINT_UNSIGNED_NULL else ele for ele in ctypes.cast( None if ele == FieldType.C_SMALLINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER( data, ctypes.POINTER(
ctypes.c_short))[ ctypes.c_ushort))[
:abs(num_of_rows)]] :abs(num_of_rows)]]
...@@ -130,13 +130,13 @@ def _crow_int_unsigned_to_python(data, num_of_rows, nbytes=None, micro=False): ...@@ -130,13 +130,13 @@ def _crow_int_unsigned_to_python(data, num_of_rows, nbytes=None, micro=False):
return [ return [
None if ele == FieldType.C_INT_UNSIGNED_NULL else ele for ele in ctypes.cast( None if ele == FieldType.C_INT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER( data, ctypes.POINTER(
ctypes.c_int))[ ctypes.c_uint))[
:abs(num_of_rows)]] :abs(num_of_rows)]]
else: else:
return [ return [
None if ele == FieldType.C_INT_UNSIGNED_NULL else ele for ele in ctypes.cast( None if ele == FieldType.C_INT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER( data, ctypes.POINTER(
ctypes.c_int))[ ctypes.c_uint))[
:abs(num_of_rows)]] :abs(num_of_rows)]]
...@@ -162,13 +162,13 @@ def _crow_bigint_unsigned_to_python( ...@@ -162,13 +162,13 @@ def _crow_bigint_unsigned_to_python(
return [ return [
None if ele == FieldType.C_BIGINT_UNSIGNED_NULL else ele for ele in ctypes.cast( None if ele == FieldType.C_BIGINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER( data, ctypes.POINTER(
ctypes.c_long))[ ctypes.c_ulong))[
:abs(num_of_rows)]] :abs(num_of_rows)]]
else: else:
return [ return [
None if ele == FieldType.C_BIGINT_UNSIGNED_NULL else ele for ele in ctypes.cast( None if ele == FieldType.C_BIGINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER( data, ctypes.POINTER(
ctypes.c_long))[ ctypes.c_ulong))[
:abs(num_of_rows)]] :abs(num_of_rows)]]
......
...@@ -19,10 +19,10 @@ class FieldType(object): ...@@ -19,10 +19,10 @@ class FieldType(object):
C_BINARY = 8 C_BINARY = 8
C_TIMESTAMP = 9 C_TIMESTAMP = 9
C_NCHAR = 10 C_NCHAR = 10
C_TINYINT_UNSIGNED = 12 C_TINYINT_UNSIGNED = 11
C_SMALLINT_UNSIGNED = 13 C_SMALLINT_UNSIGNED = 12
C_INT_UNSIGNED = 14 C_INT_UNSIGNED = 13
C_BIGINT_UNSIGNED = 15 C_BIGINT_UNSIGNED = 14
# NULL value definition # NULL value definition
# NOTE: These values should change according to C definition in tsdb.h # NOTE: These values should change according to C definition in tsdb.h
C_BOOL_NULL = 0x02 C_BOOL_NULL = 0x02
......
...@@ -67,13 +67,13 @@ def _crow_tinyint_unsigned_to_python( ...@@ -67,13 +67,13 @@ def _crow_tinyint_unsigned_to_python(
return [ return [
None if ele == FieldType.C_TINYINT_UNSIGNED_NULL else ele for ele in ctypes.cast( None if ele == FieldType.C_TINYINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER( data, ctypes.POINTER(
ctypes.c_byte))[ ctypes.c_ubyte))[
:abs(num_of_rows)]] :abs(num_of_rows)]]
else: else:
return [ return [
None if ele == FieldType.C_TINYINT_UNSIGNED_NULL else ele for ele in ctypes.cast( None if ele == FieldType.C_TINYINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER( data, ctypes.POINTER(
ctypes.c_byte))[ ctypes.c_ubyte))[
:abs(num_of_rows)]] :abs(num_of_rows)]]
...@@ -102,13 +102,13 @@ def _crow_smallint_unsigned_to_python( ...@@ -102,13 +102,13 @@ def _crow_smallint_unsigned_to_python(
return [ return [
None if ele == FieldType.C_SMALLINT_UNSIGNED_NULL else ele for ele in ctypes.cast( None if ele == FieldType.C_SMALLINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER( data, ctypes.POINTER(
ctypes.c_short))[ ctypes.c_ushort))[
:abs(num_of_rows)]] :abs(num_of_rows)]]
else: else:
return [ return [
None if ele == FieldType.C_SMALLINT_UNSIGNED_NULL else ele for ele in ctypes.cast( None if ele == FieldType.C_SMALLINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER( data, ctypes.POINTER(
ctypes.c_short))[ ctypes.c_ushort))[
:abs(num_of_rows)]] :abs(num_of_rows)]]
...@@ -130,13 +130,13 @@ def _crow_int_unsigned_to_python(data, num_of_rows, nbytes=None, micro=False): ...@@ -130,13 +130,13 @@ def _crow_int_unsigned_to_python(data, num_of_rows, nbytes=None, micro=False):
return [ return [
None if ele == FieldType.C_INT_UNSIGNED_NULL else ele for ele in ctypes.cast( None if ele == FieldType.C_INT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER( data, ctypes.POINTER(
ctypes.c_int))[ ctypes.c_uint))[
:abs(num_of_rows)]] :abs(num_of_rows)]]
else: else:
return [ return [
None if ele == FieldType.C_INT_UNSIGNED_NULL else ele for ele in ctypes.cast( None if ele == FieldType.C_INT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER( data, ctypes.POINTER(
ctypes.c_int))[ ctypes.c_uint))[
:abs(num_of_rows)]] :abs(num_of_rows)]]
...@@ -162,13 +162,13 @@ def _crow_bigint_unsigned_to_python( ...@@ -162,13 +162,13 @@ def _crow_bigint_unsigned_to_python(
return [ return [
None if ele == FieldType.C_BIGINT_UNSIGNED_NULL else ele for ele in ctypes.cast( None if ele == FieldType.C_BIGINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER( data, ctypes.POINTER(
ctypes.c_long))[ ctypes.c_ulong))[
:abs(num_of_rows)]] :abs(num_of_rows)]]
else: else:
return [ return [
None if ele == FieldType.C_BIGINT_UNSIGNED_NULL else ele for ele in ctypes.cast( None if ele == FieldType.C_BIGINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER( data, ctypes.POINTER(
ctypes.c_long))[ ctypes.c_ulong))[
:abs(num_of_rows)]] :abs(num_of_rows)]]
......
...@@ -19,10 +19,10 @@ class FieldType(object): ...@@ -19,10 +19,10 @@ class FieldType(object):
C_BINARY = 8 C_BINARY = 8
C_TIMESTAMP = 9 C_TIMESTAMP = 9
C_NCHAR = 10 C_NCHAR = 10
C_TINYINT_UNSIGNED = 12 C_TINYINT_UNSIGNED = 11
C_SMALLINT_UNSIGNED = 13 C_SMALLINT_UNSIGNED = 12
C_INT_UNSIGNED = 14 C_INT_UNSIGNED = 13
C_BIGINT_UNSIGNED = 15 C_BIGINT_UNSIGNED = 14
# NULL value definition # NULL value definition
# NOTE: These values should change according to C definition in tsdb.h # NOTE: These values should change according to C definition in tsdb.h
C_BOOL_NULL = 0x02 C_BOOL_NULL = 0x02
......
...@@ -8,6 +8,7 @@ paramstyle = 'pyformat' ...@@ -8,6 +8,7 @@ paramstyle = 'pyformat'
__all__ = ['connection', 'cursor'] __all__ = ['connection', 'cursor']
def connect(*args, **kwargs): def connect(*args, **kwargs):
""" Function to return a TDengine connector object """ Function to return a TDengine connector object
......
...@@ -2,9 +2,11 @@ from .cursor import TDengineCursor ...@@ -2,9 +2,11 @@ from .cursor import TDengineCursor
from .subscription import TDengineSubscription from .subscription import TDengineSubscription
from .cinterface import CTaosInterface from .cinterface import CTaosInterface
class TDengineConnection(object): class TDengineConnection(object):
""" TDengine connection object """ TDengine connection object
""" """
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self._conn = None self._conn = None
self._host = None self._host = None
...@@ -44,7 +46,12 @@ class TDengineConnection(object): ...@@ -44,7 +46,12 @@ class TDengineConnection(object):
self._config = kwargs['config'] self._config = kwargs['config']
self._chandle = CTaosInterface(self._config) self._chandle = CTaosInterface(self._config)
self._conn = self._chandle.connect(self._host, self._user, self._password, self._database, self._port) self._conn = self._chandle.connect(
self._host,
self._user,
self._password,
self._database,
self._port)
def close(self): def close(self):
"""Close current connection. """Close current connection.
...@@ -56,7 +63,8 @@ class TDengineConnection(object): ...@@ -56,7 +63,8 @@ class TDengineConnection(object):
""" """
if self._conn is None: if self._conn is None:
return None return None
sub = CTaosInterface.subscribe(self._conn, restart, topic, sql, interval) sub = CTaosInterface.subscribe(
self._conn, restart, topic, sql, interval)
return TDengineSubscription(sub) return TDengineSubscription(sub)
def cursor(self): def cursor(self):
...@@ -81,6 +89,7 @@ class TDengineConnection(object): ...@@ -81,6 +89,7 @@ class TDengineConnection(object):
""" """
pass pass
if __name__ == "__main__": if __name__ == "__main__":
conn = TDengineConnection(host='192.168.1.107') conn = TDengineConnection(host='192.168.1.107')
conn.close() conn.close()
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
from .dbapi import * from .dbapi import *
class FieldType(object): class FieldType(object):
"""TDengine Field Types """TDengine Field Types
""" """
...@@ -18,13 +19,21 @@ class FieldType(object): ...@@ -18,13 +19,21 @@ class FieldType(object):
C_BINARY = 8 C_BINARY = 8
C_TIMESTAMP = 9 C_TIMESTAMP = 9
C_NCHAR = 10 C_NCHAR = 10
C_TINYINT_UNSIGNED = 11
C_SMALLINT_UNSIGNED = 12
C_INT_UNSIGNED = 13
C_BIGINT_UNSIGNED = 14
# NULL value definition # NULL value definition
# NOTE: These values should change according to C definition in tsdb.h # NOTE: These values should change according to C definition in tsdb.h
C_BOOL_NULL = 0x02 C_BOOL_NULL = 0x02
C_TINYINT_NULL = -128 C_TINYINT_NULL = -128
C_TINYINT_UNSIGNED_NULL = 255
C_SMALLINT_NULL = -32768 C_SMALLINT_NULL = -32768
C_SMALLINT_UNSIGNED_NULL = 65535
C_INT_NULL = -2147483648 C_INT_NULL = -2147483648
C_INT_UNSIGNED_NULL = 4294967295
C_BIGINT_NULL = -9223372036854775808 C_BIGINT_NULL = -9223372036854775808
C_BIGINT_UNSIGNED_NULL = 18446744073709551615
C_FLOAT_NULL = float('nan') C_FLOAT_NULL = float('nan')
C_DOUBLE_NULL = float('nan') C_DOUBLE_NULL = float('nan')
C_BINARY_NULL = bytearray([int('0xff', 16)]) C_BINARY_NULL = bytearray([int('0xff', 16)])
......
...@@ -5,6 +5,7 @@ import threading ...@@ -5,6 +5,7 @@ import threading
# querySeqNum = 0 # querySeqNum = 0
class TDengineCursor(object): class TDengineCursor(object):
"""Database cursor which is used to manage the context of a fetch operation. """Database cursor which is used to manage the context of a fetch operation.
...@@ -50,7 +51,8 @@ class TDengineCursor(object): ...@@ -50,7 +51,8 @@ class TDengineCursor(object):
raise OperationalError("Invalid use of fetch iterator") raise OperationalError("Invalid use of fetch iterator")
if self._block_rows <= self._block_iter: if self._block_rows <= self._block_iter:
block, self._block_rows = CTaosInterface.fetchRow(self._result, self._fields) block, self._block_rows = CTaosInterface.fetchRow(
self._result, self._fields)
if self._block_rows == 0: if self._block_rows == 0:
raise StopIteration raise StopIteration
self._block = list(map(tuple, zip(*block))) self._block = list(map(tuple, zip(*block)))
...@@ -117,8 +119,9 @@ class TDengineCursor(object): ...@@ -117,8 +119,9 @@ class TDengineCursor(object):
errno = CTaosInterface.libtaos.taos_errno(self._result) errno = CTaosInterface.libtaos.taos_errno(self._result)
if errno == 0: if errno == 0:
if CTaosInterface.fieldsCount(self._result) == 0: if CTaosInterface.fieldsCount(self._result) == 0:
self._affected_rows += CTaosInterface.affectedRows(self._result) self._affected_rows += CTaosInterface.affectedRows(
return CTaosInterface.affectedRows(self._result ) self._result)
return CTaosInterface.affectedRows(self._result)
else: else:
self._fields = CTaosInterface.useResult(self._result) self._fields = CTaosInterface.useResult(self._result)
return self._handle_result() return self._handle_result()
...@@ -147,10 +150,13 @@ class TDengineCursor(object): ...@@ -147,10 +150,13 @@ class TDengineCursor(object):
buffer = [[] for i in range(len(self._fields))] buffer = [[] for i in range(len(self._fields))]
self._rowcount = 0 self._rowcount = 0
while True: while True:
block, num_of_fields = CTaosInterface.fetchRow(self._result, self._fields) block, num_of_fields = CTaosInterface.fetchRow(
self._result, self._fields)
errno = CTaosInterface.libtaos.taos_errno(self._result) errno = CTaosInterface.libtaos.taos_errno(self._result)
if errno != 0: if errno != 0:
raise ProgrammingError(CTaosInterface.errStr(self._result), errno) raise ProgrammingError(
CTaosInterface.errStr(
self._result), errno)
if num_of_fields == 0: if num_of_fields == 0:
break break
self._rowcount += num_of_fields self._rowcount += num_of_fields
...@@ -165,20 +171,21 @@ class TDengineCursor(object): ...@@ -165,20 +171,21 @@ class TDengineCursor(object):
buffer = [[] for i in range(len(self._fields))] buffer = [[] for i in range(len(self._fields))]
self._rowcount = 0 self._rowcount = 0
while True: while True:
block, num_of_fields = CTaosInterface.fetchBlock(self._result, self._fields) block, num_of_fields = CTaosInterface.fetchBlock(
self._result, self._fields)
errno = CTaosInterface.libtaos.taos_errno(self._result) errno = CTaosInterface.libtaos.taos_errno(self._result)
if errno != 0: if errno != 0:
raise ProgrammingError(CTaosInterface.errStr(self._result), errno) raise ProgrammingError(
if num_of_fields == 0: break CTaosInterface.errStr(
self._result), errno)
if num_of_fields == 0:
break
self._rowcount += num_of_fields self._rowcount += num_of_fields
for i in range(len(self._fields)): for i in range(len(self._fields)):
buffer[i].extend(block[i]) buffer[i].extend(block[i])
return list(map(tuple, zip(*buffer))) return list(map(tuple, zip(*buffer)))
def nextset(self): def nextset(self):
""" """
""" """
...@@ -209,6 +216,7 @@ class TDengineCursor(object): ...@@ -209,6 +216,7 @@ class TDengineCursor(object):
""" """
self._description = [] self._description = []
for ele in self._fields: for ele in self._fields:
self._description.append((ele['name'], ele['type'], None, None, None, None, False)) self._description.append(
(ele['name'], ele['type'], None, None, None, None, False))
return self._result return self._result
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
import time import time
import datetime import datetime
class DBAPITypeObject(object): class DBAPITypeObject(object):
def __init__(self, *values): def __init__(self, *values):
self.values = values self.values = values
...@@ -16,19 +17,24 @@ class DBAPITypeObject(object): ...@@ -16,19 +17,24 @@ class DBAPITypeObject(object):
else: else:
return -1 return -1
Date = datetime.date Date = datetime.date
Time = datetime.time Time = datetime.time
Timestamp = datetime.datetime Timestamp = datetime.datetime
def DataFromTicks(ticks): def DataFromTicks(ticks):
return Date(*time.localtime(ticks)[:3]) return Date(*time.localtime(ticks)[:3])
def TimeFromTicks(ticks): def TimeFromTicks(ticks):
return Time(*time.localtime(ticks)[3:6]) return Time(*time.localtime(ticks)[3:6])
def TimestampFromTicks(ticks): def TimestampFromTicks(ticks):
return Timestamp(*time.localtime(ticks)[:6]) return Timestamp(*time.localtime(ticks)[:6])
Binary = bytes Binary = bytes
# STRING = DBAPITypeObject(*constants.FieldType.get_string_types()) # STRING = DBAPITypeObject(*constants.FieldType.get_string_types())
......
"""Python exceptions """Python exceptions
""" """
class Error(Exception): class Error(Exception):
def __init__(self, msg=None, errno=None): def __init__(self, msg=None, errno=None):
self.msg = msg self.msg = msg
...@@ -10,26 +11,31 @@ class Error(Exception): ...@@ -10,26 +11,31 @@ class Error(Exception):
def __str__(self): def __str__(self):
return self._full_msg return self._full_msg
class Warning(Exception): class Warning(Exception):
"""Exception raised for important warnings like data truncations while inserting. """Exception raised for important warnings like data truncations while inserting.
""" """
pass pass
class InterfaceError(Error): class InterfaceError(Error):
"""Exception raised for errors that are related to the database interface rather than the database itself. """Exception raised for errors that are related to the database interface rather than the database itself.
""" """
pass pass
class DatabaseError(Error): class DatabaseError(Error):
"""Exception raised for errors that are related to the database. """Exception raised for errors that are related to the database.
""" """
pass pass
class DataError(DatabaseError): class DataError(DatabaseError):
"""Exception raised for errors that are due to problems with the processed data like division by zero, numeric value out of range. """Exception raised for errors that are due to problems with the processed data like division by zero, numeric value out of range.
""" """
pass pass
class OperationalError(DatabaseError): class OperationalError(DatabaseError):
"""Exception raised for errors that are related to the database's operation and not necessarily under the control of the programmer """Exception raised for errors that are related to the database's operation and not necessarily under the control of the programmer
""" """
...@@ -41,16 +47,19 @@ class IntegrityError(DatabaseError): ...@@ -41,16 +47,19 @@ class IntegrityError(DatabaseError):
""" """
pass pass
class InternalError(DatabaseError): class InternalError(DatabaseError):
"""Exception raised when the database encounters an internal error. """Exception raised when the database encounters an internal error.
""" """
pass pass
class ProgrammingError(DatabaseError): class ProgrammingError(DatabaseError):
"""Exception raised for programming errors. """Exception raised for programming errors.
""" """
pass pass
class NotSupportedError(DatabaseError): class NotSupportedError(DatabaseError):
"""Exception raised in case a method or database API was used which is not supported by the database,. """Exception raised in case a method or database API was used which is not supported by the database,.
""" """
......
from .cinterface import CTaosInterface from .cinterface import CTaosInterface
from .error import * from .error import *
class TDengineSubscription(object): class TDengineSubscription(object):
"""TDengine subscription object """TDengine subscription object
""" """
def __init__(self, sub): def __init__(self, sub):
self._sub = sub self._sub = sub
def consume(self): def consume(self):
"""Consume rows of a subscription """Consume rows of a subscription
""" """
...@@ -18,15 +19,15 @@ class TDengineSubscription(object): ...@@ -18,15 +19,15 @@ class TDengineSubscription(object):
buffer = [[] for i in range(len(fields))] buffer = [[] for i in range(len(fields))]
while True: while True:
block, num_of_fields = CTaosInterface.fetchBlock(result, fields) block, num_of_fields = CTaosInterface.fetchBlock(result, fields)
if num_of_fields == 0: break if num_of_fields == 0:
break
for i in range(len(fields)): for i in range(len(fields)):
buffer[i].extend(block[i]) buffer[i].extend(block[i])
self.fields = fields self.fields = fields
return list(map(tuple, zip(*buffer))) return list(map(tuple, zip(*buffer)))
def close(self, keepProgress=True):
def close(self, keepProgress = True):
"""Close the Subscription. """Close the Subscription.
""" """
if self._sub is None: if self._sub is None:
...@@ -38,12 +39,16 @@ class TDengineSubscription(object): ...@@ -38,12 +39,16 @@ class TDengineSubscription(object):
if __name__ == '__main__': if __name__ == '__main__':
from .connection import TDengineConnection from .connection import TDengineConnection
conn = TDengineConnection(host="127.0.0.1", user="root", password="taosdata", database="test") conn = TDengineConnection(
host="127.0.0.1",
user="root",
password="taosdata",
database="test")
# Generate a cursor object to run SQL commands # Generate a cursor object to run SQL commands
sub = conn.subscribe(True, "test", "select * from meters;", 1000) sub = conn.subscribe(True, "test", "select * from meters;", 1000)
for i in range(0,10): for i in range(0, 10):
data = sub.consume() data = sub.consume()
for d in data: for d in data:
print(d) print(d)
......
...@@ -8,6 +8,7 @@ paramstyle = 'pyformat' ...@@ -8,6 +8,7 @@ paramstyle = 'pyformat'
__all__ = ['connection', 'cursor'] __all__ = ['connection', 'cursor']
def connect(*args, **kwargs): def connect(*args, **kwargs):
""" Function to return a TDengine connector object """ Function to return a TDengine connector object
......
...@@ -2,9 +2,11 @@ from .cursor import TDengineCursor ...@@ -2,9 +2,11 @@ from .cursor import TDengineCursor
from .subscription import TDengineSubscription from .subscription import TDengineSubscription
from .cinterface import CTaosInterface from .cinterface import CTaosInterface
class TDengineConnection(object): class TDengineConnection(object):
""" TDengine connection object """ TDengine connection object
""" """
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self._conn = None self._conn = None
self._host = None self._host = None
...@@ -44,7 +46,12 @@ class TDengineConnection(object): ...@@ -44,7 +46,12 @@ class TDengineConnection(object):
self._config = kwargs['config'] self._config = kwargs['config']
self._chandle = CTaosInterface(self._config) self._chandle = CTaosInterface(self._config)
self._conn = self._chandle.connect(self._host, self._user, self._password, self._database, self._port) self._conn = self._chandle.connect(
self._host,
self._user,
self._password,
self._database,
self._port)
def close(self): def close(self):
"""Close current connection. """Close current connection.
...@@ -56,7 +63,8 @@ class TDengineConnection(object): ...@@ -56,7 +63,8 @@ class TDengineConnection(object):
""" """
if self._conn is None: if self._conn is None:
return None return None
sub = CTaosInterface.subscribe(self._conn, restart, topic, sql, interval) sub = CTaosInterface.subscribe(
self._conn, restart, topic, sql, interval)
return TDengineSubscription(sub) return TDengineSubscription(sub)
def cursor(self): def cursor(self):
...@@ -81,6 +89,7 @@ class TDengineConnection(object): ...@@ -81,6 +89,7 @@ class TDengineConnection(object):
""" """
pass pass
if __name__ == "__main__": if __name__ == "__main__":
conn = TDengineConnection(host='192.168.1.107') conn = TDengineConnection(host='192.168.1.107')
conn.close() conn.close()
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
from .dbapi import * from .dbapi import *
class FieldType(object): class FieldType(object):
"""TDengine Field Types """TDengine Field Types
""" """
...@@ -18,13 +19,21 @@ class FieldType(object): ...@@ -18,13 +19,21 @@ class FieldType(object):
C_BINARY = 8 C_BINARY = 8
C_TIMESTAMP = 9 C_TIMESTAMP = 9
C_NCHAR = 10 C_NCHAR = 10
C_TINYINT_UNSIGNED = 11
C_SMALLINT_UNSIGNED = 12
C_INT_UNSIGNED = 13
C_BIGINT_UNSIGNED = 14
# NULL value definition # NULL value definition
# NOTE: These values should change according to C definition in tsdb.h # NOTE: These values should change according to C definition in tsdb.h
C_BOOL_NULL = 0x02 C_BOOL_NULL = 0x02
C_TINYINT_NULL = -128 C_TINYINT_NULL = -128
C_TINYINT_UNSIGNED_NULL = 255
C_SMALLINT_NULL = -32768 C_SMALLINT_NULL = -32768
C_SMALLINT_UNSIGNED_NULL = 65535
C_INT_NULL = -2147483648 C_INT_NULL = -2147483648
C_INT_UNSIGNED_NULL = 4294967295
C_BIGINT_NULL = -9223372036854775808 C_BIGINT_NULL = -9223372036854775808
C_BIGINT_UNSIGNED_NULL = 18446744073709551615
C_FLOAT_NULL = float('nan') C_FLOAT_NULL = float('nan')
C_DOUBLE_NULL = float('nan') C_DOUBLE_NULL = float('nan')
C_BINARY_NULL = bytearray([int('0xff', 16)]) C_BINARY_NULL = bytearray([int('0xff', 16)])
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
import time import time
import datetime import datetime
class DBAPITypeObject(object): class DBAPITypeObject(object):
def __init__(self, *values): def __init__(self, *values):
self.values = values self.values = values
...@@ -16,19 +17,24 @@ class DBAPITypeObject(object): ...@@ -16,19 +17,24 @@ class DBAPITypeObject(object):
else: else:
return -1 return -1
Date = datetime.date Date = datetime.date
Time = datetime.time Time = datetime.time
Timestamp = datetime.datetime Timestamp = datetime.datetime
def DataFromTicks(ticks): def DataFromTicks(ticks):
return Date(*time.localtime(ticks)[:3]) return Date(*time.localtime(ticks)[:3])
def TimeFromTicks(ticks): def TimeFromTicks(ticks):
return Time(*time.localtime(ticks)[3:6]) return Time(*time.localtime(ticks)[3:6])
def TimestampFromTicks(ticks): def TimestampFromTicks(ticks):
return Timestamp(*time.localtime(ticks)[:6]) return Timestamp(*time.localtime(ticks)[:6])
Binary = bytes Binary = bytes
# STRING = DBAPITypeObject(*constants.FieldType.get_string_types()) # STRING = DBAPITypeObject(*constants.FieldType.get_string_types())
......
...@@ -155,6 +155,7 @@ void httpReleaseContext(HttpContext *pContext, bool clearRes) { ...@@ -155,6 +155,7 @@ void httpReleaseContext(HttpContext *pContext, bool clearRes) {
if (clearRes) { if (clearRes) {
httpClearParser(pContext->parser); httpClearParser(pContext->parser);
memset(&pContext->singleCmd, 0, sizeof(HttpSqlCmd));
} }
HttpContext **ppContext = pContext->ppContext; HttpContext **ppContext = pContext->ppContext;
...@@ -185,9 +186,9 @@ void httpCloseContextByApp(HttpContext *pContext) { ...@@ -185,9 +186,9 @@ void httpCloseContextByApp(HttpContext *pContext) {
pContext->parsed = false; pContext->parsed = false;
bool keepAlive = true; bool keepAlive = true;
if (parser->httpVersion == HTTP_VERSION_10 && parser->keepAlive != HTTP_KEEPALIVE_ENABLE) { if (parser && parser->httpVersion == HTTP_VERSION_10 && parser->keepAlive != HTTP_KEEPALIVE_ENABLE) {
keepAlive = false; keepAlive = false;
} else if (parser->httpVersion != HTTP_VERSION_10 && parser->keepAlive == HTTP_KEEPALIVE_DISABLE) { } else if (parser && parser->httpVersion != HTTP_VERSION_10 && parser->keepAlive == HTTP_KEEPALIVE_DISABLE) {
keepAlive = false; keepAlive = false;
} else { } else {
} }
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册