提交 b5f990b4 编写于 作者: S Shengliang Guan

Merge remote-tracking branch 'origin/develop' into feature/sim

...@@ -40,14 +40,15 @@ def pre_test(){ ...@@ -40,14 +40,15 @@ def pre_test(){
sh ''' sh '''
cd ${WKC} cd ${WKC}
rm -rf * git checkout develop
git pull
git fetch
git checkout ${CHANGE_BRANCH}
git merge develop
cd ${WK} cd ${WK}
git reset --hard git reset --hard
git checkout develop git checkout develop
git pull git pull
cd ${WKC}
rm -rf *
mv ${WORKSPACE}/* .
cd ${WK} cd ${WK}
export TZ=Asia/Harbin export TZ=Asia/Harbin
date date
...@@ -85,7 +86,7 @@ pipeline { ...@@ -85,7 +86,7 @@ pipeline {
pre_test() pre_test()
sh ''' sh '''
cd ${WKC}/tests cd ${WKC}/tests
./test-all.sh pytest ./test-all.sh pytestfq
date''' date'''
} }
} }
...@@ -95,7 +96,7 @@ pipeline { ...@@ -95,7 +96,7 @@ pipeline {
pre_test() pre_test()
sh ''' sh '''
cd ${WKC}/tests cd ${WKC}/tests
./test-all.sh b1 ./test-all.sh b1fq
date''' date'''
} }
} }
...@@ -119,7 +120,7 @@ pipeline { ...@@ -119,7 +120,7 @@ pipeline {
sh ''' sh '''
date date
cd ${WKC}/tests cd ${WKC}/tests
./test-all.sh b2 ./test-all.sh b2fq
date date
''' '''
} }
...@@ -140,7 +141,7 @@ pipeline { ...@@ -140,7 +141,7 @@ pipeline {
sh ''' sh '''
date date
cd ${WKC}/tests cd ${WKC}/tests
./test-all.sh b3 ./test-all.sh b3fq
date''' date'''
} }
} }
......
# 连接器 # 连接器
TDengine提供了丰富的应用程序开发接口,其中包括C/C++、C# 、Java、Python、Go、Node.js、RESTful 等,便于用户快速开发应用。 TDengine提供了丰富的应用程序开发接口,其中包括C/C++、Java、Python、Go、Node.js、C# 、RESTful 等,便于用户快速开发应用。
![image-connecotr](../assets/connector.png) ![image-connecotr](../assets/connector.png)
目前TDengine的连接器可支持的平台广泛,目前包括:X64/X86/ARM64/ARM32/MIPS/Alpha等硬件平台,以及Linux/Win64/Win32等开发环境。对照矩阵如下: 目前TDengine的连接器可支持的平台广泛,包括:X64/X86/ARM64/ARM32/MIPS/Alpha等硬件平台,以及Linux/Win64/Win32等开发环境。对照矩阵如下:
| **CPU** | **X64 64bit** | **X64 64bit** | **X64 64bit** | **X86 32bit** | **ARM64** | **ARM32** | **MIPS 龙芯** | **Alpha 申威** | **X64 海光** | | **CPU** | **X64 64bit** | **X64 64bit** | **X64 64bit** | **X86 32bit** | **ARM64** | **ARM32** | **MIPS 龙芯** | **Alpha 申威** | **X64 海光** |
| ----------- | --------------- | --------------- | --------------- | --------------- | --------- | --------- | --------------- | ---------------- | -------------- | | ----------- | --------------- | --------------- | --------------- | --------------- | --------- | --------- | --------------- | ---------------- | -------------- |
| **OS** | **Linux** | **Win64** | **Win32** | **Win32** | **Linux** | **Linux** | **Linux** | **Linux** | **Linux** | | **OS** | **Linux** | **Win64** | **Win32** | **Win32** | **Linux** | **Linux** | **Linux** | **Linux** | **Linux** |
| **C/C++** | ● | ● | ● | ○ | ● | ● | ● | ● | ● | | **C/C++** | ● | ● | ● | ○ | ● | ● | ○ | ○ | ○ |
| **JDBC** | ● | ● | ● | ○ | ● | ● | ● | ● | ● | | **JDBC** | ● | ● | ● | ○ | ● | ● | ○ | ○ | ○ |
| **Python** | ● | ● | ● | ○ | ● | ● | ● | -- | ● | | **Python** | ● | ● | ● | ○ | ● | ● | ○ | -- | ○ |
| **Go** | ● | ● | ● | ○ | ● | ● | ○ | -- | -- | | **Go** | ● | ● | ● | ○ | ● | ● | ○ | -- | -- |
| **NodeJs** | ● | ● | ○ | ○ | ● | ● | ○ | -- | -- | | **NodeJs** | ● | ● | ○ | ○ | ● | ● | ○ | -- | -- |
| **C#** | ○ | ● | ● | ○ | ○ | ○ | ○ | -- | -- | | **C#** | ○ | ● | ● | ○ | ○ | ○ | ○ | -- | -- |
| **RESTful** | ● | ● | ● | ● | ● | ● | ● | ● | ● | | **RESTful** | ● | ● | ● | ● | ● | ● | ○ | ○ | ○ |
其中 ● 表示经过官方测试验证, ○ 表示非官方测试验证。 其中 ● 表示经过官方测试验证, ○ 表示非官方测试验证。
注意: 注意:
* 在没有安装TDengine服务端软件的系统中使用连接器(除RESTful外)访问 TDengine 数据库,需要安装相应版本的客户端安装包来使应用驱动(Linux系统中文件名为libtaos.so,Windows系统中为taos.dll)被安装在系统中,否则会产生无法找到相应库文件的错误。
* 所有执行 SQL 语句的 API,例如 C/C++ Connector 中的 `tao_query``taos_query_a``taos_subscribe` 等,以及其它语言中与它们对应的API,每次都只能执行一条 SQL 语句,如果实际参数中包含了多条语句,它们的行为是未定义的。 * 所有执行 SQL 语句的 API,例如 C/C++ Connector 中的 `tao_query``taos_query_a``taos_subscribe` 等,以及其它语言中与它们对应的API,每次都只能执行一条 SQL 语句,如果实际参数中包含了多条语句,它们的行为是未定义的。
* 升级到TDengine到2.0.8.0版本的用户,必须更新JDBC连接TDengine必须升级taos-jdbcdriver到2.0.12及以上。 * 升级到TDengine到2.0.8.0版本的用户,必须更新JDBC连接TDengine必须升级taos-jdbcdriver到2.0.12及以上。
## 安装连接器驱动步骤
服务器应该已经安装TDengine服务端安装包。连接器驱动安装步骤如下:
**Linux**
**1. 从涛思官网(https://www.taosdata.com/cn/all-downloads/)下载**
* X64硬件环境:TDengine-client-2.x.x.x-Linux-x64.tar.gz
* ARM64硬件环境:TDengine-client-2.x.x.x-Linux-aarch64.tar.gz
* ARM32硬件环境:TDengine-client-2.x.x.x-Linux-aarch32.tar.gz
**2. 解压缩软件包**
将软件包放置在当前用户可读写的任意目录下,然后执行下面的命令:
`tar -xzvf TDengine-client-xxxxxxxxx.tar.gz`
其中xxxxxxx需要替换为实际版本的字符串。
**3. 执行安装脚本**
解压软件包之后,会在解压目录下看到以下文件(目录):
*install_client.sh*:安装脚本,用于应用驱动程序
*taos.tar.gz*:应用驱动安装包
*driver*:TDengine应用驱动driver
*connector*: 各种编程语言连接器(go/grafanaplugin/nodejs/python/JDBC)
*examples*: 各种编程语言的示例程序(c/C#/go/JDBC/matlab/python/R)
运行install_client.sh进行安装
**4. 配置taos.cfg**
编辑taos.cfg文件(默认路径/etc/taos/taos.cfg),将firstEP修改为TDengine服务器的End Point,例如:h1.taos.com:6030
**提示: 如本机没有部署TDengine服务,仅安装了应用驱动,则taos.cfg中仅需配置firstEP,无需配置FQDN。**
**Windows x64/x86**
**1. 从涛思官网(https://www.taosdata.com/cn/all-downloads/)下载 :**
* X64硬件环境:TDengine-client-2.X.X.X-Windows-x64.exe
* X86硬件环境:TDengine-client-2.X.X.X-Windows-x86.exe
**2. 执行安装程序,按提示选择默认值,完成安装**
**3. 安装路径**
默认安装路径为:C:\TDengine,其中包括以下文件(目录):
*taos.exe*:taos shell命令行程序
*cfg* : 配置文件目录
*driver*: 应用驱动动态链接库
*examples*: 示例程序 bash/C/C#/go/JDBC/Python/Node.js
*include*: 头文件
*log* : 日志文件
*unins000.exe*: 卸载程序
**4. 配置taos.cfg**
编辑taos.cfg文件(默认路径C:\TDengine\cfg\taos.cfg),将firstEP修改为TDengine服务器的End Point,例如:h1.taos.com:6030
**提示:**
**1. 如利用FQDN连接服务器,必须确认本机网络环境DNS已配置好,或在hosts文件中添加FQDN寻址记录,如编辑C:\Windows\system32\drivers\etc\hosts,添加如下的记录:** **192.168.1.99 h1.taos.com**
**2.卸载:运行unins000.exe可卸载TDengine应用驱动。**
**安装验证**
以上安装和配置完成后,并确认TDengine服务已经正常启动运行,此时可以执行taos客户端进行登录。
**Linux环境:**
在linux shell下直接执行 taos,应该就能正常链接到tdegine服务,进入到taos shell界面,示例如下:
```mysql
$ taos
Welcome to the TDengine shell from Linux, Client Version:2.0.5.0
Copyright (c) 2017 by TAOS Data, Inc. All rights reserved.
taos> show databases;
name | created_time | ntables | vgroups | replica | quorum | days | keep1,keep2,keep(D) | cache(MB)| blocks | minrows | maxrows | wallevel | fsync | comp | precision | status |
=========================================================================================================================================================================================================================
test | 2020-10-14 10:35:48.617 | 10 | 1 | 1 | 1 | 2 | 3650,3650,3650 | 16| 6 | 100 | 4096 | 1 | 3000 | 2 | ms | ready |
log | 2020-10-12 09:08:21.651 | 4 | 1 | 1 | 1 | 10 | 30,30,30 | 1| 3 | 100 | 4096 | 1 | 3000 | 2 | us | ready |
Query OK, 2 row(s) in set (0.001198s)
taos>
```
**Windows(x64/x86)环境:**
在cmd下进入到c:\TDengine目录下直接执行 taos.exe,应该就能正常链接到tdegine服务,进入到taos shell界面,示例如下:
```mysql
C:\TDengine>taos
Welcome to the TDengine shell from Linux, Client Version:2.0.5.0
Copyright (c) 2017 by TAOS Data, Inc. All rights reserved.
taos> show databases;
name | created_time | ntables | vgroups | replica | quorum | days | keep1,keep2,keep(D) | cache(MB) | blocks | minrows | maxrows | wallevel | fsync | comp | precision | status |
===================================================================================================================================================================================================================================================================
test | 2020-10-14 10:35:48.617 | 10 | 1 | 1 | 1 | 2 | 3650,3650,3650 | 16 | 6 | 100 | 4096 | 1 | 3000 | 2 | ms | ready |
log | 2020-10-12 09:08:21.651 | 4 | 1 | 1 | 1 | 10 | 30,30,30 | 1 | 3 | 100 | 4096 | 1 | 3000 | 2 | us | ready |
Query OK, 2 row(s) in set (0.045000s)
taos>
```
## C/C++ Connector ## C/C++ Connector
**C/C++连接器支持的系统有**
| **CPU类型** | x64(64bit) | | | ARM64 | ARM32 |
| ------------ | ------------ | -------- | -------- | -------- | ---------- |
| **OS类型** | Linux | Win64 | Win32 | Linux | Linux |
| **支持与否** | **支持** | **支持** | **支持** | **支持** | **开发中** |
C/C++的API类似于MySQL的C API。应用程序使用时,需要包含TDengine头文件 _taos.h_(安装后,位于 _/usr/local/taos/include_): C/C++的API类似于MySQL的C API。应用程序使用时,需要包含TDengine头文件 _taos.h_(安装后,位于 _/usr/local/taos/include_):
```C ```C
#include <taos.h> #include <taos.h>
``` ```
在编译时需要链接TDengine动态库 _libtaos.so_ (安装后,位于 _/usr/local/taos/driver_,gcc编译时,请加上 -ltaos)。 注意:
如未特别说明,当API的返回值是整数时,_0_ 代表成功,其它是代表失败原因的错误码,当返回值是指针时, _NULL_ 表示失败。 * 在编译时需要链接TDengine动态库。Linux 为 *libtaos.so* ,安装后,位于 _/usr/local/taos/driver_。Windows为 taos.dll,安装后位于 *C:\TDengine*
* 如未特别说明,当API的返回值是整数时,_0_ 代表成功,其它是代表失败原因的错误码,当返回值是指针时, _NULL_ 表示失败。
使用C/C++连接器的示例代码请参见 https://github.com/taosdata/TDengine/tree/develop/tests/examples/c。
### 基础API ### 基础API
...@@ -45,22 +166,18 @@ C/C++的API类似于MySQL的C API。应用程序使用时,需要包含TDengine ...@@ -45,22 +166,18 @@ C/C++的API类似于MySQL的C API。应用程序使用时,需要包含TDengine
初始化运行环境。如果应用没有主动调用该API,那么应用在调用`taos_connect`时将自动调用,故应用程序一般无需手动调用该API。 初始化运行环境。如果应用没有主动调用该API,那么应用在调用`taos_connect`时将自动调用,故应用程序一般无需手动调用该API。
- `void taos_cleanup()` - `void taos_cleanup()`
清理运行环境,应用退出前应调用此API。 清理运行环境,应用退出前应调用此API。
- `int taos_options(TSDB_OPTION option, const void * arg, ...)` - `int taos_options(TSDB_OPTION option, const void * arg, ...)`
设置客户端选项,目前只支持时区设置(_TSDB_OPTION_TIMEZONE_)和编码设置(_TSDB_OPTION_LOCALE_)。时区和编码默认为操作系统当前设置。 设置客户端选项,目前只支持时区设置(_TSDB_OPTION_TIMEZONE_)和编码设置(_TSDB_OPTION_LOCALE_)。时区和编码默认为操作系统当前设置。
- `char *taos_get_client_info()` - `char *taos_get_client_info()`
获取客户端版本信息。 获取客户端版本信息。
- `TAOS *taos_connect(const char *ip, const char *user, const char *pass, const char *db, int port)` - `TAOS *taos_connect(const char *ip, const char *user, const char *pass, const char *db, int port)`
创建数据库连接,初始化连接上下文。其中需要用户提供的参数包含: 创建数据库连接,初始化连接上下文。其中需要用户提供的参数包含:
...@@ -73,23 +190,18 @@ C/C++的API类似于MySQL的C API。应用程序使用时,需要包含TDengine ...@@ -73,23 +190,18 @@ C/C++的API类似于MySQL的C API。应用程序使用时,需要包含TDengine
返回值为空表示失败。应用程序需要保存返回的参数,以便后续API调用。 返回值为空表示失败。应用程序需要保存返回的参数,以便后续API调用。
- `char *taos_get_server_info(TAOS *taos)` - `char *taos_get_server_info(TAOS *taos)`
获取服务端版本信息。 获取服务端版本信息。
- `int taos_select_db(TAOS *taos, const char *db)` - `int taos_select_db(TAOS *taos, const char *db)`
将当前的缺省数据库设置为`db` 将当前的缺省数据库设置为`db`
- `void taos_close(TAOS *taos)` - `void taos_close(TAOS *taos)`
关闭连接, 其中`taos``taos_connect`函数返回的指针。 关闭连接, 其中`taos``taos_connect`函数返回的指针。
### 同步查询API ### 同步查询API
传统的数据库操作API,都属于同步操作。应用调用API后,一直处于阻塞状态,直到服务器返回结果。TDengine支持如下API: 传统的数据库操作API,都属于同步操作。应用调用API后,一直处于阻塞状态,直到服务器返回结果。TDengine支持如下API:
...@@ -98,37 +210,30 @@ C/C++的API类似于MySQL的C API。应用程序使用时,需要包含TDengine ...@@ -98,37 +210,30 @@ C/C++的API类似于MySQL的C API。应用程序使用时,需要包含TDengine
该API用来执行SQL语句,可以是DQL、DML或DDL语句。 其中的`taos`参数是通过`taos_connect`获得的指针。返回值 NULL 表示失败。 该API用来执行SQL语句,可以是DQL、DML或DDL语句。 其中的`taos`参数是通过`taos_connect`获得的指针。返回值 NULL 表示失败。
- `int taos_result_precision(TAOS_RES *res)` - `int taos_result_precision(TAOS_RES *res)`
返回结果集时间戳字段的精度,`0` 代表毫秒,`1` 代表微秒,`2` 代表纳秒。 返回结果集时间戳字段的精度,`0` 代表毫秒,`1` 代表微秒,`2` 代表纳秒。
- `TAOS_ROW taos_fetch_row(TAOS_RES *res)` - `TAOS_ROW taos_fetch_row(TAOS_RES *res)`
按行获取查询结果集中的数据。 按行获取查询结果集中的数据。
- `int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows)` - `int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows)`
批量获取查询结果集中的数据,返回值为获取到的数据的行数。 批量获取查询结果集中的数据,返回值为获取到的数据的行数。
- `int taos_num_fields(TAOS_RES *res)``int taos_field_count(TAOS_RES *res)` - `int taos_num_fields(TAOS_RES *res)``int taos_field_count(TAOS_RES *res)`
这两个API等价,用于获取查询结果集中的列数。 这两个API等价,用于获取查询结果集中的列数。
- `int* taos_fetch_lengths(TAOS_RES *res)` - `int* taos_fetch_lengths(TAOS_RES *res)`
获取结果集中每个字段的长度。 返回值是一个数组,其长度为结果集的列数。 获取结果集中每个字段的长度。 返回值是一个数组,其长度为结果集的列数。
- `int taos_affected_rows(TAOS_RES *res)` - `int taos_affected_rows(TAOS_RES *res)`
获取被所执行的 SQL 语句影响的行数。 获取被所执行的 SQL 语句影响的行数。
- `TAOS_FIELD *taos_fetch_fields(TAOS_RES *res)` - `TAOS_FIELD *taos_fetch_fields(TAOS_RES *res)`
获取查询结果集每列数据的属性(数据类型、名字、字节数),与taos_num_fileds配合使用,可用来解析`taos_fetch_row`返回的一个元组(一行)的数据。 `TAOS_FIELD` 的结构如下: 获取查询结果集每列数据的属性(数据类型、名字、字节数),与taos_num_fileds配合使用,可用来解析`taos_fetch_row`返回的一个元组(一行)的数据。 `TAOS_FIELD` 的结构如下:
...@@ -141,30 +246,24 @@ C/C++的API类似于MySQL的C API。应用程序使用时,需要包含TDengine ...@@ -141,30 +246,24 @@ C/C++的API类似于MySQL的C API。应用程序使用时,需要包含TDengine
} TAOS_FIELD; } TAOS_FIELD;
``` ```
- `void taos_stop_query(TAOS_RES *res)` - `void taos_stop_query(TAOS_RES *res)`
停止一个查询的执行。 停止一个查询的执行。
- `void taos_free_result(TAOS_RES *res)` - `void taos_free_result(TAOS_RES *res)`
释放查询结果集以及相关的资源。查询完成后,务必调用该API释放资源,否则可能导致应用内存泄露。 释放查询结果集以及相关的资源。查询完成后,务必调用该API释放资源,否则可能导致应用内存泄露。
- `char *taos_errstr(TAOS_RES *res)` - `char *taos_errstr(TAOS_RES *res)`
获取最近一次API调用失败的原因,返回值为字符串。 获取最近一次API调用失败的原因,返回值为字符串。
- `char *taos_errno(TAOS_RES *res)` - `char *taos_errno(TAOS_RES *res)`
获取最近一次API调用失败的原因,返回值为错误代码。 获取最近一次API调用失败的原因,返回值为错误代码。
**注意**:对于每个数据库应用,2.0及以上版本 TDengine 推荐只建立一个连接。同时在应用中将该连接 (TAOS*) 结构体传递到不同的线程共享使用。基于 TAOS 结构体发出的查询、写入等操作具有多线程安全性。C 语言的连接器可以按照需求动态建立面向数据库的新连接(该过程对用户不可见),同时建议只有在程序最后退出的时候才调用 taos_close 关闭连接。 **注意**:对于每个数据库应用,2.0及以上版本 TDengine 推荐只建立一个连接。同时在应用中将该连接 (TAOS*) 结构体传递到不同的线程共享使用。基于 TAOS 结构体发出的查询、写入等操作具有多线程安全性。C 语言的连接器可以按照需求动态建立面向数据库的新连接(该过程对用户不可见),同时建议只有在程序最后退出的时候才调用 taos_close 关闭连接。
### 异步查询API ### 异步查询API
同步API之外,TDengine还提供性能更高的异步调用API处理数据插入、查询操作。在软硬件环境相同的情况下,异步API处理数据插入的速度比同步API快2~4倍。异步API采用非阻塞式的调用方式,在系统真正完成某个具体数据库操作前,立即返回。调用的线程可以去处理其他工作,从而可以提升整个应用的性能。异步API在网络延迟严重的情况下,优点尤为突出。 同步API之外,TDengine还提供性能更高的异步调用API处理数据插入、查询操作。在软硬件环境相同的情况下,异步API处理数据插入的速度比同步API快2~4倍。异步API采用非阻塞式的调用方式,在系统真正完成某个具体数据库操作前,立即返回。调用的线程可以去处理其他工作,从而可以提升整个应用的性能。异步API在网络延迟严重的情况下,优点尤为突出。
...@@ -189,7 +288,6 @@ C/C++的API类似于MySQL的C API。应用程序使用时,需要包含TDengine ...@@ -189,7 +288,6 @@ C/C++的API类似于MySQL的C API。应用程序使用时,需要包含TDengine
* res:`taos_query_a`回调时返回的结果集 * res:`taos_query_a`回调时返回的结果集
* fp:回调函数。其参数`param`是用户可定义的传递给回调函数的参数结构体;`numOfRows`是获取到的数据的行数(不是整个查询结果集的函数)。 在回调函数中,应用可以通过调用`taos_fetch_row`前向迭代获取批量记录中每一行记录。读完一块内的所有记录后,应用需要在回调函数中继续调用`taos_fetch_rows_a`获取下一批记录进行处理,直到返回的记录数(numOfRows)为零(结果返回完成)或记录数为负值(查询出错)。 * fp:回调函数。其参数`param`是用户可定义的传递给回调函数的参数结构体;`numOfRows`是获取到的数据的行数(不是整个查询结果集的函数)。 在回调函数中,应用可以通过调用`taos_fetch_row`前向迭代获取批量记录中每一行记录。读完一块内的所有记录后,应用需要在回调函数中继续调用`taos_fetch_rows_a`获取下一批记录进行处理,直到返回的记录数(numOfRows)为零(结果返回完成)或记录数为负值(查询出错)。
- `void taos_fetch_row_a(TAOS_RES *res, void (*fp)(void *param, TAOS_RES *, TAOS_ROW row), void *param);` - `void taos_fetch_row_a(TAOS_RES *res, void (*fp)(void *param, TAOS_RES *, TAOS_ROW row), void *param);`
异步获取一条记录。其中: 异步获取一条记录。其中:
...@@ -199,7 +297,6 @@ C/C++的API类似于MySQL的C API。应用程序使用时,需要包含TDengine ...@@ -199,7 +297,6 @@ C/C++的API类似于MySQL的C API。应用程序使用时,需要包含TDengine
TDengine的异步API均采用非阻塞调用模式。应用程序可以用多线程同时打开多张表,并可以同时对每张打开的表进行查询或者插入操作。需要指出的是,**客户端应用必须确保对同一张表的操作完全串行化**,即对同一个表的插入或查询操作未完成时(未返回时),不能够执行第二个插入或查询操作。 TDengine的异步API均采用非阻塞调用模式。应用程序可以用多线程同时打开多张表,并可以同时对每张打开的表进行查询或者插入操作。需要指出的是,**客户端应用必须确保对同一张表的操作完全串行化**,即对同一个表的插入或查询操作未完成时(未返回时),不能够执行第二个插入或查询操作。
### 参数绑定API ### 参数绑定API
除了直接调用 `taos_query` 进行查询,TDengine也提供了支持参数绑定的Prepare API,与 MySQL 一样,这些API目前也仅支持用问号`?`来代表待绑定的参数,具体如下: 除了直接调用 `taos_query` 进行查询,TDengine也提供了支持参数绑定的Prepare API,与 MySQL 一样,这些API目前也仅支持用问号`?`来代表待绑定的参数,具体如下:
...@@ -244,7 +341,6 @@ TDengine的异步API均采用非阻塞调用模式。应用程序可以用多线 ...@@ -244,7 +341,6 @@ TDengine的异步API均采用非阻塞调用模式。应用程序可以用多线
执行完毕,释放所有资源。 执行完毕,释放所有资源。
### 连续查询接口 ### 连续查询接口
TDengine提供时间驱动的实时流式计算API。可以每隔一指定的时间段,对一张或多张数据库的表(数据流)进行各种实时聚合计算操作。操作简单,仅有打开、关闭流的API。具体如下: TDengine提供时间驱动的实时流式计算API。可以每隔一指定的时间段,对一张或多张数据库的表(数据流)进行各种实时聚合计算操作。操作简单,仅有打开、关闭流的API。具体如下:
...@@ -261,12 +357,10 @@ TDengine提供时间驱动的实时流式计算API。可以每隔一指定的时 ...@@ -261,12 +357,10 @@ TDengine提供时间驱动的实时流式计算API。可以每隔一指定的时
返回值为NULL,表示创建成功,返回值不为空,表示成功。 返回值为NULL,表示创建成功,返回值不为空,表示成功。
- `void taos_close_stream (TAOS_STREAM *tstr)` - `void taos_close_stream (TAOS_STREAM *tstr)`
关闭数据流,其中提供的参数是taos_open_stream的返回值。用户停止流式计算的时候,务必关闭该数据流。 关闭数据流,其中提供的参数是taos_open_stream的返回值。用户停止流式计算的时候,务必关闭该数据流。
### 数据订阅接口 ### 数据订阅接口
订阅API目前支持订阅一张或多张表,并通过定期轮询的方式不断获取写入表中的最新数据。 订阅API目前支持订阅一张或多张表,并通过定期轮询的方式不断获取写入表中的最新数据。
...@@ -290,7 +384,6 @@ TDengine提供时间驱动的实时流式计算API。可以每隔一指定的时 ...@@ -290,7 +384,6 @@ TDengine提供时间驱动的实时流式计算API。可以每隔一指定的时
* param:调用 `taos_subscribe`时客户程序提供的附加参数 * param:调用 `taos_subscribe`时客户程序提供的附加参数
* code:错误码 * code:错误码
* `TAOS_RES *taos_consume(TAOS_SUB *tsub)` * `TAOS_RES *taos_consume(TAOS_SUB *tsub)`
同步模式下,该函数用来获取订阅的结果。 用户应用程序将其置于一个循环之中。 如两次调用`taos_consume`的间隔小于订阅的轮询周期,API将会阻塞,直到时间间隔超过此周期。 如果数据库有新记录到达,该API将返回该最新的记录,否则返回一个没有记录的空结果集。 如果返回值为 `NULL`,说明系统出错。 异步模式下,用户程序不应调用此API。 同步模式下,该函数用来获取订阅的结果。 用户应用程序将其置于一个循环之中。 如两次调用`taos_consume`的间隔小于订阅的轮询周期,API将会阻塞,直到时间间隔超过此周期。 如果数据库有新记录到达,该API将返回该最新的记录,否则返回一个没有记录的空结果集。 如果返回值为 `NULL`,说明系统出错。 异步模式下,用户程序不应调用此API。
...@@ -299,11 +392,10 @@ TDengine提供时间驱动的实时流式计算API。可以每隔一指定的时 ...@@ -299,11 +392,10 @@ TDengine提供时间驱动的实时流式计算API。可以每隔一指定的时
取消订阅。 如参数 `keepProgress` 不为0,API会保留订阅的进度信息,后续调用 `taos_subscribe` 时可以基于此进度继续;否则将删除进度信息,后续只能重新开始读取数据。 取消订阅。 如参数 `keepProgress` 不为0,API会保留订阅的进度信息,后续调用 `taos_subscribe` 时可以基于此进度继续;否则将删除进度信息,后续只能重新开始读取数据。
## Python Connector ## Python Connector
### 安装准备 ### 安装准备
* 已安装TDengine, 如果客户端在Windows上,需要安装Windows 版本的TDengine客户端 [(Windows TDengine 客户端安装)][4] * 应用驱动安装请参考<a href="https://www.taosdata.com/cn/documentation/connector/#安装连接器驱动步骤">安装连接器驱动步骤</a>
* 已安装python 2.7 or >= 3.4 * 已安装python 2.7 or >= 3.4
* 已安装pip 或 pip3 * 已安装pip 或 pip3
...@@ -323,12 +415,12 @@ TDengine提供时间驱动的实时流式计算API。可以每隔一指定的时 ...@@ -323,12 +415,12 @@ TDengine提供时间驱动的实时流式计算API。可以每隔一指定的时
在已安装Windows TDengine 客户端的情况下, 将文件"C:\TDengine\driver\taos.dll" 拷贝到 "C:\windows\system32" 目录下, 然后进入Windwos <em>cmd</em> 命令行界面 在已安装Windows TDengine 客户端的情况下, 将文件"C:\TDengine\driver\taos.dll" 拷贝到 "C:\windows\system32" 目录下, 然后进入Windwos <em>cmd</em> 命令行界面
```cmd ```cmd
cd C:\TDengine\connector\python\windows cd C:\TDengine\connector\python\windows
pip install python2\ python -m pip install python2\
``` ```
```cmd ```cmd
cd C:\TDengine\connector\python\windows cd C:\TDengine\connector\python\windows
pip install python3\ python -m pip install python3\
``` ```
*如果机器上没有pip命令,用户可将src/connector/python/python3或src/connector/python/python2下的taos文件夹拷贝到应用程序的目录使用。 *如果机器上没有pip命令,用户可将src/connector/python/python3或src/connector/python/python2下的taos文件夹拷贝到应用程序的目录使用。
...@@ -407,7 +499,6 @@ for d in data: ...@@ -407,7 +499,6 @@ for d in data:
sub.close() sub.close()
``` ```
* 关闭连接 * 关闭连接
```python ```python
c1.close() c1.close()
...@@ -431,7 +522,6 @@ conn.close() ...@@ -431,7 +522,6 @@ conn.close()
用于生成taos.TDengineConnection的实例。 用于生成taos.TDengineConnection的实例。
### Python客户端使用示例代码 ### Python客户端使用示例代码
在tests/examples/python中,我们提供了一个示例Python程序read_example.py,可以参考这个程序来设计用户自己的写入、查询程序。在安装了对应的客户端后,通过import taos引入taos类。主要步骤如下 在tests/examples/python中,我们提供了一个示例Python程序read_example.py,可以参考这个程序来设计用户自己的写入、查询程序。在安装了对应的客户端后,通过import taos引入taos类。主要步骤如下
...@@ -638,31 +728,39 @@ HTTP请求URL采用`sqlutc`时,返回结果集的时间戳将采用UTC时间 ...@@ -638,31 +728,39 @@ HTTP请求URL采用`sqlutc`时,返回结果集的时间戳将采用UTC时间
## CSharp Connector ## CSharp Connector
在Windows系统上,C#应用程序可以使用TDengine的原生C接口来执行所有数据库操作,后续版本将提供ORM(dapper)框架驱动。 C#连接器支持的系统有:Linux 64/Windows x64/Windows x86
#### 安装TDengine客户端 ### 安装准备
C#连接器需要使用`libtaos.so``taos.h`。因此,在使用C#连接器之前,需在程序运行的Windows环境安装TDengine的Windows客户端,以便获得相关驱动文件。 * 应用驱动安装请参考<a href="https://www.taosdata.com/cn/documentation/connector/#安装连接器驱动步骤">安装连接器驱动步骤</a>
* .NET接口文件TDengineDrivercs.cs和参考程序示例TDengineTest.cs均位于Windows客户端install_directory/examples/C#目录下。
* 在Windows系统上,C#应用程序可以使用TDengine的原生C接口来执行所有数据库操作,后续版本将提供ORM(dapper)框架驱动。
安装完成后,在文件夹`C:/TDengine/examples/C#`中,将会看到两个文件 ### 安装验证
- TDengineDriver.cs 调用taos.dll文件的Native C方法 运行install_directory/examples/C#/C#Checker/C#Checker.exe
- TDengineTest.cs 参考程序示例
在文件夹`C:\Windows\System32`,将会看到`taos.dll`文件 ```cmd
cd {install_directory}/examples/C#/C#Checker
csc /optimize *.cs
C#Checker.exe -h <fqdn>
```
### C#连接器的使用
在Windows系统上,.NET应用程序可以使用TDengine的.NET接口来执行所有数据库的操作。使用.NET接口的步骤如下所示:
#### 使用方法 1. 将.NET接口文件TDengineDrivercs.cs加入到应用程序所在.NET项目中。
2. 用户可以参考TDengineTest.cs来定义数据库连接参数,以及如何执行数据插入、查询等操作;
- 将C#接口文件TDengineDriver.cs加入到应用程序所在.NET项目中 此.NET接口需要用到taos.dll文件,所以在执行应用程序前,拷贝Windows客户端install_directory/driver目录中的taos.dll文件到.NET项目最后生成.exe可执行文件所在文件夹。之后运行exe文件,即可访问TDengine数据库并做插入、查询等操作。
- 参考TDengineTest.cs来定义数据库连接参数,及执行数据插入、查询等操作的方法
- 因为C#接口需要用到`taos.dll`文件,用户可以将`taos.dll`文件加入.NET解决方案中
#### 注意事项 **注意:**
- `taos.dll`文件使用x64平台编译,所以.NET项目在生成.exe文件时,“解决方案”/“项目”的“平台”请均选择“x64”。 1. TDengine V2.0.3.0之后同时支持32位和64位Windows系统,所以.NET项目在生成.exe文件时,“解决方案”/“项目”的“平台”请选择对应的“X86” 或“x64”。
- 此.NET接口目前已经在Visual Studio 2013/2015/2017中验证过,其它VS版本尚待验证。 2. 此.NET接口目前已经在Visual Studio 2015/2017中验证过,其它VS版本尚待验证。
#### 第三方驱动 ### 第三方驱动
Maikebing.Data.Taos是一个TDengine的ADO.Net提供器,支持linux,windows。该开发包由热心贡献者`麦壳饼@@maikebing`提供,具体请参考 Maikebing.Data.Taos是一个TDengine的ADO.Net提供器,支持linux,windows。该开发包由热心贡献者`麦壳饼@@maikebing`提供,具体请参考
...@@ -673,10 +771,15 @@ https://github.com/maikebing/Maikebing.EntityFrameworkCore.Taos ...@@ -673,10 +771,15 @@ https://github.com/maikebing/Maikebing.EntityFrameworkCore.Taos
https://www.taosdata.com/blog/2020/11/02/1901.html https://www.taosdata.com/blog/2020/11/02/1901.html
``` ```
## Go Connector ## Go Connector
TDengine提供了GO驱动程序`taosSql`. `taosSql`实现了GO语言的内置接口`database/sql/driver`。用户只需按如下方式引入包就可以在应用程序中访问TDengine, 详见`https://github.com/taosdata/driver-go/blob/develop/taosSql/driver_test.go` ### 安装准备
* 应用驱动安装请参考<a href="https://www.taosdata.com/cn/documentation/connector/#安装连接器驱动步骤">安装连接器驱动步骤</a>
TDengine提供了GO驱动程序`taosSql``taosSql`实现了GO语言的内置接口`database/sql/driver`。用户只需按如下方式引入包就可以在应用程序中访问TDengine, 详见`https://github.com/taosdata/driver-go/blob/develop/taosSql/driver_test.go`
使用 Go 连接器的示例代码请参考 https://github.com/taosdata/TDengine/tree/develop/tests/examples/go。
```Go ```Go
import ( import (
...@@ -684,9 +787,9 @@ import ( ...@@ -684,9 +787,9 @@ import (
_ "github.com/taosdata/driver-go/taosSql" _ "github.com/taosdata/driver-go/taosSql"
) )
``` ```
**建议Go版本是1.13或以上,并开启模块支持:** **建议使用Go版本1.13或以上,并开启模块支持:**
``` ```bash
go env -w GO111MODULE=on go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.io,direct go env -w GOPROXY=https://goproxy.io,direct
``` ```
...@@ -725,48 +828,86 @@ go env -w GOPROXY=https://goproxy.io,direct ...@@ -725,48 +828,86 @@ go env -w GOPROXY=https://goproxy.io,direct
## Node.js Connector ## Node.js Connector
TDengine 同时也提供了node.js 的连接器。用户可以通过[npm](https://www.npmjs.com/)来进行安装,也可以通过源代码*src/connector/nodejs/* 来进行安装。[具体安装步骤如下](https://github.com/taosdata/tdengine/tree/master/src/connector/nodejs): Node.js连接器支持的系统有:
| **CPU类型** | x64(64bit) | | | aarch64 | aarch32 |
| ------------ | ------------ | -------- | -------- | -------- | -------- |
| **OS类型** | Linux | Win64 | Win32 | Linux | Linux |
| **支持与否** | **支持** | **支持** | **支持** | **支持** | **支持** |
### 安装准备
* 应用驱动安装请参考<a href="https://www.taosdata.com/cn/documentation/connector/#安装连接器驱动步骤">安装连接器驱动步骤</a>。
首先,通过[npm](https://www.npmjs.com/)安装node.js 连接器. ### 安装Node.js连接器
用户可以通过<a href="https://www.npmjs.com/">npm</a>来进行安装,也可以通过源代码*src/connector/nodejs/* 来进行安装。具体安装步骤如下:
首先,通过<a href="https://www.npmjs.com/">npm</a>安装node.js 连接器.
```bash ```bash
npm install td2.0-connector npm install td2.0-connector
``` ```
我们建议用户使用npm 安装node.js连接器。如果您没有安装npm, 可以将*src/connector/nodejs/*拷贝到您的nodejs 项目目录下 我们建议用户使用npm 安装node.js连接器。如果您没有安装npm, 可以将*src/connector/nodejs/*拷贝到您的nodejs 项目目录下
我们使用[node-gyp](https://github.com/nodejs/node-gyp)和TDengine服务端进行交互。安装node.js 连接器之前,还需安装以下软件: 我们使用<a href="https://github.com/nodejs/node-gyp">node-gyp</a>和TDengine服务端进行交互。安装node.js 连接器之前,还需安装以下软件:
### Linux ### Linux
- `python` (建议`v2.7` , `v3.x.x` 目前还不支持) - `python` (建议`v2.7` , `v3.x.x` 目前还不支持)
- `node` 必须采用v10.x版本,其他版本存在包兼容性的问题。 - `node` 必须采用v10.x版本,其他版本存在包兼容性的问题。
- `make` - `make`
- c语言编译器比如[GCC](https://gcc.gnu.org) - c语言编译器比如<a href="https://gcc.gnu.org">GCC</a>
### Windows ### Windows
#### 安装方法1 #### 安装方法1
使用微软的[windows-build-tools](https://github.com/felixrieseberg/windows-build-tools)在`cmd` 命令行界面执行`npm install --global --production windows-build-tools` 即可安装所有的必备工具 使用微软的<a href="https://github.com/felixrieseberg/windows-build-tools">windows-build-tools</a>在`cmd` 命令行界面执行`npm install --global --production windows-build-tools` 即可安装所有的必备工具
#### 安装方法2 #### 安装方法2
手动安装以下工具: 手动安装以下工具:
- 安装Visual Studio相关:[Visual Studio Build 工具](https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=BuildTools) 或者 [Visual Studio 2017 Community](https://visualstudio.microsoft.com/pl/thank-you-downloading-visual-studio/?sku=Community) - 安装Visual Studio相关:<a href="https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=BuildTools>Visual Studio Build 工具</a> 或者 <a href="https://visualstudio.microsoft.com/pl/thank-you-downloading-visual-studio/?sku=Community">Visual Studio 2017 Community</a>
- 安装 [Python 2.7](https://www.python.org/downloads/) (`v3.x.x` 暂不支持) 并执行 `npm config set python python2.7` - 安装 <a href="https://www.python.org/downloads/">Python</a> 2.7(`v3.x.x` 暂不支持) 并执行 `npm config set python python2.7`
- 进入`cmd`命令行界面, `npm config set msvs_version 2017` - 进入`cmd`命令行界面, `npm config set msvs_version 2017`
如果以上步骤不能成功执行, 可以参考微软的node.js用户手册[Microsoft's Node.js Guidelines for Windows](https://github.com/Microsoft/nodejs-guidelines/blob/master/windows-environment.md#compiling-native-addon-modules) 如果以上步骤不能成功执行, 可以参考微软的node.js用户手册<a href="https://github.com/Microsoft/nodejs-guidelines/blob/master/windows-environment.md#compiling-native-addon-modules">Microsoft's Node.js Guidelines for Windows</a>
如果在Windows 10 ARM 上使用ARM64 Node.js, 还需添加 "Visual C++ compilers and libraries for ARM64" 和 "Visual C++ ATL for ARM64". 如果在Windows 10 ARM 上使用ARM64 Node.js, 还需添加 "Visual C++ compilers and libraries for ARM64" 和 "Visual C++ ATL for ARM64".
### 使用方法 ### 示例程序
示例程序源码位于install_directory/examples/nodejs,有:
Node-example.js node.js示例源程序
Node-example-raw.js
### 安装验证
在安装好TDengine客户端后,使用nodejsChecker.js程序能够验证当前环境是否支持nodejs方式访问Tdengine。
验证方法:
1. 新建安装验证目录,例如:~/tdengine-test,拷贝github上nodejsChecker.js源程序。下载地址:(https://github.com/taosdata/TDengine/tree/develop/tests/examples/nodejs/nodejsChecker.js)。
2. 在命令中执行以下命令:
```bash
npm init -y
npm install td2.0-connector
node nodejsChecker.js host=localhost
```
3. 执行以上步骤后,在命令行会输出nodejs连接Tdengine实例,并执行简答插入和查询的结果。
### Node.js连接器的使用
(http://docs.taosdata.com/node) (http://docs.taosdata.com/node)
以下是node.js 连接器的一些基本使用方法,详细的使用方法可参考[该文档](http://docs.taosdata.com/node) 以下是node.js 连接器的一些基本使用方法,详细的使用方法可参考<a href="http://docs.taosdata.com/node">该文档</a>
#### 连接 #### 建立连接
使用node.js连接器时,必须先<em>require</em> ```td2.0-connector```,然后使用 ```taos.connect``` 函数。```taos.connect``` 函数必须提供的参数是```host```,其它参数在没有提供的情况下会使用如下的默认值。最后需要初始化```cursor``` 来和TDengine服务端通信 使用node.js连接器时,必须先<em>require</em> ```td2.0-connector```,然后使用 ```taos.connect``` 函数。```taos.connect``` 函数必须提供的参数是```host```,其它参数在没有提供的情况下会使用如下的默认值。最后需要初始化```cursor``` 来和TDengine服务端通信
...@@ -782,6 +923,26 @@ var cursor = conn.cursor(); // Initializing a new cursor ...@@ -782,6 +923,26 @@ var cursor = conn.cursor(); // Initializing a new cursor
conn.close(); conn.close();
``` ```
#### 执行SQL和插入数据
对于DDL语句(例如create database、create table、use等),可以使用cursor的execute方法。代码如下:
```js
cursor.execute('create database if not exists test;')
```
以上代码创建了一个名称为test的数据库。对于DDL语句,一般没有返回值,cursor的execute返回值为0。
对于Insert语句,代码如下:
```js
var affectRows = cursor.execute('insert into test.weather values(now, 22.3, 34);')
```
execute方法的返回值为该语句影响的行数,上面的sql向test库的weather表中,插入了一条数据,则返回值affectRows为1。
TDengine目前还不支持update和delete语句。
#### 查询 #### 查询
可通过 ```cursor.query``` 函数来查询数据库。 可通过 ```cursor.query``` 函数来查询数据库。
...@@ -808,7 +969,6 @@ query.execute().then(function(result) { ...@@ -808,7 +969,6 @@ query.execute().then(function(result) {
``` ```
如果在```query```语句里提供第二个参数并设为```true```也可以立即获取查询结果。如下: 如果在```query```语句里提供第二个参数并设为```true```也可以立即获取查询结果。如下:
```javascript ```javascript
var promise = cursor.query('select * from meterinfo.meters where v1 = 30;', true) var promise = cursor.query('select * from meterinfo.meters where v1 = 30;', true)
promise.then(function(result) { promise.then(function(result) {
...@@ -828,12 +988,7 @@ promise2.then(function(result) { ...@@ -828,12 +988,7 @@ promise2.then(function(result) {
}) })
``` ```
### 示例 ### 示例
[这里](https://github.com/taosdata/TDengine/tree/master/tests/examples/nodejs/node-example.js)提供了一个使用NodeJS 连接器建表,插入天气数据并查询插入的数据的代码示例 <a href="https://github.com/taosdata/TDengine/tree/master/tests/examples/nodejs/node-example.js">这里</a>提供了一个使用NodeJS 连接器建表,插入天气数据并查询插入的数据的代码示例
[这里](https://github.com/taosdata/TDengine/tree/master/tests/examples/nodejs/node-example-raw.js)同样是一个使用NodeJS 连接器建表,插入天气数据并查询插入的数据的代码示例,但和上面不同的是,该示例只使用`cursor`.
[4]: https://www.taosdata.com/cn/all-downloads/#TDengine-Windows-Client
<a href="https://github.com/taosdata/TDengine/tree/master/tests/examples/nodejs/node-example-raw.js">这里</a>同样是一个使用NodeJS 连接器建表,插入天气数据并查询插入的数据的代码示例,但和上面不同的是,该示例只使用`cursor`.
\ No newline at end of file
# Java Connector # Java Connector
Java连接器支持的系统有: Linux 64/Windows x64/Windows x86。 Java连接器支持的系统有:
| **CPU类型** | x64(64bit) | | | ARM64 | ARM32 |
| ------------ | ------------ | -------- | -------- | -------- | -------- |
| **OS类型** | Linux | Win64 | Win32 | Linux | Linux |
| **支持与否** | **支持** | **支持** | **支持** | **支持** | **支持** |
TDengine 为了方便 Java 应用使用,提供了遵循 JDBC 标准(3.0)API 规范的 `taos-jdbcdriver` 实现。目前可以通过 [Sonatype Repository][1] 搜索并下载。 TDengine 为了方便 Java 应用使用,提供了遵循 JDBC 标准(3.0)API 规范的 `taos-jdbcdriver` 实现。目前可以通过 [Sonatype Repository][1] 搜索并下载。
...@@ -21,7 +25,6 @@ TDengine 的 JDBC 驱动实现尽可能的与关系型数据库驱动保持一 ...@@ -21,7 +25,6 @@ TDengine 的 JDBC 驱动实现尽可能的与关系型数据库驱动保持一
* 目前不支持表间的 union 操作。 * 目前不支持表间的 union 操作。
* 目前不支持嵌套查询(nested query),对每个 Connection 的实例,至多只能有一个打开的 ResultSet 实例;如果在 ResultSet还没关闭的情况下执行了新的查询,TSDBJDBCDriver 则会自动关闭上一个 ResultSet。 * 目前不支持嵌套查询(nested query),对每个 Connection 的实例,至多只能有一个打开的 ResultSet 实例;如果在 ResultSet还没关闭的情况下执行了新的查询,TSDBJDBCDriver 则会自动关闭上一个 ResultSet。
## TAOS-JDBCDriver 版本以及支持的 TDengine 版本和 JDK 版本 ## TAOS-JDBCDriver 版本以及支持的 TDengine 版本和 JDK 版本
| taos-jdbcdriver 版本 | TDengine 版本 | JDK 版本 | | taos-jdbcdriver 版本 | TDengine 版本 | JDK 版本 |
...@@ -70,7 +73,6 @@ maven 项目中使用如下 pom.xml 配置即可: ...@@ -70,7 +73,6 @@ maven 项目中使用如下 pom.xml 配置即可:
下载 [TDengine][3] 源码之后,进入 taos-jdbcdriver 源码目录 `src/connector/jdbc` 执行 `mvn clean package` 即可生成相应 jar 包。 下载 [TDengine][3] 源码之后,进入 taos-jdbcdriver 源码目录 `src/connector/jdbc` 执行 `mvn clean package` 即可生成相应 jar 包。
## 使用说明 ## 使用说明
### 获取连接 ### 获取连接
...@@ -212,7 +214,6 @@ while(resultSet.next()){ ...@@ -212,7 +214,6 @@ while(resultSet.next()){
``` ```
> 查询和操作关系型数据库一致,使用下标获取返回字段内容时从 1 开始,建议使用字段名称获取。 > 查询和操作关系型数据库一致,使用下标获取返回字段内容时从 1 开始,建议使用字段名称获取。
### 订阅 ### 订阅
#### 创建 #### 创建
...@@ -227,7 +228,7 @@ TSDBSubscribe sub = ((TSDBConnection)conn).subscribe("topic", "select * from met ...@@ -227,7 +228,7 @@ TSDBSubscribe sub = ((TSDBConnection)conn).subscribe("topic", "select * from met
* sql:订阅的查询语句,此语句只能是 `select` 语句,只应查询原始数据,只能按时间正序查询数据 * sql:订阅的查询语句,此语句只能是 `select` 语句,只应查询原始数据,只能按时间正序查询数据
* restart:如果订阅已经存在,是重新开始,还是继续之前的订阅 * restart:如果订阅已经存在,是重新开始,还是继续之前的订阅
如上面的例子将使用 SQL 语句 `select * from meters` 创建一个名为 `topic' 的订阅,如果这个订阅已经存在,将继续之前的查询进度,而不是从头开始消费所有的数据。 如上面的例子将使用 SQL 语句 `select * from meters` 创建一个名为 `topic` 的订阅,如果这个订阅已经存在,将继续之前的查询进度,而不是从头开始消费所有的数据。
#### 消费数据 #### 消费数据
...@@ -255,7 +256,6 @@ sub.close(true); ...@@ -255,7 +256,6 @@ sub.close(true);
`close` 方法关闭一个订阅。如果其参数为 `true` 表示保留订阅进度信息,后续可以创建同名订阅继续消费数据;如为 `false` 则不保留订阅进度。 `close` 方法关闭一个订阅。如果其参数为 `true` 表示保留订阅进度信息,后续可以创建同名订阅继续消费数据;如为 `false` 则不保留订阅进度。
### 关闭资源 ### 关闭资源
```java ```java
......
...@@ -280,7 +280,10 @@ bool tSkipListIterNext(SSkipListIterator *iter) { ...@@ -280,7 +280,10 @@ bool tSkipListIterNext(SSkipListIterator *iter) {
tSkipListRLock(pSkipList); tSkipListRLock(pSkipList);
if (iter->order == TSDB_ORDER_ASC) { if (iter->order == TSDB_ORDER_ASC) {
if (iter->cur == pSkipList->pTail) return false; if (iter->cur == pSkipList->pTail) {
tSkipListUnlock(pSkipList);
return false;
}
iter->cur = SL_NODE_GET_FORWARD_POINTER(iter->cur, 0); iter->cur = SL_NODE_GET_FORWARD_POINTER(iter->cur, 0);
// a new node is inserted into between iter->cur and iter->next, ignore it // a new node is inserted into between iter->cur and iter->next, ignore it
......
...@@ -7,12 +7,12 @@ def pre_test(){ ...@@ -7,12 +7,12 @@ def pre_test(){
sh ''' sh '''
cd ${WKC} cd ${WKC}
git reset --hard git reset --hard
git checkout ${BRANCH} git checkout $BRANCH_NAME
git pull git pull
git submodule update git submodule update
cd ${WK} cd ${WK}
git reset --hard git reset --hard
git checkout ${BRANCH} git checkout $BRANCH_NAME
git pull git pull
export TZ=Asia/Harbin export TZ=Asia/Harbin
date date
...@@ -28,7 +28,7 @@ def pre_test(){ ...@@ -28,7 +28,7 @@ def pre_test(){
pipeline { pipeline {
agent none agent none
environment{ environment{
BRANCH = $branch_name
WK = '/var/lib/jenkins/workspace/TDinternal' WK = '/var/lib/jenkins/workspace/TDinternal'
WKC= '/var/lib/jenkins/workspace/TDinternal/community' WKC= '/var/lib/jenkins/workspace/TDinternal/community'
} }
......
...@@ -38,7 +38,7 @@ class ConcurrentInquiry: ...@@ -38,7 +38,7 @@ class ConcurrentInquiry:
# stableNum = 2,subtableNum = 1000,insertRows = 100): # stableNum = 2,subtableNum = 1000,insertRows = 100):
def __init__(self,ts,host,user,password,dbname, def __init__(self,ts,host,user,password,dbname,
stb_prefix,subtb_prefix,n_Therads,r_Therads,probabilities,loop, stb_prefix,subtb_prefix,n_Therads,r_Therads,probabilities,loop,
stableNum ,subtableNum ,insertRows ): stableNum ,subtableNum ,insertRows ,mix_table):
self.n_numOfTherads = n_Therads self.n_numOfTherads = n_Therads
self.r_numOfTherads = r_Therads self.r_numOfTherads = r_Therads
self.ts=ts self.ts=ts
...@@ -60,6 +60,7 @@ class ConcurrentInquiry: ...@@ -60,6 +60,7 @@ class ConcurrentInquiry:
self.stableNum = stableNum self.stableNum = stableNum
self.subtableNum = subtableNum self.subtableNum = subtableNum
self.insertRows = insertRows self.insertRows = insertRows
self.mix_table = mix_table
def SetThreadsNum(self,num): def SetThreadsNum(self,num):
self.numOfTherads=num self.numOfTherads=num
...@@ -195,7 +196,13 @@ class ConcurrentInquiry: ...@@ -195,7 +196,13 @@ class ConcurrentInquiry:
pick_func+=alias pick_func+=alias
sel_col_list.append(pick_func) sel_col_list.append(pick_func)
sql=sql+','.join(sel_col_list)+' from '+random.choice(self.stb_list+self.subtb_list)+' ' #select col & func sql=sql+','.join(sel_col_list) #select col & func
if self.mix_table == 0:
sql = sql + ' from '+random.choice(self.stb_list+self.subtb_list)+' '
elif self.mix_table == 1:
sql = sql + ' from '+random.choice(self.subtb_list)+' '
else:
sql = sql + ' from '+random.choice(self.stb_list)+' '
con_func=[self.con_where,self.con_interval,self.con_limit,self.con_group,self.con_order,self.con_fill] con_func=[self.con_where,self.con_interval,self.con_limit,self.con_group,self.con_order,self.con_fill]
sel_con=random.sample(con_func,random.randint(0,len(con_func))) sel_con=random.sample(con_func,random.randint(0,len(con_func)))
sel_con_list=[] sel_con_list=[]
...@@ -212,7 +219,7 @@ class ConcurrentInquiry: ...@@ -212,7 +219,7 @@ class ConcurrentInquiry:
col_intersection = [] col_intersection = []
tag_intersection = [] tag_intersection = []
subtable = None subtable = None
if self.mix_table == 0:
if bool(random.getrandbits(1)): if bool(random.getrandbits(1)):
subtable = True subtable = True
tbname = random.sample(self.subtb_list,2) tbname = random.sample(self.subtb_list,2)
...@@ -228,12 +235,24 @@ class ConcurrentInquiry: ...@@ -228,12 +235,24 @@ class ConcurrentInquiry:
tag_list.append(self.stb_stru_list[self.stb_list.index(i)]) tag_list.append(self.stb_stru_list[self.stb_list.index(i)])
col_intersection = list(set(col_list[0]).intersection(set(col_list[1]))) col_intersection = list(set(col_list[0]).intersection(set(col_list[1])))
tag_intersection = list(set(tag_list[0]).intersection(set(tag_list[1]))) tag_intersection = list(set(tag_list[0]).intersection(set(tag_list[1])))
elif self.mix_table == 1:
subtable = True
tbname = random.sample(self.subtb_list,2)
for i in tbname:
col_list.append(self.subtb_stru_list[self.subtb_list.index(i)])
tag_list.append(self.subtb_stru_list[self.subtb_list.index(i)])
col_intersection = list(set(col_list[0]).intersection(set(col_list[1])))
tag_intersection = list(set(tag_list[0]).intersection(set(tag_list[1])))
else:
tbname = random.sample(self.stb_list,2)
for i in tbname:
col_list.append(self.stb_stru_list[self.stb_list.index(i)])
tag_list.append(self.stb_stru_list[self.stb_list.index(i)])
col_intersection = list(set(col_list[0]).intersection(set(col_list[1])))
tag_intersection = list(set(tag_list[0]).intersection(set(tag_list[1])))
con_rand=random.randint(0,len(condition_list)) con_rand=random.randint(0,len(condition_list))
col_rand=random.randint(0,len(col_list)) col_rand=random.randint(0,len(col_list))
tag_rand=random.randint(0,len(tag_list)) tag_rand=random.randint(0,len(tag_list))
sql='select ' #select sql='select ' #select
sel_col_tag=[] sel_col_tag=[]
...@@ -247,12 +266,16 @@ class ConcurrentInquiry: ...@@ -247,12 +266,16 @@ class ConcurrentInquiry:
sql = sql + ' from '+ str(tbname[0]) +' t1,' + str(tbname[1]) + ' t2 ' #select col & func sql = sql + ' from '+ str(tbname[0]) +' t1,' + str(tbname[1]) + ' t2 ' #select col & func
join_section = None join_section = None
temp = None
if subtable: if subtable:
join_section = ''.join(random.choices(col_intersection)) temp = random.choices(col_intersection)
sql += 'where t1._c0 = t2._c0 and ' + 't1.' + join_section + '=t2.' + join_section join_section = temp.pop()
sql += 'where t1._c0 = t2._c0 and ' + 't1.' + str(join_section) + '=t2.' + str(join_section)
else: else:
join_section = ''.join(random.choices(col_intersection+tag_intersection)) temp = random.choices(col_intersection+tag_intersection)
sql += 'where t1._c0 = t2._c0 and ' + 't1.' + join_section + '=t2.' + join_section join_section = temp.pop()
print(random.choices(col_intersection))
sql += 'where t1._c0 = t2._c0 and ' + 't1.' + str(join_section) + '=t2.' + str(join_section)
return sql return sql
def random_pick(self): def random_pick(self):
...@@ -516,12 +539,20 @@ parser.add_argument( ...@@ -516,12 +539,20 @@ parser.add_argument(
default=2, default=2,
type=int, type=int,
help='Number of stables (default: 2)') help='Number of stables (default: 2)')
parser.add_argument(
'-m',
'--mix-stable-subtable',
action='store',
default=0,
type=int,
help='0:stable & substable ,1:subtable ,2:stable (default: 0)')
args = parser.parse_args() args = parser.parse_args()
q = ConcurrentInquiry( q = ConcurrentInquiry(
args.ts,args.host_name,args.user,args.password,args.db_name, args.ts,args.host_name,args.user,args.password,args.db_name,
args.stb_name_prefix,args.subtb_name_prefix,args.number_of_native_threads,args.number_of_rest_threads, args.stb_name_prefix,args.subtb_name_prefix,args.number_of_native_threads,args.number_of_rest_threads,
args.probabilities,args.loop_per_thread,args.number_of_stables,args.number_of_tables ,args.number_of_records ) args.probabilities,args.loop_per_thread,args.number_of_stables,args.number_of_tables ,args.number_of_records,
args.mix_stable_subtable )
if args.create_table: if args.create_table:
q.gen_data() q.gen_data()
......
...@@ -25,6 +25,24 @@ function runSimCaseOneByOne { ...@@ -25,6 +25,24 @@ function runSimCaseOneByOne {
fi fi
done < $1 done < $1
} }
function runSimCaseOneByOnefq {
while read -r line; do
if [[ $line =~ ^./test.sh* ]] || [[ $line =~ ^run* ]]; then
case=`echo $line | grep sim$ |awk '{print $NF}'`
start_time=`date +%s`
./test.sh -f $case > /dev/null 2>&1 && \
echo -e "${GREEN}$case success${NC}" | tee -a out.log || \
echo -e "${RED}$case failed${NC}" | tee -a out.log
out_log=`tail -1 out.log `
if [[ $out_log =~ 'failed' ]];then
exit 8
fi
end_time=`date +%s`
echo execution time of $case was `expr $end_time - $start_time`s. | tee -a out.log
fi
done < $1
}
function runPyCaseOneByOne { function runPyCaseOneByOne {
while read -r line; do while read -r line; do
...@@ -52,7 +70,32 @@ function runPyCaseOneByOne { ...@@ -52,7 +70,32 @@ function runPyCaseOneByOne {
fi fi
done < $1 done < $1
} }
function runPyCaseOneByOnefq {
while read -r line; do
if [[ $line =~ ^python.* ]]; then
if [[ $line != *sleep* ]]; then
if [[ $line =~ '-r' ]];then
case=`echo $line|awk '{print $4}'`
else
case=`echo $line|awk '{print $NF}'`
fi
start_time=`date +%s`
$line > /dev/null 2>&1 && \
echo -e "${GREEN}$case success${NC}" | tee -a pytest-out.log || \
echo -e "${RED}$case failed${NC}" | tee -a pytest-out.log
end_time=`date +%s`
out_log=`tail -1 pytest-out.log `
if [[ $out_log =~ 'failed' ]];then
exit 8
fi
echo execution time of $case was `expr $end_time - $start_time`s. | tee -a pytest-out.log
else
$line > /dev/null 2>&1
fi
fi
done < $1
}
totalFailed=0 totalFailed=0
totalPyFailed=0 totalPyFailed=0
...@@ -78,6 +121,15 @@ if [ "$2" != "python" ]; then ...@@ -78,6 +121,15 @@ if [ "$2" != "python" ]; then
elif [ "$1" == "b3" ]; then elif [ "$1" == "b3" ]; then
echo "### run TSIM b3 test ###" echo "### run TSIM b3 test ###"
runSimCaseOneByOne jenkins/basic_3.txt runSimCaseOneByOne jenkins/basic_3.txt
elif [ "$1" == "b1fq" ]; then
echo "### run TSIM b1 test ###"
runSimCaseOneByOnefq jenkins/basic_1.txt
elif [ "$1" == "b2fq" ]; then
echo "### run TSIM b2 test ###"
runSimCaseOneByOnefq jenkins/basic_2.txt
elif [ "$1" == "b3fq" ]; then
echo "### run TSIM b3 test ###"
runSimCaseOneByOnefq jenkins/basic_3.txt
elif [ "$1" == "smoke" ] || [ -z "$1" ]; then elif [ "$1" == "smoke" ] || [ -z "$1" ]; then
echo "### run TSIM smoke test ###" echo "### run TSIM smoke test ###"
runSimCaseOneByOne basicSuite.sim runSimCaseOneByOne basicSuite.sim
...@@ -137,6 +189,9 @@ if [ "$2" != "sim" ]; then ...@@ -137,6 +189,9 @@ if [ "$2" != "sim" ]; then
elif [ "$1" == "pytest" ]; then elif [ "$1" == "pytest" ]; then
echo "### run Python full test ###" echo "### run Python full test ###"
runPyCaseOneByOne fulltest.sh runPyCaseOneByOne fulltest.sh
elif [ "$1" == "pytestfq" ]; then
echo "### run Python full test ###"
runPyCaseOneByOnefq fulltest.sh
elif [ "$1" == "p1" ]; then elif [ "$1" == "p1" ]; then
echo "### run Python_1 test ###" echo "### run Python_1 test ###"
runPyCaseOneByOne pytest_1.sh runPyCaseOneByOne pytest_1.sh
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册