提交 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
## <a class="anchor" id="create-table"></a>创建表
TDengine对每个数据采集点需要独立建表。与标准的关系型数据一样,一张表有表名,Schema,但除此之外,还可以带有一到多个标签。创建时,需要使用超级表做模板,同时指定标签的具体值。以表一中的智能电表为例,可以使用如下的SQL命令建表:
```cmd
```mysql
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) 章节。
......@@ -54,10 +54,12 @@ TDengine建议将数据采集点的全局唯一ID作为表名(比如设备序列
**自动建表**:在某些特殊场景中,用户在写数据时并不确定某个数据采集点的表是否存在,此时可在写入数据时使用自动建表语法来创建不存在的表,若该表已存在则不会建立新表。比如:
```cmd
```mysql
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 单列模型
......
......@@ -152,6 +152,14 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic
```
以指定的超级表为模板,指定 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
......@@ -306,7 +314,7 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic
- **插入一条记录,数据对应到指定的列**
```mysql
INSERT INTO tb_name (field1_name, ...) VALUES (field1_value, ...)
INSERT INTO tb_name (field1_name, ...) VALUES (field1_value1, ...);
```
向表tb_name中插入一条记录,数据对应到指定的列。SQL语句中没有出现的列,数据库将自动填充为NULL。主键(时间戳)不能为NULL。
......@@ -340,6 +348,18 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic
1) 如果时间戳为0,系统将自动使用服务器当前时间作为该记录的时间戳;
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完全一样。
说明:针对 insert 类型的 SQL 语句,我们采用的流式解析策略,在发现后面的错误之前,前面正确的部分SQL仍会执行。下面的sql中,insert语句是无效的,但是d1001仍会被创建。
......@@ -383,7 +403,7 @@ SELECT select_expr [, select_expr ...]
[ORDER BY col_list { DESC | ASC }]
[SLIMIT limit_val [, SOFFSET offset_val]]
[LIMIT limit_val [, OFFSET offset_val]]
[>> export_file]
[>> export_file];
```
#### SELECT子句
......
......@@ -128,6 +128,7 @@
</includes>
<excludes>
<exclude>**/AppMemoryLeakTest.java</exclude>
<exclude>**/AuthenticationTest.java</exclude>
<exclude>**/TaosInfoMonitorTest.java</exclude>
<exclude>**/FailOverTest.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.*;
import java.util.ArrayList;
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_VESION = "2.0.x.x";
......@@ -981,9 +981,7 @@ public abstract class AbstractDatabaseMetaData implements DatabaseMetaData, Wrap
return getEmptyResultSet();
}
public Connection getConnection() throws SQLException {
return null;
}
public abstract Connection getConnection() throws SQLException;
public boolean supportsSavepoints() throws SQLException {
return false;
......@@ -1067,6 +1065,7 @@ public abstract class AbstractDatabaseMetaData implements DatabaseMetaData, Wrap
}
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();
}
......@@ -1093,20 +1092,6 @@ public abstract class AbstractDatabaseMetaData implements DatabaseMetaData, Wrap
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 {
try (Statement stmt = conn.createStatement()) {
DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet();
......
......@@ -14,41 +14,25 @@
*****************************************************************************/
package com.taosdata.jdbc;
import java.sql.Array;
import java.sql.Blob;
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;
import java.sql.*;
import java.util.Properties;
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;
private TSDBDatabaseMetaData dbMetaData;
private Properties clientInfoProps = new Properties();
private int timeoutMilliseconds = 0;
public Boolean getBatchFetch() {
return this.batchFetch;
}
private boolean batchFetch = false;
public void setBatchFetch(Boolean batchFetch) {
this.batchFetch = batchFetch;
}
public TSDBConnection(Properties info, TSDBDatabaseMetaData meta) throws SQLException {
this.dbMetaData = meta;
this.databaseMetaData = meta;
connect(info.getProperty(TSDBDriver.PROPERTY_KEY_HOST),
Integer.parseInt(info.getProperty(TSDBDriver.PROPERTY_KEY_PORT, "0")),
info.getProperty(TSDBDriver.PROPERTY_KEY_DBNAME),
......@@ -64,8 +48,8 @@ public class TSDBConnection implements Connection {
private void connect(String host, int port, String dbName, String user, String password) throws SQLException {
this.connector = new TSDBJNIConnector();
this.connector.connect(host, port, dbName, user, password);
this.setCatalog(dbName);
this.dbMetaData.setConnection(this);
this.catalog = dbName;
this.databaseMetaData.setConnection(this);
}
public TSDBJNIConnector getConnection() {
......@@ -102,52 +86,11 @@ public class TSDBConnection implements Connection {
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 {
if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
this.isClosed = true;
this.connector.closeConnection();
}
......@@ -155,105 +98,11 @@ public class TSDBConnection implements Connection {
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 {
if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
return this.dbMetaData;
}
/**
* 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
return this.databaseMetaData;
}
public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
......@@ -263,253 +112,4 @@ public class TSDBConnection implements Connection {
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 {
*/
public ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String[] types) throws SQLException {
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);
}
public ResultSet getCatalogs() throws SQLException {
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);
}
public ResultSet getTableTypes() throws SQLException {
if (conn == null || conn.isClosed())
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL));
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
return super.getTableTypes();
}
public ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) throws SQLException {
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);
}
public ResultSet getPrimaryKeys(String catalog, String schema, String table) throws SQLException {
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);
}
public ResultSet getSuperTables(String catalog, String schemaPattern, String tableNamePattern) throws SQLException {
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);
}
......
......@@ -90,7 +90,7 @@ public class TSDBDriver extends AbstractDriver {
* fetch data from native function in a batch model
*/
public static final String PROPERTY_KEY_BATCH_LOAD = "batchfetch";
private TSDBDatabaseMetaData dbMetaData = null;
static {
......@@ -179,18 +179,18 @@ public class TSDBDriver extends AbstractDriver {
while (queryParams.hasMoreElements()) {
String oneToken = queryParams.nextToken();
String[] pair = oneToken.split("=");
if ((pair[0] != null && pair[0].trim().length() > 0) && (pair[1] != null && pair[1].trim().length() > 0)) {
urlProps.setProperty(pair[0].trim(), pair[1].trim());
}
}
}
// parse Product Name
String dbProductName = url.substring(0, beginningOfSlashes);
dbProductName = dbProductName.substring(dbProductName.indexOf(":") + 1);
dbProductName = dbProductName.substring(0, dbProductName.indexOf(":"));
// parse database name
url = url.substring(beginningOfSlashes + 2);
int indexOfSlash = url.indexOf("/");
......@@ -200,7 +200,7 @@ public class TSDBDriver extends AbstractDriver {
}
url = url.substring(0, indexOfSlash);
}
// parse port
int indexOfColon = url.indexOf(":");
if (indexOfColon != -1) {
......@@ -209,11 +209,11 @@ public class TSDBDriver extends AbstractDriver {
}
url = url.substring(0, indexOfColon);
}
if (url != null && url.length() > 0 && url.trim().length() > 0) {
urlProps.setProperty(TSDBDriver.PROPERTY_KEY_HOST, url);
}
this.dbMetaData = new TSDBDatabaseMetaData(urlForMeta, urlProps.getProperty(TSDBDriver.PROPERTY_KEY_USER));
return urlProps;
}
......
package com.taosdata.jdbc;
import java.sql.SQLClientInfoException;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.HashMap;
......@@ -17,6 +18,10 @@ public class TSDBError {
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_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");
......@@ -58,4 +63,8 @@ public class TSDBError {
// JNI exception's error number is large than 0x2350
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 {
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_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
......@@ -37,6 +41,11 @@ public class TSDBErrorNumbers {
errorNumbers.add(ERROR_RESULTSET_CLOSED);
errorNumbers.add(ERROR_INVALID_WITH_EXECUTEQUERY);
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_UNSUPPORTED_ENCODING);
......
......@@ -16,9 +16,6 @@ package com.taosdata.jdbc;
import javax.management.OperationsException;
import java.sql.SQLException;
import java.util.Map;
import java.util.TimerTask;
import java.util.concurrent.*;
public class TSDBSubscribe {
private TSDBJNIConnector connecter = null;
......@@ -36,9 +33,8 @@ public class TSDBSubscribe {
/**
* consume
*
* @throws OperationsException, SQLException
*/
public TSDBResultSet consume() throws OperationsException, SQLException {
public TSDBResultSet consume() throws SQLException {
if (this.connecter.isClosed()) {
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL));
}
......
package com.taosdata.jdbc.rs;
import com.taosdata.jdbc.TSDBConstants;
import com.taosdata.jdbc.TSDBDriver;
import com.taosdata.jdbc.*;
import java.sql.*;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
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 int port;
private final Properties props;
private volatile String database;
private final String url;
private volatile String database;
/******************************************************/
private boolean isClosed;
private DatabaseMetaData metadata;
private Map<String, Class<?>> typeMap;
private Properties clientInfoProps = new Properties();
private final DatabaseMetaData metadata;
public RestfulConnection(String host, String port, Properties props, String database, String url) {
this.host = host;
this.port = Integer.parseInt(port);
this.props = props;
this.database = database;
this.url = url;
this.metadata = new RestfulDatabaseMetaData(url, props.getProperty(TSDBDriver.PROPERTY_KEY_USER), this);
......@@ -37,7 +26,7 @@ public class RestfulConnection implements Connection {
@Override
public Statement createStatement() throws SQLException {
if (isClosed())
throw new SQLException(CONNECTION_IS_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);;
return new RestfulStatement(this, database);
}
......@@ -45,61 +34,11 @@ public class RestfulConnection implements Connection {
@Override
public PreparedStatement prepareStatement(String sql) throws SQLException {
if (isClosed())
throw new SQLException(CONNECTION_IS_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);;
//TODO: prepareStatement
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
public void close() throws SQLException {
if (isClosed)
......@@ -116,356 +55,11 @@ public class RestfulConnection implements Connection {
@Override
public DatabaseMetaData getMetaData() throws SQLException {
if (isClosed())
throw new SQLException(CONNECTION_IS_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);;
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() {
return host;
}
......@@ -474,10 +68,6 @@ public class RestfulConnection implements Connection {
return port;
}
public Properties getProps() {
return props;
}
public String getDatabase() {
return database;
}
......@@ -485,4 +75,4 @@ public class RestfulConnection implements Connection {
public String getUrl() {
return url;
}
}
}
\ No newline at end of file
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.util.ArrayList;
import java.util.List;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
public class RestfulDatabaseMetaData extends AbstractDatabaseMetaData {
......@@ -33,11 +35,10 @@ public class RestfulDatabaseMetaData extends AbstractDatabaseMetaData {
return RestfulDriver.class.getName();
}
@Override
public ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String[] types) throws SQLException {
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);
}
......@@ -45,14 +46,14 @@ public class RestfulDatabaseMetaData extends AbstractDatabaseMetaData {
@Override
public ResultSet getCatalogs() throws SQLException {
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);
}
@Override
public ResultSet getTableTypes() throws SQLException {
if (connection == null || connection.isClosed()) {
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL));
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
return super.getTableTypes();
}
......@@ -60,21 +61,26 @@ public class RestfulDatabaseMetaData extends AbstractDatabaseMetaData {
@Override
public ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) throws SQLException {
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);
}
@Override
public ResultSet getPrimaryKeys(String catalog, String schema, String table) throws SQLException {
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);
}
@Override
public Connection getConnection() throws SQLException {
return this.connection;
}
@Override
public ResultSet getSuperTables(String catalog, String schemaPattern, String tableNamePattern) throws SQLException {
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);
}
......
......@@ -4,6 +4,8 @@ import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.taosdata.jdbc.AbstractStatement;
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.utils.SqlSyntaxValidator;
......@@ -63,9 +65,9 @@ public class RestfulStatement extends AbstractStatement {
@Override
public ResultSet executeQuery(String sql) throws SQLException {
if (isClosed())
throw new SQLException("statement already closed");
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
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";
if (SqlSyntaxValidator.isDatabaseUnspecifiedQuery(sql)) {
......@@ -73,7 +75,7 @@ public class RestfulStatement extends AbstractStatement {
}
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);
return executeOneQuery(url, sql);
}
......@@ -81,9 +83,9 @@ public class RestfulStatement extends AbstractStatement {
@Override
public int executeUpdate(String sql) throws SQLException {
if (isClosed())
throw new SQLException("statement already closed");
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
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";
if (SqlSyntaxValidator.isDatabaseUnspecifiedUpdate(sql)) {
......@@ -91,7 +93,8 @@ public class RestfulStatement extends AbstractStatement {
}
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);
return executeOneUpdate(url, sql);
}
......@@ -107,9 +110,9 @@ public class RestfulStatement extends AbstractStatement {
@Override
public boolean execute(String sql) throws SQLException {
if (isClosed())
throw new SQLException("Invalid method call on a closed statement.");
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
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
final String url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sql";
......@@ -134,7 +137,7 @@ public class RestfulStatement extends AbstractStatement {
private ResultSet executeOneQuery(String url, String sql) throws SQLException {
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
String result = HttpClientPoolUtil.execute(url, sql);
......@@ -165,7 +168,7 @@ public class RestfulStatement extends AbstractStatement {
private int executeOneUpdate(String url, String sql) throws SQLException {
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);
JSONObject jsonObject = JSON.parseObject(result);
......@@ -186,16 +189,16 @@ public class RestfulStatement extends AbstractStatement {
@Override
public int getUpdateCount() throws SQLException {
if (isClosed()) {
throw new SQLException("Invalid method call on a closed statement.");
}
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
return this.affectedRows;
}
@Override
public void addBatch(String sql) throws SQLException {
if (isClosed())
throw new SQLException(TSDBConstants.STATEMENT_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
//TODO:
}
......@@ -213,7 +216,7 @@ public class RestfulStatement extends AbstractStatement {
@Override
public Connection getConnection() throws SQLException {
if (isClosed())
throw new SQLException(TSDBConstants.STATEMENT_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
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 {
"jdbc:TAOS://:/test",
"jdbc:TAOS://localhost:0/?user=root&password=taosdata"
};
private Connection conn;
@Test
public void testConnectWithJdbcURL() {
public void connectWithJdbcURL() {
final String url = "jdbc:TAOS://localhost:6030/log?user=root&password=taosdata";
try {
conn = DriverManager.getConnection(url);
......@@ -40,7 +39,7 @@ public class TSDBDriverTest {
}
@Test
public void testConnectWithProperties() {
public void connectWithProperties() {
final String jdbcUrl = "jdbc:TAOS://localhost:6030/log?user=root&password=taosdata";
Properties connProps = new Properties();
connProps.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
......@@ -56,7 +55,7 @@ public class TSDBDriverTest {
}
@Test
public void testConnectWithConfigFile() {
public void connectWithConfigFile() {
String jdbcUrl = "jdbc:TAOS://:/log?user=root&password=taosdata";
Properties connProps = new Properties();
connProps.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
......@@ -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
public void testParseURL() {
TSDBDriver driver = new TSDBDriver();
......@@ -121,8 +110,19 @@ public class TSDBDriverTest {
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
public void testGetPropertyInfo() throws SQLException {
public void getPropertyInfo() throws SQLException {
Driver driver = new TSDBDriver();
final String url = "jdbc:TAOS://localhost:6030/log?user=root&password=taosdata";
Properties connProps = new Properties();
......@@ -142,23 +142,23 @@ public class TSDBDriverTest {
}
@Test
public void testGetMajorVersion() {
assertEquals("failure - getMajorVersion should be 2", 2, new TSDBDriver().getMajorVersion());
public void getMajorVersion() {
assertEquals(2, new TSDBDriver().getMajorVersion());
}
@Test
public void testGetMinorVersion() {
assertEquals("failure - getMinorVersion should be 0", 0, new TSDBDriver().getMinorVersion());
public void getMinorVersion() {
assertEquals(0, new TSDBDriver().getMinorVersion());
}
@Test
public void testJdbcCompliant() {
assertFalse("failure - jdbcCompliant should be false", new TSDBDriver().jdbcCompliant());
public void jdbcCompliant() {
assertFalse(new TSDBDriver().jdbcCompliant());
}
@Test
public void testGetParentLogger() throws SQLFeatureNotSupportedException {
assertNull("failure - getParentLogger should be be null", new TSDBDriver().getParentLogger());
public void getParentLogger() throws SQLFeatureNotSupportedException {
assertNull(new TSDBDriver().getParentLogger());
}
@BeforeClass
......@@ -169,6 +169,4 @@ public class TSDBDriverTest {
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.runners.MethodSorters;
......
package com.taosdata.jdbc;
package com.taosdata.jdbc.cases;
import com.taosdata.jdbc.TSDBDriver;
import org.junit.After;
import org.junit.Before;
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.Before;
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.BeforeClass;
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
package com.taosdata.jdbc.rs;
import com.taosdata.jdbc.TSDBDriver;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import java.sql.*;
import java.util.Properties;
public class RestfulDatabaseMetaDataTest {
// private static final String host = "master";
private static final String host = "127.0.0.1";
private static final String url = "jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata";
private static Connection connection;
private static RestfulDatabaseMetaData metaData;
@Test
public void unwrap() throws SQLException {
RestfulDatabaseMetaData unwrap = metaData.unwrap(RestfulDatabaseMetaData.class);
Assert.assertNotNull(unwrap);
}
@Test
public void isWrapperFor() throws SQLException {
Assert.assertTrue(metaData.isWrapperFor(RestfulDatabaseMetaData.class));
}
@Test
public void allProceduresAreCallable() throws SQLException {
Assert.assertFalse(metaData.allProceduresAreCallable());
}
@Test
public void allTablesAreSelectable() throws SQLException {
Assert.assertFalse(metaData.allTablesAreSelectable());
}
@Test
public void getURL() throws SQLException {
Assert.assertEquals(url, metaData.getURL());
}
@Test
public void getUserName() throws SQLException {
Assert.assertEquals("root", metaData.getUserName());
}
@Test
public void isReadOnly() throws SQLException {
Assert.assertFalse(metaData.isReadOnly());
}
@Test
public void nullsAreSortedHigh() throws SQLException {
Assert.assertFalse(metaData.nullsAreSortedHigh());
}
@Test
public void nullsAreSortedLow() throws SQLException {
Assert.assertTrue(metaData.nullsAreSortedLow());
}
@Test
public void nullsAreSortedAtStart() throws SQLException {
Assert.assertTrue(metaData.nullsAreSortedAtStart());
}
@Test
public void nullsAreSortedAtEnd() throws SQLException {
Assert.assertFalse(metaData.nullsAreSortedAtEnd());
}
@Test
public void getDatabaseProductName() throws SQLException {
Assert.assertEquals("TDengine", metaData.getDatabaseProductName());
}
@Test
public void getDatabaseProductVersion() throws SQLException {
Assert.assertEquals("2.0.x.x", metaData.getDatabaseProductVersion());
}
@Test
public void getDriverName() throws SQLException {
Assert.assertEquals("com.taosdata.jdbc.rs.RestfulDriver", metaData.getDriverName());
}
@Test
public void getDriverVersion() throws SQLException {
Assert.assertEquals("2.0.x", metaData.getDriverVersion());
}
@Test
public void getDriverMajorVersion() {
Assert.assertEquals(2, metaData.getDriverMajorVersion());
}
@Test
public void getDriverMinorVersion() {
Assert.assertEquals(0, metaData.getDriverMinorVersion());
}
@Test
public void usesLocalFiles() throws SQLException {
Assert.assertFalse(metaData.usesLocalFiles());
}
@Test
public void usesLocalFilePerTable() throws SQLException {
Assert.assertFalse(metaData.usesLocalFilePerTable());
}
@Test
public void supportsMixedCaseIdentifiers() throws SQLException {
Assert.assertFalse(metaData.supportsMixedCaseIdentifiers());
}
@Test
public void storesUpperCaseIdentifiers() throws SQLException {
Assert.assertFalse(metaData.storesUpperCaseIdentifiers());
}
@Test
public void storesLowerCaseIdentifiers() throws SQLException {
Assert.assertTrue(metaData.storesLowerCaseIdentifiers());
}
@Test
public void storesMixedCaseIdentifiers() throws SQLException {
Assert.assertFalse(metaData.storesMixedCaseIdentifiers());
}
@Test
public void supportsMixedCaseQuotedIdentifiers() throws SQLException {
Assert.assertFalse(metaData.supportsMixedCaseQuotedIdentifiers());
}
@Test
public void storesUpperCaseQuotedIdentifiers() throws SQLException {
Assert.assertFalse(metaData.storesUpperCaseQuotedIdentifiers());
}
@Test
public void storesLowerCaseQuotedIdentifiers() throws SQLException {
Assert.assertFalse(metaData.storesLowerCaseQuotedIdentifiers());
}
@Test
public void storesMixedCaseQuotedIdentifiers() throws SQLException {
Assert.assertFalse(metaData.storesMixedCaseQuotedIdentifiers());
}
@Test
public void getIdentifierQuoteString() throws SQLException {
Assert.assertEquals(" ", metaData.getIdentifierQuoteString());
}
@Test
public void getSQLKeywords() throws SQLException {
Assert.assertEquals(null, metaData.getSQLKeywords());
}
@Test
public void getNumericFunctions() throws SQLException {
Assert.assertEquals(null, metaData.getNumericFunctions());
}
@Test
public void getStringFunctions() throws SQLException {
Assert.assertEquals(null, metaData.getStringFunctions());
}
@Test
public void getSystemFunctions() throws SQLException {
Assert.assertEquals(null, metaData.getSystemFunctions());
}
@Test
public void getTimeDateFunctions() throws SQLException {
Assert.assertEquals(null, metaData.getTimeDateFunctions());
}
@Test
public void getSearchStringEscape() throws SQLException {
Assert.assertEquals(null, metaData.getSearchStringEscape());
}
@Test
public void getExtraNameCharacters() throws SQLException {
Assert.assertEquals(null, metaData.getExtraNameCharacters());
}
@Test
public void supportsAlterTableWithAddColumn() throws SQLException {
Assert.assertTrue(metaData.supportsAlterTableWithAddColumn());
}
@Test
public void supportsAlterTableWithDropColumn() throws SQLException {
Assert.assertTrue(metaData.supportsAlterTableWithDropColumn());
}
@Test
public void supportsColumnAliasing() throws SQLException {
Assert.assertTrue(metaData.supportsColumnAliasing());
}
@Test
public void nullPlusNonNullIsNull() throws SQLException {
Assert.assertFalse(metaData.nullPlusNonNullIsNull());
}
@Test
public void supportsConvert() throws SQLException {
Assert.assertFalse(metaData.supportsConvert());
}
@Test
public void testSupportsConvert() throws SQLException {
Assert.assertFalse(metaData.supportsConvert(1, 1));
}
@Test
public void supportsTableCorrelationNames() throws SQLException {
Assert.assertFalse(metaData.supportsTableCorrelationNames());
}
@Test
public void supportsDifferentTableCorrelationNames() throws SQLException {
Assert.assertFalse(metaData.supportsDifferentTableCorrelationNames());
}
@Test
public void supportsExpressionsInOrderBy() throws SQLException {
Assert.assertFalse(metaData.supportsExpressionsInOrderBy());
}
@Test
public void supportsOrderByUnrelated() throws SQLException {
Assert.assertFalse(metaData.supportsOrderByUnrelated());
}
@Test
public void supportsGroupBy() throws SQLException {
Assert.assertTrue(metaData.supportsGroupBy());
}
@Test
public void supportsGroupByUnrelated() throws SQLException {
Assert.assertFalse(metaData.supportsGroupByUnrelated());
}
@Test
public void supportsGroupByBeyondSelect() throws SQLException {
Assert.assertFalse(metaData.supportsGroupByBeyondSelect());
}
@Test
public void supportsLikeEscapeClause() throws SQLException {
Assert.assertFalse(metaData.supportsLikeEscapeClause());
}
@Test
public void supportsMultipleResultSets() throws SQLException {
Assert.assertFalse(metaData.supportsMultipleResultSets());
}
@Test
public void supportsMultipleTransactions() throws SQLException {
Assert.assertFalse(metaData.supportsMultipleTransactions());
}
@Test
public void supportsNonNullableColumns() throws SQLException {
Assert.assertFalse(metaData.supportsNonNullableColumns());
}
@Test
public void supportsMinimumSQLGrammar() throws SQLException {
Assert.assertFalse(metaData.supportsMinimumSQLGrammar());
}
@Test
public void supportsCoreSQLGrammar() throws SQLException {
Assert.assertFalse(metaData.supportsCoreSQLGrammar());
}
@Test
public void supportsExtendedSQLGrammar() throws SQLException {
Assert.assertFalse(metaData.supportsExtendedSQLGrammar());
}
@Test
public void supportsANSI92EntryLevelSQL() throws SQLException {
Assert.assertFalse(metaData.supportsANSI92EntryLevelSQL());
}
@Test
public void supportsANSI92IntermediateSQL() throws SQLException {
Assert.assertFalse(metaData.supportsANSI92IntermediateSQL());
}
@Test
public void supportsANSI92FullSQL() throws SQLException {
Assert.assertFalse(metaData.supportsANSI92FullSQL());
}
@Test
public void supportsIntegrityEnhancementFacility() throws SQLException {
Assert.assertFalse(metaData.supportsIntegrityEnhancementFacility());
}
@Test
public void supportsOuterJoins() throws SQLException {
Assert.assertFalse(metaData.supportsOuterJoins());
}
@Test
public void supportsFullOuterJoins() throws SQLException {
Assert.assertFalse(metaData.supportsFullOuterJoins());
}
@Test
public void supportsLimitedOuterJoins() throws SQLException {
Assert.assertFalse(metaData.supportsLimitedOuterJoins());
}
@Test
public void getSchemaTerm() throws SQLException {
Assert.assertNull(metaData.getSchemaTerm());
}
@Test
public void getProcedureTerm() throws SQLException {
Assert.assertNull(metaData.getProcedureTerm());
}
@Test
public void getCatalogTerm() throws SQLException {
Assert.assertEquals("database", metaData.getCatalogTerm());
}
@Test
public void isCatalogAtStart() throws SQLException {
Assert.assertTrue(metaData.isCatalogAtStart());
}
@Test
public void getCatalogSeparator() throws SQLException {
Assert.assertEquals(".", metaData.getCatalogSeparator());
}
@Test
public void supportsSchemasInDataManipulation() throws SQLException {
Assert.assertFalse(metaData.supportsSchemasInDataManipulation());
}
@Test
public void supportsSchemasInProcedureCalls() throws SQLException {
Assert.assertFalse(metaData.supportsSchemasInProcedureCalls());
}
@Test
public void supportsSchemasInTableDefinitions() throws SQLException {
Assert.assertFalse(metaData.supportsSchemasInTableDefinitions());
}
@Test
public void supportsSchemasInIndexDefinitions() throws SQLException {
Assert.assertFalse(metaData.supportsSchemasInIndexDefinitions());
}
@Test
public void supportsSchemasInPrivilegeDefinitions() throws SQLException {
Assert.assertFalse(metaData.supportsSchemasInPrivilegeDefinitions());
}
@Test
public void supportsCatalogsInDataManipulation() throws SQLException {
Assert.assertTrue(metaData.supportsCatalogsInDataManipulation());
}
@Test
public void supportsCatalogsInProcedureCalls() throws SQLException {
Assert.assertFalse(metaData.supportsCatalogsInProcedureCalls());
}
@Test
public void supportsCatalogsInTableDefinitions() throws SQLException {
Assert.assertFalse(metaData.supportsCatalogsInTableDefinitions());
}
@Test
public void supportsCatalogsInIndexDefinitions() throws SQLException {
Assert.assertFalse(metaData.supportsCatalogsInIndexDefinitions());
}
@Test
public void supportsCatalogsInPrivilegeDefinitions() throws SQLException {
Assert.assertFalse(metaData.supportsCatalogsInPrivilegeDefinitions());
}
@Test
public void supportsPositionedDelete() throws SQLException {
Assert.assertFalse(metaData.supportsPositionedDelete());
}
@Test
public void supportsPositionedUpdate() throws SQLException {
Assert.assertFalse(metaData.supportsPositionedUpdate());
}
@Test
public void supportsSelectForUpdate() throws SQLException {
Assert.assertFalse(metaData.supportsSelectForUpdate());
}
@Test
public void supportsStoredProcedures() throws SQLException {
Assert.assertFalse(metaData.supportsStoredProcedures());
}
@Test
public void supportsSubqueriesInComparisons() throws SQLException {
Assert.assertFalse(metaData.supportsSubqueriesInComparisons());
}
@Test
public void supportsSubqueriesInExists() throws SQLException {
Assert.assertFalse(metaData.supportsSubqueriesInExists());
}
@Test
public void supportsSubqueriesInIns() throws SQLException {
Assert.assertFalse(metaData.supportsSubqueriesInIns());
}
@Test
public void supportsSubqueriesInQuantifieds() throws SQLException {
Assert.assertFalse(metaData.supportsSubqueriesInQuantifieds());
}
@Test
public void supportsCorrelatedSubqueries() throws SQLException {
Assert.assertFalse(metaData.supportsCorrelatedSubqueries());
}
@Test
public void supportsUnion() throws SQLException {
Assert.assertFalse(metaData.supportsUnion());
}
@Test
public void supportsUnionAll() throws SQLException {
Assert.assertFalse(metaData.supportsUnionAll());
}
@Test
public void supportsOpenCursorsAcrossCommit() throws SQLException {
Assert.assertFalse(metaData.supportsOpenCursorsAcrossCommit());
}
@Test
public void supportsOpenCursorsAcrossRollback() throws SQLException {
Assert.assertFalse(metaData.supportsOpenCursorsAcrossRollback());
}
@Test
public void supportsOpenStatementsAcrossCommit() throws SQLException {
Assert.assertFalse(metaData.supportsOpenStatementsAcrossCommit());
}
@Test
public void supportsOpenStatementsAcrossRollback() throws SQLException {
Assert.assertFalse(metaData.supportsOpenStatementsAcrossRollback());
}
@Test
public void getMaxBinaryLiteralLength() throws SQLException {
Assert.assertEquals(0, metaData.getMaxBinaryLiteralLength());
}
@Test
public void getMaxCharLiteralLength() throws SQLException {
Assert.assertEquals(0, metaData.getMaxCharLiteralLength());
}
@Test
public void getMaxColumnNameLength() throws SQLException {
Assert.assertEquals(0, metaData.getMaxColumnNameLength());
}
@Test
public void getMaxColumnsInGroupBy() throws SQLException {
Assert.assertEquals(0, metaData.getMaxColumnsInGroupBy());
}
@Test
public void getMaxColumnsInIndex() throws SQLException {
Assert.assertEquals(0, metaData.getMaxColumnsInIndex());
}
@Test
public void getMaxColumnsInOrderBy() throws SQLException {
Assert.assertEquals(0, metaData.getMaxColumnsInOrderBy());
}
@Test
public void getMaxColumnsInSelect() throws SQLException {
Assert.assertEquals(0, metaData.getMaxColumnsInSelect());
}
@Test
public void getMaxColumnsInTable() throws SQLException {
Assert.assertEquals(0, metaData.getMaxColumnsInTable());
}
@Test
public void getMaxConnections() throws SQLException {
Assert.assertEquals(0, metaData.getMaxConnections());
}
@Test
public void getMaxCursorNameLength() throws SQLException {
Assert.assertEquals(0, metaData.getMaxCursorNameLength());
}
@Test
public void getMaxIndexLength() throws SQLException {
Assert.assertEquals(0, metaData.getMaxIndexLength());
}
@Test
public void getMaxSchemaNameLength() throws SQLException {
Assert.assertEquals(0, metaData.getMaxSchemaNameLength());
}
@Test
public void getMaxProcedureNameLength() throws SQLException {
Assert.assertEquals(0, metaData.getMaxProcedureNameLength());
}
@Test
public void getMaxCatalogNameLength() throws SQLException {
Assert.assertEquals(0, metaData.getMaxCatalogNameLength());
}
@Test
public void getMaxRowSize() throws SQLException {
Assert.assertEquals(0, metaData.getMaxRowSize());
}
@Test
public void doesMaxRowSizeIncludeBlobs() throws SQLException {
Assert.assertFalse(metaData.doesMaxRowSizeIncludeBlobs());
}
@Test
public void getMaxStatementLength() throws SQLException {
Assert.assertEquals(0, metaData.getMaxStatementLength());
}
@Test
public void getMaxStatements() throws SQLException {
Assert.assertEquals(0, metaData.getMaxStatements());
}
@Test
public void getMaxTableNameLength() throws SQLException {
Assert.assertEquals(0, metaData.getMaxTableNameLength());
}
@Test
public void getMaxTablesInSelect() throws SQLException {
Assert.assertEquals(0, metaData.getMaxTablesInSelect());
}
@Test
public void getMaxUserNameLength() throws SQLException {
Assert.assertEquals(0, metaData.getMaxUserNameLength());
}
@Test
public void getDefaultTransactionIsolation() throws SQLException {
Assert.assertEquals(Connection.TRANSACTION_NONE, metaData.getDefaultTransactionIsolation());
}
@Test
public void supportsTransactions() throws SQLException {
Assert.assertFalse(metaData.supportsTransactions());
}
@Test
public void supportsTransactionIsolationLevel() throws SQLException {
Assert.assertTrue(metaData.supportsTransactionIsolationLevel(Connection.TRANSACTION_NONE));
Assert.assertFalse(metaData.supportsTransactionIsolationLevel(Connection.TRANSACTION_READ_COMMITTED));
Assert.assertFalse(metaData.supportsTransactionIsolationLevel(Connection.TRANSACTION_READ_UNCOMMITTED));
Assert.assertFalse(metaData.supportsTransactionIsolationLevel(Connection.TRANSACTION_REPEATABLE_READ));
Assert.assertFalse(metaData.supportsTransactionIsolationLevel(Connection.TRANSACTION_SERIALIZABLE));
}
@Test
public void supportsDataDefinitionAndDataManipulationTransactions() throws SQLException {
Assert.assertFalse(metaData.supportsDataDefinitionAndDataManipulationTransactions());
}
@Test
public void supportsDataManipulationTransactionsOnly() throws SQLException {
Assert.assertFalse(metaData.supportsDataManipulationTransactionsOnly());
}
@Test
public void dataDefinitionCausesTransactionCommit() throws SQLException {
Assert.assertFalse(metaData.dataDefinitionCausesTransactionCommit());
}
@Test
public void dataDefinitionIgnoredInTransactions() throws SQLException {
Assert.assertFalse(metaData.dataDefinitionIgnoredInTransactions());
}
@Test
public void getProcedures() throws SQLException {
Assert.assertNull(metaData.getProcedures("*", "*", "*"));
}
@Test
public void getProcedureColumns() throws SQLException {
Assert.assertNull(metaData.getProcedureColumns("*", "*", "*", "*"));
}
@Test
public void getTables() throws SQLException {
System.out.println("****************************************************");
ResultSet tables = metaData.getTables("log", "", null, null);
ResultSetMetaData metaData = tables.getMetaData();
while (tables.next()) {
System.out.print(metaData.getColumnLabel(1) + ":" + tables.getString(1) + "\t");
System.out.print(metaData.getColumnLabel(3) + ":" + tables.getString(3) + "\t");
System.out.print(metaData.getColumnLabel(4) + ":" + tables.getString(4) + "\t");
System.out.print(metaData.getColumnLabel(5) + ":" + tables.getString(5) + "\n");
}
System.out.println();
Assert.assertNotNull(tables);
}
@Test
public void getSchemas() throws SQLException {
Assert.assertNotNull(metaData.getSchemas());
}
@Test
public void getCatalogs() throws SQLException {
System.out.println("****************************************************");
ResultSet catalogs = metaData.getCatalogs();
ResultSetMetaData meta = catalogs.getMetaData();
while (catalogs.next()) {
for (int i = 1; i <= meta.getColumnCount(); i++) {
System.out.print(meta.getColumnLabel(i) + ": " + catalogs.getString(i));
}
System.out.println();
}
}
@Test
public void getTableTypes() throws SQLException {
System.out.println("****************************************************");
ResultSet tableTypes = metaData.getTableTypes();
while (tableTypes.next()) {
System.out.println(tableTypes.getString("TABLE_TYPE"));
}
Assert.assertNotNull(metaData.getTableTypes());
}
@Test
public void getColumns() throws SQLException {
System.out.println("****************************************************");
ResultSet columns = metaData.getColumns("log", "", "dn", "");
ResultSetMetaData meta = columns.getMetaData();
while (columns.next()) {
System.out.print(meta.getColumnLabel(1) + ": " + columns.getString(1) + "\t");
System.out.print(meta.getColumnLabel(3) + ": " + columns.getString(3) + "\t");
System.out.print(meta.getColumnLabel(4) + ": " + columns.getString(4) + "\t");
System.out.print(meta.getColumnLabel(5) + ": " + columns.getString(5) + "\t");
System.out.print(meta.getColumnLabel(6) + ": " + columns.getString(6) + "\t");
System.out.print(meta.getColumnLabel(7) + ": " + columns.getString(7) + "\t");
System.out.print(meta.getColumnLabel(9) + ": " + columns.getString(9) + "\t");
System.out.print(meta.getColumnLabel(10) + ": " + columns.getString(10) + "\t");
System.out.print(meta.getColumnLabel(11) + ": " + columns.getString(11) + "\n");
System.out.print(meta.getColumnLabel(12) + ": " + columns.getString(12) + "\n");
}
}
@Test
public void getColumnPrivileges() throws SQLException {
Assert.assertNotNull(metaData.getColumnPrivileges("", "", "", ""));
}
@Test
public void getTablePrivileges() throws SQLException {
Assert.assertNotNull(metaData.getTablePrivileges("", "", ""));
}
@Test
public void getBestRowIdentifier() throws SQLException {
Assert.assertNotNull(metaData.getBestRowIdentifier("", "", "", 0, false));
}
@Test
public void getVersionColumns() throws SQLException {
Assert.assertNotNull(metaData.getVersionColumns("", "", ""));
}
@Test
public void getPrimaryKeys() throws SQLException {
System.out.println("****************************************************");
ResultSet rs = metaData.getPrimaryKeys("log", "", "dn1");
while (rs.next()) {
System.out.println("TABLE_NAME: " + rs.getString("TABLE_NAME"));
System.out.println("COLUMN_NAME: " + rs.getString("COLUMN_NAME"));
System.out.println("KEY_SEQ: " + rs.getString("KEY_SEQ"));
System.out.println("PK_NAME: " + rs.getString("PK_NAME"));
}
Assert.assertNotNull(rs);
}
@Test
public void getImportedKeys() throws SQLException {
Assert.assertNotNull(metaData.getImportedKeys("", "", ""));
}
@Test
public void getExportedKeys() throws SQLException {
Assert.assertNotNull(metaData.getExportedKeys("", "", ""));
}
@Test
public void getCrossReference() throws SQLException {
Assert.assertNotNull(metaData.getCrossReference("", "", "", "", "", ""));
}
@Test
public void getTypeInfo() throws SQLException {
Assert.assertNotNull(metaData.getTypeInfo());
}
@Test
public void getIndexInfo() throws SQLException {
Assert.assertNotNull(metaData.getIndexInfo("", "", "", false, false));
}
@Test
public void supportsResultSetType() throws SQLException {
Assert.assertFalse(metaData.supportsResultSetType(0));
}
@Test
public void supportsResultSetConcurrency() throws SQLException {
Assert.assertFalse(metaData.supportsResultSetConcurrency(0, 0));
}
@Test
public void ownUpdatesAreVisible() throws SQLException {
Assert.assertFalse(metaData.ownUpdatesAreVisible(0));
}
@Test
public void ownDeletesAreVisible() throws SQLException {
Assert.assertFalse(metaData.ownDeletesAreVisible(0));
}
@Test
public void ownInsertsAreVisible() throws SQLException {
Assert.assertFalse(metaData.ownInsertsAreVisible(0));
}
@Test
public void othersUpdatesAreVisible() throws SQLException {
Assert.assertFalse(metaData.othersUpdatesAreVisible(0));
}
@Test
public void othersDeletesAreVisible() throws SQLException {
Assert.assertFalse(metaData.othersDeletesAreVisible(0));
}
@Test
public void othersInsertsAreVisible() throws SQLException {
Assert.assertFalse(metaData.othersInsertsAreVisible(0));
}
@Test
public void updatesAreDetected() throws SQLException {
Assert.assertFalse(metaData.updatesAreDetected(0));
}
@Test
public void deletesAreDetected() throws SQLException {
Assert.assertFalse(metaData.deletesAreDetected(0));
}
@Test
public void insertsAreDetected() throws SQLException {
Assert.assertFalse(metaData.insertsAreDetected(0));
}
@Test
public void supportsBatchUpdates() throws SQLException {
Assert.assertFalse(metaData.supportsBatchUpdates());
}
@Test
public void getUDTs() throws SQLException {
Assert.assertNotNull(metaData.getUDTs("", "", "", null));
}
@Test
public void getConnection() throws SQLException {
Assert.assertNotNull(metaData.getConnection());
}
@Test
public void supportsSavepoints() throws SQLException {
Assert.assertFalse(metaData.supportsSavepoints());
}
@Test
public void supportsNamedParameters() throws SQLException {
Assert.assertFalse(metaData.supportsNamedParameters());
}
@Test
public void supportsMultipleOpenResults() throws SQLException {
Assert.assertFalse(metaData.supportsMultipleOpenResults());
}
@Test
public void supportsGetGeneratedKeys() throws SQLException {
Assert.assertFalse(metaData.supportsGetGeneratedKeys());
}
@Test
public void getSuperTypes() throws SQLException {
Assert.assertNotNull(metaData.getSuperTypes("", "", ""));
}
@Test
public void getSuperTables() throws SQLException {
System.out.println("****************************************************");
ResultSet rs = metaData.getSuperTables("log", "", "dn1");
while (rs.next()) {
System.out.println("TABLE_NAME: " + rs.getString("TABLE_NAME"));
System.out.println("SUPERTABLE_NAME: " + rs.getString("SUPERTABLE_NAME"));
}
Assert.assertNotNull(rs);
}
@Test
public void getAttributes() throws SQLException {
Assert.assertNotNull(metaData.getAttributes("", "", "", ""));
}
@Test
public void supportsResultSetHoldability() throws SQLException {
Assert.assertTrue(metaData.supportsResultSetHoldability(ResultSet.HOLD_CURSORS_OVER_COMMIT));
Assert.assertFalse(metaData.supportsResultSetHoldability(ResultSet.CLOSE_CURSORS_AT_COMMIT));
}
@Test
public void getResultSetHoldability() throws SQLException {
Assert.assertEquals(1, metaData.getResultSetHoldability());
}
@Test
public void getDatabaseMajorVersion() throws SQLException {
Assert.assertEquals(2, metaData.getDatabaseMajorVersion());
}
@Test
public void getDatabaseMinorVersion() throws SQLException {
Assert.assertEquals(0, metaData.getDatabaseMinorVersion());
}
@Test
public void getJDBCMajorVersion() throws SQLException {
Assert.assertEquals(2, metaData.getJDBCMajorVersion());
}
@Test
public void getJDBCMinorVersion() throws SQLException {
Assert.assertEquals(0, metaData.getJDBCMinorVersion());
}
@Test
public void getSQLStateType() throws SQLException {
Assert.assertEquals(0, metaData.getSQLStateType());
}
@Test
public void locatorsUpdateCopy() throws SQLException {
Assert.assertFalse(metaData.locatorsUpdateCopy());
}
@Test
public void supportsStatementPooling() throws SQLException {
Assert.assertFalse(metaData.supportsStatementPooling());
}
@Test
public void getRowIdLifetime() throws SQLException {
Assert.assertNull(metaData.getRowIdLifetime());
}
@Test
public void supportsStoredFunctionsUsingCallSyntax() throws SQLException {
Assert.assertFalse(metaData.supportsStoredFunctionsUsingCallSyntax());
}
@Test
public void autoCommitFailureClosesAllResultSets() throws SQLException {
Assert.assertFalse(metaData.autoCommitFailureClosesAllResultSets());
}
@Test
public void getClientInfoProperties() throws SQLException {
Assert.assertNotNull(metaData.getClientInfoProperties());
}
@Test
public void getFunctions() throws SQLException {
Assert.assertNotNull(metaData.getFunctions("", "", ""));
}
@Test
public void getFunctionColumns() throws SQLException {
Assert.assertNotNull(metaData.getFunctionColumns("", "", "", ""));
}
@Test
public void getPseudoColumns() throws SQLException {
Assert.assertNotNull(metaData.getPseudoColumns("", "", "", ""));
}
@Test
public void generatedKeyAlwaysReturned() throws SQLException {
Assert.assertFalse(metaData.generatedKeyAlwaysReturned());
}
@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");
connection = DriverManager.getConnection(url, properties);
metaData = connection.getMetaData().unwrap(RestfulDatabaseMetaData.class);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
@AfterClass
public static void afterClass() {
try {
if (connection != null)
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
\ No newline at end of file
......@@ -67,13 +67,13 @@ def _crow_tinyint_unsigned_to_python(
return [
None if ele == FieldType.C_TINYINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(
ctypes.c_byte))[
ctypes.c_ubyte))[
:abs(num_of_rows)]]
else:
return [
None if ele == FieldType.C_TINYINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(
ctypes.c_byte))[
ctypes.c_ubyte))[
:abs(num_of_rows)]]
......@@ -102,13 +102,13 @@ def _crow_smallint_unsigned_to_python(
return [
None if ele == FieldType.C_SMALLINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(
ctypes.c_short))[
ctypes.c_ushort))[
:abs(num_of_rows)]]
else:
return [
None if ele == FieldType.C_SMALLINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(
ctypes.c_short))[
ctypes.c_ushort))[
:abs(num_of_rows)]]
......@@ -130,13 +130,13 @@ def _crow_int_unsigned_to_python(data, num_of_rows, nbytes=None, micro=False):
return [
None if ele == FieldType.C_INT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(
ctypes.c_int))[
ctypes.c_uint))[
:abs(num_of_rows)]]
else:
return [
None if ele == FieldType.C_INT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(
ctypes.c_int))[
ctypes.c_uint))[
:abs(num_of_rows)]]
......@@ -162,13 +162,13 @@ def _crow_bigint_unsigned_to_python(
return [
None if ele == FieldType.C_BIGINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(
ctypes.c_long))[
ctypes.c_ulong))[
:abs(num_of_rows)]]
else:
return [
None if ele == FieldType.C_BIGINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(
ctypes.c_long))[
ctypes.c_ulong))[
:abs(num_of_rows)]]
......
......@@ -19,10 +19,10 @@ class FieldType(object):
C_BINARY = 8
C_TIMESTAMP = 9
C_NCHAR = 10
C_TINYINT_UNSIGNED = 12
C_SMALLINT_UNSIGNED = 13
C_INT_UNSIGNED = 14
C_BIGINT_UNSIGNED = 15
C_TINYINT_UNSIGNED = 11
C_SMALLINT_UNSIGNED = 12
C_INT_UNSIGNED = 13
C_BIGINT_UNSIGNED = 14
# NULL value definition
# NOTE: These values should change according to C definition in tsdb.h
C_BOOL_NULL = 0x02
......
......@@ -67,13 +67,13 @@ def _crow_tinyint_unsigned_to_python(
return [
None if ele == FieldType.C_TINYINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(
ctypes.c_byte))[
ctypes.c_ubyte))[
:abs(num_of_rows)]]
else:
return [
None if ele == FieldType.C_TINYINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(
ctypes.c_byte))[
ctypes.c_ubyte))[
:abs(num_of_rows)]]
......@@ -102,13 +102,13 @@ def _crow_smallint_unsigned_to_python(
return [
None if ele == FieldType.C_SMALLINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(
ctypes.c_short))[
ctypes.c_ushort))[
:abs(num_of_rows)]]
else:
return [
None if ele == FieldType.C_SMALLINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(
ctypes.c_short))[
ctypes.c_ushort))[
:abs(num_of_rows)]]
......@@ -130,13 +130,13 @@ def _crow_int_unsigned_to_python(data, num_of_rows, nbytes=None, micro=False):
return [
None if ele == FieldType.C_INT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(
ctypes.c_int))[
ctypes.c_uint))[
:abs(num_of_rows)]]
else:
return [
None if ele == FieldType.C_INT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(
ctypes.c_int))[
ctypes.c_uint))[
:abs(num_of_rows)]]
......@@ -162,13 +162,13 @@ def _crow_bigint_unsigned_to_python(
return [
None if ele == FieldType.C_BIGINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(
ctypes.c_long))[
ctypes.c_ulong))[
:abs(num_of_rows)]]
else:
return [
None if ele == FieldType.C_BIGINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(
ctypes.c_long))[
ctypes.c_ulong))[
:abs(num_of_rows)]]
......
......@@ -19,10 +19,10 @@ class FieldType(object):
C_BINARY = 8
C_TIMESTAMP = 9
C_NCHAR = 10
C_TINYINT_UNSIGNED = 12
C_SMALLINT_UNSIGNED = 13
C_INT_UNSIGNED = 14
C_BIGINT_UNSIGNED = 15
C_TINYINT_UNSIGNED = 11
C_SMALLINT_UNSIGNED = 12
C_INT_UNSIGNED = 13
C_BIGINT_UNSIGNED = 14
# NULL value definition
# NOTE: These values should change according to C definition in tsdb.h
C_BOOL_NULL = 0x02
......
......@@ -67,13 +67,13 @@ def _crow_tinyint_unsigned_to_python(
return [
None if ele == FieldType.C_TINYINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(
ctypes.c_byte))[
ctypes.c_ubyte))[
:abs(num_of_rows)]]
else:
return [
None if ele == FieldType.C_TINYINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(
ctypes.c_byte))[
ctypes.c_ubyte))[
:abs(num_of_rows)]]
......@@ -102,13 +102,13 @@ def _crow_smallint_unsigned_to_python(
return [
None if ele == FieldType.C_SMALLINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(
ctypes.c_short))[
ctypes.c_ushort))[
:abs(num_of_rows)]]
else:
return [
None if ele == FieldType.C_SMALLINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(
ctypes.c_short))[
ctypes.c_ushort))[
:abs(num_of_rows)]]
......@@ -130,13 +130,13 @@ def _crow_int_unsigned_to_python(data, num_of_rows, nbytes=None, micro=False):
return [
None if ele == FieldType.C_INT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(
ctypes.c_int))[
ctypes.c_uint))[
:abs(num_of_rows)]]
else:
return [
None if ele == FieldType.C_INT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(
ctypes.c_int))[
ctypes.c_uint))[
:abs(num_of_rows)]]
......@@ -162,13 +162,13 @@ def _crow_bigint_unsigned_to_python(
return [
None if ele == FieldType.C_BIGINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(
ctypes.c_long))[
ctypes.c_ulong))[
:abs(num_of_rows)]]
else:
return [
None if ele == FieldType.C_BIGINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(
ctypes.c_long))[
ctypes.c_ulong))[
:abs(num_of_rows)]]
......
......@@ -19,10 +19,10 @@ class FieldType(object):
C_BINARY = 8
C_TIMESTAMP = 9
C_NCHAR = 10
C_TINYINT_UNSIGNED = 12
C_SMALLINT_UNSIGNED = 13
C_INT_UNSIGNED = 14
C_BIGINT_UNSIGNED = 15
C_TINYINT_UNSIGNED = 11
C_SMALLINT_UNSIGNED = 12
C_INT_UNSIGNED = 13
C_BIGINT_UNSIGNED = 14
# NULL value definition
# NOTE: These values should change according to C definition in tsdb.h
C_BOOL_NULL = 0x02
......
......@@ -8,6 +8,7 @@ paramstyle = 'pyformat'
__all__ = ['connection', 'cursor']
def connect(*args, **kwargs):
""" Function to return a TDengine connector object
......
......@@ -4,11 +4,14 @@ from .error import *
import math
import datetime
def _convert_millisecond_to_datetime(milli):
return datetime.datetime.fromtimestamp(milli/1000.0)
return datetime.datetime.fromtimestamp(milli / 1000.0)
def _convert_microsecond_to_datetime(micro):
return datetime.datetime.fromtimestamp(micro/1000000.0)
return datetime.datetime.fromtimestamp(micro / 1000000.0)
def _crow_timestamp_to_python(data, num_of_rows, nbytes=None, micro=False):
"""Function to convert C bool row to python row
......@@ -18,168 +21,309 @@ def _crow_timestamp_to_python(data, num_of_rows, nbytes=None, micro=False):
_timestamp_converter = _convert_microsecond_to_datetime
if num_of_rows > 0:
return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)]))
return list(map(_timestamp_converter, ctypes.cast(
data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)]))
else:
return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)]))
return list(map(_timestamp_converter, ctypes.cast(
data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)]))
def _crow_bool_to_python(data, num_of_rows, nbytes=None, micro=False):
"""Function to convert C bool row to python row
"""
if num_of_rows > 0:
return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)] ]
return [
None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(
data, ctypes.POINTER(
ctypes.c_byte))[
:abs(num_of_rows)]]
else:
return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_bool))[:abs(num_of_rows)] ]
return [
None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(
data, ctypes.POINTER(
ctypes.c_bool))[
:abs(num_of_rows)]]
def _crow_tinyint_to_python(data, num_of_rows, nbytes=None, micro=False):
"""Function to convert C tinyint row to python row
"""
if num_of_rows > 0:
return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)] ]
return [None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)]]
else:
return [None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)]]
def _crow_tinyint_unsigned_to_python(
data,
num_of_rows,
nbytes=None,
micro=False):
"""Function to convert C tinyint row to python row
"""
if num_of_rows > 0:
return [
None if ele == FieldType.C_TINYINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(
ctypes.c_ubyte))[
:abs(num_of_rows)]]
else:
return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)] ]
return [
None if ele == FieldType.C_TINYINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(
ctypes.c_ubyte))[
:abs(num_of_rows)]]
def _crow_smallint_to_python(data, num_of_rows, nbytes=None, micro=False):
"""Function to convert C smallint row to python row
"""
if num_of_rows > 0:
return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)]]
return [
None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(
ctypes.c_short))[
:abs(num_of_rows)]]
else:
return [
None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(
ctypes.c_short))[
:abs(num_of_rows)]]
def _crow_smallint_unsigned_to_python(
data, num_of_rows, nbytes=None, micro=False):
"""Function to convert C smallint row to python row
"""
if num_of_rows > 0:
return [
None if ele == FieldType.C_SMALLINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(
ctypes.c_ushort))[
:abs(num_of_rows)]]
else:
return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)] ]
return [
None if ele == FieldType.C_SMALLINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(
ctypes.c_ushort))[
:abs(num_of_rows)]]
def _crow_int_to_python(data, num_of_rows, nbytes=None, micro=False):
"""Function to convert C int row to python row
"""
if num_of_rows > 0:
return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)] ]
return [None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)]]
else:
return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)] ]
return [None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)]]
def _crow_int_unsigned_to_python(data, num_of_rows, nbytes=None, micro=False):
"""Function to convert C int row to python row
"""
if num_of_rows > 0:
return [
None if ele == FieldType.C_INT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(
ctypes.c_uint))[
:abs(num_of_rows)]]
else:
return [
None if ele == FieldType.C_INT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(
ctypes.c_uint))[
:abs(num_of_rows)]]
def _crow_bigint_to_python(data, num_of_rows, nbytes=None, micro=False):
"""Function to convert C bigint row to python row
"""
if num_of_rows > 0:
return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)] ]
return [None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)]]
else:
return [None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)]]
def _crow_bigint_unsigned_to_python(
data,
num_of_rows,
nbytes=None,
micro=False):
"""Function to convert C bigint row to python row
"""
if num_of_rows > 0:
return [
None if ele == FieldType.C_BIGINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(
ctypes.c_ulong))[
:abs(num_of_rows)]]
else:
return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)] ]
return [
None if ele == FieldType.C_BIGINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(
ctypes.c_ulong))[
:abs(num_of_rows)]]
def _crow_float_to_python(data, num_of_rows, nbytes=None, micro=False):
"""Function to convert C float row to python row
"""
if num_of_rows > 0:
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)] ]
return [None if math.isnan(ele) else ele for ele in ctypes.cast(
data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)]]
else:
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)] ]
return [None if math.isnan(ele) else ele for ele in ctypes.cast(
data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)]]
def _crow_double_to_python(data, num_of_rows, nbytes=None, micro=False):
"""Function to convert C double row to python row
"""
if num_of_rows > 0:
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)] ]
return [None if math.isnan(ele) else ele for ele in ctypes.cast(
data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)]]
else:
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)] ]
return [None if math.isnan(ele) else ele for ele in ctypes.cast(
data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)]]
def _crow_binary_to_python(data, num_of_rows, nbytes=None, micro=False):
"""Function to convert C binary row to python row
"""
assert(nbytes is not None)
if num_of_rows > 0:
return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]]
return [None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode(
'utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]]
else:
return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]]
return [None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode(
'utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]]
def _crow_nchar_to_python(data, num_of_rows, nbytes=None, micro=False):
"""Function to convert C nchar row to python row
"""
assert(nbytes is not None)
res=[]
res = []
for i in range(abs(num_of_rows)):
try:
if num_of_rows >= 0:
tmpstr = ctypes.c_char_p(data)
res.append( tmpstr.value.decode() )
res.append(tmpstr.value.decode())
else:
res.append( (ctypes.cast(data+nbytes*i, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[0].value )
res.append((ctypes.cast(data + nbytes * i,
ctypes.POINTER(ctypes.c_wchar * (nbytes // 4))))[0].value)
except ValueError:
res.append(None)
return res
return res
def _crow_binary_to_python_block(data, num_of_rows, nbytes=None, micro=False):
"""Function to convert C binary row to python row
"""
assert(nbytes is not None)
res=[]
res = []
if num_of_rows > 0:
for i in range(abs(num_of_rows)):
try:
rbyte=ctypes.cast(data+nbytes*i,ctypes.POINTER(ctypes.c_short))[:1].pop()
tmpstr = ctypes.c_char_p(data+nbytes*i+2)
res.append( tmpstr.value.decode()[0:rbyte] )
rbyte = ctypes.cast(
data + nbytes * i,
ctypes.POINTER(
ctypes.c_short))[
:1].pop()
tmpstr = ctypes.c_char_p(data + nbytes * i + 2)
res.append(tmpstr.value.decode()[0:rbyte])
except ValueError:
res.append(None)
else:
for i in range(abs(num_of_rows)):
try:
rbyte=ctypes.cast(data+nbytes*i,ctypes.POINTER(ctypes.c_short))[:1].pop()
tmpstr = ctypes.c_char_p(data+nbytes*i+2)
res.append( tmpstr.value.decode()[0:rbyte] )
rbyte = ctypes.cast(
data + nbytes * i,
ctypes.POINTER(
ctypes.c_short))[
:1].pop()
tmpstr = ctypes.c_char_p(data + nbytes * i + 2)
res.append(tmpstr.value.decode()[0:rbyte])
except ValueError:
res.append(None)
return res
def _crow_nchar_to_python_block(data, num_of_rows, nbytes=None, micro=False):
"""Function to convert C nchar row to python row
"""
assert(nbytes is not None)
res=[]
res = []
if num_of_rows >= 0:
for i in range(abs(num_of_rows)):
try:
tmpstr = ctypes.c_char_p(data+nbytes*i+2)
res.append( tmpstr.value.decode() )
tmpstr = ctypes.c_char_p(data + nbytes * i + 2)
res.append(tmpstr.value.decode())
except ValueError:
res.append(None)
else:
for i in range(abs(num_of_rows)):
try:
res.append( (ctypes.cast(data+nbytes*i+2, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[0].value )
res.append((ctypes.cast(data + nbytes * i + 2,
ctypes.POINTER(ctypes.c_wchar * (nbytes // 4))))[0].value)
except ValueError:
res.append(None)
return res
_CONVERT_FUNC = {
FieldType.C_BOOL: _crow_bool_to_python,
FieldType.C_TINYINT : _crow_tinyint_to_python,
FieldType.C_SMALLINT : _crow_smallint_to_python,
FieldType.C_INT : _crow_int_to_python,
FieldType.C_BIGINT : _crow_bigint_to_python,
FieldType.C_FLOAT : _crow_float_to_python,
FieldType.C_DOUBLE : _crow_double_to_python,
FieldType.C_TINYINT: _crow_tinyint_to_python,
FieldType.C_SMALLINT: _crow_smallint_to_python,
FieldType.C_INT: _crow_int_to_python,
FieldType.C_BIGINT: _crow_bigint_to_python,
FieldType.C_FLOAT: _crow_float_to_python,
FieldType.C_DOUBLE: _crow_double_to_python,
FieldType.C_BINARY: _crow_binary_to_python,
FieldType.C_TIMESTAMP : _crow_timestamp_to_python,
FieldType.C_NCHAR : _crow_nchar_to_python
FieldType.C_TIMESTAMP: _crow_timestamp_to_python,
FieldType.C_NCHAR: _crow_nchar_to_python,
FieldType.C_TINYINT_UNSIGNED: _crow_tinyint_unsigned_to_python,
FieldType.C_SMALLINT_UNSIGNED: _crow_smallint_unsigned_to_python,
FieldType.C_INT_UNSIGNED: _crow_int_unsigned_to_python,
FieldType.C_BIGINT_UNSIGNED: _crow_bigint_unsigned_to_python
}
_CONVERT_FUNC_BLOCK = {
FieldType.C_BOOL: _crow_bool_to_python,
FieldType.C_TINYINT : _crow_tinyint_to_python,
FieldType.C_SMALLINT : _crow_smallint_to_python,
FieldType.C_INT : _crow_int_to_python,
FieldType.C_BIGINT : _crow_bigint_to_python,
FieldType.C_FLOAT : _crow_float_to_python,
FieldType.C_DOUBLE : _crow_double_to_python,
FieldType.C_TINYINT: _crow_tinyint_to_python,
FieldType.C_SMALLINT: _crow_smallint_to_python,
FieldType.C_INT: _crow_int_to_python,
FieldType.C_BIGINT: _crow_bigint_to_python,
FieldType.C_FLOAT: _crow_float_to_python,
FieldType.C_DOUBLE: _crow_double_to_python,
FieldType.C_BINARY: _crow_binary_to_python_block,
FieldType.C_TIMESTAMP : _crow_timestamp_to_python,
FieldType.C_NCHAR : _crow_nchar_to_python_block
FieldType.C_TIMESTAMP: _crow_timestamp_to_python,
FieldType.C_NCHAR: _crow_nchar_to_python_block,
FieldType.C_TINYINT_UNSIGNED: _crow_tinyint_unsigned_to_python,
FieldType.C_SMALLINT_UNSIGNED: _crow_smallint_unsigned_to_python,
FieldType.C_INT_UNSIGNED: _crow_int_unsigned_to_python,
FieldType.C_BIGINT_UNSIGNED: _crow_bigint_unsigned_to_python
}
# Corresponding TAOS_FIELD structure in C
class TaosField(ctypes.Structure):
_fields_ = [('name', ctypes.c_char * 65),
('type', ctypes.c_char),
('bytes', ctypes.c_short)]
# C interface class
class CTaosInterface(object):
libtaos = ctypes.windll.LoadLibrary('taos')
......@@ -216,7 +360,7 @@ class CTaosInterface(object):
except AttributeError:
raise AttributeError("config is expected as a str")
if config != None:
if config is not None:
CTaosInterface.libtaos.taos_options(3, self._config)
CTaosInterface.libtaos.taos_init()
......@@ -227,7 +371,13 @@ class CTaosInterface(object):
"""
return self._config
def connect(self, host=None, user="root", password="taosdata", db=None, port=0):
def connect(
self,
host=None,
user="root",
password="taosdata",
db=None,
port=0):
'''
Function to connect to server
......@@ -236,7 +386,7 @@ class CTaosInterface(object):
# host
try:
_host = ctypes.c_char_p(host.encode(
"utf-8")) if host != None else ctypes.c_char_p(None)
"utf-8")) if host is not None else ctypes.c_char_p(None)
except AttributeError:
raise AttributeError("host is expected as a str")
......@@ -255,7 +405,7 @@ class CTaosInterface(object):
# db
try:
_db = ctypes.c_char_p(
db.encode("utf-8")) if db != None else ctypes.c_char_p(None)
db.encode("utf-8")) if db is not None else ctypes.c_char_p(None)
except AttributeError:
raise AttributeError("db is expected as a str")
......@@ -268,11 +418,11 @@ class CTaosInterface(object):
connection = ctypes.c_void_p(CTaosInterface.libtaos.taos_connect(
_host, _user, _password, _db, _port))
if connection.value == None:
if connection.value is None:
print('connect to TDengine failed')
raise ConnectionError("connect to TDengine failed")
# sys.exit(1)
#else:
# else:
# print('connect to TDengine success')
return connection
......@@ -293,12 +443,13 @@ class CTaosInterface(object):
@rtype: 0 on success and -1 on failure
'''
try:
return CTaosInterface.libtaos.taos_query(connection, ctypes.c_char_p(sql.encode('utf-8')))
return CTaosInterface.libtaos.taos_query(
connection, ctypes.c_char_p(sql.encode('utf-8')))
except AttributeError:
raise AttributeError("sql is expected as a string")
# finally:
# CTaosInterface.libtaos.close(connection)
@staticmethod
def affectedRows(result):
"""The affected rows after runing query
......@@ -308,7 +459,7 @@ class CTaosInterface(object):
@staticmethod
def subscribe(connection, restart, topic, sql, interval):
"""Create a subscription
@restart boolean,
@restart boolean,
@sql string, sql statement for data query, must be a 'select' statement.
@topic string, name of this subscription
"""
......@@ -360,35 +511,49 @@ class CTaosInterface(object):
result, ctypes.byref(pblock))
if num_of_rows == 0:
return None, 0
isMicro = (CTaosInterface.libtaos.taos_result_precision(result) == FieldType.C_TIMESTAMP_MICRO)
isMicro = (CTaosInterface.libtaos.taos_result_precision(
result) == FieldType.C_TIMESTAMP_MICRO)
blocks = [None] * len(fields)
fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result)
fieldLen = [ele for ele in ctypes.cast(fieldL, ctypes.POINTER(ctypes.c_int))[:len(fields)]]
fieldLen = [
ele for ele in ctypes.cast(
fieldL, ctypes.POINTER(
ctypes.c_int))[
:len(fields)]]
for i in range(len(fields)):
data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i]
if fields[i]['type'] not in _CONVERT_FUNC_BLOCK:
raise DatabaseError("Invalid data type returned from database")
blocks[i] = _CONVERT_FUNC_BLOCK[fields[i]['type']](data, num_of_rows, fieldLen[i], isMicro)
blocks[i] = _CONVERT_FUNC_BLOCK[fields[i]['type']](
data, num_of_rows, fieldLen[i], isMicro)
return blocks, abs(num_of_rows)
@staticmethod
def fetchRow(result, fields):
pblock = ctypes.c_void_p(0)
pblock = CTaosInterface.libtaos.taos_fetch_row(result)
if pblock :
pblock = CTaosInterface.libtaos.taos_fetch_row(result)
if pblock:
num_of_rows = 1
isMicro = (CTaosInterface.libtaos.taos_result_precision(result) == FieldType.C_TIMESTAMP_MICRO)
isMicro = (CTaosInterface.libtaos.taos_result_precision(
result) == FieldType.C_TIMESTAMP_MICRO)
blocks = [None] * len(fields)
fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result)
fieldLen = [ele for ele in ctypes.cast(fieldL, ctypes.POINTER(ctypes.c_int))[:len(fields)]]
fieldLen = [
ele for ele in ctypes.cast(
fieldL, ctypes.POINTER(
ctypes.c_int))[
:len(fields)]]
for i in range(len(fields)):
data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i]
if fields[i]['type'] not in _CONVERT_FUNC:
raise DatabaseError("Invalid data type returned from database")
raise DatabaseError(
"Invalid data type returned from database")
if data is None:
blocks[i] = [None]
else:
blocks[i] = _CONVERT_FUNC[fields[i]['type']](data, num_of_rows, fieldLen[i], isMicro)
blocks[i] = _CONVERT_FUNC[fields[i]['type']](
data, num_of_rows, fieldLen[i], isMicro)
else:
return None, 0
return blocks, abs(num_of_rows)
......
......@@ -2,9 +2,11 @@ from .cursor import TDengineCursor
from .subscription import TDengineSubscription
from .cinterface import CTaosInterface
class TDengineConnection(object):
""" TDengine connection object
"""
def __init__(self, *args, **kwargs):
self._conn = None
self._host = None
......@@ -30,7 +32,7 @@ class TDengineConnection(object):
# password
if 'password' in kwargs:
self._password = kwargs['password']
# database
if 'database' in kwargs:
self._database = kwargs['database']
......@@ -44,7 +46,12 @@ class TDengineConnection(object):
self._config = kwargs['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):
"""Close current connection.
......@@ -56,7 +63,8 @@ class TDengineConnection(object):
"""
if self._conn is None:
return None
sub = CTaosInterface.subscribe(self._conn, restart, topic, sql, interval)
sub = CTaosInterface.subscribe(
self._conn, restart, topic, sql, interval)
return TDengineSubscription(sub)
def cursor(self):
......@@ -81,7 +89,8 @@ class TDengineConnection(object):
"""
pass
if __name__ == "__main__":
conn = TDengineConnection(host='192.168.1.107')
conn.close()
print("Hello world")
\ No newline at end of file
print("Hello world")
......@@ -3,6 +3,7 @@
from .dbapi import *
class FieldType(object):
"""TDengine Field Types
"""
......@@ -18,13 +19,21 @@ class FieldType(object):
C_BINARY = 8
C_TIMESTAMP = 9
C_NCHAR = 10
C_TINYINT_UNSIGNED = 11
C_SMALLINT_UNSIGNED = 12
C_INT_UNSIGNED = 13
C_BIGINT_UNSIGNED = 14
# NULL value definition
# NOTE: These values should change according to C definition in tsdb.h
C_BOOL_NULL = 0x02
C_TINYINT_NULL = -128
C_TINYINT_UNSIGNED_NULL = 255
C_SMALLINT_NULL = -32768
C_SMALLINT_UNSIGNED_NULL = 65535
C_INT_NULL = -2147483648
C_INT_UNSIGNED_NULL = 4294967295
C_BIGINT_NULL = -9223372036854775808
C_BIGINT_UNSIGNED_NULL = 18446744073709551615
C_FLOAT_NULL = float('nan')
C_DOUBLE_NULL = float('nan')
C_BINARY_NULL = bytearray([int('0xff', 16)])
......
......@@ -5,6 +5,7 @@ import threading
# querySeqNum = 0
class TDengineCursor(object):
"""Database cursor which is used to manage the context of a fetch operation.
......@@ -23,7 +24,7 @@ class TDengineCursor(object):
if the cursor has not had an operation invoked via the .execute*() method yet.
.rowcount:This read-only attribute specifies the number of rows that the last
.execute*() produced (for DQL statements like SELECT) or affected
.execute*() produced (for DQL statements like SELECT) or affected
"""
def __init__(self, connection=None):
......@@ -50,13 +51,14 @@ class TDengineCursor(object):
raise OperationalError("Invalid use of fetch iterator")
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:
raise StopIteration
self._block = list(map(tuple, zip(*block)))
self._block_iter = 0
data = self._block[self._block_iter]
data = self._block[self._block_iter]
self._block_iter += 1
return data
......@@ -91,7 +93,7 @@ class TDengineCursor(object):
"""
if self._connection is None:
return False
self._reset_result()
self._connection = None
......@@ -106,19 +108,20 @@ class TDengineCursor(object):
if not self._connection:
# TODO : change the exception raised here
raise ProgrammingError("Cursor is not connected")
self._reset_result()
stmt = operation
if params is not None:
pass
self._result = CTaosInterface.query(self._connection._conn, stmt)
errno = CTaosInterface.libtaos.taos_errno(self._result)
if errno == 0:
if CTaosInterface.fieldsCount(self._result) == 0:
self._affected_rows += CTaosInterface.affectedRows(self._result)
return CTaosInterface.affectedRows(self._result )
self._affected_rows += CTaosInterface.affectedRows(
self._result)
return CTaosInterface.affectedRows(self._result)
else:
self._fields = CTaosInterface.useResult(self._result)
return self._handle_result()
......@@ -147,17 +150,20 @@ class TDengineCursor(object):
buffer = [[] for i in range(len(self._fields))]
self._rowcount = 0
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)
if errno != 0:
raise ProgrammingError(CTaosInterface.errStr(self._result), errno)
raise ProgrammingError(
CTaosInterface.errStr(
self._result), errno)
if num_of_fields == 0:
break
self._rowcount += num_of_fields
for i in range(len(self._fields)):
buffer[i].extend(block[i])
return list(map(tuple, zip(*buffer)))
def fetchall(self):
if self._result is None or self._fields is None:
raise OperationalError("Invalid use of fetchall")
......@@ -165,20 +171,21 @@ class TDengineCursor(object):
buffer = [[] for i in range(len(self._fields))]
self._rowcount = 0
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)
if errno != 0:
raise ProgrammingError(CTaosInterface.errStr(self._result), errno)
if num_of_fields == 0: break
raise ProgrammingError(
CTaosInterface.errStr(
self._result), errno)
if num_of_fields == 0:
break
self._rowcount += num_of_fields
for i in range(len(self._fields)):
buffer[i].extend(block[i])
return list(map(tuple, zip(*buffer)))
def nextset(self):
"""
"""
......@@ -209,6 +216,7 @@ class TDengineCursor(object):
"""
self._description = []
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
......@@ -4,6 +4,7 @@
import time
import datetime
class DBAPITypeObject(object):
def __init__(self, *values):
self.values = values
......@@ -16,23 +17,28 @@ class DBAPITypeObject(object):
else:
return -1
Date = datetime.date
Time = datetime.time
Timestamp = datetime.datetime
def DataFromTicks(ticks):
return Date(*time.localtime(ticks)[:3])
def TimeFromTicks(ticks):
return Time(*time.localtime(ticks)[3:6])
def TimestampFromTicks(ticks):
return Timestamp(*time.localtime(ticks)[:6])
Binary = bytes
# STRING = DBAPITypeObject(*constants.FieldType.get_string_types())
# BINARY = DBAPITypeObject(*constants.FieldType.get_binary_types())
# NUMBER = BAPITypeObject(*constants.FieldType.get_number_types())
# DATETIME = DBAPITypeObject(*constants.FieldType.get_timestamp_types())
# ROWID = DBAPITypeObject()
\ No newline at end of file
# ROWID = DBAPITypeObject()
"""Python exceptions
"""
class Error(Exception):
def __init__(self, msg=None, errno=None):
self.msg = msg
self._full_msg = self.msg
self.errno = errno
def __str__(self):
return self._full_msg
class Warning(Exception):
"""Exception raised for important warnings like data truncations while inserting.
"""
pass
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
class DatabaseError(Error):
"""Exception raised for errors that are related to the database.
"""Exception raised for errors that are related to the database.
"""
pass
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.
"""
pass
class OperationalError(DatabaseError):
"""Exception raised for errors that are related to the database's operation and not necessarily under the control of the programmer
"""
......@@ -41,17 +47,20 @@ class IntegrityError(DatabaseError):
"""
pass
class InternalError(DatabaseError):
"""Exception raised when the database encounters an internal error.
"""
pass
class ProgrammingError(DatabaseError):
"""Exception raised for programming errors.
"""
pass
class NotSupportedError(DatabaseError):
"""Exception raised in case a method or database API was used which is not supported by the database,.
"""
pass
\ No newline at end of file
pass
from .cinterface import CTaosInterface
from .error import *
class TDengineSubscription(object):
"""TDengine subscription object
"""
def __init__(self, sub):
self._sub = sub
def consume(self):
"""Consume rows of a subscription
"""
if self._sub is None:
raise OperationalError("Invalid use of consume")
result, fields = CTaosInterface.consume(self._sub)
buffer = [[] for i in range(len(fields))]
while True:
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)):
buffer[i].extend(block[i])
self.fields = fields
return list(map(tuple, zip(*buffer)))
def close(self, keepProgress = True):
def close(self, keepProgress=True):
"""Close the Subscription.
"""
if self._sub is None:
......@@ -38,15 +39,19 @@ class TDengineSubscription(object):
if __name__ == '__main__':
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
sub = conn.subscribe(True, "test", "select * from meters;", 1000)
for i in range(0,10):
for i in range(0, 10):
data = sub.consume()
for d in data:
print(d)
sub.close()
conn.close()
\ No newline at end of file
conn.close()
......@@ -8,6 +8,7 @@ paramstyle = 'pyformat'
__all__ = ['connection', 'cursor']
def connect(*args, **kwargs):
""" Function to return a TDengine connector object
......
......@@ -4,11 +4,14 @@ from .error import *
import math
import datetime
def _convert_millisecond_to_datetime(milli):
return datetime.datetime.fromtimestamp(milli/1000.0)
return datetime.datetime.fromtimestamp(milli / 1000.0)
def _convert_microsecond_to_datetime(micro):
return datetime.datetime.fromtimestamp(micro/1000000.0)
return datetime.datetime.fromtimestamp(micro / 1000000.0)
def _crow_timestamp_to_python(data, num_of_rows, nbytes=None, micro=False):
"""Function to convert C bool row to python row
......@@ -18,170 +21,309 @@ def _crow_timestamp_to_python(data, num_of_rows, nbytes=None, micro=False):
_timestamp_converter = _convert_microsecond_to_datetime
if num_of_rows > 0:
return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)]))
return list(map(_timestamp_converter, ctypes.cast(
data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)]))
else:
return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)]))
return list(map(_timestamp_converter, ctypes.cast(
data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)]))
def _crow_bool_to_python(data, num_of_rows, nbytes=None, micro=False):
"""Function to convert C bool row to python row
"""
if num_of_rows > 0:
return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)] ]
return [
None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(
data, ctypes.POINTER(
ctypes.c_byte))[
:abs(num_of_rows)]]
else:
return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_bool))[:abs(num_of_rows)] ]
return [
None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(
data, ctypes.POINTER(
ctypes.c_bool))[
:abs(num_of_rows)]]
def _crow_tinyint_to_python(data, num_of_rows, nbytes=None, micro=False):
"""Function to convert C tinyint row to python row
"""
if num_of_rows > 0:
return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)] ]
return [None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)]]
else:
return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)] ]
return [None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)]]
def _crow_tinyint_unsigned_to_python(
data,
num_of_rows,
nbytes=None,
micro=False):
"""Function to convert C tinyint row to python row
"""
if num_of_rows > 0:
return [
None if ele == FieldType.C_TINYINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(
ctypes.c_ubyte))[
:abs(num_of_rows)]]
else:
return [
None if ele == FieldType.C_TINYINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(
ctypes.c_ubyte))[
:abs(num_of_rows)]]
def _crow_smallint_to_python(data, num_of_rows, nbytes=None, micro=False):
"""Function to convert C smallint row to python row
"""
if num_of_rows > 0:
return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)]]
return [
None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(
ctypes.c_short))[
:abs(num_of_rows)]]
else:
return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)] ]
return [
None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(
ctypes.c_short))[
:abs(num_of_rows)]]
def _crow_smallint_unsigned_to_python(
data, num_of_rows, nbytes=None, micro=False):
"""Function to convert C smallint row to python row
"""
if num_of_rows > 0:
return [
None if ele == FieldType.C_SMALLINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(
ctypes.c_ushort))[
:abs(num_of_rows)]]
else:
return [
None if ele == FieldType.C_SMALLINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(
ctypes.c_ushort))[
:abs(num_of_rows)]]
def _crow_int_to_python(data, num_of_rows, nbytes=None, micro=False):
"""Function to convert C int row to python row
"""
if num_of_rows > 0:
return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)] ]
return [None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)]]
else:
return [None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)]]
def _crow_int_unsigned_to_python(data, num_of_rows, nbytes=None, micro=False):
"""Function to convert C int row to python row
"""
if num_of_rows > 0:
return [
None if ele == FieldType.C_INT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(
ctypes.c_uint))[
:abs(num_of_rows)]]
else:
return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)] ]
return [
None if ele == FieldType.C_INT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(
ctypes.c_uint))[
:abs(num_of_rows)]]
def _crow_bigint_to_python(data, num_of_rows, nbytes=None, micro=False):
"""Function to convert C bigint row to python row
"""
if num_of_rows > 0:
return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)] ]
return [None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)]]
else:
return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)] ]
return [None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)]]
def _crow_bigint_unsigned_to_python(
data,
num_of_rows,
nbytes=None,
micro=False):
"""Function to convert C bigint row to python row
"""
if num_of_rows > 0:
return [
None if ele == FieldType.C_BIGINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(
ctypes.c_ulong))[
:abs(num_of_rows)]]
else:
return [
None if ele == FieldType.C_BIGINT_UNSIGNED_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(
ctypes.c_ulong))[
:abs(num_of_rows)]]
def _crow_float_to_python(data, num_of_rows, nbytes=None, micro=False):
"""Function to convert C float row to python row
"""
if num_of_rows > 0:
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)] ]
return [None if math.isnan(ele) else ele for ele in ctypes.cast(
data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)]]
else:
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)] ]
return [None if math.isnan(ele) else ele for ele in ctypes.cast(
data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)]]
def _crow_double_to_python(data, num_of_rows, nbytes=None, micro=False):
"""Function to convert C double row to python row
"""
if num_of_rows > 0:
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)] ]
return [None if math.isnan(ele) else ele for ele in ctypes.cast(
data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)]]
else:
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)] ]
return [None if math.isnan(ele) else ele for ele in ctypes.cast(
data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)]]
def _crow_binary_to_python(data, num_of_rows, nbytes=None, micro=False):
"""Function to convert C binary row to python row
"""
assert(nbytes is not None)
if num_of_rows > 0:
return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]]
return [None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode(
'utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]]
else:
return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]]
return [None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode(
'utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]]
def _crow_nchar_to_python(data, num_of_rows, nbytes=None, micro=False):
"""Function to convert C nchar row to python row
"""
assert(nbytes is not None)
res = []
for i in range(abs(num_of_rows)):
try:
if num_of_rows >= 0:
tmpstr = ctypes.c_char_p(data)
res.append( tmpstr.value.decode() )
res.append(tmpstr.value.decode())
else:
res.append( (ctypes.cast(data+nbytes*i, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[0].value )
res.append((ctypes.cast(data + nbytes * i,
ctypes.POINTER(ctypes.c_wchar * (nbytes // 4))))[0].value)
except ValueError:
res.append(None)
return res
def _crow_binary_to_python_block(data, num_of_rows, nbytes=None, micro=False):
"""Function to convert C binary row to python row
"""
assert(nbytes is not None)
res=[]
res = []
if num_of_rows > 0:
for i in range(abs(num_of_rows)):
try:
rbyte=ctypes.cast(data+nbytes*i,ctypes.POINTER(ctypes.c_short))[:1].pop()
tmpstr = ctypes.c_char_p(data+nbytes*i+2)
res.append( tmpstr.value.decode()[0:rbyte] )
rbyte = ctypes.cast(
data + nbytes * i,
ctypes.POINTER(
ctypes.c_short))[
:1].pop()
tmpstr = ctypes.c_char_p(data + nbytes * i + 2)
res.append(tmpstr.value.decode()[0:rbyte])
except ValueError:
res.append(None)
else:
for i in range(abs(num_of_rows)):
try:
rbyte=ctypes.cast(data+nbytes*i,ctypes.POINTER(ctypes.c_short))[:1].pop()
tmpstr = ctypes.c_char_p(data+nbytes*i+2)
res.append( tmpstr.value.decode()[0:rbyte] )
rbyte = ctypes.cast(
data + nbytes * i,
ctypes.POINTER(
ctypes.c_short))[
:1].pop()
tmpstr = ctypes.c_char_p(data + nbytes * i + 2)
res.append(tmpstr.value.decode()[0:rbyte])
except ValueError:
res.append(None)
return res
def _crow_nchar_to_python_block(data, num_of_rows, nbytes=None, micro=False):
"""Function to convert C nchar row to python row
"""
assert(nbytes is not None)
res=[]
res = []
if num_of_rows >= 0:
for i in range(abs(num_of_rows)):
try:
tmpstr = ctypes.c_char_p(data+nbytes*i+2)
res.append( tmpstr.value.decode() )
tmpstr = ctypes.c_char_p(data + nbytes * i + 2)
res.append(tmpstr.value.decode())
except ValueError:
res.append(None)
else:
for i in range(abs(num_of_rows)):
try:
res.append( (ctypes.cast(data+nbytes*i+2, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[0].value )
res.append((ctypes.cast(data + nbytes * i + 2,
ctypes.POINTER(ctypes.c_wchar * (nbytes // 4))))[0].value)
except ValueError:
res.append(None)
return res
_CONVERT_FUNC = {
FieldType.C_BOOL: _crow_bool_to_python,
FieldType.C_TINYINT : _crow_tinyint_to_python,
FieldType.C_SMALLINT : _crow_smallint_to_python,
FieldType.C_INT : _crow_int_to_python,
FieldType.C_BIGINT : _crow_bigint_to_python,
FieldType.C_FLOAT : _crow_float_to_python,
FieldType.C_DOUBLE : _crow_double_to_python,
FieldType.C_TINYINT: _crow_tinyint_to_python,
FieldType.C_SMALLINT: _crow_smallint_to_python,
FieldType.C_INT: _crow_int_to_python,
FieldType.C_BIGINT: _crow_bigint_to_python,
FieldType.C_FLOAT: _crow_float_to_python,
FieldType.C_DOUBLE: _crow_double_to_python,
FieldType.C_BINARY: _crow_binary_to_python,
FieldType.C_TIMESTAMP : _crow_timestamp_to_python,
FieldType.C_NCHAR : _crow_nchar_to_python
FieldType.C_TIMESTAMP: _crow_timestamp_to_python,
FieldType.C_NCHAR: _crow_nchar_to_python,
FieldType.C_TINYINT_UNSIGNED: _crow_tinyint_unsigned_to_python,
FieldType.C_SMALLINT_UNSIGNED: _crow_smallint_unsigned_to_python,
FieldType.C_INT_UNSIGNED: _crow_int_unsigned_to_python,
FieldType.C_BIGINT_UNSIGNED: _crow_bigint_unsigned_to_python
}
_CONVERT_FUNC_BLOCK = {
FieldType.C_BOOL: _crow_bool_to_python,
FieldType.C_TINYINT : _crow_tinyint_to_python,
FieldType.C_SMALLINT : _crow_smallint_to_python,
FieldType.C_INT : _crow_int_to_python,
FieldType.C_BIGINT : _crow_bigint_to_python,
FieldType.C_FLOAT : _crow_float_to_python,
FieldType.C_DOUBLE : _crow_double_to_python,
FieldType.C_TINYINT: _crow_tinyint_to_python,
FieldType.C_SMALLINT: _crow_smallint_to_python,
FieldType.C_INT: _crow_int_to_python,
FieldType.C_BIGINT: _crow_bigint_to_python,
FieldType.C_FLOAT: _crow_float_to_python,
FieldType.C_DOUBLE: _crow_double_to_python,
FieldType.C_BINARY: _crow_binary_to_python_block,
FieldType.C_TIMESTAMP : _crow_timestamp_to_python,
FieldType.C_NCHAR : _crow_nchar_to_python_block
FieldType.C_TIMESTAMP: _crow_timestamp_to_python,
FieldType.C_NCHAR: _crow_nchar_to_python_block,
FieldType.C_TINYINT_UNSIGNED: _crow_tinyint_unsigned_to_python,
FieldType.C_SMALLINT_UNSIGNED: _crow_smallint_unsigned_to_python,
FieldType.C_INT_UNSIGNED: _crow_int_unsigned_to_python,
FieldType.C_BIGINT_UNSIGNED: _crow_bigint_unsigned_to_python
}
# Corresponding TAOS_FIELD structure in C
class TaosField(ctypes.Structure):
_fields_ = [('name', ctypes.c_char * 65),
('type', ctypes.c_char),
('bytes', ctypes.c_short)]
# C interface class
class CTaosInterface(object):
libtaos = ctypes.windll.LoadLibrary('taos')
......@@ -218,7 +360,7 @@ class CTaosInterface(object):
except AttributeError:
raise AttributeError("config is expected as a str")
if config != None:
if config is not None:
CTaosInterface.libtaos.taos_options(3, self._config)
CTaosInterface.libtaos.taos_init()
......@@ -229,7 +371,13 @@ class CTaosInterface(object):
"""
return self._config
def connect(self, host=None, user="root", password="taosdata", db=None, port=0):
def connect(
self,
host=None,
user="root",
password="taosdata",
db=None,
port=0):
'''
Function to connect to server
......@@ -238,7 +386,7 @@ class CTaosInterface(object):
# host
try:
_host = ctypes.c_char_p(host.encode(
"utf-8")) if host != None else ctypes.c_char_p(None)
"utf-8")) if host is not None else ctypes.c_char_p(None)
except AttributeError:
raise AttributeError("host is expected as a str")
......@@ -257,7 +405,7 @@ class CTaosInterface(object):
# db
try:
_db = ctypes.c_char_p(
db.encode("utf-8")) if db != None else ctypes.c_char_p(None)
db.encode("utf-8")) if db is not None else ctypes.c_char_p(None)
except AttributeError:
raise AttributeError("db is expected as a str")
......@@ -270,11 +418,11 @@ class CTaosInterface(object):
connection = ctypes.c_void_p(CTaosInterface.libtaos.taos_connect(
_host, _user, _password, _db, _port))
if connection.value == None:
if connection.value is None:
print('connect to TDengine failed')
raise ConnectionError("connect to TDengine failed")
# sys.exit(1)
#else:
# else:
# print('connect to TDengine success')
return connection
......@@ -295,7 +443,8 @@ class CTaosInterface(object):
@rtype: 0 on success and -1 on failure
'''
try:
return CTaosInterface.libtaos.taos_query(connection, ctypes.c_char_p(sql.encode('utf-8')))
return CTaosInterface.libtaos.taos_query(
connection, ctypes.c_char_p(sql.encode('utf-8')))
except AttributeError:
raise AttributeError("sql is expected as a string")
# finally:
......@@ -310,7 +459,7 @@ class CTaosInterface(object):
@staticmethod
def subscribe(connection, restart, topic, sql, interval):
"""Create a subscription
@restart boolean,
@restart boolean,
@sql string, sql statement for data query, must be a 'select' statement.
@topic string, name of this subscription
"""
......@@ -362,35 +511,49 @@ class CTaosInterface(object):
result, ctypes.byref(pblock))
if num_of_rows == 0:
return None, 0
isMicro = (CTaosInterface.libtaos.taos_result_precision(result) == FieldType.C_TIMESTAMP_MICRO)
isMicro = (CTaosInterface.libtaos.taos_result_precision(
result) == FieldType.C_TIMESTAMP_MICRO)
blocks = [None] * len(fields)
fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result)
fieldLen = [ele for ele in ctypes.cast(fieldL, ctypes.POINTER(ctypes.c_int))[:len(fields)]]
fieldLen = [
ele for ele in ctypes.cast(
fieldL, ctypes.POINTER(
ctypes.c_int))[
:len(fields)]]
for i in range(len(fields)):
data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i]
if fields[i]['type'] not in _CONVERT_FUNC_BLOCK:
raise DatabaseError("Invalid data type returned from database")
blocks[i] = _CONVERT_FUNC_BLOCK[fields[i]['type']](data, num_of_rows, fieldLen[i], isMicro)
blocks[i] = _CONVERT_FUNC_BLOCK[fields[i]['type']](
data, num_of_rows, fieldLen[i], isMicro)
return blocks, abs(num_of_rows)
@staticmethod
def fetchRow(result, fields):
pblock = ctypes.c_void_p(0)
pblock = CTaosInterface.libtaos.taos_fetch_row(result)
if pblock :
pblock = CTaosInterface.libtaos.taos_fetch_row(result)
if pblock:
num_of_rows = 1
isMicro = (CTaosInterface.libtaos.taos_result_precision(result) == FieldType.C_TIMESTAMP_MICRO)
isMicro = (CTaosInterface.libtaos.taos_result_precision(
result) == FieldType.C_TIMESTAMP_MICRO)
blocks = [None] * len(fields)
fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result)
fieldLen = [ele for ele in ctypes.cast(fieldL, ctypes.POINTER(ctypes.c_int))[:len(fields)]]
fieldLen = [
ele for ele in ctypes.cast(
fieldL, ctypes.POINTER(
ctypes.c_int))[
:len(fields)]]
for i in range(len(fields)):
data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i]
if fields[i]['type'] not in _CONVERT_FUNC:
raise DatabaseError("Invalid data type returned from database")
raise DatabaseError(
"Invalid data type returned from database")
if data is None:
blocks[i] = [None]
else:
blocks[i] = _CONVERT_FUNC[fields[i]['type']](data, num_of_rows, fieldLen[i], isMicro)
blocks[i] = _CONVERT_FUNC[fields[i]['type']](
data, num_of_rows, fieldLen[i], isMicro)
else:
return None, 0
return blocks, abs(num_of_rows)
......@@ -476,4 +639,4 @@ if __name__ == '__main__':
print(data)
cinter.freeResult(result)
cinter.close(conn)
\ No newline at end of file
cinter.close(conn)
......@@ -2,9 +2,11 @@ from .cursor import TDengineCursor
from .subscription import TDengineSubscription
from .cinterface import CTaosInterface
class TDengineConnection(object):
""" TDengine connection object
"""
def __init__(self, *args, **kwargs):
self._conn = None
self._host = None
......@@ -30,7 +32,7 @@ class TDengineConnection(object):
# password
if 'password' in kwargs:
self._password = kwargs['password']
# database
if 'database' in kwargs:
self._database = kwargs['database']
......@@ -44,7 +46,12 @@ class TDengineConnection(object):
self._config = kwargs['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):
"""Close current connection.
......@@ -56,7 +63,8 @@ class TDengineConnection(object):
"""
if self._conn is None:
return None
sub = CTaosInterface.subscribe(self._conn, restart, topic, sql, interval)
sub = CTaosInterface.subscribe(
self._conn, restart, topic, sql, interval)
return TDengineSubscription(sub)
def cursor(self):
......@@ -81,7 +89,8 @@ class TDengineConnection(object):
"""
pass
if __name__ == "__main__":
conn = TDengineConnection(host='192.168.1.107')
conn.close()
print("Hello world")
\ No newline at end of file
print("Hello world")
......@@ -3,6 +3,7 @@
from .dbapi import *
class FieldType(object):
"""TDengine Field Types
"""
......@@ -18,13 +19,21 @@ class FieldType(object):
C_BINARY = 8
C_TIMESTAMP = 9
C_NCHAR = 10
C_TINYINT_UNSIGNED = 11
C_SMALLINT_UNSIGNED = 12
C_INT_UNSIGNED = 13
C_BIGINT_UNSIGNED = 14
# NULL value definition
# NOTE: These values should change according to C definition in tsdb.h
C_BOOL_NULL = 0x02
C_TINYINT_NULL = -128
C_TINYINT_UNSIGNED_NULL = 255
C_SMALLINT_NULL = -32768
C_SMALLINT_UNSIGNED_NULL = 65535
C_INT_NULL = -2147483648
C_INT_UNSIGNED_NULL = 4294967295
C_BIGINT_NULL = -9223372036854775808
C_BIGINT_UNSIGNED_NULL = 18446744073709551615
C_FLOAT_NULL = float('nan')
C_DOUBLE_NULL = float('nan')
C_BINARY_NULL = bytearray([int('0xff', 16)])
......
......@@ -24,7 +24,7 @@ class TDengineCursor(object):
if the cursor has not had an operation invoked via the .execute*() method yet.
.rowcount:This read-only attribute specifies the number of rows that the last
.execute*() produced (for DQL statements like SELECT) or affected
.execute*() produced (for DQL statements like SELECT) or affected
"""
def __init__(self, connection=None):
......@@ -51,13 +51,14 @@ class TDengineCursor(object):
raise OperationalError("Invalid use of fetch iterator")
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:
raise StopIteration
self._block = list(map(tuple, zip(*block)))
self._block_iter = 0
data = self._block[self._block_iter]
data = self._block[self._block_iter]
self._block_iter += 1
return data
......@@ -92,7 +93,7 @@ class TDengineCursor(object):
"""
if self._connection is None:
return False
self._reset_result()
self._connection = None
......@@ -107,24 +108,25 @@ class TDengineCursor(object):
if not self._connection:
# TODO : change the exception raised here
raise ProgrammingError("Cursor is not connected")
self._reset_result()
stmt = operation
if params is not None:
pass
self._result = CTaosInterface.query(self._connection._conn, stmt)
errno = CTaosInterface.libtaos.taos_errno(self._result)
if errno == 0:
if CTaosInterface.fieldsCount(self._result) == 0:
self._affected_rows += CTaosInterface.affectedRows(self._result )
return CTaosInterface.affectedRows(self._result )
self._affected_rows += CTaosInterface.affectedRows(
self._result)
return CTaosInterface.affectedRows(self._result)
else:
self._fields = CTaosInterface.useResult(self._result )
self._fields = CTaosInterface.useResult(self._result)
return self._handle_result()
else:
raise ProgrammingError(CTaosInterface.errStr(self._result ), errno)
raise ProgrammingError(CTaosInterface.errStr(self._result), errno)
def executemany(self, operation, seq_of_parameters):
"""Prepare a database operation (query or command) and then execute it against all parameter sequences or mappings found in the sequence seq_of_parameters.
......@@ -148,10 +150,13 @@ class TDengineCursor(object):
buffer = [[] for i in range(len(self._fields))]
self._rowcount = 0
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)
if errno != 0:
raise ProgrammingError(CTaosInterface.errStr(self._result), errno)
raise ProgrammingError(
CTaosInterface.errStr(
self._result), errno)
if num_of_fields == 0:
break
self._rowcount += num_of_fields
......@@ -166,20 +171,21 @@ class TDengineCursor(object):
buffer = [[] for i in range(len(self._fields))]
self._rowcount = 0
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)
if errno != 0:
raise ProgrammingError(CTaosInterface.errStr(self._result), errno)
if num_of_fields == 0: break
raise ProgrammingError(
CTaosInterface.errStr(
self._result), errno)
if num_of_fields == 0:
break
self._rowcount += num_of_fields
for i in range(len(self._fields)):
buffer[i].extend(block[i])
return list(map(tuple, zip(*buffer)))
def nextset(self):
"""
"""
......@@ -204,12 +210,13 @@ class TDengineCursor(object):
self._block_rows = -1
self._block_iter = 0
self._affected_rows = 0
def _handle_result(self):
"""Handle the return result from query.
"""
self._description = []
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
......@@ -4,6 +4,7 @@
import time
import datetime
class DBAPITypeObject(object):
def __init__(self, *values):
self.values = values
......@@ -16,23 +17,28 @@ class DBAPITypeObject(object):
else:
return -1
Date = datetime.date
Time = datetime.time
Timestamp = datetime.datetime
def DataFromTicks(ticks):
return Date(*time.localtime(ticks)[:3])
def TimeFromTicks(ticks):
return Time(*time.localtime(ticks)[3:6])
def TimestampFromTicks(ticks):
return Timestamp(*time.localtime(ticks)[:6])
Binary = bytes
# STRING = DBAPITypeObject(*constants.FieldType.get_string_types())
# BINARY = DBAPITypeObject(*constants.FieldType.get_binary_types())
# NUMBER = BAPITypeObject(*constants.FieldType.get_number_types())
# DATETIME = DBAPITypeObject(*constants.FieldType.get_timestamp_types())
# ROWID = DBAPITypeObject()
\ No newline at end of file
# ROWID = DBAPITypeObject()
"""Python exceptions
"""
class Error(Exception):
def __init__(self, msg=None, errno=None):
self.msg = msg
self._full_msg = self.msg
self.errno = errno
def __str__(self):
return self._full_msg
class Warning(Exception):
"""Exception raised for important warnings like data truncations while inserting.
"""
pass
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
class DatabaseError(Error):
"""Exception raised for errors that are related to the database.
"""Exception raised for errors that are related to the database.
"""
pass
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.
"""
pass
class OperationalError(DatabaseError):
"""Exception raised for errors that are related to the database's operation and not necessarily under the control of the programmer
"""
......@@ -41,17 +47,20 @@ class IntegrityError(DatabaseError):
"""
pass
class InternalError(DatabaseError):
"""Exception raised when the database encounters an internal error.
"""
pass
class ProgrammingError(DatabaseError):
"""Exception raised for programming errors.
"""
pass
class NotSupportedError(DatabaseError):
"""Exception raised in case a method or database API was used which is not supported by the database,.
"""
pass
\ No newline at end of file
pass
from .cinterface import CTaosInterface
from .error import *
class TDengineSubscription(object):
"""TDengine subscription object
"""
def __init__(self, sub):
self._sub = sub
def consume(self):
"""Consume rows of a subscription
"""
if self._sub is None:
raise OperationalError("Invalid use of consume")
result, fields = CTaosInterface.consume(self._sub)
buffer = [[] for i in range(len(fields))]
while True:
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)):
buffer[i].extend(block[i])
self.fields = fields
return list(map(tuple, zip(*buffer)))
def close(self, keepProgress = True):
def close(self, keepProgress=True):
"""Close the Subscription.
"""
if self._sub is None:
......@@ -38,15 +39,19 @@ class TDengineSubscription(object):
if __name__ == '__main__':
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
sub = conn.subscribe(True, "test", "select * from meters;", 1000)
for i in range(0,10):
for i in range(0, 10):
data = sub.consume()
for d in data:
print(d)
sub.close()
conn.close()
\ No newline at end of file
conn.close()
......@@ -155,6 +155,7 @@ void httpReleaseContext(HttpContext *pContext, bool clearRes) {
if (clearRes) {
httpClearParser(pContext->parser);
memset(&pContext->singleCmd, 0, sizeof(HttpSqlCmd));
}
HttpContext **ppContext = pContext->ppContext;
......@@ -185,9 +186,9 @@ void httpCloseContextByApp(HttpContext *pContext) {
pContext->parsed = false;
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;
} 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;
} else {
}
......
......@@ -229,7 +229,7 @@ static int32_t httpOnParseHeaderField(HttpParser *parser, const char *key, const
return 0;
}
else if (strncasecmp(key, "Connection: ", 12) == 0) {
else if (strncasecmp(key, "Connection", 10) == 0) {
if (strncasecmp(val, "Keep-Alive", 10) == 0) {
parser->keepAlive = HTTP_KEEPALIVE_ENABLE;
} else {
......
......@@ -67,7 +67,7 @@
<dependency>
<groupId>com.taosdata.jdbc</groupId>
<artifactId>taos-jdbcdriver</artifactId>
<version>2.0.18</version>
<version>2.0.19</version>
<!-- <scope>system</scope>-->
<!-- <systemPath>${project.basedir}/src/main/resources/lib/taos-jdbcdriver-2.0.15-dist.jar</systemPath>-->
</dependency>
......
......@@ -4,6 +4,7 @@ import com.taosdata.taosdemo.components.DataSourceFactory;
import com.taosdata.taosdemo.components.JdbcTaosdemoConfig;
import com.taosdata.taosdemo.domain.SuperTableMeta;
import com.taosdata.taosdemo.service.DatabaseService;
import com.taosdata.taosdemo.service.QueryService;
import com.taosdata.taosdemo.service.SubTableService;
import com.taosdata.taosdemo.service.SuperTableService;
import com.taosdata.taosdemo.service.data.SuperTableMetaGenerator;
......@@ -34,6 +35,7 @@ public class TaosDemoApplication {
final DatabaseService databaseService = new DatabaseService(dataSource);
final SuperTableService superTableService = new SuperTableService(dataSource);
final SubTableService subTableService = new SubTableService(dataSource);
final QueryService queryService = new QueryService(dataSource);
// 创建数据库
long start = System.currentTimeMillis();
Map<String, String> databaseParam = new HashMap<>();
......@@ -90,6 +92,11 @@ public class TaosDemoApplication {
int affectedRows = subTableService.insertMultiThreads(superTableMeta, threadSize, tableSize, startTime, gap, config);
end = System.currentTimeMillis();
logger.info("insert " + affectedRows + " rows, time cost: " + (end - start) + " ms");
/**********************************************************************************/
// 查询
/**********************************************************************************/
// 删除表
if (config.dropTable) {
......
......@@ -23,7 +23,6 @@ public class DataSourceFactory {
properties.load(is);
HikariConfig config = new HikariConfig();
if (properties.containsKey("jdbc.driver")) {
// String driverName = properties.getProperty("jdbc.driver");
// System.out.println(">>> load driver : " + driverName);
......
package com.taosdata.taosdemo.service;
import com.taosdata.jdbc.utils.SqlSyntaxValidator;
import javax.sql.DataSource;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class QueryService {
private final DataSource dataSource;
public QueryService(DataSource dataSource) {
this.dataSource = dataSource;
}
/* only select or show SQL Statement is valid for executeQuery */
public Boolean[] areValidQueries(String[] sqls) {
Boolean[] ret = new Boolean[sqls.length];
for (int i = 0; i < sqls.length; i++) {
ret[i] = true;
if (!SqlSyntaxValidator.isValidForExecuteQuery(sqls[i])) {
ret[i] = false;
continue;
}
try (Connection conn = dataSource.getConnection(); Statement stmt = conn.createStatement()) {
stmt.executeQuery(sqls[i]);
} catch (SQLException e) {
ret[i] = false;
continue;
}
}
return ret;
}
public String[] generateSuperTableQueries(String dbName) {
List<String> sqls = new ArrayList<>();
try (Connection conn = dataSource.getConnection(); Statement stmt = conn.createStatement()) {
stmt.execute("use " + dbName);
ResultSet rs = stmt.executeQuery("show stables");
while (rs.next()) {
String name = rs.getString("name");
sqls.add("select count(*) from " + dbName + "." + name);
sqls.add("select first(*) from " + dbName + "." + name);
sqls.add("select last(*) from " + dbName + "." + name);
sqls.add("select last_row(*) from " + dbName + "." + name);
}
} catch (SQLException e) {
e.printStackTrace();
}
String[] sqlArr = new String[sqls.size()];
return sqls.toArray(sqlArr);
}
public void querySuperTable(String[] sqls, int interval, int threadCount, long queryTimes) {
List<Thread> threads = IntStream.range(0, threadCount).mapToObj(i -> new Thread(() -> {
// do query
try (Connection conn = dataSource.getConnection(); Statement stmt = conn.createStatement()) {
long count = queryTimes;
if (count == 0)
count = Long.MAX_VALUE;
while (count > 0) {
for (String sql : sqls) {
long start = System.currentTimeMillis();
ResultSet rs = stmt.executeQuery(sql);
printResultSet(rs);
long end = System.currentTimeMillis();
long timecost = end - start;
if (interval - timecost > 0) {
TimeUnit.MILLISECONDS.sleep(interval - timecost);
}
}
count--;
}
} catch (SQLException | InterruptedException e) {
e.printStackTrace();
}
})).collect(Collectors.toList());
threads.stream().forEach(Thread::start);
for (Thread thread : threads) {
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void printResultSet(ResultSet rs) throws SQLException {
ResultSetMetaData meta = rs.getMetaData();
while (rs.next()) {
for (int i = 1; i <= meta.getColumnCount(); i++) {
System.out.print(meta.getColumnLabel(i) + ": " + rs.getString(i) + "\t");
}
System.out.println();
}
}
}
......@@ -2,7 +2,6 @@ package com.taosdata.taosdemo.service;
import com.taosdata.taosdemo.dao.TableMapper;
import com.taosdata.taosdemo.domain.TableMeta;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
......
......@@ -7,10 +7,10 @@
"password": "taosdata",
"databases": "db01",
"super_table_query":
{"rate":1, "concurrent":1,
{"rate":1, "concurrent":1,"time":10000,
"sqls": [{"sql": "select count(*) from stb01", "result": "./query_res0.txt"}]
},
"sub_table_query":
"sub_table_query":
{"stblname": "stb01", "rate":1, "threads":1,
"sqls": [{"sql": "select count(*) from xxxx", "result": "./query_res1.txt"}]
}
......
package com.taosdata.taosdemo.service;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import org.junit.BeforeClass;
import org.junit.Test;
public class QueryServiceTest {
private static QueryService queryService;
@Test
public void areValidQueries() {
}
@Test
public void generateSuperTableQueries() {
String[] sqls = queryService.generateSuperTableQueries("restful_test");
for (String sql : sqls) {
System.out.println(sql);
}
}
@Test
public void querySuperTable() {
String[] sqls = queryService.generateSuperTableQueries("restful_test");
queryService.querySuperTable(sqls, 1000, 10, 10);
}
@BeforeClass
public static void beforeClass() throws ClassNotFoundException {
Class.forName("com.taosdata.jdbc.TSDBDriver");
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:TAOS://127.0.0.1:6030/?charset=UTF-8&locale=en_US.UTF-8&timezone=UTC-8");
config.setUsername("root");
config.setPassword("taosdata");
HikariDataSource dataSource = new HikariDataSource(config);
queryService = new QueryService(dataSource);
}
}
\ No newline at end of file
......@@ -56,9 +56,9 @@ function runGeneralCaseOneByOne {
case=`echo $line | grep sim$ |awk '{print $NF}'`
if [ -n "$case" ]; then
./test.sh -f $case > /dev/null 2>&1 && \
echo -e "${GREEN}$case success${NC}" | tee -a $TDENGINE_COVERAGE_REPORT || \
echo -e "${RED}$case failed${NC}" | tee -a $TDENGINE_COVERAGE_REPORT
date +%F\ %T | tee -a $TDENGINE_COVERAGE_REPORT && ./test.sh -f $case > /dev/null 2>&1 && \
( grep -q 'script.*success.*m$' ../../sim/tsim/log/taoslog0.0 && echo -e "${GREEN}$case success${NC}" | tee -a $TDENGINE_COVERAGE_REPORT ) \
|| echo -e "${RED}$case failed${NC}" | tee -a $TDENGINE_COVERAGE_REPORT
fi
fi
done < $1
......
......@@ -64,7 +64,7 @@ function runQueryPerfTest {
[ -f $PERFORMANCE_TEST_REPORT ] && rm $PERFORMANCE_TEST_REPORT
nohup $WORK_DIR/TDengine/debug/build/bin/taosd -c /etc/taosperf/ > /dev/null 2>&1 &
echoInfo "Wait TDengine to start"
sleep 60
sleep 120
echoInfo "Run Performance Test"
cd $WORK_DIR/TDengine/tests/pytest
......@@ -72,7 +72,7 @@ function runQueryPerfTest {
python3 insert/insertFromCSVPerformance.py -c $LOCAL_COMMIT | tee -a $PERFORMANCE_TEST_REPORT
yes | taosdemo -c /etc/taosperf/ -d taosdemo_insert_test -t 1000 -n 1000 > taosdemoperf.txt
yes | taosdemo -c /etc/taosperf/ -d taosdemo_insert_test -x > taosdemoperf.txt
CREATETABLETIME=`grep 'Spent' taosdemoperf.txt | awk 'NR==1{print $2}'`
INSERTRECORDSTIME=`grep 'Spent' taosdemoperf.txt | awk 'NR==2{print $2}'`
......
......@@ -26,7 +26,7 @@ class TDTestCase:
tdSql.prepare()
ret = tdSql.execute(
'create table tb (ts timestamp, speed bigint unsigned)')
'create table tb (ts timestamp, speed tinyint unsigned)')
insertRows = 10
tdLog.info("insert %d rows" % (insertRows))
......@@ -38,11 +38,11 @@ class TDTestCase:
tdLog.info("insert earlier data")
tdSql.execute('insert into tb values (now - 5m , NULL)')
tdSql.execute('insert into tb values (now - 6m , 10)')
tdSql.execute('insert into tb values (now - 7m , 10)')
tdSql.execute('insert into tb values (now - 8m , 18446744073709551614)')
tdSql.execute('insert into tb values (now - 7m , NULL)')
tdSql.execute('insert into tb values (now - 8m , 254)')
tdSql.error('insert into tb values (now - 9m, -1)')
#tdSql.error('insert into tb values (now - 9m, 4294967295)')
tdSql.error('insert into tb values (now - 9m, 255)')
tdSql.query("select * from tb")
tdSql.checkRows(insertRows + 4)
......
......@@ -41,7 +41,23 @@ class TDTestCase:
tdSql.query("select * from ampere")
tdSql.checkRows(2)
tdSql.checkData(0, 6, None)
tdSql.checkData(1, 6, 'test')
tdSql.checkData(1, 6, 'test')
# Test case for: https://jira.taosdata.com:18080/browse/TD-2423
tdSql.execute("create table stb(ts timestamp, col1 int, col2 nchar(20)) tags(tg1 int, tg2 binary(20), tg3 nchar(25))")
tdSql.execute("insert into tb1 using stb(tg1, tg3) tags(1, 'test1') values(now, 1, 'test1')")
tdSql.query("select *, tg1, tg2, tg3 from tb1")
tdSql.checkRows(1)
tdSql.checkData(0, 3, 1)
tdSql.checkData(0, 4, None)
tdSql.checkData(0, 5, 'test1')
tdSql.execute("create table tb2 using stb(tg3, tg2) tags('test3', 'test2')")
tdSql.query("select tg1, tg2, tg3 from tb2")
tdSql.checkRows(1)
tdSql.checkData(0, 0, None)
tdSql.checkData(0, 1, 'test2')
tdSql.checkData(0, 2, 'test3')
def stop(self):
tdSql.close()
......
......@@ -21,8 +21,8 @@ function runSimCaseOneByOne {
if [[ $line =~ ^./test.sh* ]] || [[ $line =~ ^run* ]]; then
case=`echo $line | grep sim$ |awk '{print $NF}'`
IN_TDINTERNAL="community"
start_time=`date +%s`
IN_TDINTERNAL="community"
start_time=`date +%s`
date +%F\ %T | tee -a out.log
if [[ "$tests_dir" == *"$IN_TDINTERNAL"* ]]; then
echo -n $case
./test.sh -f $case > /dev/null 2>&1 && \
......@@ -53,6 +53,7 @@ function runSimCaseOneByOnefq {
start_time=`date +%s`
IN_TDINTERNAL="community"
date +%F\ %T | tee -a out.log
if [[ "$tests_dir" == *"$IN_TDINTERNAL"* ]]; then
echo -n $case
./test.sh -f $case > /dev/null 2>&1 && \
......@@ -94,6 +95,7 @@ function runPyCaseOneByOne {
case=`echo $line|awk '{print $NF}'`
fi
start_time=`date +%s`
date +%F\ %T | tee -a pytest-out.log
echo -n $case
$line > /dev/null 2>&1 && \
echo -e "${GREEN} success${NC}" | tee -a pytest-out.log || \
......@@ -122,6 +124,7 @@ function runPyCaseOneByOnefq {
case=`echo $line|awk '{print $NF}'`
fi
start_time=`date +%s`
date +%F\ %T | tee -a pytest-out.log
echo -n $case
$line > /dev/null 2>&1 && \
echo -e "${GREEN} success${NC}" | tee -a pytest-out.log || \
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册