Merge branch 'develop' into hotfix/test
This commit is contained in:
commit
117aa3032d
11
.travis.yml
11
.travis.yml
|
@ -146,7 +146,7 @@ matrix:
|
||||||
branch_pattern: coverity_scan
|
branch_pattern: coverity_scan
|
||||||
|
|
||||||
- os: linux
|
- os: linux
|
||||||
dist: xenial
|
dist: trusty
|
||||||
language: c
|
language: c
|
||||||
git:
|
git:
|
||||||
- depth: 1
|
- depth: 1
|
||||||
|
@ -156,8 +156,9 @@ matrix:
|
||||||
packages:
|
packages:
|
||||||
- build-essential
|
- build-essential
|
||||||
- cmake
|
- cmake
|
||||||
|
- binutils-2.26
|
||||||
env:
|
env:
|
||||||
- DESC="xenial build"
|
- DESC="trusty/gcc-4.8/bintuils-2.26 build"
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
- export TZ=Asia/Harbin
|
- export TZ=Asia/Harbin
|
||||||
|
@ -168,7 +169,7 @@ matrix:
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- cmake .. > /dev/null
|
- cmake .. > /dev/null
|
||||||
- make
|
- export PATH=/usr/lib/binutils-2.26/bin:$PATH && make
|
||||||
|
|
||||||
- os: linux
|
- os: linux
|
||||||
dist: bionic
|
dist: bionic
|
||||||
|
@ -200,7 +201,7 @@ matrix:
|
||||||
dist: bionic
|
dist: bionic
|
||||||
language: c
|
language: c
|
||||||
compiler: clang
|
compiler: clang
|
||||||
env: DESC="linux/clang build"
|
env: DESC="arm64 linux/clang build"
|
||||||
git:
|
git:
|
||||||
- depth: 1
|
- depth: 1
|
||||||
|
|
||||||
|
@ -238,7 +239,7 @@ matrix:
|
||||||
- build-essential
|
- build-essential
|
||||||
- cmake
|
- cmake
|
||||||
env:
|
env:
|
||||||
- DESC="xenial build"
|
- DESC="arm64 xenial build"
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
- export TZ=Asia/Harbin
|
- export TZ=Asia/Harbin
|
||||||
|
|
|
@ -104,6 +104,10 @@ pipeline {
|
||||||
find pytest -name '*'sql|xargs rm -rf
|
find pytest -name '*'sql|xargs rm -rf
|
||||||
./test-all.sh p2
|
./test-all.sh p2
|
||||||
date'''
|
date'''
|
||||||
|
sh '''
|
||||||
|
cd ${WKC}/tests
|
||||||
|
./test-all.sh b4fq
|
||||||
|
'''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stage('test_b1') {
|
stage('test_b1') {
|
||||||
|
|
|
@ -33,11 +33,17 @@ To build TDengine, use [CMake](https://cmake.org/) 3.5 or higher versions in the
|
||||||
|
|
||||||
## Install tools
|
## Install tools
|
||||||
|
|
||||||
### Ubuntu & Debian:
|
### Ubuntu 16.04 and above & Debian:
|
||||||
```bash
|
```bash
|
||||||
sudo apt-get install -y gcc cmake build-essential git
|
sudo apt-get install -y gcc cmake build-essential git
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Ubuntu 14.04:
|
||||||
|
```bash
|
||||||
|
sudo apt-get install -y gcc cmake3 build-essential git binutils-2.26
|
||||||
|
export PATH=/usr/lib/binutils-2.26/bin:$PATH
|
||||||
|
```
|
||||||
|
|
||||||
To compile and package the JDBC driver source code, you should have a Java jdk-8 or higher and Apache Maven 2.7 or higher installed.
|
To compile and package the JDBC driver source code, you should have a Java jdk-8 or higher and Apache Maven 2.7 or higher installed.
|
||||||
To install openjdk-8:
|
To install openjdk-8:
|
||||||
```bash
|
```bash
|
||||||
|
|
|
@ -4,7 +4,7 @@ PROJECT(TDengine)
|
||||||
IF (DEFINED VERNUMBER)
|
IF (DEFINED VERNUMBER)
|
||||||
SET(TD_VER_NUMBER ${VERNUMBER})
|
SET(TD_VER_NUMBER ${VERNUMBER})
|
||||||
ELSE ()
|
ELSE ()
|
||||||
SET(TD_VER_NUMBER "2.0.12.0")
|
SET(TD_VER_NUMBER "2.0.13.0")
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
IF (DEFINED VERCOMPATIBLE)
|
IF (DEFINED VERCOMPATIBLE)
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
TDengine采用关系型数据模型,需要建库、建表。因此对于一个具体的应用场景,需要考虑库的设计,超级表和普通表的设计。本节不讨论细致的语法规则,只介绍概念。
|
TDengine采用关系型数据模型,需要建库、建表。因此对于一个具体的应用场景,需要考虑库的设计,超级表和普通表的设计。本节不讨论细致的语法规则,只介绍概念。
|
||||||
|
|
||||||
|
关于数据建模请参考<a href="https://www.taosdata.com/blog/2020/11/11/1945.html">视频教程</a>。
|
||||||
|
|
||||||
## 创建库
|
## 创建库
|
||||||
|
|
||||||
不同类型的数据采集点往往具有不同的数据特征,包括数据采集频率的高低,数据保留时间的长短,副本的数目,数据块的大小,是否允许更新数据等等。为让各种场景下TDengine都能最大效率的工作,TDengine建议将不同数据特征的表创建在不同的库里,因为每个库可以配置不同的存储策略。创建一个库时,除SQL标准的选项外,应用还可以指定保留时长、副本数、内存块个数、时间精度、文件块里最大最小记录条数、是否压缩、一个数据文件覆盖的天数等多种参数。比如:
|
不同类型的数据采集点往往具有不同的数据特征,包括数据采集频率的高低,数据保留时间的长短,副本的数目,数据块的大小,是否允许更新数据等等。为让各种场景下TDengine都能最大效率的工作,TDengine建议将不同数据特征的表创建在不同的库里,因为每个库可以配置不同的存储策略。创建一个库时,除SQL标准的选项外,应用还可以指定保留时长、副本数、内存块个数、时间精度、文件块里最大最小记录条数、是否压缩、一个数据文件覆盖的天数等多种参数。比如:
|
||||||
|
@ -60,4 +62,3 @@ TDengine支持多列模型,只要物理量是一个数据采集点同时采集
|
||||||
|
|
||||||
TDengine建议尽可能采用多列模型,因为插入效率以及存储效率更高。但对于有些场景,一个采集点的采集量的种类经常变化,这个时候,如果采用多列模型,就需要频繁修改超级表的结构定义,让应用变的复杂,这个时候,采用单列模型会显得简单。
|
TDengine建议尽可能采用多列模型,因为插入效率以及存储效率更高。但对于有些场景,一个采集点的采集量的种类经常变化,这个时候,如果采用多列模型,就需要频繁修改超级表的结构定义,让应用变的复杂,这个时候,采用单列模型会显得简单。
|
||||||
|
|
||||||
关于数据建模请参考<a href="https://www.taosdata.com/blog/2020/11/11/1945.html">视频教程</a>。
|
|
||||||
|
|
|
@ -148,7 +148,7 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic
|
||||||
SHOW TABLES [LIKE tb_name_wildcar];
|
SHOW TABLES [LIKE tb_name_wildcar];
|
||||||
```
|
```
|
||||||
|
|
||||||
显示当前数据库下的所有数据表信息。说明:可在like中使用通配符进行名称的匹配。 通配符匹配:1)’%’ (百分号)匹配0到任意个字符;2)’_’下划线匹配一个字符。
|
显示当前数据库下的所有数据表信息。说明:可在 like 中使用通配符进行名称的匹配。 通配符匹配:1)“%”(百分号)匹配 0 到任意个字符;2)“\_”(下划线)匹配一个字符。
|
||||||
|
|
||||||
- **在线修改显示字符宽度**
|
- **在线修改显示字符宽度**
|
||||||
|
|
||||||
|
@ -263,33 +263,33 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic
|
||||||
|
|
||||||
- **插入一条记录,数据对应到指定的列**
|
- **插入一条记录,数据对应到指定的列**
|
||||||
```mysql
|
```mysql
|
||||||
INSERT INTO tb_name (field1_name, ...) VALUES(field1_value, ...)
|
INSERT INTO tb_name (field1_name, ...) VALUES (field1_value, ...)
|
||||||
```
|
```
|
||||||
向表tb_name中插入一条记录,数据对应到指定的列。SQL语句中没有出现的列,数据库将自动填充为NULL。主键(时间戳)不能为NULL。
|
向表tb_name中插入一条记录,数据对应到指定的列。SQL语句中没有出现的列,数据库将自动填充为NULL。主键(时间戳)不能为NULL。
|
||||||
|
|
||||||
- **插入多条记录**
|
- **插入多条记录**
|
||||||
```mysql
|
```mysql
|
||||||
INSERT INTO tb_name VALUES (field1_value1, ...) (field1_value2, ...)...;
|
INSERT INTO tb_name VALUES (field1_value1, ...) (field1_value2, ...) ...;
|
||||||
```
|
```
|
||||||
向表tb_name中插入多条记录
|
向表tb_name中插入多条记录
|
||||||
|
|
||||||
- **按指定的列插入多条记录**
|
- **按指定的列插入多条记录**
|
||||||
```mysql
|
```mysql
|
||||||
INSERT INTO tb_name (field1_name, ...) VALUES(field1_value1, ...) (field1_value2, ...)
|
INSERT INTO tb_name (field1_name, ...) VALUES (field1_value1, ...) (field1_value2, ...) ...;
|
||||||
```
|
```
|
||||||
向表tb_name中按指定的列插入多条记录
|
向表tb_name中按指定的列插入多条记录
|
||||||
|
|
||||||
- **向多个表插入多条记录**
|
- **向多个表插入多条记录**
|
||||||
```mysql
|
```mysql
|
||||||
INSERT INTO tb1_name VALUES (field1_value1, ...)(field1_value2, ...)...
|
INSERT INTO tb1_name VALUES (field1_value1, ...) (field1_value2, ...) ...
|
||||||
tb2_name VALUES (field1_value1, ...)(field1_value2, ...)...;
|
tb2_name VALUES (field1_value1, ...) (field1_value2, ...) ...;
|
||||||
```
|
```
|
||||||
同时向表tb1_name和tb2_name中分别插入多条记录
|
同时向表tb1_name和tb2_name中分别插入多条记录
|
||||||
|
|
||||||
- **同时向多个表按列插入多条记录**
|
- **同时向多个表按列插入多条记录**
|
||||||
```mysql
|
```mysql
|
||||||
INSERT INTO tb1_name (tb1_field1_name, ...) VALUES (field1_value1, ...) (field1_value2, ...)
|
INSERT INTO tb1_name (tb1_field1_name, ...) VALUES (field1_value1, ...) (field1_value2, ...) ...
|
||||||
tb2_name (tb2_field1_name, ...) VALUES (field1_value1, ...) (field1_value2, ...);
|
tb2_name (tb2_field1_name, ...) VALUES (field1_value1, ...) (field1_value2, ...) ...;
|
||||||
```
|
```
|
||||||
同时向表tb1_name和tb2_name中按列分别插入多条记录
|
同时向表tb1_name和tb2_name中按列分别插入多条记录
|
||||||
|
|
||||||
|
@ -318,23 +318,23 @@ SELECT select_expr [, select_expr ...]
|
||||||
```
|
```
|
||||||
说明:针对 insert 类型的 SQL 语句,我们采用的流式解析策略,在发现后面的错误之前,前面正确的部分SQL仍会执行。下面的sql中,insert语句是无效的,但是d1001仍会被创建。
|
说明:针对 insert 类型的 SQL 语句,我们采用的流式解析策略,在发现后面的错误之前,前面正确的部分SQL仍会执行。下面的sql中,insert语句是无效的,但是d1001仍会被创建。
|
||||||
```mysql
|
```mysql
|
||||||
taos> create table meters(ts timestamp, current float, voltage int, phase float) tags(location binary(30), groupId int);
|
taos> CREATE TABLE meters(ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS(location BINARY(30), groupId INT);
|
||||||
Query OK, 0 row(s) affected (0.008245s)
|
Query OK, 0 row(s) affected (0.008245s)
|
||||||
|
|
||||||
taos> show stables;
|
taos> SHOW STABLES;
|
||||||
name | created_time | columns | tags | tables |
|
name | created_time | columns | tags | tables |
|
||||||
============================================================================================
|
============================================================================================
|
||||||
meters | 2020-08-06 17:50:27.831 | 4 | 2 | 0 |
|
meters | 2020-08-06 17:50:27.831 | 4 | 2 | 0 |
|
||||||
Query OK, 1 row(s) in set (0.001029s)
|
Query OK, 1 row(s) in set (0.001029s)
|
||||||
|
|
||||||
taos> show tables;
|
taos> SHOW TABLES;
|
||||||
Query OK, 0 row(s) in set (0.000946s)
|
Query OK, 0 row(s) in set (0.000946s)
|
||||||
|
|
||||||
taos> insert into d1001 using meters tags('Beijing.Chaoyang', 2);
|
taos> INSERT INTO d1001 USING meters TAGS('Beijing.Chaoyang', 2);
|
||||||
|
|
||||||
DB error: invalid SQL: keyword VALUES or FILE required
|
DB error: invalid SQL: keyword VALUES or FILE required
|
||||||
|
|
||||||
taos> show tables;
|
taos> SHOW TABLES;
|
||||||
table_name | created_time | columns | stable_name |
|
table_name | created_time | columns | stable_name |
|
||||||
======================================================================================================
|
======================================================================================================
|
||||||
d1001 | 2020-08-06 17:52:02.097 | 4 | meters |
|
d1001 | 2020-08-06 17:52:02.097 | 4 | meters |
|
||||||
|
@ -397,27 +397,41 @@ Query OK, 1 row(s) in set (0.020443s)
|
||||||
在使用SQL函数来进行查询过程中,部分SQL函数支持通配符操作。其中的区别在于:
|
在使用SQL函数来进行查询过程中,部分SQL函数支持通配符操作。其中的区别在于:
|
||||||
```count(\*)```函数只返回一列。```first```、```last```、```last_row```函数则是返回全部列。
|
```count(\*)```函数只返回一列。```first```、```last```、```last_row```函数则是返回全部列。
|
||||||
|
|
||||||
```
|
```mysql
|
||||||
taos> select count(*) from d1001;
|
taos> SELECT COUNT(*) FROM d1001;
|
||||||
count(*) |
|
count(*) |
|
||||||
========================
|
========================
|
||||||
3 |
|
3 |
|
||||||
Query OK, 1 row(s) in set (0.001035s)
|
Query OK, 1 row(s) in set (0.001035s)
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```mysql
|
||||||
taos> select first(*) from d1001;
|
taos> SELECT FIRST(*) FROM d1001;
|
||||||
first(ts) | first(current) | first(voltage) | first(phase) |
|
first(ts) | first(current) | first(voltage) | first(phase) |
|
||||||
=========================================================================================
|
=========================================================================================
|
||||||
2018-10-03 14:38:05.000 | 10.30000 | 219 | 0.31000 |
|
2018-10-03 14:38:05.000 | 10.30000 | 219 | 0.31000 |
|
||||||
Query OK, 1 row(s) in set (0.000849s)
|
Query OK, 1 row(s) in set (0.000849s)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
##### 标签列
|
||||||
|
|
||||||
|
从 2.0.14 版本开始,支持在普通表的查询中指定 _标签列_,且标签列的值会与普通列的数据一起返回。
|
||||||
|
```mysql
|
||||||
|
taos> SELECT location, groupid, current FROM d1001 LIMIT 2;
|
||||||
|
location | groupid | current |
|
||||||
|
======================================================================
|
||||||
|
Beijing.Chaoyang | 2 | 10.30000 |
|
||||||
|
Beijing.Chaoyang | 2 | 12.60000 |
|
||||||
|
Query OK, 2 row(s) in set (0.003112s)
|
||||||
|
```
|
||||||
|
|
||||||
|
注意:普通表的通配符 * 中并不包含 _标签列_。
|
||||||
|
|
||||||
#### 结果集列名
|
#### 结果集列名
|
||||||
|
|
||||||
```SELECT```子句中,如果不指定返回结果集合的列名,结果集列名称默认使用```SELECT```子句中的表达式名称作为列名称。此外,用户可使用```AS```来重命名返回结果集合中列的名称。例如:
|
```SELECT```子句中,如果不指定返回结果集合的列名,结果集列名称默认使用```SELECT```子句中的表达式名称作为列名称。此外,用户可使用```AS```来重命名返回结果集合中列的名称。例如:
|
||||||
```
|
```mysql
|
||||||
taos> select ts, ts as primary_key_ts from d1001;
|
taos> SELECT ts, ts AS primary_key_ts FROM d1001;
|
||||||
ts | primary_key_ts |
|
ts | primary_key_ts |
|
||||||
====================================================
|
====================================================
|
||||||
2018-10-03 14:38:05.000 | 2018-10-03 14:38:05.000 |
|
2018-10-03 14:38:05.000 | 2018-10-03 14:38:05.000 |
|
||||||
|
@ -434,53 +448,53 @@ Query OK, 3 row(s) in set (0.001191s)
|
||||||
|
|
||||||
FROM关键字后面可以是若干个表(超级表)列表,也可以是子查询的结果。
|
FROM关键字后面可以是若干个表(超级表)列表,也可以是子查询的结果。
|
||||||
如果没有指定用户的当前数据库,可以在表名称之前使用数据库的名称来指定表所属的数据库。例如:```power.d1001``` 方式来跨库使用表。
|
如果没有指定用户的当前数据库,可以在表名称之前使用数据库的名称来指定表所属的数据库。例如:```power.d1001``` 方式来跨库使用表。
|
||||||
```
|
```mysql
|
||||||
SELECT * FROM power.d1001;
|
SELECT * FROM power.d1001;
|
||||||
------------------------------
|
------------------------------
|
||||||
use power;
|
USE power;
|
||||||
SELECT * FROM d1001;
|
SELECT * FROM d1001;
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 特殊功能
|
#### 特殊功能
|
||||||
部分特殊的查询功能可以不使用FROM子句执行。获取当前所在的数据库 database()
|
部分特殊的查询功能可以不使用FROM子句执行。获取当前所在的数据库 database()
|
||||||
```
|
```mysql
|
||||||
taos> SELECT database();
|
taos> SELECT DATABASE();
|
||||||
database() |
|
database() |
|
||||||
=================================
|
=================================
|
||||||
power |
|
power |
|
||||||
Query OK, 1 row(s) in set (0.000079s)
|
Query OK, 1 row(s) in set (0.000079s)
|
||||||
```
|
```
|
||||||
如果登录的时候没有指定默认数据库,且没有使用```use```命令切换数据,则返回NULL。
|
如果登录的时候没有指定默认数据库,且没有使用```use```命令切换数据,则返回NULL。
|
||||||
```
|
```mysql
|
||||||
taos> SELECT database();
|
taos> SELECT DATABASE();
|
||||||
database() |
|
database() |
|
||||||
=================================
|
=================================
|
||||||
NULL |
|
NULL |
|
||||||
Query OK, 1 row(s) in set (0.000184s)
|
Query OK, 1 row(s) in set (0.000184s)
|
||||||
```
|
```
|
||||||
获取服务器和客户端版本号:
|
获取服务器和客户端版本号:
|
||||||
```
|
```mysql
|
||||||
taos> SELECT client_version();
|
taos> SELECT CLIENT_VERSION();
|
||||||
client_version() |
|
client_version() |
|
||||||
===================
|
===================
|
||||||
2.0.0.0 |
|
2.0.0.0 |
|
||||||
Query OK, 1 row(s) in set (0.000070s)
|
Query OK, 1 row(s) in set (0.000070s)
|
||||||
|
|
||||||
taos> SELECT server_version();
|
taos> SELECT SERVER_VERSION();
|
||||||
server_version() |
|
server_version() |
|
||||||
===================
|
===================
|
||||||
2.0.0.0 |
|
2.0.0.0 |
|
||||||
Query OK, 1 row(s) in set (0.000077s)
|
Query OK, 1 row(s) in set (0.000077s)
|
||||||
```
|
```
|
||||||
服务器状态检测语句。如果服务器正常,返回一个数字(例如 1)。如果服务器异常,返回error code。该SQL语法能兼容连接池对于TDengine状态的检查及第三方工具对于数据库服务器状态的检查。并可以避免出现使用了错误的心跳检测SQL语句导致的连接池连接丢失的问题。
|
服务器状态检测语句。如果服务器正常,返回一个数字(例如 1)。如果服务器异常,返回error code。该SQL语法能兼容连接池对于TDengine状态的检查及第三方工具对于数据库服务器状态的检查。并可以避免出现使用了错误的心跳检测SQL语句导致的连接池连接丢失的问题。
|
||||||
```
|
```mysql
|
||||||
taos> SELECT server_status();
|
taos> SELECT SERVER_STATUS();
|
||||||
server_status() |
|
server_status() |
|
||||||
==================
|
==================
|
||||||
1 |
|
1 |
|
||||||
Query OK, 1 row(s) in set (0.000074s)
|
Query OK, 1 row(s) in set (0.000074s)
|
||||||
|
|
||||||
taos> SELECT server_status() as status;
|
taos> SELECT SERVER_STATUS() AS status;
|
||||||
status |
|
status |
|
||||||
==============
|
==============
|
||||||
1 |
|
1 |
|
||||||
|
@ -493,15 +507,15 @@ Query OK, 1 row(s) in set (0.000081s)
|
||||||
|
|
||||||
#### 小技巧
|
#### 小技巧
|
||||||
获取一个超级表所有的子表名及相关的标签信息:
|
获取一个超级表所有的子表名及相关的标签信息:
|
||||||
```
|
```mysql
|
||||||
SELECT TBNAME, location FROM meters;
|
SELECT TBNAME, location FROM meters;
|
||||||
```
|
```
|
||||||
统计超级表下辖子表数量:
|
统计超级表下辖子表数量:
|
||||||
```
|
```mysql
|
||||||
SELECT COUNT(TBNAME) FROM meters;
|
SELECT COUNT(TBNAME) FROM meters;
|
||||||
```
|
```
|
||||||
以上两个查询均只支持在Where条件子句中添加针对标签(TAGS)的过滤条件。例如:
|
以上两个查询均只支持在Where条件子句中添加针对标签(TAGS)的过滤条件。例如:
|
||||||
```
|
```mysql
|
||||||
taos> SELECT TBNAME, location FROM meters;
|
taos> SELECT TBNAME, location FROM meters;
|
||||||
tbname | location |
|
tbname | location |
|
||||||
==================================================================
|
==================================================================
|
||||||
|
@ -511,7 +525,7 @@ taos> SELECT TBNAME, location FROM meters;
|
||||||
d1001 | Beijing.Chaoyang |
|
d1001 | Beijing.Chaoyang |
|
||||||
Query OK, 4 row(s) in set (0.000881s)
|
Query OK, 4 row(s) in set (0.000881s)
|
||||||
|
|
||||||
taos> SELECT count(tbname) FROM meters WHERE groupId > 2;
|
taos> SELECT COUNT(tbname) FROM meters WHERE groupId > 2;
|
||||||
count(tbname) |
|
count(tbname) |
|
||||||
========================
|
========================
|
||||||
2 |
|
2 |
|
||||||
|
@ -545,7 +559,7 @@ Query OK, 1 row(s) in set (0.001091s)
|
||||||
- 对于下面的例子,表tb1用以下语句创建
|
- 对于下面的例子,表tb1用以下语句创建
|
||||||
|
|
||||||
```mysql
|
```mysql
|
||||||
CREATE TABLE tb1 (ts timestamp, col1 int, col2 float, col3 binary(50));
|
CREATE TABLE tb1 (ts TIMESTAMP, col1 INT, col2 FLOAT, col3 BINARY(50));
|
||||||
```
|
```
|
||||||
|
|
||||||
- 查询tb1刚过去的一个小时的所有记录
|
- 查询tb1刚过去的一个小时的所有记录
|
||||||
|
@ -563,7 +577,7 @@ Query OK, 1 row(s) in set (0.001091s)
|
||||||
- 查询col1与col2的和,并取名complex, 时间大于2018-06-01 08:00:00.000, col2大于1.2,结果输出仅仅10条记录,从第5条开始
|
- 查询col1与col2的和,并取名complex, 时间大于2018-06-01 08:00:00.000, col2大于1.2,结果输出仅仅10条记录,从第5条开始
|
||||||
|
|
||||||
```mysql
|
```mysql
|
||||||
SELECT (col1 + col2) AS 'complex' FROM tb1 WHERE ts > '2018-06-01 08:00:00.000' and col2 > 1.2 LIMIT 10 OFFSET 5;
|
SELECT (col1 + col2) AS 'complex' FROM tb1 WHERE ts > '2018-06-01 08:00:00.000' AND col2 > 1.2 LIMIT 10 OFFSET 5;
|
||||||
```
|
```
|
||||||
|
|
||||||
- 查询过去10分钟的记录,col2的值大于3.14,并且将结果输出到文件 `/home/testoutpu.csv`.
|
- 查询过去10分钟的记录,col2的值大于3.14,并且将结果输出到文件 `/home/testoutpu.csv`.
|
||||||
|
@ -590,13 +604,13 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数
|
||||||
|
|
||||||
示例:
|
示例:
|
||||||
```mysql
|
```mysql
|
||||||
taos> SELECT COUNT(*), COUNT(VOLTAGE) FROM meters;
|
taos> SELECT COUNT(*), COUNT(voltage) FROM meters;
|
||||||
count(*) | count(voltage) |
|
count(*) | count(voltage) |
|
||||||
================================================
|
================================================
|
||||||
9 | 9 |
|
9 | 9 |
|
||||||
Query OK, 1 row(s) in set (0.004475s)
|
Query OK, 1 row(s) in set (0.004475s)
|
||||||
|
|
||||||
taos> SELECT COUNT(*), COUNT(VOLTAGE) FROM d1001;
|
taos> SELECT COUNT(*), COUNT(voltage) FROM d1001;
|
||||||
count(*) | count(voltage) |
|
count(*) | count(voltage) |
|
||||||
================================================
|
================================================
|
||||||
3 | 3 |
|
3 | 3 |
|
||||||
|
@ -620,7 +634,7 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数
|
||||||
11.466666751 | 220.444444444 | 0.293333333 |
|
11.466666751 | 220.444444444 | 0.293333333 |
|
||||||
Query OK, 1 row(s) in set (0.004135s)
|
Query OK, 1 row(s) in set (0.004135s)
|
||||||
|
|
||||||
taos> SELECT AVG(current), AVG(voltage), AVG(phase) from d1001;
|
taos> SELECT AVG(current), AVG(voltage), AVG(phase) FROM d1001;
|
||||||
avg(current) | avg(voltage) | avg(phase) |
|
avg(current) | avg(voltage) | avg(phase) |
|
||||||
====================================================================================
|
====================================================================================
|
||||||
11.733333588 | 219.333333333 | 0.316666673 |
|
11.733333588 | 219.333333333 | 0.316666673 |
|
||||||
|
@ -648,13 +662,13 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数
|
||||||
|
|
||||||
示例:
|
示例:
|
||||||
```mysql
|
```mysql
|
||||||
taos> SELECT SUM(current), SUM(voltage), SUM(phase) from meters;
|
taos> SELECT SUM(current), SUM(voltage), SUM(phase) FROM meters;
|
||||||
sum(current) | sum(voltage) | sum(phase) |
|
sum(current) | sum(voltage) | sum(phase) |
|
||||||
================================================================================
|
================================================================================
|
||||||
103.200000763 | 1984 | 2.640000001 |
|
103.200000763 | 1984 | 2.640000001 |
|
||||||
Query OK, 1 row(s) in set (0.001702s)
|
Query OK, 1 row(s) in set (0.001702s)
|
||||||
|
|
||||||
taos> SELECT SUM(current), SUM(voltage), SUM(phase) from d1001;
|
taos> SELECT SUM(current), SUM(voltage), SUM(phase) FROM d1001;
|
||||||
sum(current) | sum(voltage) | sum(phase) |
|
sum(current) | sum(voltage) | sum(phase) |
|
||||||
================================================================================
|
================================================================================
|
||||||
35.200000763 | 658 | 0.950000018 |
|
35.200000763 | 658 | 0.950000018 |
|
||||||
|
@ -753,7 +767,7 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数
|
||||||
功能说明:统计表/超级表中某列的值最先写入的非NULL值。
|
功能说明:统计表/超级表中某列的值最先写入的非NULL值。
|
||||||
返回结果数据类型:同应用的字段。
|
返回结果数据类型:同应用的字段。
|
||||||
应用字段:所有字段。
|
应用字段:所有字段。
|
||||||
说明:1)如果要返回各个列的首个(时间戳最小)非NULL值,可以使用FIRST(*);2) 如果结果集中的某列全部为NULL值,则该列的返回结果也是NULL;3) 如果结果集中所有列全部为NULL值,则不返回结果。
|
说明:1)如果要返回各个列的首个(时间戳最小)非NULL值,可以使用FIRST(\*);2) 如果结果集中的某列全部为NULL值,则该列的返回结果也是NULL;3) 如果结果集中所有列全部为NULL值,则不返回结果。
|
||||||
|
|
||||||
示例:
|
示例:
|
||||||
```mysql
|
```mysql
|
||||||
|
@ -777,7 +791,7 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数
|
||||||
功能说明:统计表/超级表中某列的值最后写入的非NULL值。
|
功能说明:统计表/超级表中某列的值最后写入的非NULL值。
|
||||||
返回结果数据类型:同应用的字段。
|
返回结果数据类型:同应用的字段。
|
||||||
应用字段:所有字段。
|
应用字段:所有字段。
|
||||||
说明:1)如果要返回各个列的最后(时间戳最大)一个非NULL值,可以使用LAST(*);2)如果结果集中的某列全部为NULL值,则该列的返回结果也是NULL;如果结果集中所有列全部为NULL值,则不返回结果。
|
说明:1)如果要返回各个列的最后(时间戳最大)一个非NULL值,可以使用LAST(\*);2)如果结果集中的某列全部为NULL值,则该列的返回结果也是NULL;如果结果集中所有列全部为NULL值,则不返回结果。
|
||||||
|
|
||||||
示例:
|
示例:
|
||||||
```mysql
|
```mysql
|
||||||
|
@ -1004,15 +1018,15 @@ SELECT function_list FROM stb_name
|
||||||
**示例:** 智能电表的建表语句如下:
|
**示例:** 智能电表的建表语句如下:
|
||||||
|
|
||||||
```mysql
|
```mysql
|
||||||
CREATE TABLE meters (ts timestamp, current float, voltage int, phase float) TAGS (location binary(64), groupId int);
|
CREATE TABLE meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (location BINARY(64), groupId INT);
|
||||||
```
|
```
|
||||||
|
|
||||||
针对智能电表采集的数据,以10分钟为一个阶段,计算过去24小时的电流数据的平均值、最大值、电流的中位数、以及随着时间变化的电流走势拟合直线。如果没有计算值,用前一个非NULL值填充。
|
针对智能电表采集的数据,以10分钟为一个阶段,计算过去24小时的电流数据的平均值、最大值、电流的中位数、以及随着时间变化的电流走势拟合直线。如果没有计算值,用前一个非NULL值填充。
|
||||||
使用的查询语句如下:
|
使用的查询语句如下:
|
||||||
|
|
||||||
```mysql
|
```mysql
|
||||||
SELECT AVG(current),MAX(current),LEASTSQUARES(current, start_val, step_val), PERCENTILE(current, 50) FROM meters
|
SELECT AVG(current), MAX(current), LEASTSQUARES(current, start_val, step_val), PERCENTILE(current, 50) FROM meters
|
||||||
WHERE TS>=NOW-1d
|
WHERE ts>=NOW-1d
|
||||||
INTERVAL(10m)
|
INTERVAL(10m)
|
||||||
FILL(PREV);
|
FILL(PREV);
|
||||||
```
|
```
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
TDengine的集群管理极其简单,除添加和删除节点需要人工干预之外,其他全部是自动完成,最大程度的降低了运维的工作量。本章对集群管理的操作做详细的描述。
|
TDengine的集群管理极其简单,除添加和删除节点需要人工干预之外,其他全部是自动完成,最大程度的降低了运维的工作量。本章对集群管理的操作做详细的描述。
|
||||||
|
|
||||||
|
关于集群搭建请参考<a href="https://www.taosdata.com/blog/2020/11/11/1961.html">视频教程</a>。
|
||||||
|
|
||||||
## 准备工作
|
## 准备工作
|
||||||
|
|
||||||
**第零步**:规划集群所有物理节点的FQDN,将规划好的FQDN分别添加到每个物理节点的/etc/hostname;修改每个物理节点的/etc/hosts,将所有集群物理节点的IP与FQDN的对应添加好。【如部署了DNS,请联系网络管理员在DNS上做好相关配置】
|
**第零步**:规划集群所有物理节点的FQDN,将规划好的FQDN分别添加到每个物理节点的/etc/hostname;修改每个物理节点的/etc/hosts,将所有集群物理节点的IP与FQDN的对应添加好。【如部署了DNS,请联系网络管理员在DNS上做好相关配置】
|
||||||
|
@ -227,4 +229,3 @@ SHOW MNODES;
|
||||||
|
|
||||||
TDengine提供一个执行程序tarbitrator, 找任何一台Linux服务器运行它即可。请点击[安装包下载](https://www.taosdata.com/cn/all-downloads/),在TDengine Arbitrator Linux一节中,选择适合的版本下载并安装。该程序对系统资源几乎没有要求,只需要保证有网络连接即可。该应用的命令行参数`-p`可以指定其对外服务的端口号,缺省是6042。配置每个taosd实例时,可以在配置文件taos.cfg里将参数arbitrator设置为arbitrator的End Point。如果该参数配置了,当副本数为偶数数,系统将自动连接配置的arbitrator。如果副本数为奇数,即使配置了arbitrator, 系统也不会去建立连接。
|
TDengine提供一个执行程序tarbitrator, 找任何一台Linux服务器运行它即可。请点击[安装包下载](https://www.taosdata.com/cn/all-downloads/),在TDengine Arbitrator Linux一节中,选择适合的版本下载并安装。该程序对系统资源几乎没有要求,只需要保证有网络连接即可。该应用的命令行参数`-p`可以指定其对外服务的端口号,缺省是6042。配置每个taosd实例时,可以在配置文件taos.cfg里将参数arbitrator设置为arbitrator的End Point。如果该参数配置了,当副本数为偶数数,系统将自动连接配置的arbitrator。如果副本数为奇数,即使配置了arbitrator, 系统也不会去建立连接。
|
||||||
|
|
||||||
关于集群搭建请参考<a href="https://www.taosdata.com/blog/2020/11/11/1961.html">视频教程</a>。
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
name: tdengine
|
name: tdengine
|
||||||
base: core18
|
base: core18
|
||||||
version: '2.0.12.0'
|
version: '2.0.13.0'
|
||||||
icon: snap/gui/t-dengine.svg
|
icon: snap/gui/t-dengine.svg
|
||||||
summary: an open-source big data platform designed and optimized for IoT.
|
summary: an open-source big data platform designed and optimized for IoT.
|
||||||
description: |
|
description: |
|
||||||
|
@ -72,7 +72,7 @@ parts:
|
||||||
- usr/bin/taosd
|
- usr/bin/taosd
|
||||||
- usr/bin/taos
|
- usr/bin/taos
|
||||||
- usr/bin/taosdemo
|
- usr/bin/taosdemo
|
||||||
- usr/lib/libtaos.so.2.0.12.0
|
- usr/lib/libtaos.so.2.0.13.0
|
||||||
- usr/lib/libtaos.so.1
|
- usr/lib/libtaos.so.1
|
||||||
- usr/lib/libtaos.so
|
- usr/lib/libtaos.so
|
||||||
|
|
||||||
|
|
|
@ -421,7 +421,7 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) {
|
||||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||||
|
|
||||||
// check if it is a sub-query of super table query first, if true, enter another routine
|
// check if it is a sub-query of super table query first, if true, enter another routine
|
||||||
if (TSDB_QUERY_HAS_TYPE(pQueryInfo->type, (TSDB_QUERY_TYPE_STABLE_SUBQUERY|TSDB_QUERY_TYPE_TAG_FILTER_QUERY))) {
|
if (TSDB_QUERY_HAS_TYPE(pQueryInfo->type, (TSDB_QUERY_TYPE_STABLE_SUBQUERY|TSDB_QUERY_TYPE_SUBQUERY|TSDB_QUERY_TYPE_TAG_FILTER_QUERY))) {
|
||||||
tscDebug("%p update local table meta, continue to process sql and send the corresponding query", pSql);
|
tscDebug("%p update local table meta, continue to process sql and send the corresponding query", pSql);
|
||||||
|
|
||||||
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||||
|
|
|
@ -75,11 +75,11 @@ static int32_t insertResultField(SQueryInfo* pQueryInfo, int32_t outputIndex, SC
|
||||||
static int32_t convertFunctionId(int32_t optr, int16_t* functionId);
|
static int32_t convertFunctionId(int32_t optr, int16_t* functionId);
|
||||||
static uint8_t convertOptr(SStrToken *pToken);
|
static uint8_t convertOptr(SStrToken *pToken);
|
||||||
|
|
||||||
static int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSelection, bool isSTable, bool joinQuery);
|
static int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSelection, bool isSTable, bool joinQuery, bool intervalQuery);
|
||||||
|
|
||||||
static bool validateIpAddress(const char* ip, size_t size);
|
static bool validateIpAddress(const char* ip, size_t size);
|
||||||
static bool hasUnsupportFunctionsForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo);
|
static bool hasUnsupportFunctionsForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo);
|
||||||
static bool functionCompatibleCheck(SQueryInfo* pQueryInfo, bool joinQuery);
|
static bool functionCompatibleCheck(SQueryInfo* pQueryInfo, bool joinQuery, bool intervalQuery);
|
||||||
|
|
||||||
static int32_t parseGroupbyClause(SQueryInfo* pQueryInfo, SArray* pList, SSqlCmd* pCmd);
|
static int32_t parseGroupbyClause(SQueryInfo* pQueryInfo, SArray* pList, SSqlCmd* pCmd);
|
||||||
|
|
||||||
|
@ -1475,7 +1475,7 @@ static void addPrimaryTsColIntoResult(SQueryInfo* pQueryInfo) {
|
||||||
pQueryInfo->type |= TSDB_QUERY_TYPE_PROJECTION_QUERY;
|
pQueryInfo->type |= TSDB_QUERY_TYPE_PROJECTION_QUERY;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSelection, bool isSTable, bool joinQuery) {
|
int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSelection, bool isSTable, bool joinQuery, bool intervalQuery) {
|
||||||
assert(pSelection != NULL && pCmd != NULL);
|
assert(pSelection != NULL && pCmd != NULL);
|
||||||
|
|
||||||
const char* msg2 = "functions can not be mixed up";
|
const char* msg2 = "functions can not be mixed up";
|
||||||
|
@ -1531,7 +1531,7 @@ int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSel
|
||||||
addPrimaryTsColIntoResult(pQueryInfo);
|
addPrimaryTsColIntoResult(pQueryInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!functionCompatibleCheck(pQueryInfo, joinQuery)) {
|
if (!functionCompatibleCheck(pQueryInfo, joinQuery, intervalQuery)) {
|
||||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2810,7 +2810,7 @@ bool hasUnsupportFunctionsForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool functionCompatibleCheck(SQueryInfo* pQueryInfo, bool joinQuery) {
|
static bool functionCompatibleCheck(SQueryInfo* pQueryInfo, bool joinQuery, bool intervalQuery) {
|
||||||
int32_t startIdx = 0;
|
int32_t startIdx = 0;
|
||||||
|
|
||||||
size_t numOfExpr = tscSqlExprNumOfExprs(pQueryInfo);
|
size_t numOfExpr = tscSqlExprNumOfExprs(pQueryInfo);
|
||||||
|
@ -2826,6 +2826,10 @@ static bool functionCompatibleCheck(SQueryInfo* pQueryInfo, bool joinQuery) {
|
||||||
|
|
||||||
int32_t factor = functionCompatList[tscSqlExprGet(pQueryInfo, startIdx)->functionId];
|
int32_t factor = functionCompatList[tscSqlExprGet(pQueryInfo, startIdx)->functionId];
|
||||||
|
|
||||||
|
if (tscSqlExprGet(pQueryInfo, 0)->functionId == TSDB_FUNC_LAST_ROW && (joinQuery || intervalQuery)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// diff function cannot be executed with other function
|
// diff function cannot be executed with other function
|
||||||
// arithmetic function can be executed with other arithmetic functions
|
// arithmetic function can be executed with other arithmetic functions
|
||||||
size_t size = tscSqlExprNumOfExprs(pQueryInfo);
|
size_t size = tscSqlExprNumOfExprs(pQueryInfo);
|
||||||
|
@ -2850,7 +2854,7 @@ static bool functionCompatibleCheck(SQueryInfo* pQueryInfo, bool joinQuery) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (functionId == TSDB_FUNC_LAST_ROW && joinQuery) {
|
if (functionId == TSDB_FUNC_LAST_ROW && (joinQuery || intervalQuery)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4594,8 +4598,8 @@ static void setDefaultOrderInfo(SQueryInfo* pQueryInfo) {
|
||||||
int32_t parseOrderbyClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql, SSchema* pSchema) {
|
int32_t parseOrderbyClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql, SSchema* pSchema) {
|
||||||
const char* msg0 = "only support order by primary timestamp";
|
const char* msg0 = "only support order by primary timestamp";
|
||||||
const char* msg1 = "invalid column name";
|
const char* msg1 = "invalid column name";
|
||||||
const char* msg2 = "only support order by primary timestamp or queried column";
|
const char* msg2 = "only support order by primary timestamp or first tag in groupby clause allowed";
|
||||||
const char* msg3 = "only support order by primary timestamp or first tag in groupby clause";
|
const char* msg3 = "invalid column in order by clause, only primary timestamp or first tag in groupby clause allowed";
|
||||||
|
|
||||||
setDefaultOrderInfo(pQueryInfo);
|
setDefaultOrderInfo(pQueryInfo);
|
||||||
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||||
|
@ -5275,8 +5279,7 @@ int32_t parseLimitClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t clauseIn
|
||||||
|
|
||||||
const char* msg0 = "soffset/offset can not be less than 0";
|
const char* msg0 = "soffset/offset can not be less than 0";
|
||||||
const char* msg1 = "slimit/soffset only available for STable query";
|
const char* msg1 = "slimit/soffset only available for STable query";
|
||||||
const char* msg2 = "functions mixed up in table query";
|
const char* msg2 = "slimit/soffset can not apply to projection query";
|
||||||
const char* msg3 = "slimit/soffset can not apply to projection query";
|
|
||||||
|
|
||||||
// handle the limit offset value, validate the limit
|
// handle the limit offset value, validate the limit
|
||||||
pQueryInfo->limit = pQuerySql->limit;
|
pQueryInfo->limit = pQuerySql->limit;
|
||||||
|
@ -5301,7 +5304,7 @@ int32_t parseLimitClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t clauseIn
|
||||||
if (!tscQueryTags(pQueryInfo)) { // local handle the super table tag query
|
if (!tscQueryTags(pQueryInfo)) { // local handle the super table tag query
|
||||||
if (tscIsProjectionQueryOnSTable(pQueryInfo, 0)) {
|
if (tscIsProjectionQueryOnSTable(pQueryInfo, 0)) {
|
||||||
if (pQueryInfo->slimit.limit > 0 || pQueryInfo->slimit.offset > 0) {
|
if (pQueryInfo->slimit.limit > 0 || pQueryInfo->slimit.offset > 0) {
|
||||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// for projection query on super table, all queries are subqueries
|
// for projection query on super table, all queries are subqueries
|
||||||
|
@ -5359,24 +5362,6 @@ int32_t parseLimitClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t clauseIn
|
||||||
if (pQueryInfo->slimit.limit != -1 || pQueryInfo->slimit.offset != 0) {
|
if (pQueryInfo->slimit.limit != -1 || pQueryInfo->slimit.offset != 0) {
|
||||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t size = taosArrayGetSize(pQueryInfo->exprList);
|
|
||||||
|
|
||||||
bool hasTags = false;
|
|
||||||
bool hasOtherFunc = false;
|
|
||||||
// filter the query functions operating on "tbname" column that are not supported by normal columns.
|
|
||||||
for (int32_t i = 0; i < size; ++i) {
|
|
||||||
SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
|
|
||||||
if (TSDB_COL_IS_TAG(pExpr->colInfo.flag)) {
|
|
||||||
hasTags = true;
|
|
||||||
} else {
|
|
||||||
hasOtherFunc = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasTags && hasOtherFunc) {
|
|
||||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
@ -5848,14 +5833,43 @@ static int32_t doAddGroupbyColumnsOnDemand(SSqlCmd* pCmd, SQueryInfo* pQueryInfo
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t doTagFunctionCheck(SQueryInfo* pQueryInfo) {
|
||||||
|
bool tagProjection = false;
|
||||||
|
bool tableCounting = false;
|
||||||
|
|
||||||
|
int32_t numOfCols = (int32_t) tscSqlExprNumOfExprs(pQueryInfo);
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < numOfCols; ++i) {
|
||||||
|
SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
|
||||||
|
int32_t functionId = pExpr->functionId;
|
||||||
|
|
||||||
|
if (functionId == TSDB_FUNC_TAGPRJ) {
|
||||||
|
tagProjection = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (functionId == TSDB_FUNC_COUNT) {
|
||||||
|
assert(pExpr->colInfo.colId == TSDB_TBNAME_COLUMN_INDEX);
|
||||||
|
tableCounting = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (tableCounting && tagProjection)? -1:0;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) {
|
int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) {
|
||||||
const char* msg1 = "functions/columns not allowed in group by query";
|
const char* msg1 = "functions/columns not allowed in group by query";
|
||||||
const char* msg2 = "projection query on columns not allowed";
|
const char* msg2 = "projection query on columns not allowed";
|
||||||
const char* msg3 = "group by not allowed on projection query";
|
const char* msg3 = "group by not allowed on projection query";
|
||||||
const char* msg4 = "retrieve tags not compatible with group by or interval query";
|
const char* msg4 = "retrieve tags not compatible with group by or interval query";
|
||||||
|
const char* msg5 = "functions can not be mixed up";
|
||||||
|
|
||||||
// only retrieve tags, group by is not supportted
|
// only retrieve tags, group by is not supportted
|
||||||
if (tscQueryTags(pQueryInfo)) {
|
if (tscQueryTags(pQueryInfo)) {
|
||||||
|
if (doTagFunctionCheck(pQueryInfo) != TSDB_CODE_SUCCESS) {
|
||||||
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
|
||||||
|
}
|
||||||
|
|
||||||
if (pQueryInfo->groupbyExpr.numOfGroupCols > 0 || pQueryInfo->interval.interval > 0) {
|
if (pQueryInfo->groupbyExpr.numOfGroupCols > 0 || pQueryInfo->interval.interval > 0) {
|
||||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
|
||||||
} else {
|
} else {
|
||||||
|
@ -6278,10 +6292,12 @@ int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) {
|
||||||
|
|
||||||
int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) {
|
int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) {
|
||||||
const char* msg1 = "invalid table name";
|
const char* msg1 = "invalid table name";
|
||||||
|
const char* msg2 = "functions not allowed in CQ";
|
||||||
const char* msg3 = "fill only available for interval query";
|
const char* msg3 = "fill only available for interval query";
|
||||||
const char* msg4 = "fill option not supported in stream computing";
|
const char* msg4 = "fill option not supported in stream computing";
|
||||||
const char* msg5 = "sql too long"; // todo ADD support
|
const char* msg5 = "sql too long"; // todo ADD support
|
||||||
const char* msg6 = "from missing in subclause";
|
const char* msg6 = "from missing in subclause";
|
||||||
|
const char* msg7 = "time interval is required";
|
||||||
|
|
||||||
SSqlCmd* pCmd = &pSql->cmd;
|
SSqlCmd* pCmd = &pSql->cmd;
|
||||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
|
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
|
||||||
|
@ -6291,10 +6307,10 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) {
|
||||||
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||||
|
|
||||||
// if sql specifies db, use it, otherwise use default db
|
// if sql specifies db, use it, otherwise use default db
|
||||||
SStrToken* pzTableName = &(pCreateTable->name);
|
SStrToken* pName = &(pCreateTable->name);
|
||||||
SQuerySQL* pQuerySql = pCreateTable->pSelect;
|
SQuerySQL* pQuerySql = pCreateTable->pSelect;
|
||||||
|
|
||||||
if (tscValidateName(pzTableName) != TSDB_CODE_SUCCESS) {
|
if (tscValidateName(pName) != TSDB_CODE_SUCCESS) {
|
||||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6320,7 +6336,7 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isSTable = UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo);
|
bool isSTable = UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo);
|
||||||
if (parseSelectClause(&pSql->cmd, 0, pQuerySql->pSelection, isSTable, false) != TSDB_CODE_SUCCESS) {
|
if (parseSelectClause(&pSql->cmd, 0, pQuerySql->pSelection, isSTable, false, false) != TSDB_CODE_SUCCESS) {
|
||||||
return TSDB_CODE_TSC_INVALID_SQL;
|
return TSDB_CODE_TSC_INVALID_SQL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6333,15 +6349,19 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) {
|
||||||
// set interval value
|
// set interval value
|
||||||
if (parseIntervalClause(pSql, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
|
if (parseIntervalClause(pSql, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
|
||||||
return TSDB_CODE_TSC_INVALID_SQL;
|
return TSDB_CODE_TSC_INVALID_SQL;
|
||||||
} else {
|
}
|
||||||
if ((pQueryInfo->interval.interval > 0) &&
|
|
||||||
(validateFunctionsInIntervalOrGroupbyQuery(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS)) {
|
if ((pQueryInfo->interval.interval > 0) &&
|
||||||
return TSDB_CODE_TSC_INVALID_SQL;
|
(validateFunctionsInIntervalOrGroupbyQuery(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS)) {
|
||||||
}
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tscIsProjectionQuery(pQueryInfo) && pQueryInfo->interval.interval == 0) {
|
||||||
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the created table[stream] name
|
// set the created table[stream] name
|
||||||
code = tscSetTableFullName(pTableMetaInfo, pzTableName, pSql);
|
code = tscSetTableFullName(pTableMetaInfo, pName, pSql);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -6565,7 +6585,9 @@ int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) {
|
||||||
|
|
||||||
int32_t joinQuery = (pQuerySql->from != NULL && taosArrayGetSize(pQuerySql->from) > 2);
|
int32_t joinQuery = (pQuerySql->from != NULL && taosArrayGetSize(pQuerySql->from) > 2);
|
||||||
|
|
||||||
if (parseSelectClause(pCmd, index, pQuerySql->pSelection, isSTable, joinQuery) != TSDB_CODE_SUCCESS) {
|
int32_t intervalQuery = !(pQuerySql->interval.type == 0 || pQuerySql->interval.n == 0);
|
||||||
|
|
||||||
|
if (parseSelectClause(pCmd, index, pQuerySql->pSelection, isSTable, joinQuery, intervalQuery) != TSDB_CODE_SUCCESS) {
|
||||||
return TSDB_CODE_TSC_INVALID_SQL;
|
return TSDB_CODE_TSC_INVALID_SQL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,44 +65,51 @@ static int64_t tscGetRetryDelayTime(SSqlStream* pStream, int64_t slidingTime, in
|
||||||
return retryDelta;
|
return retryDelta;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tscProcessStreamLaunchQuery(SSchedMsg *pMsg) {
|
static void doLaunchQuery(void* param, TAOS_RES* tres, int32_t code) {
|
||||||
SSqlStream *pStream = (SSqlStream *)pMsg->ahandle;
|
SSqlStream *pStream = (SSqlStream *)param;
|
||||||
SSqlObj * pSql = pStream->pSql;
|
assert(pStream->pSql == tres && code == TSDB_CODE_SUCCESS);
|
||||||
|
|
||||||
pSql->fp = tscProcessStreamQueryCallback;
|
SSqlObj* pSql = (SSqlObj*) tres;
|
||||||
pSql->fetchFp = tscProcessStreamQueryCallback;
|
pSql->fp = doLaunchQuery;
|
||||||
pSql->param = pStream;
|
pSql->fetchFp = doLaunchQuery;
|
||||||
pSql->res.completed = false;
|
pSql->res.completed = false;
|
||||||
|
|
||||||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0);
|
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0);
|
||||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||||
|
|
||||||
int code = tscGetTableMeta(pSql, pTableMetaInfo);
|
code = tscGetTableMeta(pSql, pTableMetaInfo);
|
||||||
pSql->res.code = code;
|
|
||||||
|
|
||||||
if (code == 0 && UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
|
if (code == 0 && UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
|
||||||
code = tscGetSTableVgroupInfo(pSql, 0);
|
code = tscGetSTableVgroupInfo(pSql, 0);
|
||||||
pSql->res.code = code;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// failed to get meter/metric meta, retry in 10sec.
|
// failed to get table Meta or vgroup list, retry in 10sec.
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code == TSDB_CODE_SUCCESS) {
|
||||||
int64_t retryDelayTime = tscGetRetryDelayTime(pStream, pStream->interval.sliding, pStream->precision);
|
|
||||||
tscDebug("%p stream:%p,get metermeta failed, retry in %" PRId64 "ms", pStream->pSql, pStream, retryDelayTime);
|
|
||||||
tscSetRetryTimer(pStream, pSql, retryDelayTime);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
tscTansformSQLFuncForSTableQuery(pQueryInfo);
|
tscTansformSQLFuncForSTableQuery(pQueryInfo);
|
||||||
tscDebug("%p stream:%p start stream query on:%s", pSql, pStream, pTableMetaInfo->name);
|
tscDebug("%p stream:%p, start stream query on:%s", pSql, pStream, pTableMetaInfo->name);
|
||||||
tscDoQuery(pStream->pSql);
|
|
||||||
|
pSql->fp = tscProcessStreamQueryCallback;
|
||||||
|
pSql->fetchFp = tscProcessStreamQueryCallback;
|
||||||
|
tscDoQuery(pSql);
|
||||||
tscIncStreamExecutionCount(pStream);
|
tscIncStreamExecutionCount(pStream);
|
||||||
|
} else if (code != TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||||
|
pSql->res.code = code;
|
||||||
|
int64_t retryDelayTime = tscGetRetryDelayTime(pStream, pStream->interval.sliding, pStream->precision);
|
||||||
|
tscDebug("%p stream:%p, get table Meta failed, retry in %" PRId64 "ms", pSql, pStream, retryDelayTime);
|
||||||
|
tscSetRetryTimer(pStream, pSql, retryDelayTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void tscProcessStreamLaunchQuery(SSchedMsg *pMsg) {
|
||||||
|
SSqlStream *pStream = (SSqlStream *)pMsg->ahandle;
|
||||||
|
doLaunchQuery(pStream, pStream->pSql, 0);
|
||||||
|
}
|
||||||
|
|
||||||
static void tscProcessStreamTimer(void *handle, void *tmrId) {
|
static void tscProcessStreamTimer(void *handle, void *tmrId) {
|
||||||
SSqlStream *pStream = (SSqlStream *)handle;
|
SSqlStream *pStream = (SSqlStream *)handle;
|
||||||
if (pStream == NULL) return;
|
if (pStream == NULL || pStream->pTimer != tmrId) {
|
||||||
if (pStream->pTimer != tmrId) return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
pStream->pTimer = NULL;
|
pStream->pTimer = NULL;
|
||||||
|
|
||||||
pStream->numOfRes = 0; // reset the numOfRes.
|
pStream->numOfRes = 0; // reset the numOfRes.
|
||||||
|
@ -392,11 +399,16 @@ static void tscSetNextLaunchTimer(SSqlStream *pStream, SSqlObj *pSql) {
|
||||||
tscSetRetryTimer(pStream, pSql, timer);
|
tscSetRetryTimer(pStream, pSql, timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tscSetSlidingWindowInfo(SSqlObj *pSql, SSqlStream *pStream) {
|
static int32_t tscSetSlidingWindowInfo(SSqlObj *pSql, SSqlStream *pStream) {
|
||||||
int64_t minIntervalTime =
|
int64_t minIntervalTime =
|
||||||
(pStream->precision == TSDB_TIME_PRECISION_MICRO) ? tsMinIntervalTime * 1000L : tsMinIntervalTime;
|
(pStream->precision == TSDB_TIME_PRECISION_MICRO) ? tsMinIntervalTime * 1000L : tsMinIntervalTime;
|
||||||
|
|
||||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0);
|
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0);
|
||||||
|
|
||||||
|
if (!pStream->isProject && pQueryInfo->interval.interval == 0) {
|
||||||
|
sprintf(pSql->cmd.payload, "the interval value is 0");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (pQueryInfo->interval.intervalUnit != 'n' && pQueryInfo->interval.intervalUnit!= 'y' && pQueryInfo->interval.interval < minIntervalTime) {
|
if (pQueryInfo->interval.intervalUnit != 'n' && pQueryInfo->interval.intervalUnit!= 'y' && pQueryInfo->interval.interval < minIntervalTime) {
|
||||||
tscWarn("%p stream:%p, original sample interval:%" PRId64 " too small, reset to:%" PRId64, pSql, pStream,
|
tscWarn("%p stream:%p, original sample interval:%" PRId64 " too small, reset to:%" PRId64, pSql, pStream,
|
||||||
|
@ -436,6 +448,8 @@ static void tscSetSlidingWindowInfo(SSqlObj *pSql, SSqlStream *pStream) {
|
||||||
pQueryInfo->interval.interval = 0; // clear the interval value to avoid the force time window split by query processor
|
pQueryInfo->interval.interval = 0; // clear the interval value to avoid the force time window split by query processor
|
||||||
pQueryInfo->interval.sliding = 0;
|
pQueryInfo->interval.sliding = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int64_t tscGetStreamStartTimestamp(SSqlObj *pSql, SSqlStream *pStream, int64_t stime) {
|
static int64_t tscGetStreamStartTimestamp(SSqlObj *pSql, SSqlStream *pStream, int64_t stime) {
|
||||||
|
@ -485,34 +499,19 @@ static int64_t tscGetLaunchTimestamp(const SSqlStream *pStream) {
|
||||||
return (pStream->precision == TSDB_TIME_PRECISION_MICRO) ? timer / 1000L : timer;
|
return (pStream->precision == TSDB_TIME_PRECISION_MICRO) ? timer / 1000L : timer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setErrorInfo(SSqlObj* pSql, int32_t code, char* info) {
|
|
||||||
if (pSql == NULL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SSqlCmd* pCmd = &pSql->cmd;
|
|
||||||
|
|
||||||
pSql->res.code = code;
|
|
||||||
|
|
||||||
if (info != NULL) {
|
|
||||||
strncpy(pCmd->payload, info, pCmd->payloadLen);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void tscCreateStream(void *param, TAOS_RES *res, int code) {
|
static void tscCreateStream(void *param, TAOS_RES *res, int code) {
|
||||||
SSqlStream* pStream = (SSqlStream*)param;
|
SSqlStream* pStream = (SSqlStream*)param;
|
||||||
SSqlObj* pSql = pStream->pSql;
|
SSqlObj* pSql = pStream->pSql;
|
||||||
SSqlCmd* pCmd = &pSql->cmd;
|
SSqlCmd* pCmd = &pSql->cmd;
|
||||||
|
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
setErrorInfo(pSql, code, pCmd->payload);
|
pSql->res.code = code;
|
||||||
tscError("%p open stream failed, sql:%s, reason:%s, code:0x%08x", pSql, pSql->sqlstr, pCmd->payload, code);
|
tscError("%p open stream failed, sql:%s, reason:%s, code:%s", pSql, pSql->sqlstr, pCmd->payload, tstrerror(code));
|
||||||
|
|
||||||
pStream->fp(pStream->param, NULL, NULL);
|
pStream->fp(pStream->param, NULL, NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
registerSqlObj(pSql);
|
|
||||||
|
|
||||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
|
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
|
||||||
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||||
STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
|
STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
|
||||||
|
@ -523,13 +522,22 @@ static void tscCreateStream(void *param, TAOS_RES *res, int code) {
|
||||||
pStream->ctime = taosGetTimestamp(pStream->precision);
|
pStream->ctime = taosGetTimestamp(pStream->precision);
|
||||||
pStream->etime = pQueryInfo->window.ekey;
|
pStream->etime = pQueryInfo->window.ekey;
|
||||||
|
|
||||||
tscAddIntoStreamList(pStream);
|
if (tscSetSlidingWindowInfo(pSql, pStream) != TSDB_CODE_SUCCESS) {
|
||||||
|
pSql->res.code = code;
|
||||||
|
|
||||||
|
tscError("%p stream %p open failed, since the interval value is incorrect", pSql, pStream);
|
||||||
|
pStream->fp(pStream->param, NULL, NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
tscSetSlidingWindowInfo(pSql, pStream);
|
|
||||||
pStream->stime = tscGetStreamStartTimestamp(pSql, pStream, pStream->stime);
|
pStream->stime = tscGetStreamStartTimestamp(pSql, pStream, pStream->stime);
|
||||||
|
|
||||||
int64_t starttime = tscGetLaunchTimestamp(pStream);
|
int64_t starttime = tscGetLaunchTimestamp(pStream);
|
||||||
pCmd->command = TSDB_SQL_SELECT;
|
pCmd->command = TSDB_SQL_SELECT;
|
||||||
|
|
||||||
|
registerSqlObj(pSql);
|
||||||
|
tscAddIntoStreamList(pStream);
|
||||||
|
|
||||||
taosTmrReset(tscProcessStreamTimer, (int32_t)starttime, pStream, tscTmr, &pStream->pTimer);
|
taosTmrReset(tscProcessStreamTimer, (int32_t)starttime, pStream, tscTmr, &pStream->pTimer);
|
||||||
|
|
||||||
tscDebug("%p stream:%p is opened, query on:%s, interval:%" PRId64 ", sliding:%" PRId64 ", first launched in:%" PRId64 ", sql:%s", pSql,
|
tscDebug("%p stream:%p is opened, query on:%s, interval:%" PRId64 ", sliding:%" PRId64 ", first launched in:%" PRId64 ", sql:%s", pSql,
|
||||||
|
|
|
@ -188,8 +188,10 @@ static int64_t doTSBlockIntersect(SSqlObj* pSql, SJoinSupporter* pSupporter1, SJ
|
||||||
tsBufFlush(output2);
|
tsBufFlush(output2);
|
||||||
|
|
||||||
tsBufDestroy(pSupporter1->pTSBuf);
|
tsBufDestroy(pSupporter1->pTSBuf);
|
||||||
|
pSupporter1->pTSBuf = NULL;
|
||||||
tsBufDestroy(pSupporter2->pTSBuf);
|
tsBufDestroy(pSupporter2->pTSBuf);
|
||||||
|
pSupporter2->pTSBuf = NULL;
|
||||||
|
|
||||||
TSKEY et = taosGetTimestampUs();
|
TSKEY et = taosGetTimestampUs();
|
||||||
tscDebug("%p input1:%" PRId64 ", input2:%" PRId64 ", final:%" PRId64 " in %d vnodes for secondary query after ts blocks "
|
tscDebug("%p input1:%" PRId64 ", input2:%" PRId64 ", final:%" PRId64 " in %d vnodes for secondary query after ts blocks "
|
||||||
"intersecting, skey:%" PRId64 ", ekey:%" PRId64 ", numOfVnode:%d, elapsed time:%" PRId64 " us",
|
"intersecting, skey:%" PRId64 ", ekey:%" PRId64 ", numOfVnode:%d, elapsed time:%" PRId64 " us",
|
||||||
|
@ -219,12 +221,9 @@ SJoinSupporter* tscCreateJoinSupporter(SSqlObj* pSql, int32_t index) {
|
||||||
assert (pSupporter->uid != 0);
|
assert (pSupporter->uid != 0);
|
||||||
|
|
||||||
taosGetTmpfilePath("join-", pSupporter->path);
|
taosGetTmpfilePath("join-", pSupporter->path);
|
||||||
pSupporter->f = fopen(pSupporter->path, "w");
|
|
||||||
|
|
||||||
// todo handle error
|
// do NOT create file here to reduce crash generated file left issue
|
||||||
if (pSupporter->f == NULL) {
|
pSupporter->f = NULL;
|
||||||
tscError("%p failed to create tmp file:%s, reason:%s", pSql, pSupporter->path, strerror(errno));
|
|
||||||
}
|
|
||||||
|
|
||||||
return pSupporter;
|
return pSupporter;
|
||||||
}
|
}
|
||||||
|
@ -244,12 +243,19 @@ static void tscDestroyJoinSupporter(SJoinSupporter* pSupporter) {
|
||||||
|
|
||||||
tscFieldInfoClear(&pSupporter->fieldsInfo);
|
tscFieldInfoClear(&pSupporter->fieldsInfo);
|
||||||
|
|
||||||
|
if (pSupporter->pTSBuf != NULL) {
|
||||||
|
tsBufDestroy(pSupporter->pTSBuf);
|
||||||
|
pSupporter->pTSBuf = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
unlink(pSupporter->path);
|
||||||
|
|
||||||
if (pSupporter->f != NULL) {
|
if (pSupporter->f != NULL) {
|
||||||
fclose(pSupporter->f);
|
fclose(pSupporter->f);
|
||||||
unlink(pSupporter->path);
|
|
||||||
pSupporter->f = NULL;
|
pSupporter->f = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (pSupporter->pVgroupTables != NULL) {
|
if (pSupporter->pVgroupTables != NULL) {
|
||||||
taosArrayDestroy(pSupporter->pVgroupTables);
|
taosArrayDestroy(pSupporter->pVgroupTables);
|
||||||
pSupporter->pVgroupTables = NULL;
|
pSupporter->pVgroupTables = NULL;
|
||||||
|
@ -526,6 +532,8 @@ static void quitAllSubquery(SSqlObj* pSqlObj, SJoinSupporter* pSupporter) {
|
||||||
tscError("%p all subquery return and query failed, global code:%s", pSqlObj, tstrerror(pSqlObj->res.code));
|
tscError("%p all subquery return and query failed, global code:%s", pSqlObj, tstrerror(pSqlObj->res.code));
|
||||||
freeJoinSubqueryObj(pSqlObj);
|
freeJoinSubqueryObj(pSqlObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tscDestroyJoinSupporter(pSupporter);
|
||||||
}
|
}
|
||||||
|
|
||||||
// update the query time range according to the join results on timestamp
|
// update the query time range according to the join results on timestamp
|
||||||
|
@ -921,6 +929,22 @@ static void tsCompRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow
|
||||||
}
|
}
|
||||||
|
|
||||||
if (numOfRows > 0) { // write the compressed timestamp to disk file
|
if (numOfRows > 0) { // write the compressed timestamp to disk file
|
||||||
|
if(pSupporter->f == NULL) {
|
||||||
|
pSupporter->f = fopen(pSupporter->path, "w");
|
||||||
|
|
||||||
|
if (pSupporter->f == NULL) {
|
||||||
|
tscError("%p failed to create tmp file:%s, reason:%s", pSql, pSupporter->path, strerror(errno));
|
||||||
|
|
||||||
|
pParentSql->res.code = TAOS_SYSTEM_ERROR(errno);
|
||||||
|
|
||||||
|
quitAllSubquery(pParentSql, pSupporter);
|
||||||
|
|
||||||
|
tscAsyncResultOnError(pParentSql);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fwrite(pRes->data, (size_t)pRes->numOfRows, 1, pSupporter->f);
|
fwrite(pRes->data, (size_t)pRes->numOfRows, 1, pSupporter->f);
|
||||||
fclose(pSupporter->f);
|
fclose(pSupporter->f);
|
||||||
pSupporter->f = NULL;
|
pSupporter->f = NULL;
|
||||||
|
@ -930,6 +954,9 @@ static void tsCompRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow
|
||||||
tscError("%p invalid ts comp file from vnode, abort subquery, file size:%d", pSql, numOfRows);
|
tscError("%p invalid ts comp file from vnode, abort subquery, file size:%d", pSql, numOfRows);
|
||||||
|
|
||||||
pParentSql->res.code = TAOS_SYSTEM_ERROR(errno);
|
pParentSql->res.code = TAOS_SYSTEM_ERROR(errno);
|
||||||
|
|
||||||
|
quitAllSubquery(pParentSql, pSupporter);
|
||||||
|
|
||||||
tscAsyncResultOnError(pParentSql);
|
tscAsyncResultOnError(pParentSql);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -2094,6 +2121,13 @@ static SSqlObj *tscCreateSTableSubquery(SSqlObj *pSql, SRetrieveSupport *trsuppo
|
||||||
}
|
}
|
||||||
|
|
||||||
void tscRetrieveDataRes(void *param, TAOS_RES *tres, int code) {
|
void tscRetrieveDataRes(void *param, TAOS_RES *tres, int code) {
|
||||||
|
// the param may be null, since it may be done by other query threads. and the asyncOnError may enter in this
|
||||||
|
// function while kill query by a user.
|
||||||
|
if (param == NULL) {
|
||||||
|
assert(code != TSDB_CODE_SUCCESS);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
SRetrieveSupport *trsupport = (SRetrieveSupport *) param;
|
SRetrieveSupport *trsupport = (SRetrieveSupport *) param;
|
||||||
|
|
||||||
SSqlObj* pParentSql = trsupport->pParentSql;
|
SSqlObj* pParentSql = trsupport->pParentSql;
|
||||||
|
|
|
@ -19,136 +19,137 @@ using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace TDengineDriver
|
namespace TDengineDriver
|
||||||
{
|
{
|
||||||
enum TDengineDataType {
|
enum TDengineDataType
|
||||||
TSDB_DATA_TYPE_NULL = 0, // 1 bytes
|
|
||||||
TSDB_DATA_TYPE_BOOL = 1, // 1 bytes
|
|
||||||
TSDB_DATA_TYPE_TINYINT = 2, // 1 bytes
|
|
||||||
TSDB_DATA_TYPE_SMALLINT = 3, // 2 bytes
|
|
||||||
TSDB_DATA_TYPE_INT = 4, // 4 bytes
|
|
||||||
TSDB_DATA_TYPE_BIGINT = 5, // 8 bytes
|
|
||||||
TSDB_DATA_TYPE_FLOAT = 6, // 4 bytes
|
|
||||||
TSDB_DATA_TYPE_DOUBLE = 7, // 8 bytes
|
|
||||||
TSDB_DATA_TYPE_BINARY = 8, // string
|
|
||||||
TSDB_DATA_TYPE_TIMESTAMP = 9,// 8 bytes
|
|
||||||
TSDB_DATA_TYPE_NCHAR = 10 // unicode string
|
|
||||||
}
|
|
||||||
|
|
||||||
enum TDengineInitOption
|
|
||||||
{
|
|
||||||
TSDB_OPTION_LOCALE = 0,
|
|
||||||
TSDB_OPTION_CHARSET = 1,
|
|
||||||
TSDB_OPTION_TIMEZONE = 2,
|
|
||||||
TDDB_OPTION_CONFIGDIR = 3,
|
|
||||||
TDDB_OPTION_SHELL_ACTIVITY_TIMER = 4
|
|
||||||
}
|
|
||||||
|
|
||||||
class TDengineMeta
|
|
||||||
{
|
|
||||||
public string name;
|
|
||||||
public short size;
|
|
||||||
public byte type;
|
|
||||||
public string TypeName()
|
|
||||||
{
|
{
|
||||||
switch ((TDengineDataType)type)
|
TSDB_DATA_TYPE_NULL = 0, // 1 bytes
|
||||||
{
|
TSDB_DATA_TYPE_BOOL = 1, // 1 bytes
|
||||||
case TDengineDataType.TSDB_DATA_TYPE_BOOL:
|
TSDB_DATA_TYPE_TINYINT = 2, // 1 bytes
|
||||||
return "BOOLEAN";
|
TSDB_DATA_TYPE_SMALLINT = 3, // 2 bytes
|
||||||
case TDengineDataType.TSDB_DATA_TYPE_TINYINT:
|
TSDB_DATA_TYPE_INT = 4, // 4 bytes
|
||||||
return "BYTE";
|
TSDB_DATA_TYPE_BIGINT = 5, // 8 bytes
|
||||||
case TDengineDataType.TSDB_DATA_TYPE_SMALLINT:
|
TSDB_DATA_TYPE_FLOAT = 6, // 4 bytes
|
||||||
return "SHORT";
|
TSDB_DATA_TYPE_DOUBLE = 7, // 8 bytes
|
||||||
case TDengineDataType.TSDB_DATA_TYPE_INT:
|
TSDB_DATA_TYPE_BINARY = 8, // string
|
||||||
return "INT";
|
TSDB_DATA_TYPE_TIMESTAMP = 9,// 8 bytes
|
||||||
case TDengineDataType.TSDB_DATA_TYPE_BIGINT:
|
TSDB_DATA_TYPE_NCHAR = 10 // unicode string
|
||||||
return "LONG";
|
|
||||||
case TDengineDataType.TSDB_DATA_TYPE_FLOAT:
|
|
||||||
return "FLOAT";
|
|
||||||
case TDengineDataType.TSDB_DATA_TYPE_DOUBLE:
|
|
||||||
return "DOUBLE";
|
|
||||||
case TDengineDataType.TSDB_DATA_TYPE_BINARY:
|
|
||||||
return "STRING";
|
|
||||||
case TDengineDataType.TSDB_DATA_TYPE_TIMESTAMP:
|
|
||||||
return "TIMESTAMP";
|
|
||||||
case TDengineDataType.TSDB_DATA_TYPE_NCHAR:
|
|
||||||
return "NCHAR";
|
|
||||||
default:
|
|
||||||
return "undefine";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class TDengine
|
|
||||||
{
|
|
||||||
public const int TSDB_CODE_SUCCESS = 0;
|
|
||||||
|
|
||||||
[DllImport("taos.dll", EntryPoint = "taos_init", CallingConvention = CallingConvention.Cdecl)]
|
|
||||||
static extern public void Init();
|
|
||||||
|
|
||||||
[DllImport("taos.dll", EntryPoint = "taos_cleanup", CallingConvention = CallingConvention.Cdecl)]
|
|
||||||
static extern public void Cleanup();
|
|
||||||
|
|
||||||
[DllImport("taos.dll", EntryPoint = "taos_options", CallingConvention = CallingConvention.Cdecl)]
|
|
||||||
static extern public void Options(int option, string value);
|
|
||||||
|
|
||||||
[DllImport("taos.dll", EntryPoint = "taos_connect", CallingConvention = CallingConvention.Cdecl)]
|
|
||||||
static extern public IntPtr Connect(string ip, string user, string password, string db, short port);
|
|
||||||
|
|
||||||
[DllImport("taos.dll", EntryPoint = "taos_errstr", CallingConvention = CallingConvention.Cdecl)]
|
|
||||||
static extern private IntPtr taos_errstr(IntPtr res);
|
|
||||||
static public string Error(IntPtr res)
|
|
||||||
{
|
|
||||||
IntPtr errPtr = taos_errstr(res);
|
|
||||||
return Marshal.PtrToStringAnsi(errPtr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[DllImport("taos.dll", EntryPoint = "taos_errno", CallingConvention = CallingConvention.Cdecl)]
|
enum TDengineInitOption
|
||||||
static extern public int ErrorNo(IntPtr res);
|
|
||||||
|
|
||||||
[DllImport("taos.dll", EntryPoint = "taos_query", CallingConvention = CallingConvention.Cdecl)]
|
|
||||||
static extern public IntPtr Query(IntPtr conn, string sqlstr);
|
|
||||||
|
|
||||||
[DllImport("taos.dll", EntryPoint = "taos_affected_rows", CallingConvention = CallingConvention.Cdecl)]
|
|
||||||
static extern public int AffectRows(IntPtr res);
|
|
||||||
|
|
||||||
[DllImport("taos.dll", EntryPoint = "taos_field_count", CallingConvention = CallingConvention.Cdecl)]
|
|
||||||
static extern public int FieldCount(IntPtr res);
|
|
||||||
|
|
||||||
[DllImport("taos.dll", EntryPoint = "taos_fetch_fields", CallingConvention = CallingConvention.Cdecl)]
|
|
||||||
static extern private IntPtr taos_fetch_fields(IntPtr res);
|
|
||||||
static public List<TDengineMeta> FetchFields(IntPtr res)
|
|
||||||
{
|
{
|
||||||
const int fieldSize = 68;
|
TSDB_OPTION_LOCALE = 0,
|
||||||
|
TSDB_OPTION_CHARSET = 1,
|
||||||
List<TDengineMeta> metas = new List<TDengineMeta>();
|
TSDB_OPTION_TIMEZONE = 2,
|
||||||
if (res == IntPtr.Zero)
|
TDDB_OPTION_CONFIGDIR = 3,
|
||||||
{
|
TDDB_OPTION_SHELL_ACTIVITY_TIMER = 4
|
||||||
return metas;
|
|
||||||
}
|
|
||||||
|
|
||||||
int fieldCount = FieldCount(res);
|
|
||||||
IntPtr fieldsPtr = taos_fetch_fields(res);
|
|
||||||
|
|
||||||
for (int i = 0; i < fieldCount; ++i)
|
|
||||||
{
|
|
||||||
int offset = i * fieldSize;
|
|
||||||
|
|
||||||
TDengineMeta meta = new TDengineMeta();
|
|
||||||
meta.name = Marshal.PtrToStringAnsi(fieldsPtr + offset);
|
|
||||||
meta.type = Marshal.ReadByte(fieldsPtr + offset + 65);
|
|
||||||
meta.size = Marshal.ReadInt16(fieldsPtr + offset + 66);
|
|
||||||
metas.Add(meta);
|
|
||||||
}
|
|
||||||
|
|
||||||
return metas;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[DllImport("taos.dll", EntryPoint = "taos_fetch_row", CallingConvention = CallingConvention.Cdecl)]
|
class TDengineMeta
|
||||||
static extern public IntPtr FetchRows(IntPtr res);
|
{
|
||||||
|
public string name;
|
||||||
|
public short size;
|
||||||
|
public byte type;
|
||||||
|
public string TypeName()
|
||||||
|
{
|
||||||
|
switch ((TDengineDataType)type)
|
||||||
|
{
|
||||||
|
case TDengineDataType.TSDB_DATA_TYPE_BOOL:
|
||||||
|
return "BOOLEAN";
|
||||||
|
case TDengineDataType.TSDB_DATA_TYPE_TINYINT:
|
||||||
|
return "BYTE";
|
||||||
|
case TDengineDataType.TSDB_DATA_TYPE_SMALLINT:
|
||||||
|
return "SHORT";
|
||||||
|
case TDengineDataType.TSDB_DATA_TYPE_INT:
|
||||||
|
return "INT";
|
||||||
|
case TDengineDataType.TSDB_DATA_TYPE_BIGINT:
|
||||||
|
return "LONG";
|
||||||
|
case TDengineDataType.TSDB_DATA_TYPE_FLOAT:
|
||||||
|
return "FLOAT";
|
||||||
|
case TDengineDataType.TSDB_DATA_TYPE_DOUBLE:
|
||||||
|
return "DOUBLE";
|
||||||
|
case TDengineDataType.TSDB_DATA_TYPE_BINARY:
|
||||||
|
return "STRING";
|
||||||
|
case TDengineDataType.TSDB_DATA_TYPE_TIMESTAMP:
|
||||||
|
return "TIMESTAMP";
|
||||||
|
case TDengineDataType.TSDB_DATA_TYPE_NCHAR:
|
||||||
|
return "NCHAR";
|
||||||
|
default:
|
||||||
|
return "undefine";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[DllImport("taos.dll", EntryPoint = "taos_free_result", CallingConvention = CallingConvention.Cdecl)]
|
class TDengine
|
||||||
static extern public IntPtr FreeResult(IntPtr res);
|
{
|
||||||
|
public const int TSDB_CODE_SUCCESS = 0;
|
||||||
|
|
||||||
[DllImport("taos.dll", EntryPoint = "taos_close", CallingConvention = CallingConvention.Cdecl)]
|
[DllImport("taos", EntryPoint = "taos_init", CallingConvention = CallingConvention.Cdecl)]
|
||||||
static extern public int Close(IntPtr taos);
|
static extern public void Init();
|
||||||
}
|
|
||||||
}
|
[DllImport("taos", EntryPoint = "taos_cleanup", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
static extern public void Cleanup();
|
||||||
|
|
||||||
|
[DllImport("taos", EntryPoint = "taos_options", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
static extern public void Options(int option, string value);
|
||||||
|
|
||||||
|
[DllImport("taos", EntryPoint = "taos_connect", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
static extern public IntPtr Connect(string ip, string user, string password, string db, short port);
|
||||||
|
|
||||||
|
[DllImport("taos", EntryPoint = "taos_errstr", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
static extern private IntPtr taos_errstr(IntPtr res);
|
||||||
|
static public string Error(IntPtr res)
|
||||||
|
{
|
||||||
|
IntPtr errPtr = taos_errstr(res);
|
||||||
|
return Marshal.PtrToStringAnsi(errPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
[DllImport("taos", EntryPoint = "taos_errno", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
static extern public int ErrorNo(IntPtr res);
|
||||||
|
|
||||||
|
[DllImport("taos", EntryPoint = "taos_query", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
static extern public IntPtr Query(IntPtr conn, string sqlstr);
|
||||||
|
|
||||||
|
[DllImport("taos", EntryPoint = "taos_affected_rows", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
static extern public int AffectRows(IntPtr res);
|
||||||
|
|
||||||
|
[DllImport("taos", EntryPoint = "taos_field_count", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
static extern public int FieldCount(IntPtr res);
|
||||||
|
|
||||||
|
[DllImport("taos", EntryPoint = "taos_fetch_fields", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
static extern private IntPtr taos_fetch_fields(IntPtr res);
|
||||||
|
static public List<TDengineMeta> FetchFields(IntPtr res)
|
||||||
|
{
|
||||||
|
const int fieldSize = 68;
|
||||||
|
|
||||||
|
List<TDengineMeta> metas = new List<TDengineMeta>();
|
||||||
|
if (res == IntPtr.Zero)
|
||||||
|
{
|
||||||
|
return metas;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fieldCount = FieldCount(res);
|
||||||
|
IntPtr fieldsPtr = taos_fetch_fields(res);
|
||||||
|
|
||||||
|
for (int i = 0; i < fieldCount; ++i)
|
||||||
|
{
|
||||||
|
int offset = i * fieldSize;
|
||||||
|
|
||||||
|
TDengineMeta meta = new TDengineMeta();
|
||||||
|
meta.name = Marshal.PtrToStringAnsi(fieldsPtr + offset);
|
||||||
|
meta.type = Marshal.ReadByte(fieldsPtr + offset + 65);
|
||||||
|
meta.size = Marshal.ReadInt16(fieldsPtr + offset + 66);
|
||||||
|
metas.Add(meta);
|
||||||
|
}
|
||||||
|
|
||||||
|
return metas;
|
||||||
|
}
|
||||||
|
|
||||||
|
[DllImport("taos", EntryPoint = "taos_fetch_row", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
static extern public IntPtr FetchRows(IntPtr res);
|
||||||
|
|
||||||
|
[DllImport("taos", EntryPoint = "taos_free_result", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
static extern public IntPtr FreeResult(IntPtr res);
|
||||||
|
|
||||||
|
[DllImport("taos", EntryPoint = "taos_close", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
static extern public int Close(IntPtr taos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -56,6 +56,12 @@
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>mysql</groupId>
|
||||||
|
<artifactId>mysql-connector-java</artifactId>
|
||||||
|
<version>5.1.47</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- for restful -->
|
<!-- for restful -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.httpcomponents</groupId>
|
<groupId>org.apache.httpcomponents</groupId>
|
||||||
|
@ -73,7 +79,14 @@
|
||||||
<version>1.2.58</version>
|
<version>1.2.58</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>mysql</groupId>
|
||||||
|
<artifactId>mysql-connector-java</artifactId>
|
||||||
|
<version>5.1.49</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
|
|
|
@ -0,0 +1,808 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can use, redistribute, and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, version 3
|
||||||
|
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*****************************************************************************/
|
||||||
|
package com.taosdata.jdbc;
|
||||||
|
|
||||||
|
import java.sql.*;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public abstract class AbstractDatabaseMetaData implements DatabaseMetaData {
|
||||||
|
|
||||||
|
private final static String PRODUCT_NAME = "TDengine";
|
||||||
|
private final static String PRODUCT_VESION = "2.0.x.x";
|
||||||
|
private final static String DRIVER_NAME = "taos-jdbcdriver";
|
||||||
|
private final static String DRIVER_VERSION = "2.0.x";
|
||||||
|
private final static int DRIVER_MAJAR_VERSION = 2;
|
||||||
|
private final static int DRIVER_MINOR_VERSION = 0;
|
||||||
|
|
||||||
|
public boolean allProceduresAreCallable() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean allTablesAreSelectable() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract String getURL() throws SQLException;
|
||||||
|
|
||||||
|
public abstract String getUserName() throws SQLException;
|
||||||
|
|
||||||
|
public boolean isReadOnly() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean nullsAreSortedHigh() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean nullsAreSortedLow() throws SQLException {
|
||||||
|
return !nullsAreSortedHigh();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean nullsAreSortedAtStart() throws SQLException {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean nullsAreSortedAtEnd() throws SQLException {
|
||||||
|
return !nullsAreSortedAtStart();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDatabaseProductName() throws SQLException {
|
||||||
|
return PRODUCT_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDatabaseProductVersion() throws SQLException {
|
||||||
|
return PRODUCT_VESION;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDriverName() throws SQLException {
|
||||||
|
return DRIVER_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDriverVersion() throws SQLException {
|
||||||
|
return DRIVER_VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDriverMajorVersion() {
|
||||||
|
return DRIVER_MAJAR_VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDriverMinorVersion() {
|
||||||
|
return DRIVER_MINOR_VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean usesLocalFiles() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean usesLocalFilePerTable() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsMixedCaseIdentifiers() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean storesUpperCaseIdentifiers() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean storesLowerCaseIdentifiers() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean storesMixedCaseIdentifiers() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean storesUpperCaseQuotedIdentifiers() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean storesLowerCaseQuotedIdentifiers() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean storesMixedCaseQuotedIdentifiers() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getIdentifierQuoteString() throws SQLException {
|
||||||
|
return " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSQLKeywords() throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNumericFunctions() throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStringFunctions() throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSystemFunctions() throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTimeDateFunctions() throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSearchStringEscape() throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getExtraNameCharacters() throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsAlterTableWithAddColumn() throws SQLException {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsAlterTableWithDropColumn() throws SQLException {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsColumnAliasing() throws SQLException {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean nullPlusNonNullIsNull() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsConvert() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsConvert(int fromType, int toType) throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsTableCorrelationNames() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsDifferentTableCorrelationNames() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsExpressionsInOrderBy() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsOrderByUnrelated() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsGroupBy() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsGroupByUnrelated() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsGroupByBeyondSelect() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsLikeEscapeClause() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsMultipleResultSets() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsMultipleTransactions() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsNonNullableColumns() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsMinimumSQLGrammar() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsCoreSQLGrammar() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsExtendedSQLGrammar() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsANSI92EntryLevelSQL() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsANSI92IntermediateSQL() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsANSI92FullSQL() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsIntegrityEnhancementFacility() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsOuterJoins() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsFullOuterJoins() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsLimitedOuterJoins() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSchemaTerm() throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProcedureTerm() throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCatalogTerm() throws SQLException {
|
||||||
|
return "database";
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCatalogAtStart() throws SQLException {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCatalogSeparator() throws SQLException {
|
||||||
|
return ".";
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsSchemasInDataManipulation() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsSchemasInProcedureCalls() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsSchemasInTableDefinitions() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsSchemasInIndexDefinitions() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsSchemasInPrivilegeDefinitions() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsCatalogsInDataManipulation() throws SQLException {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsCatalogsInProcedureCalls() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsCatalogsInTableDefinitions() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsCatalogsInIndexDefinitions() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsCatalogsInPrivilegeDefinitions() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsPositionedDelete() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsPositionedUpdate() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsSelectForUpdate() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsStoredProcedures() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsSubqueriesInComparisons() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsSubqueriesInExists() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsSubqueriesInIns() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsSubqueriesInQuantifieds() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsCorrelatedSubqueries() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsUnion() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsUnionAll() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsOpenCursorsAcrossCommit() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsOpenCursorsAcrossRollback() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsOpenStatementsAcrossCommit() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsOpenStatementsAcrossRollback() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxBinaryLiteralLength() throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxCharLiteralLength() throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxColumnNameLength() throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxColumnsInGroupBy() throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxColumnsInIndex() throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxColumnsInOrderBy() throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxColumnsInSelect() throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxColumnsInTable() throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxConnections() throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxCursorNameLength() throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxIndexLength() throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxSchemaNameLength() throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxProcedureNameLength() throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxCatalogNameLength() throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxRowSize() throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean doesMaxRowSizeIncludeBlobs() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxStatementLength() throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxStatements() throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxTableNameLength() throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxTablesInSelect() throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxUserNameLength() throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDefaultTransactionIsolation() throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsTransactions() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsTransactionIsolationLevel(int level) throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsDataDefinitionAndDataManipulationTransactions() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsDataManipulationTransactionsOnly() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean dataDefinitionCausesTransactionCommit() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean dataDefinitionIgnoredInTransactions() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultSet getProcedures(String catalog, String schemaPattern, String procedureNamePattern)
|
||||||
|
throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultSet getProcedureColumns(String catalog, String schemaPattern, String procedureNamePattern,
|
||||||
|
String columnNamePattern) throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String[] types)
|
||||||
|
throws SQLException;
|
||||||
|
|
||||||
|
public ResultSet getSchemas() throws SQLException {
|
||||||
|
return getEmptyResultSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract ResultSet getCatalogs() throws SQLException;
|
||||||
|
|
||||||
|
public ResultSet getTableTypes() throws SQLException {
|
||||||
|
DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet();
|
||||||
|
|
||||||
|
// set up ColumnMetaDataList
|
||||||
|
List<ColumnMetaData> columnMetaDataList = new ArrayList<ColumnMetaData>(1);
|
||||||
|
ColumnMetaData colMetaData = new ColumnMetaData();
|
||||||
|
colMetaData.setColIndex(0);
|
||||||
|
colMetaData.setColName("TABLE_TYPE");
|
||||||
|
colMetaData.setColSize(10);
|
||||||
|
colMetaData.setColType(TSDBConstants.TSDB_DATA_TYPE_BINARY);
|
||||||
|
columnMetaDataList.add(colMetaData);
|
||||||
|
|
||||||
|
// set up rowDataList
|
||||||
|
List<TSDBResultSetRowData> rowDataList = new ArrayList<TSDBResultSetRowData>(2);
|
||||||
|
TSDBResultSetRowData rowData = new TSDBResultSetRowData();
|
||||||
|
rowData.setString(0, "TABLE");
|
||||||
|
rowDataList.add(rowData);
|
||||||
|
rowData = new TSDBResultSetRowData();
|
||||||
|
rowData.setString(0, "STABLE");
|
||||||
|
rowDataList.add(rowData);
|
||||||
|
|
||||||
|
resultSet.setColumnMetaDataList(columnMetaDataList);
|
||||||
|
resultSet.setRowDataList(rowDataList);
|
||||||
|
return resultSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) throws SQLException;
|
||||||
|
|
||||||
|
protected int getNullable(int index, String typeName) {
|
||||||
|
if (index == 0 && "TIMESTAMP".equals(typeName))
|
||||||
|
return DatabaseMetaData.columnNoNulls;
|
||||||
|
return DatabaseMetaData.columnNullable;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int getColumnSize(String typeName, int length) {
|
||||||
|
switch (typeName) {
|
||||||
|
case "TIMESTAMP":
|
||||||
|
return 23;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int getDecimalDigits(String typeName) {
|
||||||
|
switch (typeName) {
|
||||||
|
case "FLOAT":
|
||||||
|
return 5;
|
||||||
|
case "DOUBLE":
|
||||||
|
return 9;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int getDataType(String typeName) {
|
||||||
|
switch (typeName) {
|
||||||
|
case "TIMESTAMP":
|
||||||
|
return Types.TIMESTAMP;
|
||||||
|
case "INT":
|
||||||
|
return Types.INTEGER;
|
||||||
|
case "BIGINT":
|
||||||
|
return Types.BIGINT;
|
||||||
|
case "FLOAT":
|
||||||
|
return Types.FLOAT;
|
||||||
|
case "DOUBLE":
|
||||||
|
return Types.DOUBLE;
|
||||||
|
case "BINARY":
|
||||||
|
return Types.BINARY;
|
||||||
|
case "SMALLINT":
|
||||||
|
return Types.SMALLINT;
|
||||||
|
case "TINYINT":
|
||||||
|
return Types.TINYINT;
|
||||||
|
case "BOOL":
|
||||||
|
return Types.BOOLEAN;
|
||||||
|
case "NCHAR":
|
||||||
|
return Types.NCHAR;
|
||||||
|
default:
|
||||||
|
return Types.NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultSet getColumnPrivileges(String catalog, String schema, String table, String columnNamePattern)
|
||||||
|
throws SQLException {
|
||||||
|
return getEmptyResultSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultSet getTablePrivileges(String catalog, String schemaPattern, String tableNamePattern)
|
||||||
|
throws SQLException {
|
||||||
|
return getEmptyResultSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultSet getBestRowIdentifier(String catalog, String schema, String table, int scope, boolean nullable)
|
||||||
|
throws SQLException {
|
||||||
|
return getEmptyResultSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultSet getVersionColumns(String catalog, String schema, String table) throws SQLException {
|
||||||
|
return getEmptyResultSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultSet getPrimaryKeys(String catalog, String schema, String table) throws SQLException {
|
||||||
|
return getEmptyResultSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultSet getImportedKeys(String catalog, String schema, String table) throws SQLException {
|
||||||
|
return getEmptyResultSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultSet getExportedKeys(String catalog, String schema, String table) throws SQLException {
|
||||||
|
return getEmptyResultSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultSet getCrossReference(String parentCatalog, String parentSchema, String parentTable,
|
||||||
|
String foreignCatalog, String foreignSchema, String foreignTable) throws SQLException {
|
||||||
|
return getEmptyResultSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultSet getTypeInfo() throws SQLException {
|
||||||
|
return getEmptyResultSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultSet getIndexInfo(String catalog, String schema, String table, boolean unique, boolean approximate)
|
||||||
|
throws SQLException {
|
||||||
|
return getEmptyResultSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsResultSetType(int type) throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsResultSetConcurrency(int type, int concurrency) throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean ownUpdatesAreVisible(int type) throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean ownDeletesAreVisible(int type) throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean ownInsertsAreVisible(int type) throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean othersUpdatesAreVisible(int type) throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean othersDeletesAreVisible(int type) throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean othersInsertsAreVisible(int type) throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean updatesAreDetected(int type) throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean deletesAreDetected(int type) throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean insertsAreDetected(int type) throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsBatchUpdates() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultSet getUDTs(String catalog, String schemaPattern, String typeNamePattern, int[] types)
|
||||||
|
throws SQLException {
|
||||||
|
return getEmptyResultSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Connection getConnection() throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsSavepoints() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsNamedParameters() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsMultipleOpenResults() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsGetGeneratedKeys() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultSet getSuperTypes(String catalog, String schemaPattern, String typeNamePattern) throws SQLException {
|
||||||
|
return getEmptyResultSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultSet getSuperTables(String catalog, String schemaPattern, String tableNamePattern) throws SQLException {
|
||||||
|
return getEmptyResultSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultSet getAttributes(String catalog, String schemaPattern, String typeNamePattern,
|
||||||
|
String attributeNamePattern) throws SQLException {
|
||||||
|
return getEmptyResultSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsResultSetHoldability(int holdability) throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getResultSetHoldability() throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDatabaseMajorVersion() throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDatabaseMinorVersion() throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getJDBCMajorVersion() throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getJDBCMinorVersion() throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSQLStateType() throws SQLException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean locatorsUpdateCopy() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsStatementPooling() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RowIdLifetime getRowIdLifetime() throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultSet getSchemas(String catalog, String schemaPattern) throws SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsStoredFunctionsUsingCallSyntax() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean autoCommitFailureClosesAllResultSets() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultSet getClientInfoProperties() throws SQLException {
|
||||||
|
return getEmptyResultSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultSet getFunctions(String catalog, String schemaPattern, String functionNamePattern)
|
||||||
|
throws SQLException {
|
||||||
|
return getEmptyResultSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultSet getFunctionColumns(String catalog, String schemaPattern, String functionNamePattern,
|
||||||
|
String columnNamePattern) throws SQLException {
|
||||||
|
return getEmptyResultSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultSet getPseudoColumns(String catalog, String schemaPattern, String tableNamePattern,
|
||||||
|
String columnNamePattern) throws SQLException {
|
||||||
|
return getEmptyResultSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean generatedKeyAlwaysReturned() throws SQLException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ResultSet getEmptyResultSet() {
|
||||||
|
return new EmptyResultSet();
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,68 +19,71 @@ import java.util.Map;
|
||||||
|
|
||||||
public abstract class TSDBConstants {
|
public abstract class TSDBConstants {
|
||||||
|
|
||||||
public static final String DEFAULT_PORT = "6200";
|
public static final String DEFAULT_PORT = "6200";
|
||||||
public static final String UNSUPPORT_METHOD_EXCEPTIONZ_MSG = "this operation is NOT supported currently!";
|
public static final String UNSUPPORT_METHOD_EXCEPTIONZ_MSG = "this operation is NOT supported currently!";
|
||||||
public static final String INVALID_VARIABLES = "invalid variables";
|
public static final String INVALID_VARIABLES = "invalid variables";
|
||||||
public static Map<Integer, String> DATATYPE_MAP = null;
|
public static Map<Integer, String> DATATYPE_MAP = null;
|
||||||
|
|
||||||
public static final long JNI_NULL_POINTER = 0L;
|
public static final long JNI_NULL_POINTER = 0L;
|
||||||
|
|
||||||
public static final int JNI_SUCCESS = 0;
|
public static final int JNI_SUCCESS = 0;
|
||||||
public static final int JNI_TDENGINE_ERROR = -1;
|
public static final int JNI_TDENGINE_ERROR = -1;
|
||||||
public static final int JNI_CONNECTION_NULL = -2;
|
public static final int JNI_CONNECTION_NULL = -2;
|
||||||
public static final int JNI_RESULT_SET_NULL = -3;
|
public static final int JNI_RESULT_SET_NULL = -3;
|
||||||
public static final int JNI_NUM_OF_FIELDS_0 = -4;
|
public static final int JNI_NUM_OF_FIELDS_0 = -4;
|
||||||
public static final int JNI_SQL_NULL = -5;
|
public static final int JNI_SQL_NULL = -5;
|
||||||
public static final int JNI_FETCH_END = -6;
|
public static final int JNI_FETCH_END = -6;
|
||||||
|
|
||||||
public static final int TSDB_DATA_TYPE_NULL = 0;
|
|
||||||
public static final int TSDB_DATA_TYPE_BOOL = 1;
|
|
||||||
public static final int TSDB_DATA_TYPE_TINYINT = 2;
|
|
||||||
public static final int TSDB_DATA_TYPE_SMALLINT = 3;
|
|
||||||
public static final int TSDB_DATA_TYPE_INT = 4;
|
|
||||||
public static final int TSDB_DATA_TYPE_BIGINT = 5;
|
|
||||||
public static final int TSDB_DATA_TYPE_FLOAT = 6;
|
|
||||||
public static final int TSDB_DATA_TYPE_DOUBLE = 7;
|
|
||||||
public static final int TSDB_DATA_TYPE_BINARY = 8;
|
|
||||||
public static final int TSDB_DATA_TYPE_TIMESTAMP = 9;
|
|
||||||
public static final int TSDB_DATA_TYPE_NCHAR = 10;
|
|
||||||
|
|
||||||
public static String WrapErrMsg(String msg) {
|
|
||||||
return "TDengine Error: " + msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String FixErrMsg(int code) {
|
public static final int TSDB_DATA_TYPE_NULL = 0;
|
||||||
switch (code) {
|
public static final int TSDB_DATA_TYPE_BOOL = 1;
|
||||||
case JNI_TDENGINE_ERROR:
|
public static final int TSDB_DATA_TYPE_TINYINT = 2;
|
||||||
return WrapErrMsg("internal error of database!");
|
public static final int TSDB_DATA_TYPE_SMALLINT = 3;
|
||||||
case JNI_CONNECTION_NULL:
|
public static final int TSDB_DATA_TYPE_INT = 4;
|
||||||
return WrapErrMsg("invalid tdengine connection!");
|
public static final int TSDB_DATA_TYPE_BIGINT = 5;
|
||||||
case JNI_RESULT_SET_NULL:
|
public static final int TSDB_DATA_TYPE_FLOAT = 6;
|
||||||
return WrapErrMsg("invalid resultset pointer!");
|
public static final int TSDB_DATA_TYPE_DOUBLE = 7;
|
||||||
case JNI_NUM_OF_FIELDS_0:
|
public static final int TSDB_DATA_TYPE_BINARY = 8;
|
||||||
return WrapErrMsg("invalid num of fields!");
|
public static final int TSDB_DATA_TYPE_TIMESTAMP = 9;
|
||||||
case JNI_SQL_NULL:
|
public static final int TSDB_DATA_TYPE_NCHAR = 10;
|
||||||
return WrapErrMsg("can't execute empty sql!");
|
|
||||||
case JNI_FETCH_END:
|
|
||||||
return WrapErrMsg("fetch to the end of resultset");
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return WrapErrMsg("unkown error!");
|
|
||||||
}
|
|
||||||
|
|
||||||
static {
|
// nchar field's max length
|
||||||
DATATYPE_MAP = new HashMap<Integer, String>();
|
public static final int maxFieldSize = 16 * 1024;
|
||||||
DATATYPE_MAP.put(1, "BOOL");
|
|
||||||
DATATYPE_MAP.put(2, "TINYINT");
|
public static String WrapErrMsg(String msg) {
|
||||||
DATATYPE_MAP.put(3, "SMALLINT");
|
return "TDengine Error: " + msg;
|
||||||
DATATYPE_MAP.put(4, "INT");
|
}
|
||||||
DATATYPE_MAP.put(5, "BIGINT");
|
|
||||||
DATATYPE_MAP.put(6, "FLOAT");
|
public static String FixErrMsg(int code) {
|
||||||
DATATYPE_MAP.put(7, "DOUBLE");
|
switch (code) {
|
||||||
DATATYPE_MAP.put(8, "BINARY");
|
case JNI_TDENGINE_ERROR:
|
||||||
DATATYPE_MAP.put(9, "TIMESTAMP");
|
return WrapErrMsg("internal error of database!");
|
||||||
DATATYPE_MAP.put(10, "NCHAR");
|
case JNI_CONNECTION_NULL:
|
||||||
}
|
return WrapErrMsg("invalid tdengine connection!");
|
||||||
|
case JNI_RESULT_SET_NULL:
|
||||||
|
return WrapErrMsg("invalid resultset pointer!");
|
||||||
|
case JNI_NUM_OF_FIELDS_0:
|
||||||
|
return WrapErrMsg("invalid num of fields!");
|
||||||
|
case JNI_SQL_NULL:
|
||||||
|
return WrapErrMsg("can't execute empty sql!");
|
||||||
|
case JNI_FETCH_END:
|
||||||
|
return WrapErrMsg("fetch to the end of resultset");
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return WrapErrMsg("unkown error!");
|
||||||
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
DATATYPE_MAP = new HashMap<Integer, String>();
|
||||||
|
DATATYPE_MAP.put(1, "BOOL");
|
||||||
|
DATATYPE_MAP.put(2, "TINYINT");
|
||||||
|
DATATYPE_MAP.put(3, "SMALLINT");
|
||||||
|
DATATYPE_MAP.put(4, "INT");
|
||||||
|
DATATYPE_MAP.put(5, "BIGINT");
|
||||||
|
DATATYPE_MAP.put(6, "FLOAT");
|
||||||
|
DATATYPE_MAP.put(7, "DOUBLE");
|
||||||
|
DATATYPE_MAP.put(8, "BINARY");
|
||||||
|
DATATYPE_MAP.put(9, "TIMESTAMP");
|
||||||
|
DATATYPE_MAP.put(10, "NCHAR");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,29 @@
|
||||||
package com.taosdata.jdbc.rs;
|
package com.taosdata.jdbc.rs;
|
||||||
|
|
||||||
import com.taosdata.jdbc.TSDBConstants;
|
import com.taosdata.jdbc.TSDBConstants;
|
||||||
|
import com.taosdata.jdbc.TSDBDriver;
|
||||||
|
|
||||||
import java.sql.*;
|
import java.sql.*;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
public class RestfulConnection implements Connection {
|
public class RestfulConnection implements Connection {
|
||||||
|
|
||||||
|
private static final String CONNECTION_IS_CLOSED = "connection is closed.";
|
||||||
|
private static final String AUTO_COMMIT_IS_TRUE = "auto commit is true";
|
||||||
private final String host;
|
private final String host;
|
||||||
private final int port;
|
private final int port;
|
||||||
private final Properties props;
|
private final Properties props;
|
||||||
private final String database;
|
private volatile String database;
|
||||||
private final String url;
|
private final String url;
|
||||||
|
/******************************************************/
|
||||||
|
private boolean isClosed;
|
||||||
|
private DatabaseMetaData metadata;
|
||||||
|
private Map<String, Class<?>> typeMap;
|
||||||
|
private Properties clientInfoProps = new Properties();
|
||||||
|
|
||||||
public RestfulConnection(String host, String port, Properties props, String database, String url) {
|
public RestfulConnection(String host, String port, Properties props, String database, String url) {
|
||||||
this.host = host;
|
this.host = host;
|
||||||
|
@ -21,280 +31,424 @@ public class RestfulConnection implements Connection {
|
||||||
this.props = props;
|
this.props = props;
|
||||||
this.database = database;
|
this.database = database;
|
||||||
this.url = url;
|
this.url = url;
|
||||||
|
this.metadata = new RestfulDatabaseMetaData(url, props.getProperty(TSDBDriver.PROPERTY_KEY_USER), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Statement createStatement() throws SQLException {
|
public Statement createStatement() throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg("restful TDengine connection is closed."));
|
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||||
|
|
||||||
return new RestfulStatement(this, database);
|
return new RestfulStatement(this, database);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PreparedStatement prepareStatement(String sql) throws SQLException {
|
public PreparedStatement prepareStatement(String sql) throws SQLException {
|
||||||
return null;
|
if (isClosed())
|
||||||
|
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||||
|
//TODO: prepareStatement
|
||||||
|
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CallableStatement prepareCall(String sql) throws SQLException {
|
public CallableStatement prepareCall(String sql) throws SQLException {
|
||||||
return null;
|
if (isClosed())
|
||||||
|
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||||
|
|
||||||
|
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String nativeSQL(String sql) throws SQLException {
|
public String nativeSQL(String sql) throws SQLException {
|
||||||
return null;
|
if (isClosed())
|
||||||
|
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||||
|
|
||||||
|
//nothing did
|
||||||
|
return sql;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setAutoCommit(boolean autoCommit) throws SQLException {
|
public void setAutoCommit(boolean autoCommit) throws SQLException {
|
||||||
|
if (isClosed())
|
||||||
|
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||||
|
if (!autoCommit)
|
||||||
|
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean getAutoCommit() throws SQLException {
|
public boolean getAutoCommit() throws SQLException {
|
||||||
return false;
|
if (isClosed())
|
||||||
|
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void commit() throws SQLException {
|
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
|
@Override
|
||||||
public void rollback() throws SQLException {
|
public void rollback() throws SQLException {
|
||||||
|
if (isClosed())
|
||||||
|
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||||
|
if (getAutoCommit())
|
||||||
|
throw new SQLException(AUTO_COMMIT_IS_TRUE);
|
||||||
|
//nothing to do
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() throws SQLException {
|
public void close() throws SQLException {
|
||||||
|
if (isClosed)
|
||||||
|
return;
|
||||||
|
//TODO: release all resources
|
||||||
|
isClosed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isClosed() throws SQLException {
|
public boolean isClosed() throws SQLException {
|
||||||
return false;
|
return isClosed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DatabaseMetaData getMetaData() throws SQLException {
|
public DatabaseMetaData getMetaData() throws SQLException {
|
||||||
//TODO: RestfulDatabaseMetaData is not implemented
|
if (isClosed())
|
||||||
return new RestfulDatabaseMetaData();
|
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||||
|
|
||||||
|
return this.metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setReadOnly(boolean readOnly) throws SQLException {
|
public void setReadOnly(boolean readOnly) throws SQLException {
|
||||||
|
if (isClosed())
|
||||||
|
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||||
|
// nothing to do
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isReadOnly() throws SQLException {
|
public boolean isReadOnly() throws SQLException {
|
||||||
return false;
|
if (isClosed())
|
||||||
|
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setCatalog(String catalog) throws SQLException {
|
public void setCatalog(String catalog) throws SQLException {
|
||||||
|
if (isClosed())
|
||||||
|
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||||
|
synchronized (RestfulConnection.class) {
|
||||||
|
this.database = catalog;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getCatalog() throws SQLException {
|
public String getCatalog() throws SQLException {
|
||||||
return null;
|
if (isClosed())
|
||||||
|
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||||
|
return this.database;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setTransactionIsolation(int level) throws SQLException {
|
public void setTransactionIsolation(int level) throws SQLException {
|
||||||
//transaction is not supported
|
if (isClosed())
|
||||||
throw new SQLFeatureNotSupportedException("transactions are not supported");
|
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.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
default:
|
||||||
|
throw new SQLException(TSDBConstants.INVALID_VARIABLES);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public int getTransactionIsolation() throws SQLException {
|
public int getTransactionIsolation() throws SQLException {
|
||||||
|
if (isClosed())
|
||||||
|
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||||
//Connection.TRANSACTION_NONE specifies that transactions are not supported.
|
//Connection.TRANSACTION_NONE specifies that transactions are not supported.
|
||||||
return Connection.TRANSACTION_NONE;
|
return Connection.TRANSACTION_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SQLWarning getWarnings() throws SQLException {
|
public SQLWarning getWarnings() throws SQLException {
|
||||||
//TODO: getWarnings not implemented
|
if (isClosed())
|
||||||
|
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void clearWarnings() throws SQLException {
|
public void clearWarnings() throws SQLException {
|
||||||
throw new SQLFeatureNotSupportedException("clearWarnings not supported.");
|
if (isClosed())
|
||||||
|
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||||
|
//nothing to do
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
|
public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
|
||||||
return null;
|
if (isClosed())
|
||||||
|
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||||
|
|
||||||
|
if (resultSetType != ResultSet.TYPE_FORWARD_ONLY) {
|
||||||
|
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
if (resultSetConcurrency != ResultSet.CONCUR_READ_ONLY)
|
||||||
|
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
return createStatement();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
|
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
|
||||||
return null;
|
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
|
@Override
|
||||||
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
|
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
|
||||||
return null;
|
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.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Class<?>> getTypeMap() throws SQLException {
|
public Map<String, Class<?>> getTypeMap() throws SQLException {
|
||||||
return null;
|
if (isClosed())
|
||||||
|
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||||
|
|
||||||
|
synchronized (RestfulConnection.class) {
|
||||||
|
if (this.typeMap == null) {
|
||||||
|
this.typeMap = new HashMap<>();
|
||||||
|
}
|
||||||
|
return this.typeMap;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
|
public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
|
||||||
|
if (isClosed())
|
||||||
|
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||||
|
|
||||||
|
synchronized (RestfulConnection.class) {
|
||||||
|
this.typeMap = map;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setHoldability(int holdability) throws SQLException {
|
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.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getHoldability() throws SQLException {
|
public int getHoldability() throws SQLException {
|
||||||
return 0;
|
if (isClosed())
|
||||||
|
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||||
|
return ResultSet.HOLD_CURSORS_OVER_COMMIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Savepoint setSavepoint() throws SQLException {
|
public Savepoint setSavepoint() throws SQLException {
|
||||||
return null;
|
if (isClosed())
|
||||||
|
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||||
|
if (getAutoCommit())
|
||||||
|
throw new SQLException(TSDBConstants.INVALID_VARIABLES);
|
||||||
|
//nothing to do
|
||||||
|
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Savepoint setSavepoint(String name) throws SQLException {
|
public Savepoint setSavepoint(String name) throws SQLException {
|
||||||
return null;
|
if (isClosed())
|
||||||
|
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||||
|
if (getAutoCommit())
|
||||||
|
throw new SQLException(TSDBConstants.INVALID_VARIABLES);
|
||||||
|
//nothing to do
|
||||||
|
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void rollback(Savepoint savepoint) throws SQLException {
|
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.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void releaseSavepoint(Savepoint savepoint) throws SQLException {
|
public void releaseSavepoint(Savepoint savepoint) throws SQLException {
|
||||||
|
if (isClosed())
|
||||||
|
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||||
|
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
|
public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
|
||||||
return null;
|
if (resultSetHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT)
|
||||||
|
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
return createStatement(resultSetType, resultSetConcurrency);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
|
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
|
||||||
return null;
|
if (resultSetHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT)
|
||||||
|
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
return prepareStatement(sql, resultSetType, resultSetConcurrency);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
|
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
|
||||||
return null;
|
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
|
public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
|
||||||
return null;
|
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
|
public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
|
||||||
return null;
|
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
|
public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
|
||||||
return null;
|
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Clob createClob() throws SQLException {
|
public Clob createClob() throws SQLException {
|
||||||
//TODO: not supported
|
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
throw new SQLFeatureNotSupportedException();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Blob createBlob() throws SQLException {
|
public Blob createBlob() throws SQLException {
|
||||||
//TODO: not supported
|
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
throw new SQLFeatureNotSupportedException();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NClob createNClob() throws SQLException {
|
public NClob createNClob() throws SQLException {
|
||||||
//TODO: not supported
|
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
throw new SQLFeatureNotSupportedException();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SQLXML createSQLXML() throws SQLException {
|
public SQLXML createSQLXML() throws SQLException {
|
||||||
//TODO: not supported
|
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
throw new SQLFeatureNotSupportedException();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isValid(int timeout) throws SQLException {
|
public boolean isValid(int timeout) throws SQLException {
|
||||||
return false;
|
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
|
@Override
|
||||||
public void setClientInfo(String name, String value) throws SQLClientInfoException {
|
public void setClientInfo(String name, String value) throws SQLClientInfoException {
|
||||||
|
if (isClosed)
|
||||||
|
throw new SQLClientInfoException();
|
||||||
|
clientInfoProps.setProperty(name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setClientInfo(Properties properties) throws SQLClientInfoException {
|
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
|
@Override
|
||||||
public String getClientInfo(String name) throws SQLException {
|
public String getClientInfo(String name) throws SQLException {
|
||||||
return null;
|
if (isClosed)
|
||||||
|
throw new SQLClientInfoException();
|
||||||
|
|
||||||
|
return clientInfoProps.getProperty(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Properties getClientInfo() throws SQLException {
|
public Properties getClientInfo() throws SQLException {
|
||||||
return null;
|
if (isClosed)
|
||||||
|
throw new SQLClientInfoException();
|
||||||
|
|
||||||
|
return clientInfoProps;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
|
public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
|
||||||
//TODO: not supported
|
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
throw new SQLFeatureNotSupportedException();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
|
public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
|
||||||
//TODO: not supported
|
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
throw new SQLFeatureNotSupportedException();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setSchema(String schema) throws SQLException {
|
public void setSchema(String schema) throws SQLException {
|
||||||
|
if (isClosed())
|
||||||
|
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||||
|
synchronized (RestfulConnection.class) {
|
||||||
|
this.database = schema;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getSchema() throws SQLException {
|
public String getSchema() throws SQLException {
|
||||||
return null;
|
if (isClosed())
|
||||||
|
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||||
|
return this.database;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void abort(Executor executor) throws SQLException {
|
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
|
@Override
|
||||||
public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {
|
public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {
|
||||||
|
if (isClosed())
|
||||||
|
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||||
|
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getNetworkTimeout() throws SQLException {
|
public int getNetworkTimeout() throws SQLException {
|
||||||
|
if (isClosed())
|
||||||
|
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -33,7 +33,7 @@ public class RestfulDriver extends AbstractTaosDriver {
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
Properties props = parseURL(url, info);
|
Properties props = parseURL(url, info);
|
||||||
String host = props.getProperty(TSDBDriver.PROPERTY_KEY_HOST, "localhost");
|
String host = props.getProperty(TSDBDriver.PROPERTY_KEY_HOST);
|
||||||
String port = props.getProperty(TSDBDriver.PROPERTY_KEY_PORT, "6041");
|
String port = props.getProperty(TSDBDriver.PROPERTY_KEY_PORT, "6041");
|
||||||
String database = props.containsKey(TSDBDriver.PROPERTY_KEY_DBNAME) ? props.getProperty(TSDBDriver.PROPERTY_KEY_DBNAME) : null;
|
String database = props.containsKey(TSDBDriver.PROPERTY_KEY_DBNAME) ? props.getProperty(TSDBDriver.PROPERTY_KEY_DBNAME) : null;
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -2,13 +2,15 @@ package com.taosdata.jdbc.rs;
|
||||||
|
|
||||||
import java.sql.ResultSetMetaData;
|
import java.sql.ResultSetMetaData;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.List;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
public class RestfulResultSetMetaData implements ResultSetMetaData {
|
public class RestfulResultSetMetaData implements ResultSetMetaData {
|
||||||
|
|
||||||
private List<String> fields;
|
private final String database;
|
||||||
|
private ArrayList<RestfulResultSet.Field> fields;
|
||||||
|
|
||||||
public RestfulResultSetMetaData(List<String> fields) {
|
public RestfulResultSetMetaData(String database, ArrayList<RestfulResultSet.Field> fields) {
|
||||||
|
this.database = database;
|
||||||
this.fields = fields;
|
this.fields = fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,6 +26,7 @@ public class RestfulResultSetMetaData implements ResultSetMetaData {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isCaseSensitive(int column) throws SQLException {
|
public boolean isCaseSensitive(int column) throws SQLException {
|
||||||
|
//TODO
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +42,7 @@ public class RestfulResultSetMetaData implements ResultSetMetaData {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int isNullable(int column) throws SQLException {
|
public int isNullable(int column) throws SQLException {
|
||||||
return 0;
|
return ResultSetMetaData.columnNullable;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -54,7 +57,7 @@ public class RestfulResultSetMetaData implements ResultSetMetaData {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getColumnLabel(int column) throws SQLException {
|
public String getColumnLabel(int column) throws SQLException {
|
||||||
return fields.get(column - 1);
|
return fields.get(column - 1).name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -64,7 +67,7 @@ public class RestfulResultSetMetaData implements ResultSetMetaData {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getSchemaName(int column) throws SQLException {
|
public String getSchemaName(int column) throws SQLException {
|
||||||
return null;
|
return this.database;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -84,7 +87,7 @@ public class RestfulResultSetMetaData implements ResultSetMetaData {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getCatalogName(int column) throws SQLException {
|
public String getCatalogName(int column) throws SQLException {
|
||||||
return null;
|
return this.database;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -7,20 +7,60 @@ import com.taosdata.jdbc.rs.util.HttpClientPoolUtil;
|
||||||
import com.taosdata.jdbc.utils.SqlSyntaxValidator;
|
import com.taosdata.jdbc.utils.SqlSyntaxValidator;
|
||||||
|
|
||||||
import java.sql.*;
|
import java.sql.*;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class RestfulStatement implements Statement {
|
public class RestfulStatement implements Statement {
|
||||||
|
|
||||||
|
private static final String STATEMENT_CLOSED = "Statement already closed.";
|
||||||
private boolean closed;
|
private boolean closed;
|
||||||
private String database;
|
private String database;
|
||||||
private final RestfulConnection conn;
|
private final RestfulConnection conn;
|
||||||
|
|
||||||
public RestfulStatement(RestfulConnection c, String database) {
|
private volatile RestfulResultSet resultSet;
|
||||||
this.conn = c;
|
private volatile int affectedRows;
|
||||||
|
private volatile boolean closeOnCompletion;
|
||||||
|
|
||||||
|
public RestfulStatement(RestfulConnection conn, String database) {
|
||||||
|
this.conn = conn;
|
||||||
this.database = database;
|
this.database = database;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String[] parseTableIdentifier(String sql) {
|
||||||
|
sql = sql.trim().toLowerCase();
|
||||||
|
String[] ret = null;
|
||||||
|
if (sql.contains("where"))
|
||||||
|
sql = sql.substring(0, sql.indexOf("where"));
|
||||||
|
if (sql.contains("interval"))
|
||||||
|
sql = sql.substring(0, sql.indexOf("interval"));
|
||||||
|
if (sql.contains("fill"))
|
||||||
|
sql = sql.substring(0, sql.indexOf("fill"));
|
||||||
|
if (sql.contains("sliding"))
|
||||||
|
sql = sql.substring(0, sql.indexOf("sliding"));
|
||||||
|
if (sql.contains("group by"))
|
||||||
|
sql = sql.substring(0, sql.indexOf("group by"));
|
||||||
|
if (sql.contains("order by"))
|
||||||
|
sql = sql.substring(0, sql.indexOf("order by"));
|
||||||
|
if (sql.contains("slimit"))
|
||||||
|
sql = sql.substring(0, sql.indexOf("slimit"));
|
||||||
|
if (sql.contains("limit"))
|
||||||
|
sql = sql.substring(0, sql.indexOf("limit"));
|
||||||
|
// parse
|
||||||
|
if (sql.contains("from")) {
|
||||||
|
sql = sql.substring(sql.indexOf("from") + 4).trim();
|
||||||
|
return Arrays.asList(sql.split(",")).stream()
|
||||||
|
.map(tableIdentifier -> {
|
||||||
|
tableIdentifier = tableIdentifier.trim();
|
||||||
|
if (tableIdentifier.contains(" "))
|
||||||
|
tableIdentifier = tableIdentifier.substring(0, tableIdentifier.indexOf(" "));
|
||||||
|
return tableIdentifier;
|
||||||
|
}).collect(Collectors.joining(",")).split(",");
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResultSet executeQuery(String sql) throws SQLException {
|
public ResultSet executeQuery(String sql) throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
|
@ -29,43 +69,33 @@ public class RestfulStatement implements Statement {
|
||||||
throw new SQLException("not a select sql for executeQuery: " + sql);
|
throw new SQLException("not a select sql for executeQuery: " + sql);
|
||||||
|
|
||||||
final String url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sql";
|
final String url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sql";
|
||||||
|
// row data
|
||||||
String result = HttpClientPoolUtil.execute(url, sql);
|
String result = HttpClientPoolUtil.execute(url, sql);
|
||||||
String fields = "";
|
JSONObject resultJson = JSON.parseObject(result);
|
||||||
List<String> words = Arrays.asList(sql.split(" "));
|
if (resultJson.getString("status").equals("error")) {
|
||||||
if (words.get(0).equalsIgnoreCase("select")) {
|
throw new SQLException(TSDBConstants.WrapErrMsg("SQL execution error: " + resultJson.getString("desc") + "\n" + "error code: " + resultJson.getString("code")));
|
||||||
int index = 0;
|
}
|
||||||
if (words.contains("from")) {
|
|
||||||
index = words.indexOf("from");
|
// parse table name from sql
|
||||||
|
String[] tableIdentifiers = parseTableIdentifier(sql);
|
||||||
|
if (tableIdentifiers != null) {
|
||||||
|
List<JSONObject> fieldJsonList = new ArrayList<>();
|
||||||
|
for (String tableIdentifier : tableIdentifiers) {
|
||||||
|
// field meta
|
||||||
|
String fields = HttpClientPoolUtil.execute(url, "DESCRIBE " + tableIdentifier);
|
||||||
|
JSONObject fieldJson = JSON.parseObject(fields);
|
||||||
|
if (fieldJson.getString("status").equals("error")) {
|
||||||
|
throw new SQLException(TSDBConstants.WrapErrMsg("SQL execution error: " + fieldJson.getString("desc") + "\n" + "error code: " + fieldJson.getString("code")));
|
||||||
|
}
|
||||||
|
fieldJsonList.add(fieldJson);
|
||||||
}
|
}
|
||||||
if (words.contains("FROM")) {
|
this.resultSet = new RestfulResultSet(database, this, resultJson, fieldJsonList);
|
||||||
index = words.indexOf("FROM");
|
} else {
|
||||||
}
|
this.resultSet = new RestfulResultSet(database, this, resultJson);
|
||||||
fields = HttpClientPoolUtil.execute(url, "DESCRIBE " + words.get(index + 1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JSONObject jsonObject = JSON.parseObject(result);
|
this.affectedRows = 0;
|
||||||
if (jsonObject.getString("status").equals("error")) {
|
return resultSet;
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg("SQL execution error: " +
|
|
||||||
jsonObject.getString("desc") + "\n" +
|
|
||||||
"error code: " + jsonObject.getString("code")));
|
|
||||||
}
|
|
||||||
String dataStr = jsonObject.getString("data");
|
|
||||||
if ("use".equalsIgnoreCase(fields.split(" ")[0])) {
|
|
||||||
return new RestfulResultSet(dataStr, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
JSONObject jsonField = JSON.parseObject(fields);
|
|
||||||
if (jsonField == null) {
|
|
||||||
return new RestfulResultSet(dataStr, "");
|
|
||||||
}
|
|
||||||
if (jsonField.getString("status").equals("error")) {
|
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg("SQL execution error: " +
|
|
||||||
jsonField.getString("desc") + "\n" +
|
|
||||||
"error code: " + jsonField.getString("code")));
|
|
||||||
}
|
|
||||||
String fieldData = jsonField.getString("data");
|
|
||||||
|
|
||||||
return new RestfulResultSet(dataStr, fieldData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -78,77 +108,103 @@ public class RestfulStatement implements Statement {
|
||||||
if (this.database == null)
|
if (this.database == null)
|
||||||
throw new SQLException("Database not specified or available");
|
throw new SQLException("Database not specified or available");
|
||||||
|
|
||||||
final String url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sql";
|
final String url = "http://" + conn.getHost().trim() + ":" + conn.getPort() + "/rest/sql";
|
||||||
HttpClientPoolUtil.execute(url, "use " + conn.getDatabase());
|
// HttpClientPoolUtil.execute(url, "use " + conn.getDatabase());
|
||||||
String result = HttpClientPoolUtil.execute(url, sql);
|
String result = HttpClientPoolUtil.execute(url, sql);
|
||||||
JSONObject jsonObject = JSON.parseObject(result);
|
JSONObject jsonObject = JSON.parseObject(result);
|
||||||
if (jsonObject.getString("status").equals("error")) {
|
if (jsonObject.getString("status").equals("error")) {
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg("SQL execution error: " +
|
throw new SQLException(TSDBConstants.WrapErrMsg("SQL execution error: " + jsonObject.getString("desc") + "\n" + "error code: " + jsonObject.getString("code")));
|
||||||
jsonObject.getString("desc") + "\n" +
|
|
||||||
"error code: " + jsonObject.getString("code")));
|
|
||||||
}
|
}
|
||||||
return Integer.parseInt(jsonObject.getString("rows"));
|
this.resultSet = null;
|
||||||
|
this.affectedRows = Integer.parseInt(jsonObject.getString("rows"));
|
||||||
|
return this.affectedRows;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() throws SQLException {
|
public void close() throws SQLException {
|
||||||
this.closed = true;
|
synchronized (RestfulStatement.class) {
|
||||||
|
if (!isClosed())
|
||||||
|
this.closed = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMaxFieldSize() throws SQLException {
|
public int getMaxFieldSize() throws SQLException {
|
||||||
return 0;
|
if (isClosed())
|
||||||
|
throw new SQLException(STATEMENT_CLOSED);
|
||||||
|
return TSDBConstants.maxFieldSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setMaxFieldSize(int max) throws SQLException {
|
public void setMaxFieldSize(int max) throws SQLException {
|
||||||
|
if (isClosed())
|
||||||
|
throw new SQLException(STATEMENT_CLOSED);
|
||||||
|
if (max < 0)
|
||||||
|
throw new SQLException(TSDBConstants.INVALID_VARIABLES);
|
||||||
|
// nothing to do
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMaxRows() throws SQLException {
|
public int getMaxRows() throws SQLException {
|
||||||
|
if (isClosed())
|
||||||
|
throw new SQLException(STATEMENT_CLOSED);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setMaxRows(int max) throws SQLException {
|
public void setMaxRows(int max) throws SQLException {
|
||||||
|
if (isClosed())
|
||||||
|
throw new SQLException(STATEMENT_CLOSED);
|
||||||
|
if (max < 0)
|
||||||
|
throw new SQLException(TSDBConstants.INVALID_VARIABLES);
|
||||||
|
// nothing to do
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setEscapeProcessing(boolean enable) throws SQLException {
|
public void setEscapeProcessing(boolean enable) throws SQLException {
|
||||||
|
if (isClosed())
|
||||||
|
throw new SQLException(RestfulStatement.STATEMENT_CLOSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getQueryTimeout() throws SQLException {
|
public int getQueryTimeout() throws SQLException {
|
||||||
|
if (isClosed())
|
||||||
|
throw new SQLException(STATEMENT_CLOSED);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setQueryTimeout(int seconds) throws SQLException {
|
public void setQueryTimeout(int seconds) throws SQLException {
|
||||||
|
if (isClosed())
|
||||||
|
throw new SQLException(STATEMENT_CLOSED);
|
||||||
|
if (seconds < 0)
|
||||||
|
throw new SQLException(TSDBConstants.INVALID_VARIABLES);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cancel() throws SQLException {
|
public void cancel() throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SQLWarning getWarnings() throws SQLException {
|
public SQLWarning getWarnings() throws SQLException {
|
||||||
//TODO: getWarnings not Implemented
|
if (isClosed())
|
||||||
|
throw new SQLException(STATEMENT_CLOSED);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void clearWarnings() throws SQLException {
|
public void clearWarnings() throws SQLException {
|
||||||
|
// nothing to do
|
||||||
|
if (isClosed())
|
||||||
|
throw new SQLException(STATEMENT_CLOSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setCursorName(String name) throws SQLException {
|
public void setCursorName(String name) throws SQLException {
|
||||||
|
if (isClosed())
|
||||||
|
throw new SQLException(RestfulStatement.STATEMENT_CLOSED);
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -159,133 +215,181 @@ public class RestfulStatement implements Statement {
|
||||||
//如果执行了use操作应该将当前Statement的catalog设置为新的database
|
//如果执行了use操作应该将当前Statement的catalog设置为新的database
|
||||||
if (SqlSyntaxValidator.isUseSql(sql)) {
|
if (SqlSyntaxValidator.isUseSql(sql)) {
|
||||||
this.database = sql.trim().replace("use", "").trim();
|
this.database = sql.trim().replace("use", "").trim();
|
||||||
|
this.conn.setCatalog(this.database);
|
||||||
}
|
}
|
||||||
if (this.database == null)
|
if (this.database == null)
|
||||||
throw new SQLException("Database not specified or available");
|
throw new SQLException("Database not specified or available");
|
||||||
|
|
||||||
final String url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sql";
|
if (SqlSyntaxValidator.isSelectSql(sql)) {
|
||||||
// use database
|
executeQuery(sql);
|
||||||
HttpClientPoolUtil.execute(url, "use " + conn.getDatabase());
|
} else if (SqlSyntaxValidator.isShowSql(sql) || SqlSyntaxValidator.isDescribeSql(sql)) {
|
||||||
// execute sql
|
final String url = "http://" + conn.getHost().trim() + ":" + conn.getPort() + "/rest/sql";
|
||||||
String result = HttpClientPoolUtil.execute(url, sql);
|
if (!SqlSyntaxValidator.isShowDatabaseSql(sql)) {
|
||||||
// parse result
|
HttpClientPoolUtil.execute(url, "use " + conn.getDatabase());
|
||||||
JSONObject jsonObject = JSON.parseObject(result);
|
}
|
||||||
if (jsonObject.getString("status").equals("error")) {
|
String result = HttpClientPoolUtil.execute(url, sql);
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg("SQL execution error: " +
|
JSONObject resultJson = JSON.parseObject(result);
|
||||||
jsonObject.getString("desc") + "\n" +
|
if (resultJson.getString("status").equals("error")) {
|
||||||
"error code: " + jsonObject.getString("code")));
|
throw new SQLException(TSDBConstants.WrapErrMsg("SQL execution error: " + resultJson.getString("desc") + "\n" + "error code: " + resultJson.getString("code")));
|
||||||
|
}
|
||||||
|
this.resultSet = new RestfulResultSet(database, this, resultJson);
|
||||||
|
} else {
|
||||||
|
executeUpdate(sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResultSet getResultSet() throws SQLException {
|
public ResultSet getResultSet() throws SQLException {
|
||||||
return null;
|
if (isClosed())
|
||||||
|
throw new SQLException(STATEMENT_CLOSED);
|
||||||
|
return resultSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getUpdateCount() throws SQLException {
|
public int getUpdateCount() throws SQLException {
|
||||||
return 0;
|
if (isClosed()) {
|
||||||
|
throw new SQLException("Invalid method call on a closed statement.");
|
||||||
|
}
|
||||||
|
return this.affectedRows;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean getMoreResults() throws SQLException {
|
public boolean getMoreResults() throws SQLException {
|
||||||
return false;
|
return getMoreResults(CLOSE_CURRENT_RESULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setFetchDirection(int direction) throws SQLException {
|
public void setFetchDirection(int direction) throws SQLException {
|
||||||
|
if (direction != ResultSet.FETCH_FORWARD && direction != ResultSet.FETCH_REVERSE && direction != ResultSet.FETCH_UNKNOWN)
|
||||||
|
throw new SQLException(TSDBConstants.INVALID_VARIABLES);
|
||||||
|
this.resultSet.setFetchDirection(direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getFetchDirection() throws SQLException {
|
public int getFetchDirection() throws SQLException {
|
||||||
return 0;
|
return this.resultSet.getFetchDirection();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setFetchSize(int rows) throws SQLException {
|
public void setFetchSize(int rows) throws SQLException {
|
||||||
|
if (isClosed())
|
||||||
|
throw new SQLException(STATEMENT_CLOSED);
|
||||||
|
if (rows < 0)
|
||||||
|
throw new SQLException(TSDBConstants.INVALID_VARIABLES);
|
||||||
|
//nothing to do
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getFetchSize() throws SQLException {
|
public int getFetchSize() throws SQLException {
|
||||||
|
if (isClosed())
|
||||||
|
throw new SQLException(STATEMENT_CLOSED);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getResultSetConcurrency() throws SQLException {
|
public int getResultSetConcurrency() throws SQLException {
|
||||||
return 0;
|
if (isClosed())
|
||||||
|
throw new SQLException(STATEMENT_CLOSED);
|
||||||
|
return this.resultSet.getConcurrency();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getResultSetType() throws SQLException {
|
public int getResultSetType() throws SQLException {
|
||||||
return 0;
|
if (isClosed())
|
||||||
|
throw new SQLException(STATEMENT_CLOSED);
|
||||||
|
return this.resultSet.getType();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addBatch(String sql) throws SQLException {
|
public void addBatch(String sql) throws SQLException {
|
||||||
|
if (isClosed())
|
||||||
|
throw new SQLException(STATEMENT_CLOSED);
|
||||||
|
//TODO:
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void clearBatch() throws SQLException {
|
public void clearBatch() throws SQLException {
|
||||||
|
//TODO:
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int[] executeBatch() throws SQLException {
|
public int[] executeBatch() throws SQLException {
|
||||||
|
//TODO:
|
||||||
return new int[0];
|
return new int[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Connection getConnection() throws SQLException {
|
public Connection getConnection() throws SQLException {
|
||||||
return null;
|
if (isClosed())
|
||||||
|
throw new SQLException(STATEMENT_CLOSED);
|
||||||
|
return this.conn;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean getMoreResults(int current) throws SQLException {
|
public boolean getMoreResults(int current) throws SQLException {
|
||||||
|
if (isClosed())
|
||||||
|
throw new SQLException(STATEMENT_CLOSED);
|
||||||
|
if (resultSet == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// switch (current) {
|
||||||
|
// case CLOSE_CURRENT_RESULT:
|
||||||
|
// resultSet.close();
|
||||||
|
// break;
|
||||||
|
// case KEEP_CURRENT_RESULT:
|
||||||
|
// break;
|
||||||
|
// case CLOSE_ALL_RESULTS:
|
||||||
|
// resultSet.close();
|
||||||
|
// break;
|
||||||
|
// default:
|
||||||
|
// throw new SQLException(TSDBConstants.INVALID_VARIABLES);
|
||||||
|
// }
|
||||||
|
// return next;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResultSet getGeneratedKeys() throws SQLException {
|
public ResultSet getGeneratedKeys() throws SQLException {
|
||||||
return null;
|
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
|
public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
|
||||||
return 0;
|
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int executeUpdate(String sql, int[] columnIndexes) throws SQLException {
|
public int executeUpdate(String sql, int[] columnIndexes) throws SQLException {
|
||||||
return 0;
|
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int executeUpdate(String sql, String[] columnNames) throws SQLException {
|
public int executeUpdate(String sql, String[] columnNames) throws SQLException {
|
||||||
return 0;
|
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
|
public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
|
||||||
return false;
|
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean execute(String sql, int[] columnIndexes) throws SQLException {
|
public boolean execute(String sql, int[] columnIndexes) throws SQLException {
|
||||||
return false;
|
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean execute(String sql, String[] columnNames) throws SQLException {
|
public boolean execute(String sql, String[] columnNames) throws SQLException {
|
||||||
return false;
|
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getResultSetHoldability() throws SQLException {
|
public int getResultSetHoldability() throws SQLException {
|
||||||
return 0;
|
if (isClosed())
|
||||||
|
throw new SQLException(STATEMENT_CLOSED);
|
||||||
|
return this.resultSet.getHoldability();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -295,22 +399,30 @@ public class RestfulStatement implements Statement {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setPoolable(boolean poolable) throws SQLException {
|
public void setPoolable(boolean poolable) throws SQLException {
|
||||||
|
if (isClosed())
|
||||||
|
throw new SQLException(STATEMENT_CLOSED);
|
||||||
|
//nothing to do
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPoolable() throws SQLException {
|
public boolean isPoolable() throws SQLException {
|
||||||
|
if (isClosed())
|
||||||
|
throw new SQLException(STATEMENT_CLOSED);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void closeOnCompletion() throws SQLException {
|
public void closeOnCompletion() throws SQLException {
|
||||||
|
if (isClosed())
|
||||||
|
throw new SQLException(STATEMENT_CLOSED);
|
||||||
|
this.closeOnCompletion = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isCloseOnCompletion() throws SQLException {
|
public boolean isCloseOnCompletion() throws SQLException {
|
||||||
return false;
|
if (isClosed())
|
||||||
|
throw new SQLException(STATEMENT_CLOSED);
|
||||||
|
return this.closeOnCompletion;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -17,6 +17,8 @@ import org.apache.http.protocol.HTTP;
|
||||||
import org.apache.http.protocol.HttpContext;
|
import org.apache.http.protocol.HttpContext;
|
||||||
import org.apache.http.util.EntityUtils;
|
import org.apache.http.util.EntityUtils;
|
||||||
|
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
|
|
||||||
public class HttpClientPoolUtil {
|
public class HttpClientPoolUtil {
|
||||||
public static PoolingHttpClientConnectionManager cm = null;
|
public static PoolingHttpClientConnectionManager cm = null;
|
||||||
|
@ -94,7 +96,9 @@ public class HttpClientPoolUtil {
|
||||||
initPools();
|
initPools();
|
||||||
}
|
}
|
||||||
method = (HttpEntityEnclosingRequestBase) getRequest(uri, HttpPost.METHOD_NAME, DEFAULT_CONTENT_TYPE, 0);
|
method = (HttpEntityEnclosingRequestBase) getRequest(uri, HttpPost.METHOD_NAME, DEFAULT_CONTENT_TYPE, 0);
|
||||||
method.setEntity(new StringEntity(data));
|
method.setHeader("Authorization", "Basic cm9vdDp0YW9zZGF0YQ==");
|
||||||
|
method.setHeader("Content-Type", "text/plain");
|
||||||
|
method.setEntity(new StringEntity(data, Charset.forName("UTF-8")));
|
||||||
HttpContext context = HttpClientContext.create();
|
HttpContext context = HttpClientContext.create();
|
||||||
CloseableHttpResponse httpResponse = httpClient.execute(method, context);
|
CloseableHttpResponse httpResponse = httpClient.execute(method, context);
|
||||||
httpEntity = httpResponse.getEntity();
|
httpEntity = httpResponse.getEntity();
|
||||||
|
@ -105,26 +109,13 @@ public class HttpClientPoolUtil {
|
||||||
if (method != null) {
|
if (method != null) {
|
||||||
method.abort();
|
method.abort();
|
||||||
}
|
}
|
||||||
// e.printStackTrace();
|
new Exception("execute post request exception, url:" + uri + ", exception:" + e.toString() + ", cost time(ms):" + (System.currentTimeMillis() - startTime)).printStackTrace();
|
||||||
// logger.error("execute post request exception, url:" + uri + ", exception:" + e.toString()
|
|
||||||
// + ", cost time(ms):" + (System.currentTimeMillis() - startTime));
|
|
||||||
new Exception("execute post request exception, url:"
|
|
||||||
+ uri + ", exception:" + e.toString() +
|
|
||||||
", cost time(ms):" + (System.currentTimeMillis() - startTime))
|
|
||||||
.printStackTrace();
|
|
||||||
} finally {
|
} finally {
|
||||||
if (httpEntity != null) {
|
if (httpEntity != null) {
|
||||||
try {
|
try {
|
||||||
EntityUtils.consumeQuietly(httpEntity);
|
EntityUtils.consumeQuietly(httpEntity);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// e.printStackTrace();
|
new Exception("close response exception, url:" + uri + ", exception:" + e.toString() + ", cost time(ms):" + (System.currentTimeMillis() - startTime)).printStackTrace();
|
||||||
// logger.error("close response exception, url:" + uri + ", exception:" + e.toString()
|
|
||||||
// + ", cost time(ms):" + (System.currentTimeMillis() - startTime));
|
|
||||||
new Exception(
|
|
||||||
"close response exception, url:" + uri +
|
|
||||||
", exception:" + e.toString()
|
|
||||||
+ ", cost time(ms):" + (System.currentTimeMillis() - startTime))
|
|
||||||
.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,14 +15,12 @@
|
||||||
package com.taosdata.jdbc.utils;
|
package com.taosdata.jdbc.utils;
|
||||||
|
|
||||||
import com.taosdata.jdbc.TSDBConnection;
|
import com.taosdata.jdbc.TSDBConnection;
|
||||||
import com.taosdata.jdbc.TSDBJNIConnector;
|
|
||||||
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.SQLException;
|
|
||||||
|
|
||||||
public class SqlSyntaxValidator {
|
public class SqlSyntaxValidator {
|
||||||
|
|
||||||
private static final String[] updateSQL = {"insert", "update", "delete", "create", "alter", "drop", "show", "describe", "use"};
|
private static final String[] updateSQL = {"insert", "update", "delete", "create", "alter", "drop", "show", "describe", "use", "import"};
|
||||||
private static final String[] querySQL = {"select"};
|
private static final String[] querySQL = {"select"};
|
||||||
|
|
||||||
private TSDBConnection tsdbConnection;
|
private TSDBConnection tsdbConnection;
|
||||||
|
@ -31,22 +29,6 @@ public class SqlSyntaxValidator {
|
||||||
this.tsdbConnection = (TSDBConnection) connection;
|
this.tsdbConnection = (TSDBConnection) connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean validateSqlSyntax(String sql) throws SQLException {
|
|
||||||
|
|
||||||
boolean res = false;
|
|
||||||
if (tsdbConnection == null || tsdbConnection.isClosed()) {
|
|
||||||
throw new SQLException("invalid connection");
|
|
||||||
} else {
|
|
||||||
TSDBJNIConnector jniConnector = tsdbConnection.getConnection();
|
|
||||||
if (jniConnector == null) {
|
|
||||||
throw new SQLException("jniConnector is null");
|
|
||||||
} else {
|
|
||||||
res = jniConnector.validateCreateTableSql(sql);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isValidForExecuteUpdate(String sql) {
|
public static boolean isValidForExecuteUpdate(String sql) {
|
||||||
for (String prefix : updateSQL) {
|
for (String prefix : updateSQL) {
|
||||||
if (sql.trim().toLowerCase().startsWith(prefix))
|
if (sql.trim().toLowerCase().startsWith(prefix))
|
||||||
|
@ -56,18 +38,28 @@ public class SqlSyntaxValidator {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isUseSql(String sql) {
|
public static boolean isUseSql(String sql) {
|
||||||
return sql.trim().toLowerCase().startsWith(updateSQL[8]) || sql.trim().toLowerCase().matches("create\\s*database.*") || sql.toLowerCase().toLowerCase().matches("drop\\s*database.*");
|
return sql.trim().toLowerCase().startsWith("use") || sql.trim().toLowerCase().matches("create\\s*database.*") || sql.toLowerCase().toLowerCase().matches("drop\\s*database.*");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isUpdateSql(String sql) {
|
public static boolean isShowSql(String sql) {
|
||||||
return sql.trim().toLowerCase().startsWith(updateSQL[1]);
|
return sql.trim().toLowerCase().startsWith("show");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isDescribeSql(String sql) {
|
||||||
|
return sql.trim().toLowerCase().startsWith("describe");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static boolean isInsertSql(String sql) {
|
public static boolean isInsertSql(String sql) {
|
||||||
return sql.trim().toLowerCase().startsWith(updateSQL[0]);
|
return sql.trim().toLowerCase().startsWith("insert") || sql.trim().toLowerCase().startsWith("import");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isSelectSql(String sql) {
|
public static boolean isSelectSql(String sql) {
|
||||||
return sql.trim().toLowerCase().startsWith(querySQL[0]);
|
return sql.trim().toLowerCase().startsWith("select");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static boolean isShowDatabaseSql(String sql) {
|
||||||
|
return sql.trim().toLowerCase().matches("show\\s*databases");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import org.junit.Test;
|
||||||
import java.sql.*;
|
import java.sql.*;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
public class DatabaseMetaDataTest extends BaseTest {
|
public class DatabaseMetaDataTest {
|
||||||
static Connection connection = null;
|
static Connection connection = null;
|
||||||
static PreparedStatement statement = null;
|
static PreparedStatement statement = null;
|
||||||
static String dbName = "test";
|
static String dbName = "test";
|
||||||
|
@ -23,20 +23,21 @@ public class DatabaseMetaDataTest extends BaseTest {
|
||||||
}
|
}
|
||||||
Properties properties = new Properties();
|
Properties properties = new Properties();
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_HOST, host);
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_HOST, host);
|
||||||
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_USER, "root");
|
||||||
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_PASSWORD, "taosdata");
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
||||||
connection = DriverManager.getConnection("jdbc:TAOS://" + host + ":0/", properties);
|
connection = DriverManager.getConnection("jdbc:TAOS://" + host + ":0/", properties);
|
||||||
|
|
||||||
String sql = "drop database if exists " + dbName;
|
String sql = "drop database if exists " + dbName;
|
||||||
statement = (TSDBPreparedStatement) connection.prepareStatement(sql);
|
statement = connection.prepareStatement(sql);
|
||||||
statement.executeUpdate("create database if not exists " + dbName);
|
statement.executeUpdate("create database if not exists " + dbName);
|
||||||
statement.executeUpdate("create table if not exists " + dbName + "." + tName + " (ts timestamp, k int, v int)");
|
statement.executeUpdate("create table if not exists " + dbName + "." + tName + " (ts timestamp, k int, v int)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMetaDataTest() throws SQLException {
|
public void testMetaDataTest() throws SQLException {
|
||||||
|
|
||||||
DatabaseMetaData databaseMetaData = connection.getMetaData();
|
DatabaseMetaData databaseMetaData = connection.getMetaData();
|
||||||
ResultSet resultSet = databaseMetaData.getTables(dbName, "t*", "t*", new String[]{"t"});
|
ResultSet resultSet = databaseMetaData.getTables(dbName, "t*", "t*", new String[]{"t"});
|
||||||
while (resultSet.next()) {
|
while (resultSet.next()) {
|
||||||
|
@ -180,7 +181,7 @@ public class DatabaseMetaDataTest extends BaseTest {
|
||||||
databaseMetaData.getCatalogs();
|
databaseMetaData.getCatalogs();
|
||||||
// databaseMetaData.getTableTypes();
|
// databaseMetaData.getTableTypes();
|
||||||
|
|
||||||
databaseMetaData.getColumns("", "", "", "");
|
databaseMetaData.getColumns(dbName, "", tName, "");
|
||||||
databaseMetaData.getColumnPrivileges("", "", "", "");
|
databaseMetaData.getColumnPrivileges("", "", "", "");
|
||||||
databaseMetaData.getTablePrivileges("", "", "");
|
databaseMetaData.getTablePrivileges("", "", "");
|
||||||
databaseMetaData.getBestRowIdentifier("", "", "", 0, false);
|
databaseMetaData.getBestRowIdentifier("", "", "", 0, false);
|
||||||
|
|
|
@ -19,7 +19,7 @@ public class AppMemoryLeakTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test(expected = Exception.class)
|
||||||
public void testCreateTooManyStatement() throws ClassNotFoundException, SQLException {
|
public void testCreateTooManyStatement() throws ClassNotFoundException, SQLException {
|
||||||
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
||||||
int stmtCnt = 0;
|
int stmtCnt = 0;
|
||||||
|
@ -30,15 +30,4 @@ public class AppMemoryLeakTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws ClassNotFoundException, SQLException {
|
|
||||||
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
|
||||||
int stmtCnt = 0;
|
|
||||||
Connection conn = DriverManager.getConnection("jdbc:TAOS://localhost:6030/?user=root&password=taosdata");
|
|
||||||
while (true) {
|
|
||||||
Statement stmt = conn.createStatement();
|
|
||||||
System.out.println(++stmtCnt + " : " + stmt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
package com.taosdata.jdbc.cases;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.sql.DriverManager;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
public class ConnectWrongDatabaseTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void connect() {
|
||||||
|
try {
|
||||||
|
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
||||||
|
DriverManager.getConnection("jdbc:TAOS://localhost:6030/wrong_db?user=root&password=taosdata");
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
System.out.println(e.getMessage());
|
||||||
|
Assert.assertEquals("TDengine Error: Invalid database name", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
package com.taosdata.jdbc.rs;
|
package com.taosdata.jdbc.rs;
|
||||||
|
|
||||||
|
|
||||||
import org.junit.*;
|
import org.junit.*;
|
||||||
import org.junit.runners.MethodSorters;
|
import org.junit.runners.MethodSorters;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,399 @@
|
||||||
|
package com.taosdata.jdbc.rs;
|
||||||
|
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.FixMethodOrder;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runners.MethodSorters;
|
||||||
|
|
||||||
|
import java.sql.*;
|
||||||
|
|
||||||
|
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||||
|
public class SQLTest {
|
||||||
|
private static final String host = "master";
|
||||||
|
|
||||||
|
private static Connection connection;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase001() {
|
||||||
|
String sql = "create database if not exists restful_test";
|
||||||
|
execute(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase002() {
|
||||||
|
String sql = "use restful_test";
|
||||||
|
execute(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase003() {
|
||||||
|
String sql = "show databases";
|
||||||
|
executeWithResult(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase004() {
|
||||||
|
String sql = "show tables";
|
||||||
|
executeWithResult(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase005() {
|
||||||
|
String sql = "show stables";
|
||||||
|
executeWithResult(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase006() {
|
||||||
|
String sql = "show dnodes";
|
||||||
|
executeWithResult(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase007() {
|
||||||
|
String sql = "show vgroups";
|
||||||
|
executeWithResult(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase008() {
|
||||||
|
String sql = "drop table if exists restful_test.weather";
|
||||||
|
execute(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase009() {
|
||||||
|
String sql = "create table if not exists restful_test.weather(ts timestamp, temperature float) tags(location nchar(64))";
|
||||||
|
execute(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase010() {
|
||||||
|
String sql = "create table t1 using restful_test.weather tags('北京')";
|
||||||
|
execute(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase011() {
|
||||||
|
String sql = "insert into restful_test.t1 values(now, 22.22)";
|
||||||
|
executeUpdate(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase012() {
|
||||||
|
String sql = "insert into restful_test.t1 values('2020-01-01 00:00:00.000', 22.22)";
|
||||||
|
executeUpdate(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase013() {
|
||||||
|
String sql = "insert into restful_test.t1 values('2020-01-01 00:01:00.000', 22.22),('2020-01-01 00:02:00.000', 22.22)";
|
||||||
|
executeUpdate(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase014() {
|
||||||
|
String sql = "insert into restful_test.t2 using weather tags('上海') values('2020-01-01 00:03:00.000', 22.22)";
|
||||||
|
executeUpdate(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase015() {
|
||||||
|
String sql = "insert into restful_test.t2 using weather tags('上海') values('2020-01-01 00:01:00.000', 22.22),('2020-01-01 00:02:00.000', 22.22)";
|
||||||
|
executeUpdate(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase016() {
|
||||||
|
String sql = "insert into t1 values('2020-01-01 01:0:00.000', 22.22),('2020-01-01 02:00:00.000', 22.22) t2 values('2020-01-01 01:0:00.000', 33.33),('2020-01-01 02:00:00.000', 33.33)";
|
||||||
|
executeUpdate(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase017() {
|
||||||
|
String sql = "Insert into t3 using weather tags('广东') values('2020-01-01 01:0:00.000', 22.22),('2020-01-01 02:00:00.000', 22.22) t4 using weather tags('天津') values('2020-01-01 01:0:00.000', 33.33),('2020-01-01 02:00:00.000', 33.33)";
|
||||||
|
executeUpdate(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase018() {
|
||||||
|
String sql = "select * from restful_test.t1";
|
||||||
|
executeQuery(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase019() {
|
||||||
|
String sql = "select * from restful_test.weather";
|
||||||
|
executeQuery(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase020() {
|
||||||
|
String sql = "select ts, temperature from restful_test.t1";
|
||||||
|
executeQuery(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase021() {
|
||||||
|
String sql = "select ts, temperature from restful_test.weather";
|
||||||
|
executeQuery(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase022() {
|
||||||
|
String sql = "select temperature, ts from restful_test.t1";
|
||||||
|
executeQuery(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase023() {
|
||||||
|
String sql = "select temperature, ts from restful_test.weather";
|
||||||
|
executeQuery(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase024() {
|
||||||
|
String sql = "import into restful_test.t5 using weather tags('石家庄') values('2020-01-01 00:01:00.000', 22.22)";
|
||||||
|
executeUpdate(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase025() {
|
||||||
|
String sql = "import into restful_test.t6 using weather tags('沈阳') values('2020-01-01 00:01:00.000', 22.22),('2020-01-01 00:02:00.000', 22.22)";
|
||||||
|
executeUpdate(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase026() {
|
||||||
|
String sql = "import into restful_test.t7 using weather tags('长沙') values('2020-01-01 00:01:00.000', 22.22) restful_test.t8 using weather tags('吉林') values('2020-01-01 00:01:00.000', 22.22)";
|
||||||
|
executeUpdate(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase027() {
|
||||||
|
String sql = "import into restful_test.t9 using weather tags('武汉') values('2020-01-01 00:01:00.000', 22.22) ,('2020-01-02 00:01:00.000', 22.22) restful_test.t10 using weather tags('哈尔滨') values('2020-01-01 00:01:00.000', 22.22),('2020-01-02 00:01:00.000', 22.22)";
|
||||||
|
executeUpdate(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase028() {
|
||||||
|
String sql = "select location, temperature, ts from restful_test.weather where temperature > 1";
|
||||||
|
executeQuery(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase029() {
|
||||||
|
String sql = "select location, temperature, ts from restful_test.weather where temperature < 1";
|
||||||
|
executeQuery(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase030() {
|
||||||
|
String sql = "select location, temperature, ts from restful_test.weather where ts > now";
|
||||||
|
executeQuery(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase031() {
|
||||||
|
String sql = "select location, temperature, ts from restful_test.weather where ts < now";
|
||||||
|
executeQuery(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase032() {
|
||||||
|
String sql = "select count(*) from restful_test.weather";
|
||||||
|
executeQuery(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase033() {
|
||||||
|
String sql = "select first(*) from restful_test.weather";
|
||||||
|
executeQuery(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase034() {
|
||||||
|
String sql = "select last(*) from restful_test.weather";
|
||||||
|
executeQuery(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase035() {
|
||||||
|
String sql = "select last_row(*) from restful_test.weather";
|
||||||
|
executeQuery(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase036() {
|
||||||
|
String sql = "select ts, ts as primary_key from restful_test.weather";
|
||||||
|
executeQuery(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase037() {
|
||||||
|
String sql = "select database()";
|
||||||
|
execute("use restful_test");
|
||||||
|
executeQuery(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase038() {
|
||||||
|
String sql = "select client_version()";
|
||||||
|
executeQuery(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase039() {
|
||||||
|
String sql = "select server_status()";
|
||||||
|
executeQuery(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase040() {
|
||||||
|
String sql = "select server_status() as status";
|
||||||
|
executeQuery(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase041() {
|
||||||
|
String sql = "select tbname, location from restful_test.weather";
|
||||||
|
executeQuery(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase042() {
|
||||||
|
String sql = "select count(tbname) from restful_test.weather";
|
||||||
|
executeQuery(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase043() {
|
||||||
|
String sql = "select * from restful_test.weather where ts < now - 1h";
|
||||||
|
executeQuery(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase044() {
|
||||||
|
String sql = "select * from restful_test.weather where ts < now - 1h and location like '%'";
|
||||||
|
executeQuery(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase045() {
|
||||||
|
String sql = "select * from restful_test.weather where ts < now - 1h order by ts";
|
||||||
|
executeQuery(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase046() {
|
||||||
|
String sql = "select last(*) from restful_test.weather where ts < now - 1h group by tbname order by tbname";
|
||||||
|
executeQuery(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase047() {
|
||||||
|
String sql = "select * from restful_test.weather limit 2";
|
||||||
|
executeQuery(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase048() {
|
||||||
|
String sql = "select * from restful_test.weather limit 2 offset 5";
|
||||||
|
executeQuery(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase049() {
|
||||||
|
String sql = "select * from restful_test.t1, restful_test.t3 where t1.ts = t3.ts ";
|
||||||
|
executeQuery(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase050() {
|
||||||
|
String sql = "select * from restful_test.t1, restful_test.t3 where t1.ts = t3.ts and t1.location = t3.location";
|
||||||
|
executeQuery(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase051() {
|
||||||
|
String sql = "select * from restful_test.t1 tt, restful_test.t3 yy where tt.ts = yy.ts";
|
||||||
|
executeQuery(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void executeUpdate(String sql) {
|
||||||
|
try (Statement statement = connection.createStatement()) {
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
int affectedRows = statement.executeUpdate(sql);
|
||||||
|
long end = System.currentTimeMillis();
|
||||||
|
System.out.println("[ affected rows : " + affectedRows + " ] time cost: " + (end - start) + " ms, execute statement ====> " + sql);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void executeWithResult(String sql) {
|
||||||
|
try (Statement statement = connection.createStatement()) {
|
||||||
|
statement.execute(sql);
|
||||||
|
ResultSet resultSet = statement.getResultSet();
|
||||||
|
printResult(resultSet);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void execute(String sql) {
|
||||||
|
try (Statement statement = connection.createStatement()) {
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
boolean execute = statement.execute(sql);
|
||||||
|
long end = System.currentTimeMillis();
|
||||||
|
printSql(sql, execute, (end - start));
|
||||||
|
} catch (SQLException e) {
|
||||||
|
System.out.println("ERROR execute SQL ===> " + sql);
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void printSql(String sql, boolean succeed, long cost) {
|
||||||
|
System.out.println("[ " + (succeed ? "OK" : "ERROR!") + " ] time cost: " + cost + " ms, execute statement ====> " + sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void executeQuery(String sql) {
|
||||||
|
try (Statement statement = connection.createStatement()) {
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
ResultSet resultSet = statement.executeQuery(sql);
|
||||||
|
long end = System.currentTimeMillis();
|
||||||
|
printSql(sql, true, (end - start));
|
||||||
|
printResult(resultSet);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
System.out.println("ERROR execute SQL ===> " + sql);
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void printResult(ResultSet resultSet) throws SQLException {
|
||||||
|
ResultSetMetaData metaData = resultSet.getMetaData();
|
||||||
|
while (resultSet.next()) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (int i = 1; i <= metaData.getColumnCount(); i++) {
|
||||||
|
String columnLabel = metaData.getColumnLabel(i);
|
||||||
|
String value = resultSet.getString(i);
|
||||||
|
sb.append(columnLabel + ": " + value + "\t");
|
||||||
|
}
|
||||||
|
System.out.println(sb.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void before() throws ClassNotFoundException, SQLException {
|
||||||
|
Class.forName("com.taosdata.jdbc.rs.RestfulDriver");
|
||||||
|
connection = DriverManager.getConnection("jdbc:TAOS-RS://" + host + ":6041/restful_test?user=root&password=taosdata");
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void after() throws SQLException {
|
||||||
|
connection.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -5,10 +5,6 @@ import org.junit.Test;
|
||||||
|
|
||||||
public class SqlSyntaxValidatorTest {
|
public class SqlSyntaxValidatorTest {
|
||||||
|
|
||||||
@Test
|
|
||||||
public void validateSqlSyntax() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void isSelectSQL() {
|
public void isSelectSQL() {
|
||||||
Assert.assertTrue(SqlSyntaxValidator.isSelectSql("select * from test.weather"));
|
Assert.assertTrue(SqlSyntaxValidator.isSelectSql("select * from test.weather"));
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const ref = require('ref');
|
const ref = require('ref');
|
||||||
|
const os = require('os');
|
||||||
const ffi = require('ffi');
|
const ffi = require('ffi');
|
||||||
const ArrayType = require('ref-array');
|
const ArrayType = require('ref-array');
|
||||||
const Struct = require('ref-struct');
|
const Struct = require('ref-struct');
|
||||||
|
@ -188,7 +189,13 @@ function CTaosInterface (config = null, pass = false) {
|
||||||
ref.types.void_ptr2 = ref.refType(ref.types.void_ptr);
|
ref.types.void_ptr2 = ref.refType(ref.types.void_ptr);
|
||||||
/*Declare a bunch of functions first*/
|
/*Declare a bunch of functions first*/
|
||||||
/* Note, pointers to TAOS_RES, TAOS, are ref.types.void_ptr. The connection._conn buffer is supplied for pointers to TAOS * */
|
/* Note, pointers to TAOS_RES, TAOS, are ref.types.void_ptr. The connection._conn buffer is supplied for pointers to TAOS * */
|
||||||
this.libtaos = ffi.Library('libtaos', {
|
|
||||||
|
if ('win32' == os.platform()) {
|
||||||
|
taoslibname = 'taos';
|
||||||
|
} else {
|
||||||
|
taoslibname = 'libtaos';
|
||||||
|
}
|
||||||
|
this.libtaos = ffi.Library(taoslibname, {
|
||||||
'taos_options': [ ref.types.int, [ ref.types.int , ref.types.void_ptr ] ],
|
'taos_options': [ ref.types.int, [ ref.types.int , ref.types.void_ptr ] ],
|
||||||
'taos_init': [ ref.types.void, [ ] ],
|
'taos_init': [ ref.types.void, [ ] ],
|
||||||
//TAOS *taos_connect(char *ip, char *user, char *pass, char *db, int port)
|
//TAOS *taos_connect(char *ip, char *user, char *pass, char *db, int port)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "td2.0-connector",
|
"name": "td2.0-connector",
|
||||||
"version": "2.0.4",
|
"version": "2.0.5",
|
||||||
"description": "A Node.js connector for TDengine.",
|
"description": "A Node.js connector for TDengine.",
|
||||||
"main": "tdengine.js",
|
"main": "tdengine.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|
|
@ -23,8 +23,7 @@ extern "C" {
|
||||||
|
|
||||||
int32_t dnodeInitModules();
|
int32_t dnodeInitModules();
|
||||||
void dnodeCleanupModules();
|
void dnodeCleanupModules();
|
||||||
bool dnodeStartMnode(SMInfos *pMinfos);
|
int32_t dnodeStartMnode(SMInfos *pMinfos);
|
||||||
void dnodeProcessModuleStatus(uint32_t moduleStatus);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -188,8 +188,8 @@ void dnodeReprocessMWriteMsg(void *pMsg) {
|
||||||
++pWrite->pBatchMasterMsg->received;
|
++pWrite->pBatchMasterMsg->received;
|
||||||
if (pWrite->pBatchMasterMsg->successed + pWrite->pBatchMasterMsg->received
|
if (pWrite->pBatchMasterMsg->successed + pWrite->pBatchMasterMsg->received
|
||||||
>= pWrite->pBatchMasterMsg->expected) {
|
>= pWrite->pBatchMasterMsg->expected) {
|
||||||
dnodeSendRedirectMsg(&pWrite->rpcMsg, true);
|
dnodeSendRedirectMsg(&pWrite->pBatchMasterMsg->rpcMsg, true);
|
||||||
dnodeFreeMWriteMsg(pWrite);
|
dnodeFreeMWriteMsg(pWrite->pBatchMasterMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
mnodeDestroySubMsg(pWrite);
|
mnodeDestroySubMsg(pWrite);
|
||||||
|
|
|
@ -127,14 +127,16 @@ int32_t dnodeInitModules() {
|
||||||
return dnodeStartModules();
|
return dnodeStartModules();
|
||||||
}
|
}
|
||||||
|
|
||||||
void dnodeProcessModuleStatus(uint32_t moduleStatus) {
|
int32_t dnodeProcessModuleStatus(uint32_t moduleStatus) {
|
||||||
|
int32_t code = 0;
|
||||||
|
|
||||||
for (int32_t module = TSDB_MOD_MNODE; module < TSDB_MOD_HTTP; ++module) {
|
for (int32_t module = TSDB_MOD_MNODE; module < TSDB_MOD_HTTP; ++module) {
|
||||||
bool enableModule = moduleStatus & (1 << module);
|
bool enableModule = moduleStatus & (1 << module);
|
||||||
if (!tsModule[module].enable && enableModule) {
|
if (!tsModule[module].enable && enableModule) {
|
||||||
dInfo("module status:%u is set, start %s module", moduleStatus, tsModule[module].name);
|
dInfo("module status:%u is set, start %s module", moduleStatus, tsModule[module].name);
|
||||||
tsModule[module].enable = true;
|
tsModule[module].enable = true;
|
||||||
dnodeSetModuleStatus(module);
|
dnodeSetModuleStatus(module);
|
||||||
(*tsModule[module].startFp)();
|
code = (*tsModule[module].startFp)();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tsModule[module].enable && !enableModule) {
|
if (tsModule[module].enable && !enableModule) {
|
||||||
|
@ -144,21 +146,29 @@ void dnodeProcessModuleStatus(uint32_t moduleStatus) {
|
||||||
(*tsModule[module].stopFp)();
|
(*tsModule[module].stopFp)();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool dnodeStartMnode(SMInfos *pMinfos) {
|
int32_t dnodeStartMnode(SMInfos *pMinfos) {
|
||||||
SMInfos *pMnodes = pMinfos;
|
|
||||||
|
|
||||||
if (tsModuleStatus & (1 << TSDB_MOD_MNODE)) {
|
if (tsModuleStatus & (1 << TSDB_MOD_MNODE)) {
|
||||||
dDebug("mnode module is already started, module status:%d", tsModuleStatus);
|
dDebug("mnode module is already started, module status:%d", tsModuleStatus);
|
||||||
return false;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t moduleStatus = tsModuleStatus | (1 << TSDB_MOD_MNODE);
|
uint32_t moduleStatus = tsModuleStatus | (1 << TSDB_MOD_MNODE);
|
||||||
dInfo("start mnode module, module status:%d, new status:%d", tsModuleStatus, moduleStatus);
|
dInfo("start mnode module, module status:%d, new status:%d", tsModuleStatus, moduleStatus);
|
||||||
dnodeProcessModuleStatus(moduleStatus);
|
|
||||||
|
|
||||||
sdbUpdateSync(pMnodes);
|
int32_t code = dnodeProcessModuleStatus(moduleStatus);
|
||||||
|
if (code == 0) {
|
||||||
|
code = sdbUpdateSync(pMinfos);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
if (code != 0) {
|
||||||
|
dError("failed to start mnode module since %s", tstrerror(code));
|
||||||
|
moduleStatus = tsModuleStatus & ~(1 << TSDB_MOD_MNODE);
|
||||||
|
dnodeProcessModuleStatus(moduleStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@ int32_t dnodeInitServer() {
|
||||||
rpcInit.label = "DND-S";
|
rpcInit.label = "DND-S";
|
||||||
rpcInit.numOfThreads = 1;
|
rpcInit.numOfThreads = 1;
|
||||||
rpcInit.cfp = dnodeProcessReqMsgFromDnode;
|
rpcInit.cfp = dnodeProcessReqMsgFromDnode;
|
||||||
rpcInit.sessions = TSDB_MAX_VNODES;
|
rpcInit.sessions = TSDB_MAX_VNODES << 4;
|
||||||
rpcInit.connType = TAOS_CONN_SERVER;
|
rpcInit.connType = TAOS_CONN_SERVER;
|
||||||
rpcInit.idleTime = tsShellActivityTimer * 1000;
|
rpcInit.idleTime = tsShellActivityTimer * 1000;
|
||||||
|
|
||||||
|
@ -123,7 +123,7 @@ int32_t dnodeInitClient() {
|
||||||
rpcInit.label = "DND-C";
|
rpcInit.label = "DND-C";
|
||||||
rpcInit.numOfThreads = 1;
|
rpcInit.numOfThreads = 1;
|
||||||
rpcInit.cfp = dnodeProcessRspFromDnode;
|
rpcInit.cfp = dnodeProcessRspFromDnode;
|
||||||
rpcInit.sessions = TSDB_MAX_VNODES;
|
rpcInit.sessions = TSDB_MAX_VNODES << 4;
|
||||||
rpcInit.connType = TAOS_CONN_CLIENT;
|
rpcInit.connType = TAOS_CONN_CLIENT;
|
||||||
rpcInit.idleTime = tsShellActivityTimer * 1000;
|
rpcInit.idleTime = tsShellActivityTimer * 1000;
|
||||||
rpcInit.user = "t";
|
rpcInit.user = "t";
|
||||||
|
|
|
@ -214,7 +214,5 @@ static int32_t dnodeProcessCreateMnodeMsg(SRpcMsg *pMsg) {
|
||||||
dDebug("mnode index:%d, mnode:%d:%s", i, pCfg->mnodes.mnodeInfos[i].mnodeId, pCfg->mnodes.mnodeInfos[i].mnodeEp);
|
dDebug("mnode index:%d, mnode:%d:%s", i, pCfg->mnodes.mnodeInfos[i].mnodeId, pCfg->mnodes.mnodeInfos[i].mnodeEp);
|
||||||
}
|
}
|
||||||
|
|
||||||
dnodeStartMnode(&pCfg->mnodes);
|
return dnodeStartMnode(&pCfg->mnodes);
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ void dnodeGetClusterId(char *clusterId);
|
||||||
|
|
||||||
void dnodeUpdateEp(int32_t dnodeId, char *ep, char *fqdn, uint16_t *port);
|
void dnodeUpdateEp(int32_t dnodeId, char *ep, char *fqdn, uint16_t *port);
|
||||||
bool dnodeCheckEpChanged(int32_t dnodeId, char *epstr);
|
bool dnodeCheckEpChanged(int32_t dnodeId, char *epstr);
|
||||||
bool dnodeStartMnode(SMInfos *pMinfos);
|
int32_t dnodeStartMnode(SMInfos *pMinfos);
|
||||||
|
|
||||||
void dnodeAddClientRspHandle(uint8_t msgType, void (*fp)(SRpcMsg *rpcMsg));
|
void dnodeAddClientRspHandle(uint8_t msgType, void (*fp)(SRpcMsg *rpcMsg));
|
||||||
void dnodeSendMsgToDnode(SRpcEpSet *epSet, SRpcMsg *rpcMsg);
|
void dnodeSendMsgToDnode(SRpcEpSet *epSet, SRpcMsg *rpcMsg);
|
||||||
|
|
|
@ -65,7 +65,7 @@ int32_t mnodeStartSystem();
|
||||||
void mnodeCleanupSystem();
|
void mnodeCleanupSystem();
|
||||||
void mnodeStopSystem();
|
void mnodeStopSystem();
|
||||||
void sdbUpdateAsync();
|
void sdbUpdateAsync();
|
||||||
void sdbUpdateSync(void *pMnodes);
|
int32_t sdbUpdateSync(void *pMnodes);
|
||||||
bool mnodeIsRunning();
|
bool mnodeIsRunning();
|
||||||
int32_t mnodeProcessRead(SMnodeMsg *pMsg);
|
int32_t mnodeProcessRead(SMnodeMsg *pMsg);
|
||||||
int32_t mnodeProcessWrite(SMnodeMsg *pMsg);
|
int32_t mnodeProcessWrite(SMnodeMsg *pMsg);
|
||||||
|
|
|
@ -86,6 +86,7 @@ void qDestroyQueryInfo(qinfo_t qHandle);
|
||||||
|
|
||||||
void* qOpenQueryMgmt(int32_t vgId);
|
void* qOpenQueryMgmt(int32_t vgId);
|
||||||
void qQueryMgmtNotifyClosed(void* pExecutor);
|
void qQueryMgmtNotifyClosed(void* pExecutor);
|
||||||
|
void qQueryMgmtReOpen(void *pExecutor);
|
||||||
void qCleanupQueryMgmt(void* pExecutor);
|
void qCleanupQueryMgmt(void* pExecutor);
|
||||||
void** qRegisterQInfo(void* pMgmt, uint64_t qInfo);
|
void** qRegisterQInfo(void* pMgmt, uint64_t qInfo);
|
||||||
void** qAcquireQInfo(void* pMgmt, uint64_t key);
|
void** qAcquireQInfo(void* pMgmt, uint64_t key);
|
||||||
|
|
|
@ -126,6 +126,11 @@ TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_SHOWOBJ, 0, 0x030B, "Data expir
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_QUERY_ID, 0, 0x030C, "Invalid query id")
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_QUERY_ID, 0, 0x030C, "Invalid query id")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_STREAM_ID, 0, 0x030D, "Invalid stream id")
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_STREAM_ID, 0, 0x030D, "Invalid stream id")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_CONN_ID, 0, 0x030E, "Invalid connection id")
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_CONN_ID, 0, 0x030E, "Invalid connection id")
|
||||||
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_MNODE_IS_RUNNING, 0, 0x0310, "mnode is alreay running")
|
||||||
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_FAILED_TO_CONFIG_SYNC, 0, 0x0311, "failed to config sync")
|
||||||
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_FAILED_TO_START_SYNC, 0, 0x0312, "failed to start sync")
|
||||||
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_FAILED_TO_CREATE_DIR, 0, 0x0313, "failed to create mnode dir")
|
||||||
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_FAILED_TO_INIT_STEP, 0, 0x0314, "failed to init components")
|
||||||
|
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_SDB_OBJ_ALREADY_THERE, 0, 0x0320, "Object already there")
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_SDB_OBJ_ALREADY_THERE, 0, 0x0320, "Object already there")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_SDB_ERROR, 0, 0x0321, "Unexpected generic error in sdb")
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_SDB_ERROR, 0, 0x0321, "Unexpected generic error in sdb")
|
||||||
|
|
|
@ -311,6 +311,11 @@ static int32_t mnodeCheckDbCfg(SDbCfg *pCfg) {
|
||||||
return TSDB_CODE_MND_INVALID_DB_OPTION;
|
return TSDB_CODE_MND_INVALID_DB_OPTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pCfg->replications > mnodeGetDnodesNum()) {
|
||||||
|
mError("no enough dnode to config replica: %d, #dnodes: %d", pCfg->replications, mnodeGetDnodesNum());
|
||||||
|
return TSDB_CODE_MND_INVALID_DB_OPTION;
|
||||||
|
}
|
||||||
|
|
||||||
if (pCfg->quorum < TSDB_MIN_DB_REPLICA_OPTION || pCfg->quorum > TSDB_MAX_DB_REPLICA_OPTION) {
|
if (pCfg->quorum < TSDB_MIN_DB_REPLICA_OPTION || pCfg->quorum > TSDB_MAX_DB_REPLICA_OPTION) {
|
||||||
mError("invalid db option quorum:%d valid range: [%d, %d]", pCfg->quorum, TSDB_MIN_DB_REPLICA_OPTION,
|
mError("invalid db option quorum:%d valid range: [%d, %d]", pCfg->quorum, TSDB_MIN_DB_REPLICA_OPTION,
|
||||||
TSDB_MAX_DB_REPLICA_OPTION);
|
TSDB_MAX_DB_REPLICA_OPTION);
|
||||||
|
|
|
@ -74,13 +74,13 @@ static int32_t mnodeInitComponents() {
|
||||||
int32_t mnodeStartSystem() {
|
int32_t mnodeStartSystem() {
|
||||||
if (tsMgmtIsRunning) {
|
if (tsMgmtIsRunning) {
|
||||||
mInfo("mnode module already started...");
|
mInfo("mnode module already started...");
|
||||||
return 0;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
mInfo("starting to initialize mnode ...");
|
mInfo("starting to initialize mnode ...");
|
||||||
if (mkdir(tsMnodeDir, 0755) != 0 && errno != EEXIST) {
|
if (mkdir(tsMnodeDir, 0755) != 0 && errno != EEXIST) {
|
||||||
mError("failed to init mnode dir:%s, reason:%s", tsMnodeDir, strerror(errno));
|
mError("failed to init mnode dir:%s, reason:%s", tsMnodeDir, strerror(errno));
|
||||||
return -1;
|
return TSDB_CODE_MND_FAILED_TO_CREATE_DIR;
|
||||||
}
|
}
|
||||||
|
|
||||||
dnodeAllocMWritequeue();
|
dnodeAllocMWritequeue();
|
||||||
|
@ -88,7 +88,7 @@ int32_t mnodeStartSystem() {
|
||||||
dnodeAllocateMPeerQueue();
|
dnodeAllocateMPeerQueue();
|
||||||
|
|
||||||
if (mnodeInitComponents() != 0) {
|
if (mnodeInitComponents() != 0) {
|
||||||
return -1;
|
return TSDB_CODE_MND_FAILED_TO_INIT_STEP;
|
||||||
}
|
}
|
||||||
|
|
||||||
dnodeReportStep("mnode-grant", "start to set grant infomation", 0);
|
dnodeReportStep("mnode-grant", "start to set grant infomation", 0);
|
||||||
|
@ -99,7 +99,7 @@ int32_t mnodeStartSystem() {
|
||||||
|
|
||||||
sdbUpdateSync(NULL);
|
sdbUpdateSync(NULL);
|
||||||
|
|
||||||
return 0;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t mnodeInitSystem() {
|
int32_t mnodeInitSystem() {
|
||||||
|
|
|
@ -318,11 +318,11 @@ void sdbUpdateAsync() {
|
||||||
taosTmrReset(sdbUpdateSyncTmrFp, 200, NULL, tsMnodeTmr, &tsSdbTmr);
|
taosTmrReset(sdbUpdateSyncTmrFp, 200, NULL, tsMnodeTmr, &tsSdbTmr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sdbUpdateSync(void *pMnodes) {
|
int32_t sdbUpdateSync(void *pMnodes) {
|
||||||
SMInfos *pMinfos = pMnodes;
|
SMInfos *pMinfos = pMnodes;
|
||||||
if (!mnodeIsRunning()) {
|
if (!mnodeIsRunning()) {
|
||||||
mDebug("vgId:1, mnode not start yet, update sync config later");
|
mDebug("vgId:1, mnode not start yet, update sync config later");
|
||||||
return;
|
return TSDB_CODE_MND_MNODE_IS_RUNNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
mDebug("vgId:1, update sync config, pMnodes:%p", pMnodes);
|
mDebug("vgId:1, update sync config, pMnodes:%p", pMnodes);
|
||||||
|
@ -377,12 +377,12 @@ void sdbUpdateSync(void *pMnodes) {
|
||||||
|
|
||||||
if (!hasThisDnode) {
|
if (!hasThisDnode) {
|
||||||
sdbDebug("vgId:1, update sync config, this dnode not exist");
|
sdbDebug("vgId:1, update sync config, this dnode not exist");
|
||||||
return;
|
return TSDB_CODE_MND_FAILED_TO_CONFIG_SYNC;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (memcmp(&syncCfg, &tsSdbMgmt.cfg, sizeof(SSyncCfg)) == 0) {
|
if (memcmp(&syncCfg, &tsSdbMgmt.cfg, sizeof(SSyncCfg)) == 0) {
|
||||||
sdbDebug("vgId:1, update sync config, info not changed");
|
sdbDebug("vgId:1, update sync config, info not changed");
|
||||||
return;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
sdbInfo("vgId:1, work as mnode, replica:%d", syncCfg.replica);
|
sdbInfo("vgId:1, work as mnode, replica:%d", syncCfg.replica);
|
||||||
|
@ -407,12 +407,15 @@ void sdbUpdateSync(void *pMnodes) {
|
||||||
tsSdbMgmt.cfg = syncCfg;
|
tsSdbMgmt.cfg = syncCfg;
|
||||||
|
|
||||||
if (tsSdbMgmt.sync) {
|
if (tsSdbMgmt.sync) {
|
||||||
syncReconfig(tsSdbMgmt.sync, &syncCfg);
|
int32_t code = syncReconfig(tsSdbMgmt.sync, &syncCfg);
|
||||||
|
if (code != 0) return code;
|
||||||
} else {
|
} else {
|
||||||
tsSdbMgmt.sync = syncStart(&syncInfo);
|
tsSdbMgmt.sync = syncStart(&syncInfo);
|
||||||
|
if (tsSdbMgmt.sync <= 0) return TSDB_CODE_MND_FAILED_TO_START_SYNC;
|
||||||
}
|
}
|
||||||
|
|
||||||
sdbUpdateMnodeRoles();
|
sdbUpdateMnodeRoles();
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t sdbInitRef() {
|
int32_t sdbInitRef() {
|
||||||
|
@ -1051,7 +1054,10 @@ static int32_t sdbWriteFwdToQueue(int32_t vgId, void *wparam, int32_t qtype, voi
|
||||||
memcpy(pRow->pHead, pHead, sizeof(SWalHead) + pHead->len);
|
memcpy(pRow->pHead, pHead, sizeof(SWalHead) + pHead->len);
|
||||||
pRow->rowData = pRow->pHead->cont;
|
pRow->rowData = pRow->pHead->cont;
|
||||||
|
|
||||||
return sdbWriteToQueue(pRow, qtype);
|
int32_t code = sdbWriteToQueue(pRow, qtype);
|
||||||
|
if (code == TSDB_CODE_MND_ACTION_IN_PROGRESS) code = 0;
|
||||||
|
|
||||||
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t sdbWriteRowToQueue(SSdbRow *pInputRow, int32_t action) {
|
static int32_t sdbWriteRowToQueue(SSdbRow *pInputRow, int32_t action) {
|
||||||
|
|
|
@ -827,21 +827,21 @@ static int32_t mnodeProcessBatchCreateTableMsg(SMnodeMsg *pMsg) {
|
||||||
SCreateTableMsg *pCreateTable = (SCreateTableMsg*) ((char*) pCreate + sizeof(SCMCreateTableMsg));
|
SCreateTableMsg *pCreateTable = (SCreateTableMsg*) ((char*) pCreate + sizeof(SCMCreateTableMsg));
|
||||||
int32_t code = mnodeValidateCreateTableMsg(pCreateTable, pMsg);
|
int32_t code = mnodeValidateCreateTableMsg(pCreateTable, pMsg);
|
||||||
if (code == TSDB_CODE_SUCCESS || code == TSDB_CODE_MND_TABLE_ALREADY_EXIST) {
|
if (code == TSDB_CODE_SUCCESS || code == TSDB_CODE_MND_TABLE_ALREADY_EXIST) {
|
||||||
++pMsg->pBatchMasterMsg->successed;
|
++pMsg->pBatchMasterMsg->successed;
|
||||||
mnodeDestroySubMsg(pMsg);
|
mnodeDestroySubMsg(pMsg);
|
||||||
}
|
} else if (code == TSDB_CODE_MND_ACTION_NEED_REPROCESSED) {
|
||||||
|
return code;
|
||||||
if (code != TSDB_CODE_MND_ACTION_IN_PROGRESS) {
|
} else if (code != TSDB_CODE_MND_ACTION_IN_PROGRESS) {
|
||||||
mnodeDestroySubMsg(pMsg);
|
++pMsg->pBatchMasterMsg->received;
|
||||||
return code;
|
mnodeDestroySubMsg(pMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pMsg->pBatchMasterMsg->successed + pMsg->pBatchMasterMsg->received
|
if (pMsg->pBatchMasterMsg->successed + pMsg->pBatchMasterMsg->received
|
||||||
>= pMsg->pBatchMasterMsg->expected) {
|
>= pMsg->pBatchMasterMsg->expected) {
|
||||||
return code;
|
dnodeSendRpcMWriteRsp(pMsg->pBatchMasterMsg, TSDB_CODE_SUCCESS);
|
||||||
} else {
|
|
||||||
return TSDB_CODE_MND_ACTION_IN_PROGRESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return TSDB_CODE_MND_ACTION_IN_PROGRESS;
|
||||||
} else { // batch master replay, reprocess the whole batch
|
} else { // batch master replay, reprocess the whole batch
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,12 +89,17 @@ int taosInitTimer(void (*callback)(int), int ms) {
|
||||||
if (code != 0) {
|
if (code != 0) {
|
||||||
uError("failed to create timer thread");
|
uError("failed to create timer thread");
|
||||||
return -1;
|
return -1;
|
||||||
|
} else {
|
||||||
|
uDebug("timer thread:0x%08" PRIx64 " is created", taosGetPthreadId(timerThread));
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void taosUninitTimer() {
|
void taosUninitTimer() {
|
||||||
stopTimer = true;
|
stopTimer = true;
|
||||||
|
|
||||||
|
uDebug("join timer thread:0x%08" PRIx64, taosGetPthreadId(timerThread));
|
||||||
pthread_join(timerThread, NULL);
|
pthread_join(timerThread, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -152,7 +152,7 @@ typedef struct SQuery {
|
||||||
int16_t precision;
|
int16_t precision;
|
||||||
int16_t numOfOutput;
|
int16_t numOfOutput;
|
||||||
int16_t fillType;
|
int16_t fillType;
|
||||||
int16_t checkBuffer; // check if the buffer is full during scan each block
|
int16_t checkResultBuf; // check if the buffer is full during scan each block
|
||||||
SLimitVal limit;
|
SLimitVal limit;
|
||||||
int32_t rowSize;
|
int32_t rowSize;
|
||||||
SSqlGroupbyExpr* pGroupbyExpr;
|
SSqlGroupbyExpr* pGroupbyExpr;
|
||||||
|
|
|
@ -88,6 +88,7 @@ typedef struct STSBuf {
|
||||||
STSList tsData; // uncompressed raw ts data
|
STSList tsData; // uncompressed raw ts data
|
||||||
uint64_t numOfTotal;
|
uint64_t numOfTotal;
|
||||||
bool autoDelete;
|
bool autoDelete;
|
||||||
|
bool remainOpen;
|
||||||
int32_t tsOrder; // order of timestamp in ts comp buffer
|
int32_t tsOrder; // order of timestamp in ts comp buffer
|
||||||
STSCursor cur;
|
STSCursor cur;
|
||||||
} STSBuf;
|
} STSBuf;
|
||||||
|
|
|
@ -1268,12 +1268,14 @@ static void min_function_f(SQLFunctionCtx *pCtx, int32_t index) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stddev_function(SQLFunctionCtx *pCtx) {
|
static void stddev_function(SQLFunctionCtx *pCtx) {
|
||||||
// the second stage to calculate standard deviation
|
|
||||||
SStddevInfo *pStd = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx));
|
SStddevInfo *pStd = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx));
|
||||||
|
|
||||||
if (pStd->stage == 0) { // the first stage is to calculate average value
|
if (pStd->stage == 0) {
|
||||||
|
// the first stage is to calculate average value
|
||||||
avg_function(pCtx);
|
avg_function(pCtx);
|
||||||
} else {
|
} else if (pStd->num > 0) {
|
||||||
|
// the second stage to calculate standard deviation
|
||||||
|
// if pStd->num == 0, there are no numbers in the first round check. No need to do the second round
|
||||||
double *retVal = &pStd->res;
|
double *retVal = &pStd->res;
|
||||||
double avg = pStd->avg;
|
double avg = pStd->avg;
|
||||||
|
|
||||||
|
@ -1326,7 +1328,7 @@ static void stddev_function_f(SQLFunctionCtx *pCtx, int32_t index) {
|
||||||
/* the first stage is to calculate average value */
|
/* the first stage is to calculate average value */
|
||||||
if (pStd->stage == 0) {
|
if (pStd->stage == 0) {
|
||||||
avg_function_f(pCtx, index);
|
avg_function_f(pCtx, index);
|
||||||
} else {
|
} else if (pStd->num > 0) {
|
||||||
double avg = pStd->avg;
|
double avg = pStd->avg;
|
||||||
void * pData = GET_INPUT_DATA(pCtx, index);
|
void * pData = GET_INPUT_DATA(pCtx, index);
|
||||||
|
|
||||||
|
@ -3836,8 +3838,10 @@ static void ts_comp_finalize(SQLFunctionCtx *pCtx) {
|
||||||
STSBuf * pTSbuf = pInfo->pTSBuf;
|
STSBuf * pTSbuf = pInfo->pTSBuf;
|
||||||
|
|
||||||
tsBufFlush(pTSbuf);
|
tsBufFlush(pTSbuf);
|
||||||
strcpy(pCtx->aOutputBuf, pTSbuf->path);
|
|
||||||
|
|
||||||
|
*(FILE **)pCtx->aOutputBuf = pTSbuf->f;
|
||||||
|
|
||||||
|
pTSbuf->remainOpen = true;
|
||||||
tsBufDestroy(pTSbuf);
|
tsBufDestroy(pTSbuf);
|
||||||
doFinalizer(pCtx);
|
doFinalizer(pCtx);
|
||||||
}
|
}
|
||||||
|
|
|
@ -548,7 +548,7 @@ static STimeWindow getActiveTimeWindow(SResultRowInfo *pWindowResInfo, int64_t t
|
||||||
if (pWindowResInfo->curIndex == -1) { // the first window, from the previous stored value
|
if (pWindowResInfo->curIndex == -1) { // the first window, from the previous stored value
|
||||||
w.skey = pWindowResInfo->prevSKey;
|
w.skey = pWindowResInfo->prevSKey;
|
||||||
if (pQuery->interval.intervalUnit == 'n' || pQuery->interval.intervalUnit == 'y') {
|
if (pQuery->interval.intervalUnit == 'n' || pQuery->interval.intervalUnit == 'y') {
|
||||||
w.ekey = taosTimeAdd(w.skey, pQuery->interval.interval, pQuery->interval.intervalUnit, pQuery->precision);
|
w.ekey = taosTimeAdd(w.skey, pQuery->interval.interval, pQuery->interval.intervalUnit, pQuery->precision) - 1;
|
||||||
} else {
|
} else {
|
||||||
w.ekey = w.skey + pQuery->interval.interval - 1;
|
w.ekey = w.skey + pQuery->interval.interval - 1;
|
||||||
}
|
}
|
||||||
|
@ -758,7 +758,12 @@ static void doUpdateResultRowIndex(SResultRowInfo*pResultRowInfo, TSKEY lastKey,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pResultRowInfo->curIndex = i + 1; // current not closed result object
|
if (i == pResultRowInfo->size - 1) {
|
||||||
|
pResultRowInfo->curIndex = i;
|
||||||
|
} else {
|
||||||
|
pResultRowInfo->curIndex = i + 1; // current not closed result object
|
||||||
|
}
|
||||||
|
|
||||||
pResultRowInfo->prevSKey = pResultRowInfo->pResult[pResultRowInfo->curIndex]->win.skey;
|
pResultRowInfo->prevSKey = pResultRowInfo->pResult[pResultRowInfo->curIndex]->win.skey;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1667,7 +1672,7 @@ static void rowwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SDataStatis *pS
|
||||||
|
|
||||||
_end:
|
_end:
|
||||||
assert(offset >= 0 && tsCols != NULL);
|
assert(offset >= 0 && tsCols != NULL);
|
||||||
if (prevTs != INT64_MIN) {
|
if (prevTs != INT64_MIN && prevTs != *(int64_t*)pRuntimeEnv->prevRow[0]) {
|
||||||
assert(prevRowIndex >= 0);
|
assert(prevRowIndex >= 0);
|
||||||
item->lastKey = prevTs + step;
|
item->lastKey = prevTs + step;
|
||||||
}
|
}
|
||||||
|
@ -1708,7 +1713,7 @@ static int32_t tableApplyFunctionsOnBlock(SQueryRuntimeEnv *pRuntimeEnv, SDataBl
|
||||||
numOfRes = (int32_t) getNumOfResult(pRuntimeEnv);
|
numOfRes = (int32_t) getNumOfResult(pRuntimeEnv);
|
||||||
|
|
||||||
// update the number of output result
|
// update the number of output result
|
||||||
if (numOfRes > 0 && pQuery->checkBuffer == 1) {
|
if (numOfRes > 0 && pQuery->checkResultBuf == 1) {
|
||||||
assert(numOfRes >= pQuery->rec.rows);
|
assert(numOfRes >= pQuery->rec.rows);
|
||||||
pQuery->rec.rows = numOfRes;
|
pQuery->rec.rows = numOfRes;
|
||||||
|
|
||||||
|
@ -2005,6 +2010,7 @@ static void doFreeQueryHandle(SQInfo* pQInfo) {
|
||||||
assert(pMemRef->ref == 0 && pMemRef->imem == NULL && pMemRef->mem == NULL);
|
assert(pMemRef->ref == 0 && pMemRef->imem == NULL && pMemRef->mem == NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void teardownQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv) {
|
static void teardownQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv) {
|
||||||
if (pRuntimeEnv->pQuery == NULL) {
|
if (pRuntimeEnv->pQuery == NULL) {
|
||||||
return;
|
return;
|
||||||
|
@ -2016,6 +2022,16 @@ static void teardownQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv) {
|
||||||
qDebug("QInfo:%p teardown runtime env", pQInfo);
|
qDebug("QInfo:%p teardown runtime env", pQInfo);
|
||||||
cleanupResultRowInfo(&pRuntimeEnv->windowResInfo);
|
cleanupResultRowInfo(&pRuntimeEnv->windowResInfo);
|
||||||
|
|
||||||
|
if (isTSCompQuery(pQuery)) {
|
||||||
|
FILE *f = *(FILE **)pQuery->sdata[0]->data;
|
||||||
|
|
||||||
|
if (f) {
|
||||||
|
fclose(f);
|
||||||
|
*(FILE **)pQuery->sdata[0]->data = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (pRuntimeEnv->pCtx != NULL) {
|
if (pRuntimeEnv->pCtx != NULL) {
|
||||||
for (int32_t i = 0; i < pQuery->numOfOutput; ++i) {
|
for (int32_t i = 0; i < pQuery->numOfOutput; ++i) {
|
||||||
SQLFunctionCtx *pCtx = &pRuntimeEnv->pCtx[i];
|
SQLFunctionCtx *pCtx = &pRuntimeEnv->pCtx[i];
|
||||||
|
@ -2222,9 +2238,9 @@ void getAlignQueryTimeWindow(SQuery *pQuery, int64_t key, int64_t keyFirst, int6
|
||||||
|
|
||||||
static void setScanLimitationByResultBuffer(SQuery *pQuery) {
|
static void setScanLimitationByResultBuffer(SQuery *pQuery) {
|
||||||
if (isTopBottomQuery(pQuery)) {
|
if (isTopBottomQuery(pQuery)) {
|
||||||
pQuery->checkBuffer = 0;
|
pQuery->checkResultBuf = 0;
|
||||||
} else if (isGroupbyNormalCol(pQuery->pGroupbyExpr)) {
|
} else if (isGroupbyNormalCol(pQuery->pGroupbyExpr)) {
|
||||||
pQuery->checkBuffer = 0;
|
pQuery->checkResultBuf = 0;
|
||||||
} else {
|
} else {
|
||||||
bool hasMultioutput = false;
|
bool hasMultioutput = false;
|
||||||
for (int32_t i = 0; i < pQuery->numOfOutput; ++i) {
|
for (int32_t i = 0; i < pQuery->numOfOutput; ++i) {
|
||||||
|
@ -2239,7 +2255,7 @@ static void setScanLimitationByResultBuffer(SQuery *pQuery) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pQuery->checkBuffer = hasMultioutput ? 1 : 0;
|
pQuery->checkResultBuf = hasMultioutput ? 1 : 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2911,7 +2927,7 @@ void setTagVal(SQueryRuntimeEnv *pRuntimeEnv, void *pTable, void *tsdb) {
|
||||||
SQInfo* pQInfo = GET_QINFO_ADDR(pRuntimeEnv);
|
SQInfo* pQInfo = GET_QINFO_ADDR(pRuntimeEnv);
|
||||||
|
|
||||||
SExprInfo *pExprInfo = &pQuery->pExpr1[0];
|
SExprInfo *pExprInfo = &pQuery->pExpr1[0];
|
||||||
if (pQuery->numOfOutput == 1 && pExprInfo->base.functionId == TSDB_FUNC_TS_COMP) {
|
if (pQuery->numOfOutput == 1 && pExprInfo->base.functionId == TSDB_FUNC_TS_COMP && pRuntimeEnv->stableQuery) {
|
||||||
assert(pExprInfo->base.numOfParams == 1);
|
assert(pExprInfo->base.numOfParams == 1);
|
||||||
|
|
||||||
int16_t tagColId = (int16_t)pExprInfo->base.arg->argValue.i64;
|
int16_t tagColId = (int16_t)pExprInfo->base.arg->argValue.i64;
|
||||||
|
@ -3674,6 +3690,10 @@ void scanOneTableDataBlocks(SQueryRuntimeEnv *pRuntimeEnv, TSKEY start) {
|
||||||
SQueryStatusInfo qstatus = getQueryStatusInfo(pRuntimeEnv, start);
|
SQueryStatusInfo qstatus = getQueryStatusInfo(pRuntimeEnv, start);
|
||||||
SET_MASTER_SCAN_FLAG(pRuntimeEnv);
|
SET_MASTER_SCAN_FLAG(pRuntimeEnv);
|
||||||
|
|
||||||
|
if (!pRuntimeEnv->groupbyColumn && pRuntimeEnv->hasTagResults) {
|
||||||
|
setTagVal(pRuntimeEnv, pTableQueryInfo->pTable, pQInfo->tsdb);
|
||||||
|
}
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
doScanAllDataBlocks(pRuntimeEnv);
|
doScanAllDataBlocks(pRuntimeEnv);
|
||||||
|
|
||||||
|
@ -4757,20 +4777,21 @@ static void enableExecutionForNextTable(SQueryRuntimeEnv *pRuntimeEnv) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO refactor: setAdditionalInfo
|
||||||
static FORCE_INLINE void setEnvForEachBlock(SQInfo* pQInfo, STableQueryInfo* pTableQueryInfo, SDataBlockInfo* pBlockInfo) {
|
static FORCE_INLINE void setEnvForEachBlock(SQInfo* pQInfo, STableQueryInfo* pTableQueryInfo, SDataBlockInfo* pBlockInfo) {
|
||||||
SQueryRuntimeEnv* pRuntimeEnv = &pQInfo->runtimeEnv;
|
SQueryRuntimeEnv* pRuntimeEnv = &pQInfo->runtimeEnv;
|
||||||
SQuery* pQuery = pQInfo->runtimeEnv.pQuery;
|
SQuery* pQuery = pQInfo->runtimeEnv.pQuery;
|
||||||
int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQuery->order.order);
|
int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQuery->order.order);
|
||||||
|
|
||||||
if (!QUERY_IS_INTERVAL_QUERY(pQuery)) {
|
if (QUERY_IS_INTERVAL_QUERY(pQuery)) {
|
||||||
setExecutionContext(pQInfo, pTableQueryInfo->groupIndex, pBlockInfo->window.ekey + step);
|
|
||||||
} else { // interval query
|
|
||||||
TSKEY nextKey = pBlockInfo->window.skey;
|
TSKEY nextKey = pBlockInfo->window.skey;
|
||||||
setIntervalQueryRange(pQInfo, nextKey);
|
setIntervalQueryRange(pQInfo, nextKey);
|
||||||
|
|
||||||
if (pRuntimeEnv->hasTagResults || pRuntimeEnv->pTsBuf != NULL) {
|
if (pRuntimeEnv->hasTagResults || pRuntimeEnv->pTsBuf != NULL) {
|
||||||
setAdditionalInfo(pQInfo, pTableQueryInfo->pTable, pTableQueryInfo);
|
setAdditionalInfo(pQInfo, pTableQueryInfo->pTable, pTableQueryInfo);
|
||||||
}
|
}
|
||||||
|
} else { // non-interval query
|
||||||
|
setExecutionContext(pQInfo, pTableQueryInfo->groupIndex, pBlockInfo->window.ekey + step);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5626,8 +5647,6 @@ static void tableAggregationProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pQuery->current = pTableInfo; // set current query table info
|
|
||||||
|
|
||||||
scanOneTableDataBlocks(pRuntimeEnv, pTableInfo->lastKey);
|
scanOneTableDataBlocks(pRuntimeEnv, pTableInfo->lastKey);
|
||||||
finalizeQueryResult(pRuntimeEnv);
|
finalizeQueryResult(pRuntimeEnv);
|
||||||
|
|
||||||
|
@ -5646,10 +5665,8 @@ static void tableAggregationProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo)
|
||||||
static void tableProjectionProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo) {
|
static void tableProjectionProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo) {
|
||||||
SQueryRuntimeEnv *pRuntimeEnv = &pQInfo->runtimeEnv;
|
SQueryRuntimeEnv *pRuntimeEnv = &pQInfo->runtimeEnv;
|
||||||
|
|
||||||
SQuery *pQuery = pRuntimeEnv->pQuery;
|
|
||||||
pQuery->current = pTableInfo;
|
|
||||||
|
|
||||||
// for ts_comp query, re-initialized is not allowed
|
// for ts_comp query, re-initialized is not allowed
|
||||||
|
SQuery *pQuery = pRuntimeEnv->pQuery;
|
||||||
if (!isTSCompQuery(pQuery)) {
|
if (!isTSCompQuery(pQuery)) {
|
||||||
resetDefaultResInfoOutputBuf(pRuntimeEnv);
|
resetDefaultResInfoOutputBuf(pRuntimeEnv);
|
||||||
}
|
}
|
||||||
|
@ -5701,9 +5718,7 @@ static void tableProjectionProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo)
|
||||||
// handle time interval query on table
|
// handle time interval query on table
|
||||||
static void tableIntervalProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo) {
|
static void tableIntervalProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo) {
|
||||||
SQueryRuntimeEnv *pRuntimeEnv = &(pQInfo->runtimeEnv);
|
SQueryRuntimeEnv *pRuntimeEnv = &(pQInfo->runtimeEnv);
|
||||||
|
|
||||||
SQuery *pQuery = pRuntimeEnv->pQuery;
|
SQuery *pQuery = pRuntimeEnv->pQuery;
|
||||||
pQuery->current = pTableInfo;
|
|
||||||
|
|
||||||
TSKEY newStartKey = QUERY_IS_ASC_QUERY(pQuery)? INT64_MIN:INT64_MAX;
|
TSKEY newStartKey = QUERY_IS_ASC_QUERY(pQuery)? INT64_MIN:INT64_MAX;
|
||||||
|
|
||||||
|
@ -5773,7 +5788,6 @@ static void tableQueryImpl(SQInfo *pQInfo) {
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug("QInfo:%p current:%" PRId64 " returned, total:%" PRId64, pQInfo, pQuery->rec.rows, pQuery->rec.total);
|
qDebug("QInfo:%p current:%" PRId64 " returned, total:%" PRId64, pQInfo, pQuery->rec.rows, pQuery->rec.total);
|
||||||
return;
|
|
||||||
} else {
|
} else {
|
||||||
pQuery->rec.rows = 0;
|
pQuery->rec.rows = 0;
|
||||||
assert(pRuntimeEnv->windowResInfo.size > 0);
|
assert(pRuntimeEnv->windowResInfo.size > 0);
|
||||||
|
@ -5791,9 +5805,9 @@ static void tableQueryImpl(SQInfo *pQInfo) {
|
||||||
if (pQuery->rec.rows <= 0 || pRuntimeEnv->windowResInfo.size <= pQInfo->groupIndex) {
|
if (pQuery->rec.rows <= 0 || pRuntimeEnv->windowResInfo.size <= pQInfo->groupIndex) {
|
||||||
qDebug("QInfo:%p query over, %" PRId64 " rows are returned", pQInfo, pQuery->rec.total);
|
qDebug("QInfo:%p query over, %" PRId64 " rows are returned", pQInfo, pQuery->rec.total);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// number of points returned during this query
|
// number of points returned during this query
|
||||||
|
@ -5802,7 +5816,9 @@ static void tableQueryImpl(SQInfo *pQInfo) {
|
||||||
|
|
||||||
assert(pQInfo->tableqinfoGroupInfo.numOfTables == 1);
|
assert(pQInfo->tableqinfoGroupInfo.numOfTables == 1);
|
||||||
SArray* g = GET_TABLEGROUP(pQInfo, 0);
|
SArray* g = GET_TABLEGROUP(pQInfo, 0);
|
||||||
|
|
||||||
STableQueryInfo* item = taosArrayGetP(g, 0);
|
STableQueryInfo* item = taosArrayGetP(g, 0);
|
||||||
|
pQuery->current = item;
|
||||||
|
|
||||||
// group by normal column, sliding window query, interval query are handled by interval query processor
|
// group by normal column, sliding window query, interval query are handled by interval query processor
|
||||||
if (QUERY_IS_INTERVAL_QUERY(pQuery) || pRuntimeEnv->groupbyColumn) { // interval (down sampling operation)
|
if (QUERY_IS_INTERVAL_QUERY(pQuery) || pRuntimeEnv->groupbyColumn) { // interval (down sampling operation)
|
||||||
|
@ -5810,7 +5826,7 @@ static void tableQueryImpl(SQInfo *pQInfo) {
|
||||||
} else if (isFixedOutputQuery(pRuntimeEnv)) {
|
} else if (isFixedOutputQuery(pRuntimeEnv)) {
|
||||||
tableAggregationProcess(pQInfo, item);
|
tableAggregationProcess(pQInfo, item);
|
||||||
} else { // diff/add/multiply/subtract/division
|
} else { // diff/add/multiply/subtract/division
|
||||||
assert(pQuery->checkBuffer == 1);
|
assert(pQuery->checkResultBuf == 1);
|
||||||
tableProjectionProcess(pQInfo, item);
|
tableProjectionProcess(pQInfo, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5830,7 +5846,7 @@ static void stableQueryImpl(SQInfo *pQInfo) {
|
||||||
(isFixedOutputQuery(pRuntimeEnv) && (!isPointInterpoQuery(pQuery)) && (!pRuntimeEnv->groupbyColumn))) {
|
(isFixedOutputQuery(pRuntimeEnv) && (!isPointInterpoQuery(pQuery)) && (!pRuntimeEnv->groupbyColumn))) {
|
||||||
multiTableQueryProcess(pQInfo);
|
multiTableQueryProcess(pQInfo);
|
||||||
} else {
|
} else {
|
||||||
assert((pQuery->checkBuffer == 1 && pQuery->interval.interval == 0) || isPointInterpoQuery(pQuery) ||
|
assert((pQuery->checkResultBuf == 1 && pQuery->interval.interval == 0) || isPointInterpoQuery(pQuery) ||
|
||||||
pRuntimeEnv->groupbyColumn);
|
pRuntimeEnv->groupbyColumn);
|
||||||
|
|
||||||
sequentialTableProcess(pQInfo);
|
sequentialTableProcess(pQInfo);
|
||||||
|
@ -6944,10 +6960,10 @@ static size_t getResultSize(SQInfo *pQInfo, int64_t *numOfRows) {
|
||||||
* TODO handle the case that the file is too large to send back one time
|
* TODO handle the case that the file is too large to send back one time
|
||||||
*/
|
*/
|
||||||
if (isTSCompQuery(pQuery) && (*numOfRows) > 0) {
|
if (isTSCompQuery(pQuery) && (*numOfRows) > 0) {
|
||||||
struct stat fstat;
|
struct stat fStat;
|
||||||
if (stat(pQuery->sdata[0]->data, &fstat) == 0) {
|
if (fstat(fileno(*(FILE **)pQuery->sdata[0]->data), &fStat) == 0) {
|
||||||
*numOfRows = fstat.st_size;
|
*numOfRows = fStat.st_size;
|
||||||
return fstat.st_size;
|
return fStat.st_size;
|
||||||
} else {
|
} else {
|
||||||
qError("QInfo:%p failed to get file info, path:%s, reason:%s", pQInfo, pQuery->sdata[0]->data, strerror(errno));
|
qError("QInfo:%p failed to get file info, path:%s, reason:%s", pQInfo, pQuery->sdata[0]->data, strerror(errno));
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -6963,15 +6979,16 @@ static int32_t doDumpQueryResult(SQInfo *pQInfo, char *data) {
|
||||||
|
|
||||||
// load data from file to msg buffer
|
// load data from file to msg buffer
|
||||||
if (isTSCompQuery(pQuery)) {
|
if (isTSCompQuery(pQuery)) {
|
||||||
int32_t fd = open(pQuery->sdata[0]->data, O_RDONLY, 0666);
|
|
||||||
|
FILE *f = *(FILE **)pQuery->sdata[0]->data;
|
||||||
|
|
||||||
// make sure file exist
|
// make sure file exist
|
||||||
if (FD_VALID(fd)) {
|
if (f) {
|
||||||
uint64_t s = lseek(fd, 0, SEEK_END);
|
off_t s = lseek(fileno(f), 0, SEEK_END);
|
||||||
|
|
||||||
qDebug("QInfo:%p ts comp data return, file:%s, size:%"PRId64, pQInfo, pQuery->sdata[0]->data, s);
|
qDebug("QInfo:%p ts comp data return, file:%p, size:%"PRId64, pQInfo, f, s);
|
||||||
if (lseek(fd, 0, SEEK_SET) >= 0) {
|
if (fseek(f, 0, SEEK_SET) >= 0) {
|
||||||
size_t sz = read(fd, data, (uint32_t) s);
|
size_t sz = fread(data, 1, s, f);
|
||||||
if(sz < s) { // todo handle error
|
if(sz < s) { // todo handle error
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
@ -6979,15 +6996,8 @@ static int32_t doDumpQueryResult(SQInfo *pQInfo, char *data) {
|
||||||
UNUSED(s);
|
UNUSED(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
close(fd);
|
fclose(f);
|
||||||
unlink(pQuery->sdata[0]->data);
|
*(FILE **)pQuery->sdata[0]->data = NULL;
|
||||||
} else {
|
|
||||||
// todo return the error code to client and handle invalid fd
|
|
||||||
qError("QInfo:%p failed to open tmp file to send ts-comp data to client, path:%s, reason:%s", pQInfo,
|
|
||||||
pQuery->sdata[0]->data, strerror(errno));
|
|
||||||
if (fd != -1) {
|
|
||||||
close(fd);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// all data returned, set query over
|
// all data returned, set query over
|
||||||
|
@ -7635,6 +7645,19 @@ void qQueryMgmtNotifyClosed(void* pQMgmt) {
|
||||||
taosCacheRefresh(pQueryMgmt->qinfoPool, queryMgmtKillQueryFn);
|
taosCacheRefresh(pQueryMgmt->qinfoPool, queryMgmtKillQueryFn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void qQueryMgmtReOpen(void *pQMgmt) {
|
||||||
|
if (pQMgmt == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SQueryMgmt *pQueryMgmt = pQMgmt;
|
||||||
|
qDebug("vgId:%d, set querymgmt reopen", pQueryMgmt->vgId);
|
||||||
|
|
||||||
|
pthread_mutex_lock(&pQueryMgmt->lock);
|
||||||
|
pQueryMgmt->closed = false;
|
||||||
|
pthread_mutex_unlock(&pQueryMgmt->lock);
|
||||||
|
}
|
||||||
|
|
||||||
void qCleanupQueryMgmt(void* pQMgmt) {
|
void qCleanupQueryMgmt(void* pQMgmt) {
|
||||||
if (pQMgmt == NULL) {
|
if (pQMgmt == NULL) {
|
||||||
return;
|
return;
|
||||||
|
@ -7715,4 +7738,4 @@ void** qReleaseQInfo(void* pMgmt, void* pQInfo, bool freeHandle) {
|
||||||
|
|
||||||
taosCacheRelease(pQueryMgmt->qinfoPool, pQInfo, freeHandle);
|
taosCacheRelease(pQueryMgmt->qinfoPool, pQInfo, freeHandle);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -143,6 +143,9 @@ SHistogramInfo* tHistogramCreateFrom(void* pBuf, int32_t numOfBins) {
|
||||||
|
|
||||||
SHistogramInfo* pHisto = (SHistogramInfo*)pBuf;
|
SHistogramInfo* pHisto = (SHistogramInfo*)pBuf;
|
||||||
pHisto->elems = (SHistBin*)((char*)pBuf + sizeof(SHistogramInfo));
|
pHisto->elems = (SHistBin*)((char*)pBuf + sizeof(SHistogramInfo));
|
||||||
|
for(int32_t i = 0; i < numOfBins; ++i) {
|
||||||
|
pHisto->elems[i].val = -DBL_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
pHisto->maxEntries = numOfBins;
|
pHisto->maxEntries = numOfBins;
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,8 @@ STSBuf* tsBufCreate(bool autoDelete, int32_t order) {
|
||||||
if (pTSBuf == NULL) {
|
if (pTSBuf == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pTSBuf->autoDelete = autoDelete;
|
||||||
|
|
||||||
taosGetTmpfilePath("join", pTSBuf->path);
|
taosGetTmpfilePath("join", pTSBuf->path);
|
||||||
pTSBuf->f = fopen(pTSBuf->path, "w+");
|
pTSBuf->f = fopen(pTSBuf->path, "w+");
|
||||||
|
@ -26,6 +28,10 @@ STSBuf* tsBufCreate(bool autoDelete, int32_t order) {
|
||||||
free(pTSBuf);
|
free(pTSBuf);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!autoDelete) {
|
||||||
|
unlink(pTSBuf->path);
|
||||||
|
}
|
||||||
|
|
||||||
if (NULL == allocResForTSBuf(pTSBuf)) {
|
if (NULL == allocResForTSBuf(pTSBuf)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -37,8 +43,7 @@ STSBuf* tsBufCreate(bool autoDelete, int32_t order) {
|
||||||
|
|
||||||
tsBufResetPos(pTSBuf);
|
tsBufResetPos(pTSBuf);
|
||||||
pTSBuf->cur.order = TSDB_ORDER_ASC;
|
pTSBuf->cur.order = TSDB_ORDER_ASC;
|
||||||
|
|
||||||
pTSBuf->autoDelete = autoDelete;
|
|
||||||
pTSBuf->tsOrder = order;
|
pTSBuf->tsOrder = order;
|
||||||
|
|
||||||
return pTSBuf;
|
return pTSBuf;
|
||||||
|
@ -49,6 +54,8 @@ STSBuf* tsBufCreateFromFile(const char* path, bool autoDelete) {
|
||||||
if (pTSBuf == NULL) {
|
if (pTSBuf == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pTSBuf->autoDelete = autoDelete;
|
||||||
|
|
||||||
tstrncpy(pTSBuf->path, path, sizeof(pTSBuf->path));
|
tstrncpy(pTSBuf->path, path, sizeof(pTSBuf->path));
|
||||||
|
|
||||||
|
@ -129,7 +136,6 @@ STSBuf* tsBufCreateFromFile(const char* path, bool autoDelete) {
|
||||||
|
|
||||||
// ascending by default
|
// ascending by default
|
||||||
pTSBuf->cur.order = TSDB_ORDER_ASC;
|
pTSBuf->cur.order = TSDB_ORDER_ASC;
|
||||||
pTSBuf->autoDelete = autoDelete;
|
|
||||||
|
|
||||||
// tscDebug("create tsBuf from file:%s, fd:%d, size:%d, numOfGroups:%d, autoDelete:%d", pTSBuf->path, fileno(pTSBuf->f),
|
// tscDebug("create tsBuf from file:%s, fd:%d, size:%d, numOfGroups:%d, autoDelete:%d", pTSBuf->path, fileno(pTSBuf->f),
|
||||||
// pTSBuf->fileSize, pTSBuf->numOfGroups, pTSBuf->autoDelete);
|
// pTSBuf->fileSize, pTSBuf->numOfGroups, pTSBuf->autoDelete);
|
||||||
|
@ -147,8 +153,10 @@ void* tsBufDestroy(STSBuf* pTSBuf) {
|
||||||
|
|
||||||
tfree(pTSBuf->pData);
|
tfree(pTSBuf->pData);
|
||||||
tfree(pTSBuf->block.payload);
|
tfree(pTSBuf->block.payload);
|
||||||
|
|
||||||
fclose(pTSBuf->f);
|
if (!pTSBuf->remainOpen) {
|
||||||
|
fclose(pTSBuf->f);
|
||||||
|
}
|
||||||
|
|
||||||
if (pTSBuf->autoDelete) {
|
if (pTSBuf->autoDelete) {
|
||||||
// ("tsBuf %p destroyed, delete tmp file:%s", pTSBuf, pTSBuf->path);
|
// ("tsBuf %p destroyed, delete tmp file:%s", pTSBuf, pTSBuf->path);
|
||||||
|
|
|
@ -4,42 +4,9 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "taos.h"
|
#include "taos.h"
|
||||||
#include "tsdb.h"
|
|
||||||
|
|
||||||
#include "tstoken.h"
|
|
||||||
#include "tutil.h"
|
|
||||||
|
|
||||||
#include "qHistogram.h"
|
#include "qHistogram.h"
|
||||||
|
namespace {
|
||||||
/* test validate the names for table/database */
|
void doHistogramAddTest() {
|
||||||
TEST(testCase, histogram_binary_search) {
|
|
||||||
SHistogramInfo* pHisto = tHistogramCreate(MAX_HISTOGRAM_BIN);
|
|
||||||
|
|
||||||
pHisto->numOfEntries = 10;
|
|
||||||
for (int32_t i = 0; i < 10; ++i) {
|
|
||||||
pHisto->elems[i].num = 1;
|
|
||||||
pHisto->elems[i].val = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t idx = histoBinarySearch(pHisto->elems, pHisto->numOfEntries, 1);
|
|
||||||
assert(idx == 1);
|
|
||||||
|
|
||||||
idx = histoBinarySearch(pHisto->elems, pHisto->numOfEntries, 9);
|
|
||||||
assert(idx == 9);
|
|
||||||
|
|
||||||
idx = histoBinarySearch(pHisto->elems, pHisto->numOfEntries, 20);
|
|
||||||
assert(idx == 10);
|
|
||||||
|
|
||||||
idx = histoBinarySearch(pHisto->elems, pHisto->numOfEntries, -1);
|
|
||||||
assert(idx == 0);
|
|
||||||
|
|
||||||
idx = histoBinarySearch(pHisto->elems, pHisto->numOfEntries, 3.9);
|
|
||||||
assert(idx == 4);
|
|
||||||
|
|
||||||
free(pHisto);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(testCase, histogram_add) {
|
|
||||||
SHistogramInfo* pHisto = NULL;
|
SHistogramInfo* pHisto = NULL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -99,6 +66,56 @@ TEST(testCase, histogram_add) {
|
||||||
tHistogramDestroy(&pRes);
|
tHistogramDestroy(&pRes);
|
||||||
free(res);
|
free(res);
|
||||||
}
|
}
|
||||||
|
void doHistogramRepeatTest() {
|
||||||
|
SHistogramInfo* pHisto = NULL;
|
||||||
|
struct timeval systemTime;
|
||||||
|
|
||||||
|
gettimeofday(&systemTime, NULL);
|
||||||
|
int64_t st =
|
||||||
|
(int64_t)systemTime.tv_sec * 1000L + (uint64_t)systemTime.tv_usec / 1000;
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < 1000; ++i) {
|
||||||
|
tHistogramAdd(&pHisto, -24 + i);
|
||||||
|
// tHistogramPrint(pHisto);
|
||||||
|
}
|
||||||
|
|
||||||
|
tHistogramDestroy(&pHisto);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* test validate the names for table/database */
|
||||||
|
TEST(testCase, histogram_binary_search) {
|
||||||
|
SHistogramInfo* pHisto = tHistogramCreate(MAX_HISTOGRAM_BIN);
|
||||||
|
|
||||||
|
pHisto->numOfEntries = 10;
|
||||||
|
for (int32_t i = 0; i < 10; ++i) {
|
||||||
|
pHisto->elems[i].num = 1;
|
||||||
|
pHisto->elems[i].val = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t idx = histoBinarySearch(pHisto->elems, pHisto->numOfEntries, 1);
|
||||||
|
assert(idx == 1);
|
||||||
|
|
||||||
|
idx = histoBinarySearch(pHisto->elems, pHisto->numOfEntries, 9);
|
||||||
|
assert(idx == 9);
|
||||||
|
|
||||||
|
idx = histoBinarySearch(pHisto->elems, pHisto->numOfEntries, 20);
|
||||||
|
assert(idx == 10);
|
||||||
|
|
||||||
|
idx = histoBinarySearch(pHisto->elems, pHisto->numOfEntries, -1);
|
||||||
|
assert(idx == 0);
|
||||||
|
|
||||||
|
idx = histoBinarySearch(pHisto->elems, pHisto->numOfEntries, 3.9);
|
||||||
|
assert(idx == 4);
|
||||||
|
|
||||||
|
free(pHisto);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(testCase, histogram_add) {
|
||||||
|
doHistogramAddTest();
|
||||||
|
doHistogramRepeatTest();
|
||||||
|
}
|
||||||
|
|
||||||
TEST(testCase, heapsort) {
|
TEST(testCase, heapsort) {
|
||||||
// int32_t num = 20;
|
// int32_t num = 20;
|
||||||
|
|
|
@ -1567,6 +1567,7 @@ static int rpcCheckAuthentication(SRpcConn *pConn, char *msg, int msgLen) {
|
||||||
// for response, if code is auth failure, it shall bypass the auth process
|
// for response, if code is auth failure, it shall bypass the auth process
|
||||||
code = htonl(pHead->code);
|
code = htonl(pHead->code);
|
||||||
if (code == TSDB_CODE_RPC_INVALID_TIME_STAMP || code == TSDB_CODE_RPC_AUTH_FAILURE ||
|
if (code == TSDB_CODE_RPC_INVALID_TIME_STAMP || code == TSDB_CODE_RPC_AUTH_FAILURE ||
|
||||||
|
code == TSDB_CODE_RPC_INVALID_VERSION ||
|
||||||
code == TSDB_CODE_RPC_AUTH_REQUIRED || code == TSDB_CODE_MND_INVALID_USER || code == TSDB_CODE_RPC_NOT_READY) {
|
code == TSDB_CODE_RPC_AUTH_REQUIRED || code == TSDB_CODE_MND_INVALID_USER || code == TSDB_CODE_RPC_NOT_READY) {
|
||||||
pHead->msgLen = (int32_t)htonl((uint32_t)pHead->msgLen);
|
pHead->msgLen = (int32_t)htonl((uint32_t)pHead->msgLen);
|
||||||
// tTrace("%s, dont check authentication since code is:0x%x", pConn->info, code);
|
// tTrace("%s, dont check authentication since code is:0x%x", pConn->info, code);
|
||||||
|
|
|
@ -375,6 +375,8 @@ int32_t syncReconfig(int64_t rid, const SSyncCfg *pNewCfg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t syncForwardToPeer(int64_t rid, void *data, void *mhandle, int32_t qtype) {
|
int32_t syncForwardToPeer(int64_t rid, void *data, void *mhandle, int32_t qtype) {
|
||||||
|
if (rid <= 0) return 0;
|
||||||
|
|
||||||
SSyncNode *pNode = syncAcquireNode(rid);
|
SSyncNode *pNode = syncAcquireNode(rid);
|
||||||
if (pNode == NULL) return 0;
|
if (pNode == NULL) return 0;
|
||||||
|
|
||||||
|
|
|
@ -90,7 +90,7 @@ static int32_t syncRestoreFile(SSyncPeer *pPeer, uint64_t *fversion) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
sDebug("%s, file:%s info is received from master, index:%d size:%" PRId64 " fver:%" PRIu64 " magic:%d", pPeer->id,
|
sDebug("%s, file:%s info is received from master, index:%d size:%" PRId64 " fver:%" PRIu64 " magic:%u", pPeer->id,
|
||||||
minfo.name, minfo.index, minfo.size, minfo.fversion, minfo.magic);
|
minfo.name, minfo.index, minfo.size, minfo.fversion, minfo.magic);
|
||||||
|
|
||||||
// remove extra files on slave between the current and last index
|
// remove extra files on slave between the current and last index
|
||||||
|
@ -100,13 +100,13 @@ static int32_t syncRestoreFile(SSyncPeer *pPeer, uint64_t *fversion) {
|
||||||
// check the file info
|
// check the file info
|
||||||
sinfo = minfo;
|
sinfo = minfo;
|
||||||
sinfo.magic = (*pNode->getFileInfo)(pNode->vgId, sinfo.name, &sinfo.index, TAOS_SYNC_MAX_INDEX, &sinfo.size, &sinfo.fversion);
|
sinfo.magic = (*pNode->getFileInfo)(pNode->vgId, sinfo.name, &sinfo.index, TAOS_SYNC_MAX_INDEX, &sinfo.size, &sinfo.fversion);
|
||||||
sDebug("%s, local file:%s info, index:%d size:%" PRId64 " fver:%" PRIu64 " magic:%d", pPeer->id, sinfo.name,
|
sDebug("%s, local file:%s info, index:%d size:%" PRId64 " fver:%" PRIu64 " magic:%u", pPeer->id, sinfo.name,
|
||||||
sinfo.index, sinfo.size, sinfo.fversion, sinfo.magic);
|
sinfo.index, sinfo.size, sinfo.fversion, sinfo.magic);
|
||||||
|
|
||||||
// if file not there or magic is not the same, file shall be synced
|
// if file not there or magic is not the same, file shall be synced
|
||||||
memset(&fileAck, 0, sizeof(SFileAck));
|
memset(&fileAck, 0, sizeof(SFileAck));
|
||||||
syncBuildFileAck(&fileAck, pNode->vgId);
|
syncBuildFileAck(&fileAck, pNode->vgId);
|
||||||
fileAck.sync = (sinfo.magic != minfo.magic || sinfo.name[0] == 0) ? 1 : 0;
|
fileAck.sync = (sinfo.magic != minfo.magic || sinfo.size != minfo.size || sinfo.name[0] == 0) ? 1 : 0;
|
||||||
|
|
||||||
// send file ack
|
// send file ack
|
||||||
ret = taosWriteMsg(pPeer->syncFd, &fileAck, sizeof(SFileAck));
|
ret = taosWriteMsg(pPeer->syncFd, &fileAck, sizeof(SFileAck));
|
||||||
|
@ -195,7 +195,11 @@ static int32_t syncRestoreWal(SSyncPeer *pPeer, uint64_t *wver) {
|
||||||
}
|
}
|
||||||
lastVer = pHead->version;
|
lastVer = pHead->version;
|
||||||
|
|
||||||
(*pNode->writeToCache)(pNode->vgId, pHead, TAOS_QTYPE_WAL, NULL);
|
ret = (*pNode->writeToCache)(pNode->vgId, pHead, TAOS_QTYPE_WAL, NULL);
|
||||||
|
if (ret != 0) {
|
||||||
|
sError("%s, failed to restore record since %s, hver:%" PRIu64, pPeer->id, tstrerror(ret), pHead->version);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (code < 0) {
|
if (code < 0) {
|
||||||
|
|
|
@ -104,7 +104,7 @@ static int32_t syncRetrieveFile(SSyncPeer *pPeer) {
|
||||||
fileInfo.magic = (*pNode->getFileInfo)(pNode->vgId, fileInfo.name, &fileInfo.index, TAOS_SYNC_MAX_INDEX,
|
fileInfo.magic = (*pNode->getFileInfo)(pNode->vgId, fileInfo.name, &fileInfo.index, TAOS_SYNC_MAX_INDEX,
|
||||||
&fileInfo.size, &fileInfo.fversion);
|
&fileInfo.size, &fileInfo.fversion);
|
||||||
syncBuildFileInfo(&fileInfo, pNode->vgId);
|
syncBuildFileInfo(&fileInfo, pNode->vgId);
|
||||||
sDebug("%s, file:%s info is sent, index:%d size:%" PRId64 " fver:%" PRIu64 " magic:%d", pPeer->id, fileInfo.name,
|
sDebug("%s, file:%s info is sent, index:%d size:%" PRId64 " fver:%" PRIu64 " magic:%u", pPeer->id, fileInfo.name,
|
||||||
fileInfo.index, fileInfo.size, fileInfo.fversion, fileInfo.magic);
|
fileInfo.index, fileInfo.size, fileInfo.fversion, fileInfo.magic);
|
||||||
|
|
||||||
// send the file info
|
// send the file info
|
||||||
|
@ -143,10 +143,10 @@ static int32_t syncRetrieveFile(SSyncPeer *pPeer) {
|
||||||
// if sync is not required, continue
|
// if sync is not required, continue
|
||||||
if (fileAck.sync == 0) {
|
if (fileAck.sync == 0) {
|
||||||
fileInfo.index++;
|
fileInfo.index++;
|
||||||
sDebug("%s, %s is the same", pPeer->id, fileInfo.name);
|
sDebug("%s, %s is the same, fver:%" PRIu64, pPeer->id, fileInfo.name, fileInfo.fversion);
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
sDebug("%s, %s will be sent", pPeer->id, fileInfo.name);
|
sDebug("%s, %s will be sent, fver:%" PRIu64, pPeer->id, fileInfo.name, fileInfo.fversion);
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the full path to file
|
// get the full path to file
|
||||||
|
@ -328,7 +328,8 @@ static int32_t syncProcessLastWal(SSyncPeer *pPeer, char *wname, int64_t index)
|
||||||
// if bytes > 0, file is updated, or fversion is not reached but file still open, read again
|
// if bytes > 0, file is updated, or fversion is not reached but file still open, read again
|
||||||
once = 1;
|
once = 1;
|
||||||
offset += bytes;
|
offset += bytes;
|
||||||
sDebug("%s, continue retrieve last wal, bytes:%d offset:%" PRId64, pPeer->id, bytes, offset);
|
sDebug("%s, continue retrieve last wal, bytes:%d offset:%" PRId64 " sver:%" PRIu64 " fver:%" PRIu64, pPeer->id,
|
||||||
|
bytes, offset, pPeer->sversion, fversion);
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -477,8 +477,6 @@ void taosHashEmpty(SHashObj *pHashObj) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uDebug("hash:%p cleanup hash table", pHashObj);
|
|
||||||
|
|
||||||
SHashNode *pNode, *pNext;
|
SHashNode *pNode, *pNext;
|
||||||
|
|
||||||
__wr_lock(&pHashObj->lock, pHashObj->type);
|
__wr_lock(&pHashObj->lock, pHashObj->type);
|
||||||
|
|
|
@ -27,6 +27,7 @@ void vnodeCleanupRead(void);
|
||||||
int32_t vnodeWriteToRQueue(void *pVnode, void *pCont, int32_t contLen, int8_t qtype, void *rparam);
|
int32_t vnodeWriteToRQueue(void *pVnode, void *pCont, int32_t contLen, int8_t qtype, void *rparam);
|
||||||
void vnodeFreeFromRQueue(void *pVnode, SVReadMsg *pRead);
|
void vnodeFreeFromRQueue(void *pVnode, SVReadMsg *pRead);
|
||||||
int32_t vnodeProcessRead(void *pVnode, SVReadMsg *pRead);
|
int32_t vnodeProcessRead(void *pVnode, SVReadMsg *pRead);
|
||||||
|
void vnodeWaitReadCompleted(void *pVnode);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ bool vnodeSetResetStatus(SVnodeObj* pVnode);
|
||||||
|
|
||||||
bool vnodeInInitStatus(SVnodeObj* pVnode);
|
bool vnodeInInitStatus(SVnodeObj* pVnode);
|
||||||
bool vnodeInReadyStatus(SVnodeObj* pVnode);
|
bool vnodeInReadyStatus(SVnodeObj* pVnode);
|
||||||
|
bool vnodeInReadyOrUpdatingStatus(SVnodeObj* pVnode);
|
||||||
bool vnodeInClosingStatus(SVnodeObj* pVnode);
|
bool vnodeInClosingStatus(SVnodeObj* pVnode);
|
||||||
bool vnodeInResetStatus(SVnodeObj* pVnode);
|
bool vnodeInResetStatus(SVnodeObj* pVnode);
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ void vnodeCleanupWrite(void);
|
||||||
int32_t vnodeWriteToWQueue(void *pVnode, void *pHead, int32_t qtype, void *pRpcMsg);
|
int32_t vnodeWriteToWQueue(void *pVnode, void *pHead, int32_t qtype, void *pRpcMsg);
|
||||||
void vnodeFreeFromWQueue(void *pVnode, SVWriteMsg *pWrite);
|
void vnodeFreeFromWQueue(void *pVnode, SVWriteMsg *pWrite);
|
||||||
int32_t vnodeProcessWrite(void *pVnode, void *pHead, int32_t qtype, void *pRspRet);
|
int32_t vnodeProcessWrite(void *pVnode, void *pHead, int32_t qtype, void *pRspRet);
|
||||||
|
void vnodeWaitWriteCompleted(void *pVnode);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -153,6 +153,11 @@ static int32_t vnodeAlterImp(SVnodeObj *pVnode, SCreateVnodeMsg *pVnodeCfg) {
|
||||||
|
|
||||||
int32_t vnodeAlter(void *vparam, SCreateVnodeMsg *pVnodeCfg) {
|
int32_t vnodeAlter(void *vparam, SCreateVnodeMsg *pVnodeCfg) {
|
||||||
SVnodeObj *pVnode = vparam;
|
SVnodeObj *pVnode = vparam;
|
||||||
|
if (pVnode->dbCfgVersion == pVnodeCfg->cfg.dbCfgVersion && pVnode->vgCfgVersion == pVnodeCfg->cfg.vgCfgVersion) {
|
||||||
|
vDebug("vgId:%d, dbCfgVersion:%d and vgCfgVersion:%d not change", pVnode->vgId, pVnode->dbCfgVersion,
|
||||||
|
pVnode->vgCfgVersion);
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
// vnode in non-ready state and still needs to return success instead of TSDB_CODE_VND_INVALID_STATUS
|
// vnode in non-ready state and still needs to return success instead of TSDB_CODE_VND_INVALID_STATUS
|
||||||
// dbCfgVersion can be corrected by status msg
|
// dbCfgVersion can be corrected by status msg
|
||||||
|
@ -411,15 +416,12 @@ void vnodeDestroy(SVnodeObj *pVnode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void vnodeCleanUp(SVnodeObj *pVnode) {
|
void vnodeCleanUp(SVnodeObj *pVnode) {
|
||||||
if (!vnodeInInitStatus(pVnode)) {
|
vDebug("vgId:%d, vnode will cleanup, refCount:%d pVnode:%p", pVnode->vgId, pVnode->refCount, pVnode);
|
||||||
// it may be in updateing or reset state, then it shall wait
|
|
||||||
int32_t i = 0;
|
vnodeSetClosingStatus(pVnode);
|
||||||
while (!vnodeSetClosingStatus(pVnode)) {
|
|
||||||
if (++i % 1000 == 0) {
|
// release local resources only after cutting off outside connections
|
||||||
sched_yield();
|
qQueryMgmtNotifyClosed(pVnode->qMgmt);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// stop replication module
|
// stop replication module
|
||||||
if (pVnode->sync > 0) {
|
if (pVnode->sync > 0) {
|
||||||
|
@ -428,10 +430,7 @@ void vnodeCleanUp(SVnodeObj *pVnode) {
|
||||||
syncStop(sync);
|
syncStop(sync);
|
||||||
}
|
}
|
||||||
|
|
||||||
vDebug("vgId:%d, vnode will cleanup, refCount:%d pVnode:%p", pVnode->vgId, pVnode->refCount, pVnode);
|
vDebug("vgId:%d, vnode is cleaned, refCount:%d pVnode:%p", pVnode->vgId, pVnode->refCount, pVnode);
|
||||||
|
|
||||||
// release local resources only after cutting off outside connections
|
|
||||||
qQueryMgmtNotifyClosed(pVnode->qMgmt);
|
|
||||||
vnodeRelease(pVnode);
|
vnodeRelease(pVnode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -88,22 +88,15 @@ void vnodeFreeFromRQueue(void *vparam, SVReadMsg *pRead) {
|
||||||
vnodeRelease(pVnode);
|
vnodeRelease(pVnode);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t vnodeWriteToRQueue(void *vparam, void *pCont, int32_t contLen, int8_t qtype, void *rparam) {
|
static SVReadMsg *vnodeBuildVReadMsg(SVnodeObj *pVnode, void *pCont, int32_t contLen, int8_t qtype, SRpcMsg *pRpcMsg) {
|
||||||
SVnodeObj *pVnode = vparam;
|
|
||||||
|
|
||||||
if (qtype == TAOS_QTYPE_RPC || qtype == TAOS_QTYPE_QUERY) {
|
|
||||||
int32_t code = vnodeCheckRead(pVnode);
|
|
||||||
if (code != TSDB_CODE_SUCCESS) return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t size = sizeof(SVReadMsg) + contLen;
|
int32_t size = sizeof(SVReadMsg) + contLen;
|
||||||
SVReadMsg *pRead = taosAllocateQitem(size);
|
SVReadMsg *pRead = taosAllocateQitem(size);
|
||||||
if (pRead == NULL) {
|
if (pRead == NULL) {
|
||||||
return TSDB_CODE_VND_OUT_OF_MEMORY;
|
terrno = TSDB_CODE_VND_OUT_OF_MEMORY;
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rparam != NULL) {
|
if (pRpcMsg != NULL) {
|
||||||
SRpcMsg *pRpcMsg = rparam;
|
|
||||||
pRead->rpcHandle = pRpcMsg->handle;
|
pRead->rpcHandle = pRpcMsg->handle;
|
||||||
pRead->rpcAhandle = pRpcMsg->ahandle;
|
pRead->rpcAhandle = pRpcMsg->ahandle;
|
||||||
pRead->msgType = pRpcMsg->msgType;
|
pRead->msgType = pRpcMsg->msgType;
|
||||||
|
@ -119,13 +112,35 @@ int32_t vnodeWriteToRQueue(void *vparam, void *pCont, int32_t contLen, int8_t qt
|
||||||
|
|
||||||
pRead->qtype = qtype;
|
pRead->qtype = qtype;
|
||||||
atomic_add_fetch_32(&pVnode->refCount, 1);
|
atomic_add_fetch_32(&pVnode->refCount, 1);
|
||||||
|
|
||||||
|
return pRead;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t vnodeWriteToRQueue(void *vparam, void *pCont, int32_t contLen, int8_t qtype, void *rparam) {
|
||||||
|
SVReadMsg *pRead = vnodeBuildVReadMsg(vparam, pCont, contLen, qtype, rparam);
|
||||||
|
if (pRead == NULL) {
|
||||||
|
assert(terrno != 0);
|
||||||
|
return terrno;
|
||||||
|
}
|
||||||
|
|
||||||
|
SVnodeObj *pVnode = vparam;
|
||||||
|
|
||||||
|
int32_t code = vnodeCheckRead(pVnode);
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
taosFreeQitem(pRead);
|
||||||
|
vnodeRelease(pVnode);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
atomic_add_fetch_32(&pVnode->queuedRMsg, 1);
|
atomic_add_fetch_32(&pVnode->queuedRMsg, 1);
|
||||||
|
|
||||||
if (pRead->code == TSDB_CODE_RPC_NETWORK_UNAVAIL || pRead->msgType == TSDB_MSG_TYPE_FETCH) {
|
if (pRead->code == TSDB_CODE_RPC_NETWORK_UNAVAIL || pRead->msgType == TSDB_MSG_TYPE_FETCH) {
|
||||||
vTrace("vgId:%d, write into vfetch queue, refCount:%d queued:%d", pVnode->vgId, pVnode->refCount, pVnode->queuedRMsg);
|
vTrace("vgId:%d, write into vfetch queue, refCount:%d queued:%d", pVnode->vgId, pVnode->refCount,
|
||||||
|
pVnode->queuedRMsg);
|
||||||
return taosWriteQitem(pVnode->fqueue, qtype, pRead);
|
return taosWriteQitem(pVnode->fqueue, qtype, pRead);
|
||||||
} else {
|
} else {
|
||||||
vTrace("vgId:%d, write into vquery queue, refCount:%d queued:%d", pVnode->vgId, pVnode->refCount, pVnode->queuedRMsg);
|
vTrace("vgId:%d, write into vquery queue, refCount:%d queued:%d", pVnode->vgId, pVnode->refCount,
|
||||||
|
pVnode->queuedRMsg);
|
||||||
return taosWriteQitem(pVnode->qqueue, qtype, pRead);
|
return taosWriteQitem(pVnode->qqueue, qtype, pRead);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -420,3 +435,5 @@ int32_t vnodeNotifyCurrentQhandle(void *handle, void *qhandle, int32_t vgId) {
|
||||||
vTrace("QInfo:%p register qhandle to connect:%p", qhandle, handle);
|
vTrace("QInfo:%p register qhandle to connect:%p", qhandle, handle);
|
||||||
return rpcReportProgress(handle, (char *)pMsg, sizeof(SRetrieveTableMsg));
|
return rpcReportProgress(handle, (char *)pMsg, sizeof(SRetrieveTableMsg));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void vnodeWaitReadCompleted(void *pVnode) {}
|
|
@ -15,6 +15,8 @@
|
||||||
|
|
||||||
#define _DEFAULT_SOURCE
|
#define _DEFAULT_SOURCE
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
|
#include "taosmsg.h"
|
||||||
|
#include "query.h"
|
||||||
#include "vnodeStatus.h"
|
#include "vnodeStatus.h"
|
||||||
|
|
||||||
char* vnodeStatus[] = {
|
char* vnodeStatus[] = {
|
||||||
|
@ -44,11 +46,13 @@ bool vnodeSetReadyStatus(SVnodeObj* pVnode) {
|
||||||
vDebug("vgId:%d, cannot set status:ready, old:%s", pVnode->vgId, vnodeStatus[pVnode->status]);
|
vDebug("vgId:%d, cannot set status:ready, old:%s", pVnode->vgId, vnodeStatus[pVnode->status]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qQueryMgmtReOpen(pVnode->qMgmt);
|
||||||
|
|
||||||
pthread_mutex_unlock(&pVnode->statusMutex);
|
pthread_mutex_unlock(&pVnode->statusMutex);
|
||||||
return set;
|
return set;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool vnodeSetClosingStatus(SVnodeObj* pVnode) {
|
static bool vnodeSetClosingStatusImp(SVnodeObj* pVnode) {
|
||||||
bool set = false;
|
bool set = false;
|
||||||
pthread_mutex_lock(&pVnode->statusMutex);
|
pthread_mutex_lock(&pVnode->statusMutex);
|
||||||
|
|
||||||
|
@ -63,6 +67,20 @@ bool vnodeSetClosingStatus(SVnodeObj* pVnode) {
|
||||||
return set;
|
return set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool vnodeSetClosingStatus(SVnodeObj* pVnode) {
|
||||||
|
if (!vnodeInInitStatus(pVnode)) {
|
||||||
|
// it may be in updating or reset state, then it shall wait
|
||||||
|
int32_t i = 0;
|
||||||
|
while (!vnodeSetClosingStatusImp(pVnode)) {
|
||||||
|
if (++i % 1000 == 0) {
|
||||||
|
sched_yield();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool vnodeSetUpdatingStatus(SVnodeObj* pVnode) {
|
bool vnodeSetUpdatingStatus(SVnodeObj* pVnode) {
|
||||||
bool set = false;
|
bool set = false;
|
||||||
pthread_mutex_lock(&pVnode->statusMutex);
|
pthread_mutex_lock(&pVnode->statusMutex);
|
||||||
|
@ -117,6 +135,18 @@ bool vnodeInReadyStatus(SVnodeObj* pVnode) {
|
||||||
return in;
|
return in;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool vnodeInReadyOrUpdatingStatus(SVnodeObj* pVnode) {
|
||||||
|
bool in = false;
|
||||||
|
pthread_mutex_lock(&pVnode->statusMutex);
|
||||||
|
|
||||||
|
if (pVnode->status == TAOS_VN_STATUS_READY || pVnode->status == TAOS_VN_STATUS_UPDATING) {
|
||||||
|
in = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&pVnode->statusMutex);
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
bool vnodeInClosingStatus(SVnodeObj* pVnode) {
|
bool vnodeInClosingStatus(SVnodeObj* pVnode) {
|
||||||
bool in = false;
|
bool in = false;
|
||||||
pthread_mutex_lock(&pVnode->statusMutex);
|
pthread_mutex_lock(&pVnode->statusMutex);
|
||||||
|
|
|
@ -90,7 +90,10 @@ int32_t vnodeProcessWrite(void *vparam, void *wparam, int32_t qtype, void *rpara
|
||||||
|
|
||||||
// write into WAL
|
// write into WAL
|
||||||
code = walWrite(pVnode->wal, pHead);
|
code = walWrite(pVnode->wal, pHead);
|
||||||
if (code < 0) return code;
|
if (code < 0) {
|
||||||
|
vError("vgId:%d, hver:%" PRIu64 " vver:%" PRIu64 " code:0x%x", pVnode->vgId, pHead->version, pVnode->version, code);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
pVnode->version = pHead->version;
|
pVnode->version = pHead->version;
|
||||||
|
|
||||||
|
@ -120,12 +123,6 @@ static int32_t vnodeCheckWrite(SVnodeObj *pVnode) {
|
||||||
return TSDB_CODE_APP_NOT_READY;
|
return TSDB_CODE_APP_NOT_READY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vnodeInClosingStatus(pVnode)) {
|
|
||||||
vDebug("vgId:%d, vnode status is %s, refCount:%d pVnode:%p", pVnode->vgId, vnodeStatus[pVnode->status],
|
|
||||||
pVnode->refCount, pVnode);
|
|
||||||
return TSDB_CODE_APP_NOT_READY;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pVnode->isFull) {
|
if (pVnode->isFull) {
|
||||||
vDebug("vgId:%d, vnode is full, refCount:%d", pVnode->vgId, pVnode->refCount);
|
vDebug("vgId:%d, vnode is full, refCount:%d", pVnode->vgId, pVnode->refCount);
|
||||||
return TSDB_CODE_VND_IS_FULL;
|
return TSDB_CODE_VND_IS_FULL;
|
||||||
|
@ -248,12 +245,21 @@ static int32_t vnodeWriteToWQueueImp(SVWriteMsg *pWrite) {
|
||||||
if (pWrite->qtype == TAOS_QTYPE_RPC) {
|
if (pWrite->qtype == TAOS_QTYPE_RPC) {
|
||||||
int32_t code = vnodeCheckWrite(pVnode);
|
int32_t code = vnodeCheckWrite(pVnode);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
vError("vgId:%d, failed to write into vwqueue since %s", pVnode->vgId, tstrerror(code));
|
||||||
taosFreeQitem(pWrite);
|
taosFreeQitem(pWrite);
|
||||||
vnodeRelease(pVnode);
|
vnodeRelease(pVnode);
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!vnodeInReadyOrUpdatingStatus(pVnode)) {
|
||||||
|
vError("vgId:%d, failed to write into vwqueue, vstatus is %s, refCount:%d pVnode:%p", pVnode->vgId,
|
||||||
|
vnodeStatus[pVnode->status], pVnode->refCount, pVnode);
|
||||||
|
taosFreeQitem(pWrite);
|
||||||
|
vnodeRelease(pVnode);
|
||||||
|
return TSDB_CODE_APP_NOT_READY;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t queued = atomic_add_fetch_32(&pVnode->queuedWMsg, 1);
|
int32_t queued = atomic_add_fetch_32(&pVnode->queuedWMsg, 1);
|
||||||
if (queued > MAX_QUEUED_MSG_NUM) {
|
if (queued > MAX_QUEUED_MSG_NUM) {
|
||||||
int32_t ms = (queued / MAX_QUEUED_MSG_NUM) * 10 + 3;
|
int32_t ms = (queued / MAX_QUEUED_MSG_NUM) * 10 + 3;
|
||||||
|
@ -337,4 +343,6 @@ static int32_t vnodePerformFlowCtrl(SVWriteMsg *pWrite) {
|
||||||
pWrite->processedCount);
|
pWrite->processedCount);
|
||||||
return TSDB_CODE_VND_ACTION_IN_PROGRESS;
|
return TSDB_CODE_VND_ACTION_IN_PROGRESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void vnodeWaitWriteCompleted(void *pVnode) {}
|
|
@ -98,7 +98,15 @@ pipeline {
|
||||||
sh '''
|
sh '''
|
||||||
cd ${WKC}/tests/examples/JDBC/JDBCDemo/
|
cd ${WKC}/tests/examples/JDBC/JDBCDemo/
|
||||||
mvn clean package assembly:single -DskipTests >/dev/null
|
mvn clean package assembly:single -DskipTests >/dev/null
|
||||||
java -jar target/jdbcChecker-SNAPSHOT-jar-with-dependencies.jar -host 127.0.0.1
|
java -jar target/JDBCDemo-SNAPSHOT-jar-with-dependencies.jar -host 127.0.0.1
|
||||||
|
'''
|
||||||
|
}
|
||||||
|
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
|
||||||
|
sh '''
|
||||||
|
cd ${WKC}/src/connector/jdbc
|
||||||
|
mvn clean package -Dmaven.test.skip=true >/dev/null
|
||||||
|
cd ${WKC}/tests/examples/JDBC/JDBCDemo/
|
||||||
|
java --class-path=../../../../src/connector/jdbc/target:$JAVA_HOME/jre/lib/ext -jar target/JDBCDemo-SNAPSHOT-jar-with-dependencies.jar -host 127.0.0.1
|
||||||
'''
|
'''
|
||||||
}
|
}
|
||||||
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
|
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
|
||||||
|
|
|
@ -10,12 +10,14 @@ run C# version taosdemo
|
||||||
===
|
===
|
||||||
Usage: mono taosdemo.exe [OPTION...]
|
Usage: mono taosdemo.exe [OPTION...]
|
||||||
|
|
||||||
|
--help Show usage.
|
||||||
|
|
||||||
-h host, The host to connect to TDengine. Default is localhost.
|
-h host, The host to connect to TDengine. Default is localhost.
|
||||||
-p port, The TCP/IP port number to use for the connection. Default is 0.
|
-p port, The TCP/IP port number to use for the connection. Default is 0.
|
||||||
-u user, The user name to use when connecting to the server. Default is 'root'.
|
-u user, The user name to use when connecting to the server. Default is 'root'.
|
||||||
-P password, The password to use when connecting to the server. Default is 'taosdata'.
|
-P password, The password to use when connecting to the server. Default is 'taosdata'.
|
||||||
-d database, Destination database. Default is 'test'.
|
-d database, Destination database. Default is 'test'.
|
||||||
-a replica, Set the replica parameters of the database, Default 1, min: 1, max: 3.
|
-a replica, Set the replica parameters of the database, Default 1, min: 1, max: 5.
|
||||||
-m table_prefix, Table prefix name. Default is 't'.
|
-m table_prefix, Table prefix name. Default is 't'.
|
||||||
-s sql file, The select sql file.
|
-s sql file, The select sql file.
|
||||||
-M stable, Use super table.
|
-M stable, Use super table.
|
||||||
|
@ -26,8 +28,8 @@ Usage: mono taosdemo.exe [OPTION...]
|
||||||
-l num_of_cols_per_record, The number of columns per record. Default is 3.
|
-l num_of_cols_per_record, The number of columns per record. Default is 3.
|
||||||
-T num_of_threads, The number of threads. Default is 10.
|
-T num_of_threads, The number of threads. Default is 10.
|
||||||
-r num_of_records_per_req, The number of records per request. Default is 1000.
|
-r num_of_records_per_req, The number of records per request. Default is 1000.
|
||||||
-t num_of_tables, The number of tables. Default is 10000.
|
-t num_of_tables, The number of tables. Default is 1.
|
||||||
-n num_of_records_per_table, The number of records per table. Default is 10000.
|
-n num_of_records_per_table, The number of records per table. Default is 1.
|
||||||
-c config_directory, Configuration directory. Default is '/etc/taos/'.
|
-c config_directory, Configuration directory. Default is '/etc/taos/'.
|
||||||
-x flag, Insert only flag.
|
-x flag, Insert only flag.
|
||||||
-O order, Insert mode--0: In order, 1: Out of order. Default is in order.
|
-O order, Insert mode--0: In order, 1: Out of order. Default is in order.
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
../../../../src/connector/C#/TDengineDriver.cs
|
|
|
@ -0,0 +1,155 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can use, redistribute, and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, version 3
|
||||||
|
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace TDengineDriver
|
||||||
|
{
|
||||||
|
enum TDengineDataType
|
||||||
|
{
|
||||||
|
TSDB_DATA_TYPE_NULL = 0, // 1 bytes
|
||||||
|
TSDB_DATA_TYPE_BOOL = 1, // 1 bytes
|
||||||
|
TSDB_DATA_TYPE_TINYINT = 2, // 1 bytes
|
||||||
|
TSDB_DATA_TYPE_SMALLINT = 3, // 2 bytes
|
||||||
|
TSDB_DATA_TYPE_INT = 4, // 4 bytes
|
||||||
|
TSDB_DATA_TYPE_BIGINT = 5, // 8 bytes
|
||||||
|
TSDB_DATA_TYPE_FLOAT = 6, // 4 bytes
|
||||||
|
TSDB_DATA_TYPE_DOUBLE = 7, // 8 bytes
|
||||||
|
TSDB_DATA_TYPE_BINARY = 8, // string
|
||||||
|
TSDB_DATA_TYPE_TIMESTAMP = 9,// 8 bytes
|
||||||
|
TSDB_DATA_TYPE_NCHAR = 10 // unicode string
|
||||||
|
}
|
||||||
|
|
||||||
|
enum TDengineInitOption
|
||||||
|
{
|
||||||
|
TSDB_OPTION_LOCALE = 0,
|
||||||
|
TSDB_OPTION_CHARSET = 1,
|
||||||
|
TSDB_OPTION_TIMEZONE = 2,
|
||||||
|
TDDB_OPTION_CONFIGDIR = 3,
|
||||||
|
TDDB_OPTION_SHELL_ACTIVITY_TIMER = 4
|
||||||
|
}
|
||||||
|
|
||||||
|
class TDengineMeta
|
||||||
|
{
|
||||||
|
public string name;
|
||||||
|
public short size;
|
||||||
|
public byte type;
|
||||||
|
public string TypeName()
|
||||||
|
{
|
||||||
|
switch ((TDengineDataType)type)
|
||||||
|
{
|
||||||
|
case TDengineDataType.TSDB_DATA_TYPE_BOOL:
|
||||||
|
return "BOOLEAN";
|
||||||
|
case TDengineDataType.TSDB_DATA_TYPE_TINYINT:
|
||||||
|
return "BYTE";
|
||||||
|
case TDengineDataType.TSDB_DATA_TYPE_SMALLINT:
|
||||||
|
return "SHORT";
|
||||||
|
case TDengineDataType.TSDB_DATA_TYPE_INT:
|
||||||
|
return "INT";
|
||||||
|
case TDengineDataType.TSDB_DATA_TYPE_BIGINT:
|
||||||
|
return "LONG";
|
||||||
|
case TDengineDataType.TSDB_DATA_TYPE_FLOAT:
|
||||||
|
return "FLOAT";
|
||||||
|
case TDengineDataType.TSDB_DATA_TYPE_DOUBLE:
|
||||||
|
return "DOUBLE";
|
||||||
|
case TDengineDataType.TSDB_DATA_TYPE_BINARY:
|
||||||
|
return "STRING";
|
||||||
|
case TDengineDataType.TSDB_DATA_TYPE_TIMESTAMP:
|
||||||
|
return "TIMESTAMP";
|
||||||
|
case TDengineDataType.TSDB_DATA_TYPE_NCHAR:
|
||||||
|
return "NCHAR";
|
||||||
|
default:
|
||||||
|
return "undefine";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TDengine
|
||||||
|
{
|
||||||
|
public const int TSDB_CODE_SUCCESS = 0;
|
||||||
|
|
||||||
|
[DllImport("taos", EntryPoint = "taos_init", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
static extern public void Init();
|
||||||
|
|
||||||
|
[DllImport("taos", EntryPoint = "taos_cleanup", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
static extern public void Cleanup();
|
||||||
|
|
||||||
|
[DllImport("taos", EntryPoint = "taos_options", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
static extern public void Options(int option, string value);
|
||||||
|
|
||||||
|
[DllImport("taos", EntryPoint = "taos_connect", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
static extern public IntPtr Connect(string ip, string user, string password, string db, short port);
|
||||||
|
|
||||||
|
[DllImport("taos", EntryPoint = "taos_errstr", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
static extern private IntPtr taos_errstr(IntPtr res);
|
||||||
|
static public string Error(IntPtr res)
|
||||||
|
{
|
||||||
|
IntPtr errPtr = taos_errstr(res);
|
||||||
|
return Marshal.PtrToStringAnsi(errPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
[DllImport("taos", EntryPoint = "taos_errno", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
static extern public int ErrorNo(IntPtr res);
|
||||||
|
|
||||||
|
[DllImport("taos", EntryPoint = "taos_query", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
static extern public IntPtr Query(IntPtr conn, string sqlstr);
|
||||||
|
|
||||||
|
[DllImport("taos", EntryPoint = "taos_affected_rows", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
static extern public int AffectRows(IntPtr res);
|
||||||
|
|
||||||
|
[DllImport("taos", EntryPoint = "taos_field_count", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
static extern public int FieldCount(IntPtr res);
|
||||||
|
|
||||||
|
[DllImport("taos", EntryPoint = "taos_fetch_fields", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
static extern private IntPtr taos_fetch_fields(IntPtr res);
|
||||||
|
static public List<TDengineMeta> FetchFields(IntPtr res)
|
||||||
|
{
|
||||||
|
const int fieldSize = 68;
|
||||||
|
|
||||||
|
List<TDengineMeta> metas = new List<TDengineMeta>();
|
||||||
|
if (res == IntPtr.Zero)
|
||||||
|
{
|
||||||
|
return metas;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fieldCount = FieldCount(res);
|
||||||
|
IntPtr fieldsPtr = taos_fetch_fields(res);
|
||||||
|
|
||||||
|
for (int i = 0; i < fieldCount; ++i)
|
||||||
|
{
|
||||||
|
int offset = i * fieldSize;
|
||||||
|
|
||||||
|
TDengineMeta meta = new TDengineMeta();
|
||||||
|
meta.name = Marshal.PtrToStringAnsi(fieldsPtr + offset);
|
||||||
|
meta.type = Marshal.ReadByte(fieldsPtr + offset + 65);
|
||||||
|
meta.size = Marshal.ReadInt16(fieldsPtr + offset + 66);
|
||||||
|
metas.Add(meta);
|
||||||
|
}
|
||||||
|
|
||||||
|
return metas;
|
||||||
|
}
|
||||||
|
|
||||||
|
[DllImport("taos", EntryPoint = "taos_fetch_row", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
static extern public IntPtr FetchRows(IntPtr res);
|
||||||
|
|
||||||
|
[DllImport("taos", EntryPoint = "taos_free_result", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
static extern public IntPtr FreeResult(IntPtr res);
|
||||||
|
|
||||||
|
[DllImport("taos", EntryPoint = "taos_close", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
static extern public int Close(IntPtr taos);
|
||||||
|
}
|
||||||
|
}
|
|
@ -26,10 +26,10 @@ namespace TDengineDriver
|
||||||
class TDengineTest
|
class TDengineTest
|
||||||
{
|
{
|
||||||
//connect parameters
|
//connect parameters
|
||||||
private string host;
|
private string host = "127.0.0.1";
|
||||||
private string configDir;
|
private string configDir = "C:/TDengine/cfg";
|
||||||
private string user;
|
private string user = "root";
|
||||||
private string password;
|
private string password = "taosdata";
|
||||||
private short port = 0;
|
private short port = 0;
|
||||||
|
|
||||||
//sql parameters
|
//sql parameters
|
||||||
|
@ -40,11 +40,12 @@ namespace TDengineDriver
|
||||||
private bool isInsertOnly = false;
|
private bool isInsertOnly = false;
|
||||||
private int queryMode = 1;
|
private int queryMode = 1;
|
||||||
|
|
||||||
private long recordsPerTable = 10000;
|
private long recordsPerTable = 1;
|
||||||
private int recordsPerRequest = 1;
|
private int recordsPerRequest = 1;
|
||||||
private int colsPerRecord = 3;
|
private int colsPerRecord = 3;
|
||||||
private long batchRows = 1000;
|
private long batchRows = 1000;
|
||||||
private long numOfTables = 10000;
|
private long numOfTables = 1;
|
||||||
|
private short replica = 1;
|
||||||
|
|
||||||
private IntPtr conn = IntPtr.Zero;
|
private IntPtr conn = IntPtr.Zero;
|
||||||
// private long rowsInserted = 0;
|
// private long rowsInserted = 0;
|
||||||
|
@ -66,6 +67,8 @@ namespace TDengineDriver
|
||||||
Console.WriteLine("Usage: mono taosdemo.exe [OPTION...]");
|
Console.WriteLine("Usage: mono taosdemo.exe [OPTION...]");
|
||||||
Console.WriteLine("");
|
Console.WriteLine("");
|
||||||
string indent = " ";
|
string indent = " ";
|
||||||
|
Console.WriteLine("{0}{1}", indent, "--help Show usage.");
|
||||||
|
Console.WriteLine("");
|
||||||
Console.Write("{0}{1}", indent, "-h");
|
Console.Write("{0}{1}", indent, "-h");
|
||||||
Console.Write("{0}{1}{2}\n", indent, indent, "host, The host to connect to TDengine. Default is localhost.");
|
Console.Write("{0}{1}{2}\n", indent, indent, "host, The host to connect to TDengine. Default is localhost.");
|
||||||
Console.Write("{0}{1}", indent, "-p");
|
Console.Write("{0}{1}", indent, "-p");
|
||||||
|
@ -77,7 +80,7 @@ namespace TDengineDriver
|
||||||
Console.Write("{0}{1}", indent, "-d");
|
Console.Write("{0}{1}", indent, "-d");
|
||||||
Console.Write("{0}{1}{2}\n", indent, indent, "database, Destination database. Default is 'test'.");
|
Console.Write("{0}{1}{2}\n", indent, indent, "database, Destination database. Default is 'test'.");
|
||||||
Console.Write("{0}{1}", indent, "-a");
|
Console.Write("{0}{1}", indent, "-a");
|
||||||
Console.Write("{0}{1}{2}\n", indent, indent, "replica, Set the replica parameters of the database, Default 1, min: 1, max: 3.");
|
Console.Write("{0}{1}{2}\n", indent, indent, "replica, Set the replica parameters of the database, Default 1, min: 1, max: 5.");
|
||||||
Console.Write("{0}{1}", indent, "-m");
|
Console.Write("{0}{1}", indent, "-m");
|
||||||
Console.Write("{0}{1}{2}\n", indent, indent, "table_prefix, Table prefix name. Default is 't'.");
|
Console.Write("{0}{1}{2}\n", indent, indent, "table_prefix, Table prefix name. Default is 't'.");
|
||||||
Console.Write("{0}{1}", indent, "-s");
|
Console.Write("{0}{1}", indent, "-s");
|
||||||
|
@ -99,9 +102,9 @@ namespace TDengineDriver
|
||||||
Console.Write("{0}{1}", indent, "-r");
|
Console.Write("{0}{1}", indent, "-r");
|
||||||
Console.Write("{0}{1}{2}\n", indent, indent, "num_of_records_per_req, The number of records per request. Default is 1000.");
|
Console.Write("{0}{1}{2}\n", indent, indent, "num_of_records_per_req, The number of records per request. Default is 1000.");
|
||||||
Console.Write("{0}{1}", indent, "-t");
|
Console.Write("{0}{1}", indent, "-t");
|
||||||
Console.Write("{0}{1}{2}\n", indent, indent, "num_of_tables, The number of tables. Default is 10000.");
|
Console.Write("{0}{1}{2}\n", indent, indent, "num_of_tables, The number of tables. Default is 1.");
|
||||||
Console.Write("{0}{1}", indent, "-n");
|
Console.Write("{0}{1}", indent, "-n");
|
||||||
Console.Write("{0}{1}{2}\n", indent, indent, "num_of_records_per_table, The number of records per table. Default is 10000.");
|
Console.Write("{0}{1}{2}\n", indent, indent, "num_of_records_per_table, The number of records per table. Default is 1.");
|
||||||
Console.Write("{0}{1}", indent, "-c");
|
Console.Write("{0}{1}", indent, "-c");
|
||||||
Console.Write("{0}{1}{2}\n", indent, indent, "config_directory, Configuration directory. Default is '/etc/taos/'.");
|
Console.Write("{0}{1}{2}\n", indent, indent, "config_directory, Configuration directory. Default is '/etc/taos/'.");
|
||||||
Console.Write("{0}{1}", indent, "-x");
|
Console.Write("{0}{1}", indent, "-x");
|
||||||
|
@ -133,14 +136,15 @@ namespace TDengineDriver
|
||||||
tablePrefix = this.GetArgumentAsString(argv, "-m", "t");
|
tablePrefix = this.GetArgumentAsString(argv, "-m", "t");
|
||||||
isInsertOnly = this.GetArgumentAsFlag(argv, "-x");
|
isInsertOnly = this.GetArgumentAsFlag(argv, "-x");
|
||||||
queryMode = (int)this.GetArgumentAsLong(argv, "-q", 0, 1, 0);
|
queryMode = (int)this.GetArgumentAsLong(argv, "-q", 0, 1, 0);
|
||||||
numOfTables = this.GetArgumentAsLong(argv, "-t", 1, 1000000000, 10000);
|
numOfTables = this.GetArgumentAsLong(argv, "-t", 1, 1000000000, 1);
|
||||||
batchRows = this.GetArgumentAsLong(argv, "-r", 1, 10000, 1000);
|
batchRows = this.GetArgumentAsLong(argv, "-r", 1, 10000, 1000);
|
||||||
recordsPerTable = this.GetArgumentAsLong(argv, "-n", 1, 100000000000, 10000);
|
recordsPerTable = this.GetArgumentAsLong(argv, "-n", 1, 100000000000, 1);
|
||||||
recordsPerRequest = (int)this.GetArgumentAsLong(argv, "-r", 1, 10000, 1);
|
recordsPerRequest = (int)this.GetArgumentAsLong(argv, "-r", 1, 10000, 1);
|
||||||
colsPerRecord = (int)this.GetArgumentAsLong(argv, "-l", 1, 1024, 3);
|
colsPerRecord = (int)this.GetArgumentAsLong(argv, "-l", 1, 1024, 3);
|
||||||
configDir = this.GetArgumentAsString(argv, "-c", "C:/TDengine/cfg");
|
configDir = this.GetArgumentAsString(argv, "-c", "C:/TDengine/cfg");
|
||||||
useStable = this.GetArgumentAsFlag(argv, "-M");
|
useStable = this.GetArgumentAsFlag(argv, "-M");
|
||||||
|
|
||||||
|
replica = (short)this.GetArgumentAsLong(argv, "-a", 1, 5, 1);
|
||||||
methodOfDelete = (short)this.GetArgumentAsLong(argv, "-D", 0, 3, 0);
|
methodOfDelete = (short)this.GetArgumentAsLong(argv, "-D", 0, 3, 0);
|
||||||
numOfThreads = (short)this.GetArgumentAsLong(argv, "-T", 1, 10000, 1);
|
numOfThreads = (short)this.GetArgumentAsLong(argv, "-T", 1, 10000, 1);
|
||||||
order = this.GetArgumentAsFlag(argv, "-O");
|
order = this.GetArgumentAsFlag(argv, "-O");
|
||||||
|
@ -153,13 +157,14 @@ namespace TDengineDriver
|
||||||
Console.Write("# Server IP: {0}\n", host);
|
Console.Write("# Server IP: {0}\n", host);
|
||||||
Console.Write("# User: {0}\n", user);
|
Console.Write("# User: {0}\n", user);
|
||||||
Console.Write("# Password: {0}\n", password);
|
Console.Write("# Password: {0}\n", password);
|
||||||
Console.Write("# Use super table: {0}\n", useStable);
|
|
||||||
Console.Write("# Number of Columns per record: {0}\n", colsPerRecord);
|
Console.Write("# Number of Columns per record: {0}\n", colsPerRecord);
|
||||||
Console.Write("# Number of Threads: {0}\n", numOfThreads);
|
Console.Write("# Number of Threads: {0}\n", numOfThreads);
|
||||||
Console.Write("# Number of Tables: {0}\n", numOfTables);
|
Console.Write("# Number of Tables: {0}\n", numOfTables);
|
||||||
Console.Write("# Number of Data per Table: {0}\n", recordsPerTable);
|
Console.Write("# Number of Data per Table: {0}\n", recordsPerTable);
|
||||||
Console.Write("# Records/Request: {0}\n", recordsPerRequest);
|
Console.Write("# Records/Request: {0}\n", recordsPerRequest);
|
||||||
Console.Write("# Database name: {0}\n", dbName);
|
Console.Write("# Database name: {0}\n", dbName);
|
||||||
|
Console.Write("# Replica: {0}\n", replica);
|
||||||
|
Console.Write("# Use STable: {0}\n", useStable);
|
||||||
Console.Write("# Table prefix: {0}\n", tablePrefix);
|
Console.Write("# Table prefix: {0}\n", tablePrefix);
|
||||||
Console.Write("# Data order: {0}\n", order);
|
Console.Write("# Data order: {0}\n", order);
|
||||||
Console.Write("# Data out of order rate: {0}\n", rateOfOutorder);
|
Console.Write("# Data out of order rate: {0}\n", rateOfOutorder);
|
||||||
|
@ -280,7 +285,7 @@ namespace TDengineDriver
|
||||||
public void ConnectTDengine()
|
public void ConnectTDengine()
|
||||||
{
|
{
|
||||||
string db = "";
|
string db = "";
|
||||||
DebugPrintFormat("host:{0} user:{1}, pass:{2}; db:{3}, port:{4}",
|
DebugPrintFormat("host:{0} user:{1}, pass:{2}; db:{3}, port:{4}\n",
|
||||||
this.host, this.user, this.password, db, this.port);
|
this.host, this.user, this.password, db, this.port);
|
||||||
this.conn = TDengine.Connect(this.host, this.user, this.password, db, this.port);
|
this.conn = TDengine.Connect(this.host, this.user, this.password, db, this.port);
|
||||||
if (this.conn == IntPtr.Zero)
|
if (this.conn == IntPtr.Zero)
|
||||||
|
@ -320,6 +325,7 @@ namespace TDengineDriver
|
||||||
createTableThread.verbose = verbose;
|
createTableThread.verbose = verbose;
|
||||||
createTableThread.dbName = this.dbName;
|
createTableThread.dbName = this.dbName;
|
||||||
createTableThread.tablePrefix = this.tablePrefix;
|
createTableThread.tablePrefix = this.tablePrefix;
|
||||||
|
createTableThread.useStable = useStable;
|
||||||
if (useStable)
|
if (useStable)
|
||||||
{
|
{
|
||||||
createTableThread.stableName = stableName;
|
createTableThread.stableName = stableName;
|
||||||
|
@ -363,7 +369,7 @@ namespace TDengineDriver
|
||||||
public void CreateDb()
|
public void CreateDb()
|
||||||
{
|
{
|
||||||
StringBuilder sql = new StringBuilder();
|
StringBuilder sql = new StringBuilder();
|
||||||
sql.Append("CREATE DATABASE IF NOT EXISTS ").Append(this.dbName);
|
sql.Append("CREATE DATABASE IF NOT EXISTS ").Append(this.dbName).Append(" replica ").Append(this.replica);
|
||||||
IntPtr res = TDengine.Query(this.conn, sql.ToString());
|
IntPtr res = TDengine.Query(this.conn, sql.ToString());
|
||||||
if (res != IntPtr.Zero)
|
if (res != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
|
@ -429,7 +435,7 @@ namespace TDengineDriver
|
||||||
insertThread.tablePrefix = this.tablePrefix;
|
insertThread.tablePrefix = this.tablePrefix;
|
||||||
if (useStable)
|
if (useStable)
|
||||||
{
|
{
|
||||||
insertThread.stableName = stableName;
|
// insertThread.stableName = stableName;
|
||||||
}
|
}
|
||||||
insertThread.conn = conn;
|
insertThread.conn = conn;
|
||||||
|
|
||||||
|
@ -584,15 +590,20 @@ namespace TDengineDriver
|
||||||
|
|
||||||
tester.InitTDengine();
|
tester.InitTDengine();
|
||||||
tester.ConnectTDengine();
|
tester.ConnectTDengine();
|
||||||
tester.dropDatabase();
|
|
||||||
tester.CreateDb();
|
|
||||||
|
|
||||||
if (tester.useStable == true)
|
if (tester.isInsertOnly == false)
|
||||||
{
|
{
|
||||||
tester.CreateStable();
|
tester.dropDatabase();
|
||||||
}
|
tester.CreateDb();
|
||||||
|
|
||||||
tester.CreateTablesByThreads();
|
|
||||||
|
if (tester.useStable == true)
|
||||||
|
{
|
||||||
|
tester.CreateStable();
|
||||||
|
}
|
||||||
|
|
||||||
|
tester.CreateTablesByThreads();
|
||||||
|
}
|
||||||
|
|
||||||
Stopwatch watch = Stopwatch.StartNew();
|
Stopwatch watch = Stopwatch.StartNew();
|
||||||
tester.InsertByThreads();
|
tester.InsertByThreads();
|
||||||
|
@ -619,7 +630,7 @@ namespace TDengineDriver
|
||||||
public string dbName { set; get; }
|
public string dbName { set; get; }
|
||||||
public IntPtr conn { set; get; }
|
public IntPtr conn { set; get; }
|
||||||
public string tablePrefix { set; get; }
|
public string tablePrefix { set; get; }
|
||||||
public string stableName { set; get; }
|
// public string stableName { set; get; }
|
||||||
public long recordsPerTable { set; get; }
|
public long recordsPerTable { set; get; }
|
||||||
public long batchRows { set; get; }
|
public long batchRows { set; get; }
|
||||||
public long numOfTables { set; get; }
|
public long numOfTables { set; get; }
|
||||||
|
@ -643,9 +654,18 @@ namespace TDengineDriver
|
||||||
|
|
||||||
public void ThreadMain()
|
public void ThreadMain()
|
||||||
{
|
{
|
||||||
DebugPrintFormat("InsertDataThread {0} from {1} to {2}", id, start, end);
|
DebugPrintFormat("InsertDataThread {0} from {1} to {2}\n", id, start, end);
|
||||||
StringBuilder sql = new StringBuilder();
|
StringBuilder sql = new StringBuilder();
|
||||||
long beginTimestamp = 1551369600000L;
|
|
||||||
|
DateTime now = DateTime.Now;
|
||||||
|
int h = now.Hour;
|
||||||
|
int m = now.Minute;
|
||||||
|
int s = now.Second;
|
||||||
|
|
||||||
|
long baseTimestamp = 1609430400000; // 2021/01/01 0:0:0
|
||||||
|
DebugPrintFormat("beginTime is {0} + {1}h:{2}m:{3}s\n", baseTimestamp, h, m, s);
|
||||||
|
long beginTimestamp = baseTimestamp + ((h*60 + m) * 60 + s) * 1000;
|
||||||
|
|
||||||
long rowsInserted = 0;
|
long rowsInserted = 0;
|
||||||
|
|
||||||
// System.DateTime startTime = new System.DateTime();
|
// System.DateTime startTime = new System.DateTime();
|
||||||
|
@ -660,7 +680,11 @@ namespace TDengineDriver
|
||||||
sql.Append("INSERT INTO ").
|
sql.Append("INSERT INTO ").
|
||||||
Append(this.dbName).Append(".").Append(this.tablePrefix).Append(table).
|
Append(this.dbName).Append(".").Append(this.tablePrefix).Append(table).
|
||||||
Append(" VALUES");
|
Append(" VALUES");
|
||||||
for (int batch = 0; batch < this.batchRows; ++batch)
|
if (recordsPerTable < batchRows)
|
||||||
|
{
|
||||||
|
batchRows = recordsPerTable;
|
||||||
|
}
|
||||||
|
for (int batch = 0; batch < batchRows; ++batch)
|
||||||
{
|
{
|
||||||
sql.Append("(")
|
sql.Append("(")
|
||||||
.Append(beginTimestamp + i + batch)
|
.Append(beginTimestamp + i + batch)
|
||||||
|
@ -701,6 +725,7 @@ namespace TDengineDriver
|
||||||
public string tablePrefix { set; get; }
|
public string tablePrefix { set; get; }
|
||||||
public string stableName { set; get; }
|
public string stableName { set; get; }
|
||||||
public bool verbose { set; get; }
|
public bool verbose { set; get; }
|
||||||
|
public bool useStable { set; get; }
|
||||||
|
|
||||||
private void DebugPrintFormat(string format, params object[] parameters)
|
private void DebugPrintFormat(string format, params object[] parameters)
|
||||||
{
|
{
|
||||||
|
@ -720,7 +745,7 @@ namespace TDengineDriver
|
||||||
|
|
||||||
public void ThreadMain()
|
public void ThreadMain()
|
||||||
{
|
{
|
||||||
DebugPrintFormat("CreateTable {0} from {1} to {2}", id, start, end);
|
DebugPrintFormat("CreateTable {0} from {1} to {2}\n", id, start, end);
|
||||||
|
|
||||||
StringBuilder sql = new StringBuilder();
|
StringBuilder sql = new StringBuilder();
|
||||||
|
|
||||||
|
@ -728,9 +753,16 @@ namespace TDengineDriver
|
||||||
{
|
{
|
||||||
sql.Clear();
|
sql.Clear();
|
||||||
sql = sql.Append("CREATE TABLE IF NOT EXISTS ").
|
sql = sql.Append("CREATE TABLE IF NOT EXISTS ").
|
||||||
Append(this.dbName).Append(".").Append(this.tablePrefix).Append(tableId).
|
Append(this.dbName).Append(".").Append(this.tablePrefix).Append(tableId);
|
||||||
Append(" USING ").Append(this.dbName).Append(".").Append(this.stableName).
|
if (useStable == true)
|
||||||
Append(" TAGS(").Append(tableId).Append(")");
|
{
|
||||||
|
sql = sql.Append(" USING ").Append(this.dbName).Append(".").Append(this.stableName).
|
||||||
|
Append(" TAGS(").Append(tableId).Append(")");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sql = sql.Append("(ts timestamp, v1 bool, v2 tinyint, v3 smallint, v4 int, v5 bigint, v6 float, v7 double, v8 binary(10), v9 nchar(10))");
|
||||||
|
}
|
||||||
IntPtr res = TDengine.Query(this.conn, sql.ToString());
|
IntPtr res = TDengine.Query(this.conn, sql.ToString());
|
||||||
if (res != IntPtr.Zero)
|
if (res != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,17 +5,12 @@
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<groupId>com.taosdata.jdbc</groupId>
|
<groupId>com.taosdata.jdbc</groupId>
|
||||||
<artifactId>jdbcChecker</artifactId>
|
<artifactId>JDBCDemo</artifactId>
|
||||||
<version>SNAPSHOT</version>
|
<version>SNAPSHOT</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-assembly-plugin</artifactId>
|
|
||||||
<version>3.0.0</version>
|
|
||||||
</plugin>
|
|
||||||
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-assembly-plugin</artifactId>
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
@ -23,7 +18,7 @@
|
||||||
<configuration>
|
<configuration>
|
||||||
<archive>
|
<archive>
|
||||||
<manifest>
|
<manifest>
|
||||||
<mainClass>com.taosdata.example.JdbcChecker</mainClass>
|
<mainClass>com.taosdata.example.JDBCDemo</mainClass>
|
||||||
</manifest>
|
</manifest>
|
||||||
</archive>
|
</archive>
|
||||||
<descriptorRefs>
|
<descriptorRefs>
|
||||||
|
@ -49,6 +44,7 @@
|
||||||
<target>8</target>
|
<target>8</target>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
|
@ -56,18 +52,8 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.taosdata.jdbc</groupId>
|
<groupId>com.taosdata.jdbc</groupId>
|
||||||
<artifactId>taos-jdbcdriver</artifactId>
|
<artifactId>taos-jdbcdriver</artifactId>
|
||||||
<version>2.0.12</version>
|
<version>2.0.15</version>
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>log4j</groupId>
|
|
||||||
<artifactId>log4j</artifactId>
|
|
||||||
<version>1.2.17</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>junit</groupId>
|
|
||||||
<artifactId>junit</artifactId>
|
|
||||||
<version>4.13.1</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -1,29 +1,37 @@
|
||||||
# How to Run the JDBC Demo Code On A Linux OS
|
# How to Run the JDBC Demo Code On Linux OS
|
||||||
TDengine's JDBC demo project is organized in a Maven way so that users can easily compile, package and run the project. If you don't have Maven on your server, you may install it using
|
TDengine's JDBC demo project is organized in a Maven way so that users can easily compile, package and run the project. If you don't have Maven on your server, you may install it using
|
||||||
<pre>sudo apt-get install maven</pre>
|
```
|
||||||
|
sudo apt-get install maven
|
||||||
|
```
|
||||||
|
|
||||||
## Install TDengine Client
|
## Install TDengine Client
|
||||||
Make sure you have already installed a tdengine client on your current develop environment.
|
Make sure you have already installed a tdengine client on your current develop environment.
|
||||||
Download the tdengine package on our website: ``https://www.taosdata.com/cn/all-downloads/`` and install the client.
|
Download the tdengine package on our website: ``https://www.taosdata.com/cn/all-downloads/`` and install the client.
|
||||||
|
|
||||||
## How to run jdbcChecker
|
## Run jdbcDemo using mvn plugin
|
||||||
<pre>mvn clean compile exec:java -Dexec.mainClass="com.taosdata.example.JdbcChecker" -Dexec.args="-host localhost"</pre>
|
|
||||||
|
|
||||||
## How to run jdbcTaosDemo
|
|
||||||
run command:
|
run command:
|
||||||
<pre> mvn clean compile exec:java -Dexec.mainClass="com.taosdata.example.jdbcTaosdemo.JdbcTaosdemo"</pre>
|
```
|
||||||
|
mvn clean compile exec:java -Dexec.mainClass="com.taosdata.example.JdbcDemo"
|
||||||
|
```
|
||||||
|
|
||||||
and run with your customed args
|
and run with your customed args
|
||||||
<pre>mvn clean compile exec:java -Dexec.mainClass="com.taosdata.example.jdbcTaosdemo.JdbcTaosdemo" -Dexec.args="-host localhost"</pre>
|
```
|
||||||
|
mvn clean compile exec:java -Dexec.mainClass="com.taosdata.example.JdbcDemo" -Dexec.args="-host [HOSTNAME]"
|
||||||
|
```
|
||||||
|
|
||||||
## Compile the Demo Code and Run It
|
## Compile the Demo Code and Run It
|
||||||
|
To compile taos-jdbcdriver, go to the source directory ``TDengine/src/connector/jdbc`` and execute
|
||||||
|
```
|
||||||
|
mvn clean package -Dmaven.test.skip=true
|
||||||
|
```
|
||||||
|
|
||||||
To compile the demo project, go to the source directory ``TDengine/tests/examples/JDBC/JDBCDemo`` and execute
|
To compile the demo project, go to the source directory ``TDengine/tests/examples/JDBC/JDBCDemo`` and execute
|
||||||
|
```
|
||||||
<pre>
|
|
||||||
mvn clean package assembly:single
|
mvn clean package assembly:single
|
||||||
</pre>
|
```
|
||||||
|
|
||||||
The ``pom.xml`` is configured to package all the dependencies into one executable jar file.
|
To run JDBCDemo.jar, go to ``TDengine/tests/examples/JDBC/JDBCDemo`` and execute
|
||||||
|
```
|
||||||
|
java -Djava.ext.dirs=../../../../src/connector/jdbc/target:$JAVA_HOME/jre/lib/ext -jar target/JDBCDemo-SNAPSHOT-jar-with-dependencies.jar -host [HOSTNAME]
|
||||||
|
```
|
||||||
|
|
||||||
To run it, go to ``examples/JDBC/JDBCDemo/target`` and execute
|
|
||||||
<pre>java -jar jdbcChecker-SNAPSHOT-jar-with-dependencies.jar -host localhost</pre>
|
|
||||||
|
|
|
@ -1,56 +1,77 @@
|
||||||
package com.taosdata.example;
|
package com.taosdata.example;
|
||||||
|
|
||||||
import com.taosdata.jdbc.TSDBDriver;
|
|
||||||
|
|
||||||
import java.sql.*;
|
import java.sql.*;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
public class JdbcChecker {
|
public class JDBCDemo {
|
||||||
private static String host;
|
private static String host;
|
||||||
private static String dbName = "test";
|
private static String driverType = "jni";
|
||||||
private static String tbName = "weather";
|
private static final String dbName = "test";
|
||||||
|
private static final String tbName = "weather";
|
||||||
private Connection connection;
|
private Connection connection;
|
||||||
|
|
||||||
/**
|
public static void main(String[] args) {
|
||||||
* get connection
|
for (int i = 0; i < args.length; i++) {
|
||||||
**/
|
if ("-host".equalsIgnoreCase(args[i]) && i < args.length - 1)
|
||||||
|
host = args[++i];
|
||||||
|
if ("-driverType".equalsIgnoreCase(args[i]) && i < args.length - 1) {
|
||||||
|
driverType = args[++i];
|
||||||
|
if (!"jni".equalsIgnoreCase(driverType) && !"restful".equalsIgnoreCase(driverType))
|
||||||
|
printHelp();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (host == null) {
|
||||||
|
printHelp();
|
||||||
|
}
|
||||||
|
|
||||||
|
JDBCDemo demo = new JDBCDemo();
|
||||||
|
demo.init();
|
||||||
|
demo.createDatabase();
|
||||||
|
demo.useDatabase();
|
||||||
|
demo.dropTable();
|
||||||
|
demo.createTable();
|
||||||
|
demo.insert();
|
||||||
|
demo.select();
|
||||||
|
demo.dropTable();
|
||||||
|
demo.close();
|
||||||
|
}
|
||||||
|
|
||||||
private void init() {
|
private void init() {
|
||||||
|
// get connection
|
||||||
try {
|
try {
|
||||||
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
String url = "jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata";
|
||||||
|
if (driverType.equals("restful")) {
|
||||||
|
Class.forName("com.taosdata.jdbc.rs.RestfulDriver");
|
||||||
|
url = "jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata";
|
||||||
|
} else {
|
||||||
|
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
||||||
|
}
|
||||||
Properties properties = new Properties();
|
Properties properties = new Properties();
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_HOST, host);
|
properties.setProperty("host", host);
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
properties.setProperty("charset", "UTF-8");
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
properties.setProperty("locale", "en_US.UTF-8");
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
properties.setProperty("timezone", "UTC-8");
|
||||||
System.out.println("get connection starting...");
|
System.out.println("get connection starting...");
|
||||||
connection = DriverManager.getConnection("jdbc:TAOS://" + host + ":0/", properties);
|
connection = DriverManager.getConnection(url, properties);
|
||||||
if (connection != null)
|
if (connection != null)
|
||||||
System.out.println("[ OK ] Connection established.");
|
System.out.println("[ OK ] Connection established.");
|
||||||
} catch (ClassNotFoundException | SQLException e) {
|
} catch (ClassNotFoundException | SQLException e) {
|
||||||
throw new RuntimeException("connection failed: " + host);
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* create database
|
|
||||||
*/
|
|
||||||
private void createDatabase() {
|
private void createDatabase() {
|
||||||
String sql = "create database if not exists " + dbName;
|
String sql = "create database if not exists " + dbName;
|
||||||
exuete(sql);
|
exuete(sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* use database
|
|
||||||
*/
|
|
||||||
private void useDatabase() {
|
private void useDatabase() {
|
||||||
String sql = "use " + dbName;
|
String sql = "use " + dbName;
|
||||||
exuete(sql);
|
exuete(sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private void select() {
|
||||||
* select
|
|
||||||
*/
|
|
||||||
private void checkSelect() {
|
|
||||||
final String sql = "select * from test.weather";
|
final String sql = "select * from test.weather";
|
||||||
executeQuery(sql);
|
executeQuery(sql);
|
||||||
}
|
}
|
||||||
|
@ -79,40 +100,21 @@ public class JdbcChecker {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String formatString(String str) {
|
private void insert() {
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
int blankCnt = (26 - str.length()) / 2;
|
|
||||||
for (int j = 0; j < blankCnt; j++)
|
|
||||||
sb.append(" ");
|
|
||||||
sb.append(str);
|
|
||||||
for (int j = 0; j < blankCnt; j++)
|
|
||||||
sb.append(" ");
|
|
||||||
sb.append("|");
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* insert
|
|
||||||
*/
|
|
||||||
private void checkInsert() {
|
|
||||||
final String sql = "insert into test.weather (ts, temperature, humidity) values(now, 20.5, 34)";
|
final String sql = "insert into test.weather (ts, temperature, humidity) values(now, 20.5, 34)";
|
||||||
exuete(sql);
|
exuete(sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* create table
|
|
||||||
*/
|
|
||||||
private void createTable() {
|
private void createTable() {
|
||||||
final String sql = "create table if not exists " + dbName + "." + tbName + " (ts timestamp, temperature float, humidity int)";
|
final String sql = "create table if not exists " + dbName + "." + tbName + " (ts timestamp, temperature float, humidity int)";
|
||||||
exuete(sql);
|
exuete(sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final void printSql(String sql, boolean succeed, long cost) {
|
private void printSql(String sql, boolean succeed, long cost) {
|
||||||
System.out.println("[ " + (succeed ? "OK" : "ERROR!") + " ] time cost: " + cost + " ms, execute statement ====> " + sql);
|
System.out.println("[ " + (succeed ? "OK" : "ERROR!") + " ] time cost: " + cost + " ms, execute statement ====> " + sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final void exuete(String sql) {
|
private void exuete(String sql) {
|
||||||
try (Statement statement = connection.createStatement()) {
|
try (Statement statement = connection.createStatement()) {
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
boolean execute = statement.execute(sql);
|
boolean execute = statement.execute(sql);
|
||||||
|
@ -120,7 +122,7 @@ public class JdbcChecker {
|
||||||
printSql(sql, execute, (end - start));
|
printSql(sql, execute, (end - start));
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,39 +137,15 @@ public class JdbcChecker {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkDropTable() {
|
private void dropTable() {
|
||||||
final String sql = "drop table if exists " + dbName + "." + tbName + "";
|
final String sql = "drop table if exists " + dbName + "." + tbName + "";
|
||||||
exuete(sql);
|
exuete(sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
private static void printHelp() {
|
||||||
for (int i = 0; i < args.length; i++) {
|
System.out.println("Usage: java -jar JdbcDemo.jar -host <hostname> -driverType <jni|restful>");
|
||||||
if ("-host".equalsIgnoreCase(args[i]) && i < args.length - 1) {
|
System.exit(0);
|
||||||
host = args[++i];
|
|
||||||
}
|
|
||||||
if ("-db".equalsIgnoreCase(args[i]) && i < args.length - 1) {
|
|
||||||
dbName = args[++i];
|
|
||||||
}
|
|
||||||
if ("-t".equalsIgnoreCase(args[i]) && i < args.length - 1) {
|
|
||||||
tbName = args[++i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (host == null) {
|
|
||||||
System.out.println("Usage: java -jar JDBCConnectorChecker.jar -host <hostname>");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
JdbcChecker checker = new JdbcChecker();
|
|
||||||
checker.init();
|
|
||||||
checker.createDatabase();
|
|
||||||
checker.useDatabase();
|
|
||||||
checker.checkDropTable();
|
|
||||||
checker.createTable();
|
|
||||||
checker.checkInsert();
|
|
||||||
checker.checkSelect();
|
|
||||||
checker.checkDropTable();
|
|
||||||
checker.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,357 +0,0 @@
|
||||||
package com.taosdata.example.jdbcTaosdemo;
|
|
||||||
|
|
||||||
import com.taosdata.example.jdbcTaosdemo.domain.JdbcTaosdemoConfig;
|
|
||||||
import com.taosdata.example.jdbcTaosdemo.task.CreateTableTask;
|
|
||||||
import com.taosdata.example.jdbcTaosdemo.task.InsertTableDatetimeTask;
|
|
||||||
import com.taosdata.example.jdbcTaosdemo.task.InsertTableTask;
|
|
||||||
import com.taosdata.example.jdbcTaosdemo.utils.ConnectionFactory;
|
|
||||||
import com.taosdata.example.jdbcTaosdemo.utils.SqlSpeller;
|
|
||||||
import com.taosdata.example.jdbcTaosdemo.utils.TimeStampUtil;
|
|
||||||
import org.apache.log4j.Logger;
|
|
||||||
|
|
||||||
import java.sql.*;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class JdbcTaosdemo {
|
|
||||||
|
|
||||||
private static Logger logger = Logger.getLogger(JdbcTaosdemo.class);
|
|
||||||
private final JdbcTaosdemoConfig config;
|
|
||||||
private Connection connection;
|
|
||||||
|
|
||||||
public JdbcTaosdemo(JdbcTaosdemoConfig config) {
|
|
||||||
this.config = config;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
|
||||||
// parse config from args
|
|
||||||
JdbcTaosdemoConfig config = new JdbcTaosdemoConfig(args);
|
|
||||||
|
|
||||||
boolean isHelp = Arrays.asList(args).contains("--help");
|
|
||||||
if (isHelp) {
|
|
||||||
JdbcTaosdemoConfig.printHelp();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (config.getHost() == null) {
|
|
||||||
JdbcTaosdemoConfig.printHelp();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
JdbcTaosdemo taosdemo = new JdbcTaosdemo(config);
|
|
||||||
// establish connection
|
|
||||||
taosdemo.init();
|
|
||||||
// drop database
|
|
||||||
taosdemo.dropDatabase();
|
|
||||||
// create database
|
|
||||||
taosdemo.createDatabase();
|
|
||||||
// use db
|
|
||||||
taosdemo.useDatabase();
|
|
||||||
// create super table
|
|
||||||
taosdemo.createSuperTable();
|
|
||||||
// create sub tables
|
|
||||||
taosdemo.createTableMultiThreads();
|
|
||||||
|
|
||||||
boolean infinite = Arrays.asList(args).contains("--infinite");
|
|
||||||
if (infinite) {
|
|
||||||
logger.info("!!! Infinite Insert Mode Started. !!!");
|
|
||||||
taosdemo.insertInfinite();
|
|
||||||
} else {
|
|
||||||
// insert into table
|
|
||||||
taosdemo.insertMultiThreads();
|
|
||||||
// select from sub table
|
|
||||||
taosdemo.selectFromTableLimit();
|
|
||||||
taosdemo.selectCountFromTable();
|
|
||||||
taosdemo.selectAvgMinMaxFromTable();
|
|
||||||
// select last from
|
|
||||||
taosdemo.selectLastFromTable();
|
|
||||||
// select from super table
|
|
||||||
taosdemo.selectFromSuperTableLimit();
|
|
||||||
taosdemo.selectCountFromSuperTable();
|
|
||||||
taosdemo.selectAvgMinMaxFromSuperTable();
|
|
||||||
//select avg ,max from stb where tag
|
|
||||||
taosdemo.selectAvgMinMaxFromSuperTableWhereTag();
|
|
||||||
//select last from stb where location = ''
|
|
||||||
taosdemo.selectLastFromSuperTableWhere();
|
|
||||||
// select group by
|
|
||||||
taosdemo.selectGroupBy();
|
|
||||||
// select like
|
|
||||||
taosdemo.selectLike();
|
|
||||||
// select where ts >= ts<=
|
|
||||||
taosdemo.selectLastOneHour();
|
|
||||||
taosdemo.selectLastOneDay();
|
|
||||||
taosdemo.selectLastOneWeek();
|
|
||||||
taosdemo.selectLastOneMonth();
|
|
||||||
taosdemo.selectLastOneYear();
|
|
||||||
|
|
||||||
// drop super table
|
|
||||||
if (config.isDeleteTable())
|
|
||||||
taosdemo.dropSuperTable();
|
|
||||||
taosdemo.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* establish the connection
|
|
||||||
*/
|
|
||||||
private void init() {
|
|
||||||
try {
|
|
||||||
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
|
||||||
connection = ConnectionFactory.build(config);
|
|
||||||
if (connection != null)
|
|
||||||
logger.info("[ OK ] Connection established.");
|
|
||||||
} catch (ClassNotFoundException | SQLException e) {
|
|
||||||
logger.error(e.getMessage());
|
|
||||||
throw new RuntimeException("connection failed: " + config.getHost());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* create database
|
|
||||||
*/
|
|
||||||
private void createDatabase() {
|
|
||||||
String sql = SqlSpeller.createDatabaseSQL(config.getDbName(), config.getKeep(), config.getDays());
|
|
||||||
execute(sql);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* drop database
|
|
||||||
*/
|
|
||||||
private void dropDatabase() {
|
|
||||||
String sql = SqlSpeller.dropDatabaseSQL(config.getDbName());
|
|
||||||
execute(sql);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* use database
|
|
||||||
*/
|
|
||||||
private void useDatabase() {
|
|
||||||
String sql = SqlSpeller.useDatabaseSQL(config.getDbName());
|
|
||||||
execute(sql);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* create super table
|
|
||||||
*/
|
|
||||||
private void createSuperTable() {
|
|
||||||
String sql = SqlSpeller.createSuperTableSQL(config.getStbName());
|
|
||||||
execute(sql);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* create table use super table with multi threads
|
|
||||||
*/
|
|
||||||
private void createTableMultiThreads() {
|
|
||||||
try {
|
|
||||||
final int tableSize = config.getNumberOfTable() / config.getNumberOfThreads();
|
|
||||||
List<Thread> threads = new ArrayList<>();
|
|
||||||
for (int i = 0; i < config.getNumberOfThreads(); i++) {
|
|
||||||
Thread thread = new Thread(new CreateTableTask(config, i * tableSize, tableSize), "Thread-" + i);
|
|
||||||
threads.add(thread);
|
|
||||||
thread.start();
|
|
||||||
}
|
|
||||||
for (Thread thread : threads) {
|
|
||||||
thread.join();
|
|
||||||
}
|
|
||||||
logger.info("<<< Multi Threads create table finished.");
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
logger.error(e.getMessage());
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* insert data infinitely
|
|
||||||
*/
|
|
||||||
private void insertInfinite() {
|
|
||||||
try {
|
|
||||||
final long startDatetime = TimeStampUtil.datetimeToLong("2005-01-01 00:00:00.000");
|
|
||||||
final long finishDatetime = TimeStampUtil.datetimeToLong("2030-01-01 00:00:00.000");
|
|
||||||
|
|
||||||
final int tableSize = config.getNumberOfTable() / config.getNumberOfThreads();
|
|
||||||
List<Thread> threads = new ArrayList<>();
|
|
||||||
for (int i = 0; i < config.getNumberOfThreads(); i++) {
|
|
||||||
Thread thread = new Thread(new InsertTableDatetimeTask(config, i * tableSize, tableSize, startDatetime, finishDatetime), "Thread-" + i);
|
|
||||||
threads.add(thread);
|
|
||||||
thread.start();
|
|
||||||
}
|
|
||||||
for (Thread thread : threads) {
|
|
||||||
thread.join();
|
|
||||||
}
|
|
||||||
logger.info("<<< Multi Threads insert table finished.");
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
logger.error(e.getMessage());
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void insertMultiThreads() {
|
|
||||||
try {
|
|
||||||
final int tableSize = config.getNumberOfTable() / config.getNumberOfThreads();
|
|
||||||
final int numberOfRecordsPerTable = config.getNumberOfRecordsPerTable();
|
|
||||||
List<Thread> threads = new ArrayList<>();
|
|
||||||
for (int i = 0; i < config.getNumberOfThreads(); i++) {
|
|
||||||
Thread thread = new Thread(new InsertTableTask(config, i * tableSize, tableSize, numberOfRecordsPerTable), "Thread-" + i);
|
|
||||||
threads.add(thread);
|
|
||||||
thread.start();
|
|
||||||
}
|
|
||||||
for (Thread thread : threads) {
|
|
||||||
thread.join();
|
|
||||||
}
|
|
||||||
logger.info("<<< Multi Threads insert table finished.");
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
logger.error(e.getMessage());
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void selectFromTableLimit() {
|
|
||||||
String sql = SqlSpeller.selectFromTableLimitSQL(config.getDbName(), config.getTbPrefix(), 1, 10, 0);
|
|
||||||
executeQuery(sql);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void selectCountFromTable() {
|
|
||||||
String sql = SqlSpeller.selectCountFromTableSQL(config.getDbName(), config.getTbPrefix(), 1);
|
|
||||||
executeQuery(sql);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void selectAvgMinMaxFromTable() {
|
|
||||||
String sql = SqlSpeller.selectAvgMinMaxFromTableSQL("current", config.getDbName(), config.getTbPrefix(), 1);
|
|
||||||
executeQuery(sql);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void selectLastFromTable() {
|
|
||||||
String sql = SqlSpeller.selectLastFromTableSQL(config.getDbName(), config.getTbPrefix(), 1);
|
|
||||||
executeQuery(sql);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void selectFromSuperTableLimit() {
|
|
||||||
String sql = SqlSpeller.selectFromSuperTableLimitSQL(config.getDbName(), config.getStbName(), 10, 0);
|
|
||||||
executeQuery(sql);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void selectCountFromSuperTable() {
|
|
||||||
String sql = SqlSpeller.selectCountFromSuperTableSQL(config.getDbName(), config.getStbName());
|
|
||||||
executeQuery(sql);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void selectAvgMinMaxFromSuperTable() {
|
|
||||||
String sql = SqlSpeller.selectAvgMinMaxFromSuperTableSQL("current", config.getDbName(), config.getStbName());
|
|
||||||
executeQuery(sql);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void selectAvgMinMaxFromSuperTableWhereTag() {
|
|
||||||
String sql = SqlSpeller.selectAvgMinMaxFromSuperTableWhere("current", config.getDbName(), config.getStbName());
|
|
||||||
executeQuery(sql);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void selectLastFromSuperTableWhere() {
|
|
||||||
String sql = SqlSpeller.selectLastFromSuperTableWhere("current", config.getDbName(), config.getStbName());
|
|
||||||
executeQuery(sql);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void selectGroupBy() {
|
|
||||||
String sql = SqlSpeller.selectGroupBy("current", config.getDbName(), config.getStbName());
|
|
||||||
executeQuery(sql);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void selectLike() {
|
|
||||||
String sql = SqlSpeller.selectLike(config.getDbName(), config.getStbName());
|
|
||||||
executeQuery(sql);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void selectLastOneHour() {
|
|
||||||
String sql = SqlSpeller.selectLastOneHour(config.getDbName(), config.getStbName());
|
|
||||||
executeQuery(sql);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void selectLastOneDay() {
|
|
||||||
String sql = SqlSpeller.selectLastOneDay(config.getDbName(), config.getStbName());
|
|
||||||
executeQuery(sql);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void selectLastOneWeek() {
|
|
||||||
String sql = SqlSpeller.selectLastOneWeek(config.getDbName(), config.getStbName());
|
|
||||||
executeQuery(sql);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void selectLastOneMonth() {
|
|
||||||
String sql = SqlSpeller.selectLastOneMonth(config.getDbName(), config.getStbName());
|
|
||||||
executeQuery(sql);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void selectLastOneYear() {
|
|
||||||
String sql = SqlSpeller.selectLastOneYear(config.getDbName(), config.getStbName());
|
|
||||||
executeQuery(sql);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void close() {
|
|
||||||
try {
|
|
||||||
if (connection != null) {
|
|
||||||
this.connection.close();
|
|
||||||
logger.info("connection closed.");
|
|
||||||
}
|
|
||||||
} catch (SQLException e) {
|
|
||||||
logger.error(e.getMessage());
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* drop super table
|
|
||||||
*/
|
|
||||||
private void dropSuperTable() {
|
|
||||||
String sql = SqlSpeller.dropSuperTableSQL(config.getDbName(), config.getStbName());
|
|
||||||
execute(sql);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* execute sql, use this method when sql is create, alter, drop..
|
|
||||||
*/
|
|
||||||
private void execute(String sql) {
|
|
||||||
try (Statement statement = connection.createStatement()) {
|
|
||||||
long start = System.currentTimeMillis();
|
|
||||||
boolean execute = statement.execute(sql);
|
|
||||||
long end = System.currentTimeMillis();
|
|
||||||
printSql(sql, execute, (end - start));
|
|
||||||
} catch (SQLException e) {
|
|
||||||
logger.error("ERROR execute SQL ===> " + sql);
|
|
||||||
logger.error(e.getMessage());
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void printSql(String sql, boolean succeed, long cost) {
|
|
||||||
System.out.println("[ " + (succeed ? "OK" : "ERROR!") + " ] time cost: " + cost + " ms, execute statement ====> " + sql);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void executeQuery(String sql) {
|
|
||||||
try (Statement statement = connection.createStatement()) {
|
|
||||||
long start = System.currentTimeMillis();
|
|
||||||
ResultSet resultSet = statement.executeQuery(sql);
|
|
||||||
long end = System.currentTimeMillis();
|
|
||||||
printSql(sql, true, (end - start));
|
|
||||||
printResult(resultSet);
|
|
||||||
} catch (SQLException e) {
|
|
||||||
logger.error("ERROR execute SQL ===> " + sql);
|
|
||||||
logger.error(e.getMessage());
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void printResult(ResultSet resultSet) throws SQLException {
|
|
||||||
ResultSetMetaData metaData = resultSet.getMetaData();
|
|
||||||
while (resultSet.next()) {
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
for (int i = 1; i <= metaData.getColumnCount(); i++) {
|
|
||||||
String columnLabel = metaData.getColumnLabel(i);
|
|
||||||
String value = resultSet.getString(i);
|
|
||||||
sb.append(columnLabel + ": " + value + "\t");
|
|
||||||
}
|
|
||||||
System.out.println(sb.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,153 +0,0 @@
|
||||||
package com.taosdata.example.jdbcTaosdemo.domain;
|
|
||||||
|
|
||||||
public final class JdbcTaosdemoConfig {
|
|
||||||
|
|
||||||
//The host to connect to TDengine. Must insert one
|
|
||||||
private String host;
|
|
||||||
//The TCP/IP port number to use for the connection. Default is 6030.
|
|
||||||
private int port = 6030;
|
|
||||||
//The TDengine user name to use when connecting to the server. Default is 'root'
|
|
||||||
private String user = "root";
|
|
||||||
//The password to use when connecting to the server. Default is 'taosdata'
|
|
||||||
private String password = "taosdata";
|
|
||||||
|
|
||||||
//Destination database. Default is 'test'
|
|
||||||
private String dbName = "test";
|
|
||||||
//keep
|
|
||||||
private int keep = 36500;
|
|
||||||
//days
|
|
||||||
private int days = 120;
|
|
||||||
|
|
||||||
//Super table Name. Default is 'meters'
|
|
||||||
private String stbName = "meters";
|
|
||||||
//Table name prefix. Default is 'd'
|
|
||||||
private String tbPrefix = "d";
|
|
||||||
//The number of tables. Default is 10.
|
|
||||||
private int numberOfTable = 10;
|
|
||||||
//The number of records per table. Default is 2
|
|
||||||
private int numberOfRecordsPerTable = 2;
|
|
||||||
//The number of records per request. Default is 100
|
|
||||||
private int numberOfRecordsPerRequest = 100;
|
|
||||||
|
|
||||||
//The number of threads. Default is 1.
|
|
||||||
private int numberOfThreads = 1;
|
|
||||||
//Delete data. Default is false
|
|
||||||
private boolean deleteTable = false;
|
|
||||||
|
|
||||||
public static void printHelp() {
|
|
||||||
System.out.println("Usage: java -jar JdbcTaosDemo.jar [OPTION...]");
|
|
||||||
System.out.println("-h host The host to connect to TDengine. you must input one");
|
|
||||||
System.out.println("-p port The TCP/IP port number to use for the connection. Default is 6030");
|
|
||||||
System.out.println("-u user The TDengine user name to use when connecting to the server. Default is 'root'");
|
|
||||||
System.out.println("-P password The password to use when connecting to the server.Default is 'taosdata'");
|
|
||||||
System.out.println("-d database Destination database. Default is 'test'");
|
|
||||||
System.out.println("-m tablePrefix Table prefix name. Default is 'd'");
|
|
||||||
System.out.println("-t num_of_tables The number of tables. Default is 10");
|
|
||||||
System.out.println("-n num_of_records_per_table The number of records per table. Default is 2");
|
|
||||||
System.out.println("-r num_of_records_per_req The number of records per request. Default is 100");
|
|
||||||
System.out.println("-T num_of_threads The number of threads. Default is 1");
|
|
||||||
System.out.println("-D delete table Delete data methods. Default is false");
|
|
||||||
System.out.println("--help Give this help list");
|
|
||||||
// System.out.println("--infinite infinite insert mode");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* parse args from command line
|
|
||||||
*
|
|
||||||
* @param args command line args
|
|
||||||
* @return JdbcTaosdemoConfig
|
|
||||||
*/
|
|
||||||
public JdbcTaosdemoConfig(String[] args) {
|
|
||||||
for (int i = 0; i < args.length; i++) {
|
|
||||||
if ("-h".equals(args[i]) && i < args.length - 1) {
|
|
||||||
host = args[++i];
|
|
||||||
}
|
|
||||||
if ("-p".equals(args[i]) && i < args.length - 1) {
|
|
||||||
port = Integer.parseInt(args[++i]);
|
|
||||||
}
|
|
||||||
if ("-u".equals(args[i]) && i < args.length - 1) {
|
|
||||||
user = args[++i];
|
|
||||||
}
|
|
||||||
if ("-P".equals(args[i]) && i < args.length - 1) {
|
|
||||||
password = args[++i];
|
|
||||||
}
|
|
||||||
if ("-d".equals(args[i]) && i < args.length - 1) {
|
|
||||||
dbName = args[++i];
|
|
||||||
}
|
|
||||||
if ("-m".equals(args[i]) && i < args.length - 1) {
|
|
||||||
tbPrefix = args[++i];
|
|
||||||
}
|
|
||||||
if ("-t".equals(args[i]) && i < args.length - 1) {
|
|
||||||
numberOfTable = Integer.parseInt(args[++i]);
|
|
||||||
}
|
|
||||||
if ("-n".equals(args[i]) && i < args.length - 1) {
|
|
||||||
numberOfRecordsPerTable = Integer.parseInt(args[++i]);
|
|
||||||
}
|
|
||||||
if ("-r".equals(args[i]) && i < args.length - 1) {
|
|
||||||
numberOfRecordsPerRequest = Integer.parseInt(args[++i]);
|
|
||||||
}
|
|
||||||
if ("-T".equals(args[i]) && i < args.length - 1) {
|
|
||||||
numberOfThreads = Integer.parseInt(args[++i]);
|
|
||||||
}
|
|
||||||
if ("-D".equals(args[i]) && i < args.length - 1) {
|
|
||||||
deleteTable = Boolean.parseBoolean(args[++i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getHost() {
|
|
||||||
return host;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getPort() {
|
|
||||||
return port;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUser() {
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPassword() {
|
|
||||||
return password;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDbName() {
|
|
||||||
return dbName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getKeep() {
|
|
||||||
return keep;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getDays() {
|
|
||||||
return days;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getStbName() {
|
|
||||||
return stbName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getTbPrefix() {
|
|
||||||
return tbPrefix;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getNumberOfTable() {
|
|
||||||
return numberOfTable;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getNumberOfRecordsPerTable() {
|
|
||||||
return numberOfRecordsPerTable;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getNumberOfThreads() {
|
|
||||||
return numberOfThreads;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isDeleteTable() {
|
|
||||||
return deleteTable;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getNumberOfRecordsPerRequest() {
|
|
||||||
return numberOfRecordsPerRequest;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,42 +0,0 @@
|
||||||
package com.taosdata.example.jdbcTaosdemo.task;
|
|
||||||
|
|
||||||
import com.taosdata.example.jdbcTaosdemo.domain.JdbcTaosdemoConfig;
|
|
||||||
import com.taosdata.example.jdbcTaosdemo.utils.ConnectionFactory;
|
|
||||||
import com.taosdata.example.jdbcTaosdemo.utils.SqlSpeller;
|
|
||||||
import org.apache.log4j.Logger;
|
|
||||||
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.sql.Statement;
|
|
||||||
|
|
||||||
public class CreateTableTask implements Runnable {
|
|
||||||
|
|
||||||
private static Logger logger = Logger.getLogger(CreateTableTask.class);
|
|
||||||
private final JdbcTaosdemoConfig config;
|
|
||||||
private final int startIndex;
|
|
||||||
private final int tableNumber;
|
|
||||||
|
|
||||||
public CreateTableTask(JdbcTaosdemoConfig config, int startIndex, int tableNumber) {
|
|
||||||
this.config = config;
|
|
||||||
this.startIndex = startIndex;
|
|
||||||
this.tableNumber = tableNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
Connection connection = ConnectionFactory.build(config);
|
|
||||||
for (int i = startIndex; i < startIndex + tableNumber; i++) {
|
|
||||||
Statement statement = connection.createStatement();
|
|
||||||
String sql = SqlSpeller.createTableSQL(i + 1, config.getDbName(), config.getStbName());
|
|
||||||
statement.execute(sql);
|
|
||||||
statement.close();
|
|
||||||
logger.info(">>> " + sql);
|
|
||||||
}
|
|
||||||
connection.close();
|
|
||||||
} catch (SQLException e) {
|
|
||||||
logger.error(e.getMessage());
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,49 +0,0 @@
|
||||||
package com.taosdata.example.jdbcTaosdemo.task;
|
|
||||||
|
|
||||||
import com.taosdata.example.jdbcTaosdemo.domain.JdbcTaosdemoConfig;
|
|
||||||
import com.taosdata.example.jdbcTaosdemo.utils.ConnectionFactory;
|
|
||||||
import com.taosdata.example.jdbcTaosdemo.utils.SqlSpeller;
|
|
||||||
import org.apache.log4j.Logger;
|
|
||||||
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.sql.Statement;
|
|
||||||
|
|
||||||
public class InsertTableDatetimeTask implements Runnable {
|
|
||||||
private static Logger logger = Logger.getLogger(InsertTableDatetimeTask.class);
|
|
||||||
|
|
||||||
private final JdbcTaosdemoConfig config;
|
|
||||||
private final int startTableIndex;
|
|
||||||
private final int tableNumber;
|
|
||||||
private final long startDatetime;
|
|
||||||
private final long finishedDatetime;
|
|
||||||
|
|
||||||
public InsertTableDatetimeTask(JdbcTaosdemoConfig config, int startTableIndex, int tableNumber, long startDatetime, long finishedDatetime) {
|
|
||||||
this.config = config;
|
|
||||||
this.startTableIndex = startTableIndex;
|
|
||||||
this.tableNumber = tableNumber;
|
|
||||||
this.startDatetime = startDatetime;
|
|
||||||
this.finishedDatetime = finishedDatetime;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
Connection connection = ConnectionFactory.build(config);
|
|
||||||
int valuesCount = config.getNumberOfRecordsPerRequest();
|
|
||||||
for (long ts = startDatetime; ts < finishedDatetime; ts += valuesCount) {
|
|
||||||
for (int i = startTableIndex; i < startTableIndex + tableNumber; i++) {
|
|
||||||
String sql = SqlSpeller.insertBatchSizeRowsSQL(config.getDbName(), config.getTbPrefix(), i + 1, ts, valuesCount);
|
|
||||||
Statement statement = connection.createStatement();
|
|
||||||
statement.execute(sql);
|
|
||||||
statement.close();
|
|
||||||
logger.info(Thread.currentThread().getName() + ">>> " + sql);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
connection.close();
|
|
||||||
} catch (SQLException e) {
|
|
||||||
logger.error(e.getMessage());
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,57 +0,0 @@
|
||||||
package com.taosdata.example.jdbcTaosdemo.task;
|
|
||||||
|
|
||||||
import com.taosdata.example.jdbcTaosdemo.domain.JdbcTaosdemoConfig;
|
|
||||||
import com.taosdata.example.jdbcTaosdemo.utils.ConnectionFactory;
|
|
||||||
import com.taosdata.example.jdbcTaosdemo.utils.SqlSpeller;
|
|
||||||
import org.apache.log4j.Logger;
|
|
||||||
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.sql.Statement;
|
|
||||||
import java.time.Duration;
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.time.temporal.ChronoUnit;
|
|
||||||
|
|
||||||
public class InsertTableTask implements Runnable {
|
|
||||||
private static final Logger logger = Logger.getLogger(InsertTableTask.class);
|
|
||||||
|
|
||||||
private final JdbcTaosdemoConfig config;
|
|
||||||
private final int startTbIndex;
|
|
||||||
private final int tableNumber;
|
|
||||||
private final int recordsNumberPerTable;
|
|
||||||
|
|
||||||
public InsertTableTask(JdbcTaosdemoConfig config, int startTbIndex, int tableNumber, int recordsNumberPerTable) {
|
|
||||||
this.config = config;
|
|
||||||
this.startTbIndex = startTbIndex;
|
|
||||||
this.tableNumber = tableNumber;
|
|
||||||
this.recordsNumberPerTable = recordsNumberPerTable;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
Connection connection = ConnectionFactory.build(config);
|
|
||||||
int keep = config.getKeep();
|
|
||||||
Instant end = Instant.now();
|
|
||||||
Instant start = end.minus(Duration.ofDays(keep - 1));
|
|
||||||
long timeGap = ChronoUnit.MILLIS.between(start, end) / (recordsNumberPerTable - 1);
|
|
||||||
|
|
||||||
// iterate insert
|
|
||||||
for (int j = 0; j < recordsNumberPerTable; j++) {
|
|
||||||
long ts = start.toEpochMilli() + (j * timeGap);
|
|
||||||
// insert data into echo table
|
|
||||||
for (int i = startTbIndex; i < startTbIndex + tableNumber; i++) {
|
|
||||||
String sql = SqlSpeller.insertBatchSizeRowsSQL(config.getDbName(), config.getTbPrefix(), i + 1, ts, config.getNumberOfRecordsPerRequest());
|
|
||||||
logger.info(Thread.currentThread().getName() + ">>> " + sql);
|
|
||||||
Statement statement = connection.createStatement();
|
|
||||||
statement.execute(sql);
|
|
||||||
statement.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
connection.close();
|
|
||||||
} catch (SQLException e) {
|
|
||||||
logger.error(e.getMessage());
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,32 +0,0 @@
|
||||||
package com.taosdata.example.jdbcTaosdemo.utils;
|
|
||||||
|
|
||||||
import com.taosdata.example.jdbcTaosdemo.domain.JdbcTaosdemoConfig;
|
|
||||||
import com.taosdata.jdbc.TSDBDriver;
|
|
||||||
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.DriverManager;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
public class ConnectionFactory {
|
|
||||||
|
|
||||||
public static Connection build(JdbcTaosdemoConfig config) throws SQLException {
|
|
||||||
return build(config.getHost(), config.getPort(), config.getDbName(), config.getUser(), config.getPassword());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Connection build(String host, int port, String dbName) throws SQLException {
|
|
||||||
return build(host, port, dbName, "root", "taosdata");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Connection build(String host, int port, String dbName, String user, String password) throws SQLException {
|
|
||||||
Properties properties = new Properties();
|
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_USER, user);
|
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_PASSWORD, password);
|
|
||||||
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");
|
|
||||||
return DriverManager.getConnection("jdbc:TAOS://" + host + ":" + port + "/" + dbName + "", properties);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,126 +0,0 @@
|
||||||
package com.taosdata.example.jdbcTaosdemo.utils;
|
|
||||||
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
public class SqlSpeller {
|
|
||||||
private static final Random random = new Random(System.currentTimeMillis());
|
|
||||||
private static final String[] locations = {
|
|
||||||
"Beijing", "Shanghai", "Guangzhou", "Shenzhen",
|
|
||||||
"HangZhou", "Tianjin", "Wuhan", "Changsha", "Nanjing", "Xian"
|
|
||||||
};
|
|
||||||
|
|
||||||
public static String createDatabaseSQL(String dbName, int keep, int days) {
|
|
||||||
return "create database if not exists " + dbName + " keep " + keep + " days " + days;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String dropDatabaseSQL(String dbName) {
|
|
||||||
return "drop database if exists " + dbName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String useDatabaseSQL(String dbName) {
|
|
||||||
return "use " + dbName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String createSuperTableSQL(String superTableName) {
|
|
||||||
return "create table if not exists " + superTableName + "(ts timestamp, current float, voltage int, phase float) tags(location binary(64), groupId int)";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String dropSuperTableSQL(String dbName, String superTableName) {
|
|
||||||
return "drop table if exists " + dbName + "." + superTableName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String createTableSQL(int tableIndex, String dbName, String superTableName) {
|
|
||||||
String location = locations[random.nextInt(locations.length)];
|
|
||||||
return "create table d" + tableIndex + " using " + dbName + "." + superTableName + " tags('" + location + "'," + tableIndex + ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String insertOneRowSQL(String dbName, String tbPrefix, int tableIndex, long ts) {
|
|
||||||
float current = 10 + random.nextFloat();
|
|
||||||
int voltage = 200 + random.nextInt(20);
|
|
||||||
float phase = random.nextFloat();
|
|
||||||
String sql = "insert into " + dbName + "." + tbPrefix + "" + tableIndex + " " + "values(" + ts + ", " + current + ", " + voltage + ", " + phase + ")";
|
|
||||||
return sql;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String insertBatchSizeRowsSQL(String dbName, String tbPrefix, int tbIndex, long ts, int valuesCount) {
|
|
||||||
float current = 10 + random.nextFloat();
|
|
||||||
int voltage = 200 + random.nextInt(20);
|
|
||||||
float phase = random.nextFloat();
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
sb.append("insert into " + dbName + "." + tbPrefix + "" + tbIndex + " " + "values");
|
|
||||||
for (int i = 0; i < valuesCount; i++) {
|
|
||||||
sb.append("(" + (ts + i) + ", " + current + ", " + voltage + ", " + phase + ") ");
|
|
||||||
}
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String selectFromTableLimitSQL(String dbName, String tbPrefix, int tbIndex, int limit, int offset) {
|
|
||||||
return "select * from " + dbName + "." + tbPrefix + "" + tbIndex + " limit " + limit + " offset " + offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String selectCountFromTableSQL(String dbName, String tbPrefix, int tbIndex) {
|
|
||||||
return "select count(*) from " + dbName + "." + tbPrefix + "" + tbIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String selectAvgMinMaxFromTableSQL(String field, String dbName, String tbPrefix, int tbIndex) {
|
|
||||||
return "select avg(" + field + "),min(" + field + "),max(" + field + ") from " + dbName + "." + tbPrefix + "" + tbIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String selectFromSuperTableLimitSQL(String dbName, String stbName, int limit, int offset) {
|
|
||||||
return "select * from " + dbName + "." + stbName + " limit " + limit + " offset " + offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String selectCountFromSuperTableSQL(String dbName, String stableName) {
|
|
||||||
return "select count(*) from " + dbName + "." + stableName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String selectAvgMinMaxFromSuperTableSQL(String field, String dbName, String stbName) {
|
|
||||||
return "select avg(" + field + "),min(" + field + "),max(" + field + ") from " + dbName + "." + stbName + "";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String selectLastFromTableSQL(String dbName, String tbPrefix, int tbIndex) {
|
|
||||||
return "select last(*) from " + dbName + "." + tbPrefix + "" + tbIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
//select avg ,max from stb where tag
|
|
||||||
public static String selectAvgMinMaxFromSuperTableWhere(String field, String dbName, String stbName) {
|
|
||||||
return "select avg(" + field + "),min(" + field + "),max(" + field + ") from " + dbName + "." + stbName + " where location = '" + locations[random.nextInt(locations.length)] + "'";
|
|
||||||
}
|
|
||||||
|
|
||||||
//select last from stb where
|
|
||||||
public static String selectLastFromSuperTableWhere(String field, String dbName, String stbName) {
|
|
||||||
return "select last(" + field + ") from " + dbName + "." + stbName + " where location = '" + locations[random.nextInt(locations.length)] + "'";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String selectGroupBy(String field, String dbName, String stbName) {
|
|
||||||
return "select avg(" + field + ") from " + dbName + "." + stbName + " group by location";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String selectLike(String dbName, String stbName) {
|
|
||||||
return "select * from " + dbName + "." + stbName + " where location like 'S%'";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String selectLastOneHour(String dbName, String stbName) {
|
|
||||||
return "select * from " + dbName + "." + stbName + " where ts >= now - 1h";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String selectLastOneDay(String dbName, String stbName) {
|
|
||||||
return "select * from " + dbName + "." + stbName + " where ts >= now - 1d";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String selectLastOneWeek(String dbName, String stbName) {
|
|
||||||
return "select * from " + dbName + "." + stbName + " where ts >= now - 1w";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String selectLastOneMonth(String dbName, String stbName) {
|
|
||||||
return "select * from " + dbName + "." + stbName + " where ts >= now - 1n";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String selectLastOneYear(String dbName, String stbName) {
|
|
||||||
return "select * from " + dbName + "." + stbName + " where ts >= now - 1y";
|
|
||||||
}
|
|
||||||
|
|
||||||
// select group by
|
|
||||||
// select like
|
|
||||||
// select ts >= ts<=
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
package com.taosdata.example.jdbcTaosdemo.utils;
|
|
||||||
|
|
||||||
import java.text.ParseException;
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.time.Duration;
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
public class TimeStampUtil {
|
|
||||||
private static final String datetimeFormat = "yyyy-MM-dd HH:mm:ss.SSS";
|
|
||||||
|
|
||||||
public static long datetimeToLong(String dateTime) {
|
|
||||||
SimpleDateFormat sdf = new SimpleDateFormat(datetimeFormat);
|
|
||||||
try {
|
|
||||||
return sdf.parse(dateTime).getTime();
|
|
||||||
} catch (ParseException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String longToDatetime(long time) {
|
|
||||||
SimpleDateFormat sdf = new SimpleDateFormat(datetimeFormat);
|
|
||||||
return sdf.format(new Date(time));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args) throws ParseException {
|
|
||||||
|
|
||||||
// Instant now = Instant.now();
|
|
||||||
// System.out.println(now);
|
|
||||||
// Instant years20Ago = now.minus(Duration.ofDays(365));
|
|
||||||
// System.out.println(years20Ago);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
### 设置###
|
|
||||||
log4j.rootLogger=debug,stdout,DebugLog,ErrorLog
|
|
||||||
### 输出信息到控制抬 ###
|
|
||||||
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
|
||||||
log4j.appender.stdout.Target=System.out
|
|
||||||
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
|
||||||
log4j.appender.stdout.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
|
|
||||||
### 输出DEBUG 级别以上的日志到=logs/error.log ###
|
|
||||||
log4j.appender.DebugLog=org.apache.log4j.DailyRollingFileAppender
|
|
||||||
log4j.appender.DebugLog.File=logs/debug.log
|
|
||||||
log4j.appender.DebugLog.Append=true
|
|
||||||
log4j.appender.DebugLog.Threshold=DEBUG
|
|
||||||
log4j.appender.DebugLog.layout=org.apache.log4j.PatternLayout
|
|
||||||
log4j.appender.DebugLog.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
|
|
||||||
### 输出ERROR 级别以上的日志到=logs/error.log ###
|
|
||||||
log4j.appender.ErrorLog=org.apache.log4j.DailyRollingFileAppender
|
|
||||||
log4j.appender.ErrorLog.File=logs/error.log
|
|
||||||
log4j.appender.ErrorLog.Append=true
|
|
||||||
log4j.appender.ErrorLog.Threshold=ERROR
|
|
||||||
log4j.appender.ErrorLog.layout=org.apache.log4j.PatternLayout
|
|
||||||
log4j.appender.ErrorLog.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
|
|
|
@ -1,52 +0,0 @@
|
||||||
package com.taosdata.example.jdbcTaosdemo.utils;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import java.text.ParseException;
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.time.Duration;
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.time.format.DateTimeFormatter;
|
|
||||||
import java.time.temporal.ChronoUnit;
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
|
||||||
|
|
||||||
public class TimeStampUtilTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void datetimeToLong() {
|
|
||||||
final String startTime = "2005-01-01 00:00:00.000";
|
|
||||||
long start = TimeStampUtil.datetimeToLong(startTime);
|
|
||||||
assertEquals(1104508800000l, start);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void longToDatetime() {
|
|
||||||
String datetime = TimeStampUtil.longToDatetime(1510000000000L);
|
|
||||||
assertEquals("2017-11-07 04:26:40.000", datetime);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void getStartDateTime() {
|
|
||||||
int keep = 365;
|
|
||||||
|
|
||||||
Instant end = Instant.now();
|
|
||||||
System.out.println(end.toString());
|
|
||||||
System.out.println(end.toEpochMilli());
|
|
||||||
|
|
||||||
Instant start = end.minus(Duration.ofDays(keep));
|
|
||||||
System.out.println(start.toString());
|
|
||||||
System.out.println(start.toEpochMilli());
|
|
||||||
|
|
||||||
int numberOfRecordsPerTable = 10;
|
|
||||||
long timeGap = ChronoUnit.MILLIS.between(start, end) / (numberOfRecordsPerTable - 1);
|
|
||||||
System.out.println(timeGap);
|
|
||||||
|
|
||||||
System.out.println("===========================");
|
|
||||||
for (int i = 0; i < numberOfRecordsPerTable; i++) {
|
|
||||||
long ts = start.toEpochMilli() + (i * timeGap);
|
|
||||||
System.out.println(i + " : " + ts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -82,12 +82,27 @@ public class ConnectionPoolDemo {
|
||||||
|
|
||||||
init(dataSource);
|
init(dataSource);
|
||||||
|
|
||||||
ExecutorService executor = Executors.newFixedThreadPool(threadCount);
|
try {
|
||||||
while (true) {
|
Connection connection = dataSource.getConnection();
|
||||||
executor.execute(new InsertTask(dataSource, dbName, tableSize, batchSize));
|
Statement statement = connection.createStatement();
|
||||||
if (sleep > 0)
|
String sql = "insert into " + dbName + ".t_1 values('2020-01-01 00:00:00.000',12.12,111)";
|
||||||
TimeUnit.MILLISECONDS.sleep(sleep);
|
int affectRows = statement.executeUpdate(sql);
|
||||||
|
System.out.println("affectRows >>> " + affectRows);
|
||||||
|
affectRows = statement.executeUpdate(sql);
|
||||||
|
System.out.println("affectRows >>> " + affectRows);
|
||||||
|
statement.close();
|
||||||
|
connection.close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ExecutorService executor = Executors.newFixedThreadPool(threadCount);
|
||||||
|
// while (true) {
|
||||||
|
// executor.execute(new InsertTask(dataSource, dbName, tableSize, batchSize));
|
||||||
|
// if (sleep > 0)
|
||||||
|
// TimeUnit.MILLISECONDS.sleep(sleep);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void init(DataSource dataSource) {
|
private static void init(DataSource dataSource) {
|
||||||
|
|
|
@ -6,7 +6,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
@MapperScan(basePackages = {"com.taosdata.jdbc.springbootdemo.dao"})
|
@MapperScan(basePackages = {"com.taosdata.jdbc.springbootdemo.dao"})
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
public class SpringbootdemoApplication {
|
public class cd {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
SpringApplication.run(SpringbootdemoApplication.class, args);
|
SpringApplication.run(SpringbootdemoApplication.class, args);
|
||||||
|
|
|
@ -2,41 +2,87 @@
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<parent>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-parent</artifactId>
|
|
||||||
<version>2.4.0</version>
|
|
||||||
<relativePath/> <!-- lookup parent from repository -->
|
|
||||||
</parent>
|
|
||||||
<groupId>com.taosdata</groupId>
|
<groupId>com.taosdata</groupId>
|
||||||
<artifactId>taosdemo</artifactId>
|
<artifactId>taosdemo</artifactId>
|
||||||
<version>2.0</version>
|
<version>2.0</version>
|
||||||
<name>taosdemo</name>
|
<name>taosdemo</name>
|
||||||
|
<packaging>jar</packaging>
|
||||||
<description>Demo project for TDengine</description>
|
<description>Demo project for TDengine</description>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<java.version>1.8</java.version>
|
<spring.version>5.3.2</spring.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<!-- spring -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-context</artifactId>
|
||||||
|
<version>${spring.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-core</artifactId>
|
||||||
|
<version>${spring.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-beans</artifactId>
|
||||||
|
<version>${spring.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-expression</artifactId>
|
||||||
|
<version>${spring.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-aop</artifactId>
|
||||||
|
<version>${spring.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-aspects</artifactId>
|
||||||
|
<version>${spring.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-test</artifactId>
|
||||||
|
<version>${spring.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-jdbc</artifactId>
|
||||||
|
<version>${spring.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- HikariCP -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.zaxxer</groupId>
|
||||||
|
<artifactId>HikariCP</artifactId>
|
||||||
|
<version>3.4.5</version>
|
||||||
|
</dependency>
|
||||||
<!-- taos jdbc -->
|
<!-- taos jdbc -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.taosdata.jdbc</groupId>
|
<groupId>com.taosdata.jdbc</groupId>
|
||||||
<artifactId>taos-jdbcdriver</artifactId>
|
<artifactId>taos-jdbcdriver</artifactId>
|
||||||
<version>2.0.14</version>
|
<version>2.0.15</version>
|
||||||
|
<scope>system</scope>
|
||||||
|
<systemPath>${project.basedir}/src/main/resources/lib/taos-jdbcdriver-2.0.15-dist.jar</systemPath>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- mysql -->
|
<!-- fastjson -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba</groupId>
|
||||||
|
<artifactId>fastjson</artifactId>
|
||||||
|
<version>1.2.75</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- mysql: just for test -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>mysql</groupId>
|
<groupId>mysql</groupId>
|
||||||
<artifactId>mysql-connector-java</artifactId>
|
<artifactId>mysql-connector-java</artifactId>
|
||||||
<version>5.1.47</version>
|
<version>5.1.47</version>
|
||||||
</dependency>
|
<scope>test</scope>
|
||||||
<!-- mybatis-plus -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.baomidou</groupId>
|
|
||||||
<artifactId>mybatis-plus-boot-starter</artifactId>
|
|
||||||
<version>3.1.2</version>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- log4j -->
|
<!-- log4j -->
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -44,46 +90,19 @@
|
||||||
<artifactId>log4j</artifactId>
|
<artifactId>log4j</artifactId>
|
||||||
<version>1.2.17</version>
|
<version>1.2.17</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- junit -->
|
||||||
<!-- springboot -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-jdbc</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-web</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.mybatis.spring.boot</groupId>
|
|
||||||
<artifactId>mybatis-spring-boot-starter</artifactId>
|
|
||||||
<version>2.1.4</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
<version>4.12</version>
|
<version>4.12</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<!-- lombok -->
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-devtools</artifactId>
|
|
||||||
<scope>runtime</scope>
|
|
||||||
<optional>true</optional>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.projectlombok</groupId>
|
<groupId>org.projectlombok</groupId>
|
||||||
<artifactId>lombok</artifactId>
|
<artifactId>lombok</artifactId>
|
||||||
<optional>true</optional>
|
<version>1.18.16</version>
|
||||||
</dependency>
|
<scope>provided</scope>
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-test</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
@ -94,6 +113,7 @@
|
||||||
<includes>
|
<includes>
|
||||||
<include>**/*.properties</include>
|
<include>**/*.properties</include>
|
||||||
<include>**/*.xml</include>
|
<include>**/*.xml</include>
|
||||||
|
<include>**/*.jar</include>
|
||||||
</includes>
|
</includes>
|
||||||
<filtering>true</filtering>
|
<filtering>true</filtering>
|
||||||
</resource>
|
</resource>
|
||||||
|
@ -108,10 +128,41 @@
|
||||||
|
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<source>8</source>
|
||||||
|
<target>8</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<version>3.1.0</version>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<!-- 指定JdbcChecker为mainClass -->
|
||||||
|
<mainClass>com.taosdata.taosdemo.TaosDemoApplication</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
<descriptorRefs>
|
||||||
|
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||||
|
</descriptorRefs>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>make-assembly</id>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>single</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
|
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
需求:
|
||||||
|
1. 可以读lowa的配置文件
|
||||||
|
2. 支持对JNI方式和Restful方式的taos-driver
|
|
@ -0,0 +1,112 @@
|
||||||
|
package com.taosdata.taosdemo;
|
||||||
|
|
||||||
|
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.SubTableService;
|
||||||
|
import com.taosdata.taosdemo.service.SuperTableService;
|
||||||
|
import com.taosdata.taosdemo.service.data.SuperTableMetaGenerator;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class TaosDemoApplication {
|
||||||
|
|
||||||
|
private static Logger logger = Logger.getLogger(TaosDemoApplication.class);
|
||||||
|
|
||||||
|
public static void main(String[] args) throws IOException {
|
||||||
|
// 读配置参数
|
||||||
|
JdbcTaosdemoConfig config = new JdbcTaosdemoConfig(args);
|
||||||
|
boolean isHelp = Arrays.asList(args).contains("--help");
|
||||||
|
if (isHelp || config.host == null || config.host.isEmpty()) {
|
||||||
|
// if (isHelp) {
|
||||||
|
JdbcTaosdemoConfig.printHelp();
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
// 初始化
|
||||||
|
final DataSource dataSource = DataSourceFactory.getInstance(config.host, config.port, config.user, config.password);
|
||||||
|
final DatabaseService databaseService = new DatabaseService(dataSource);
|
||||||
|
final SuperTableService superTableService = new SuperTableService(dataSource);
|
||||||
|
final SubTableService subTableService = new SubTableService(dataSource);
|
||||||
|
// 创建数据库
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
Map<String, String> databaseParam = new HashMap<>();
|
||||||
|
databaseParam.put("database", config.database);
|
||||||
|
databaseParam.put("keep", Integer.toString(config.keep));
|
||||||
|
databaseParam.put("days", Integer.toString(config.days));
|
||||||
|
databaseParam.put("replica", Integer.toString(config.replica));
|
||||||
|
//TODO: other database parameters
|
||||||
|
databaseService.createDatabase(databaseParam);
|
||||||
|
databaseService.useDatabase(config.database);
|
||||||
|
long end = System.currentTimeMillis();
|
||||||
|
logger.info(">>> create database time cost : " + (end - start) + " ms.");
|
||||||
|
/**********************************************************************************/
|
||||||
|
// 构造超级表的meta
|
||||||
|
SuperTableMeta superTableMeta;
|
||||||
|
// create super table
|
||||||
|
if (config.superTableSQL != null) {
|
||||||
|
// use a sql to create super table
|
||||||
|
superTableMeta = SuperTableMetaGenerator.generate(config.superTableSQL);
|
||||||
|
if (config.database != null && !config.database.isEmpty())
|
||||||
|
superTableMeta.setDatabase(config.database);
|
||||||
|
} else if (config.numOfFields == 0) {
|
||||||
|
String sql = "create table " + config.database + "." + config.superTable + " (ts timestamp, temperature float, humidity int) tags(location nchar(64), groupId int)";
|
||||||
|
superTableMeta = SuperTableMetaGenerator.generate(sql);
|
||||||
|
} else {
|
||||||
|
// create super table with specified field size and tag size
|
||||||
|
superTableMeta = SuperTableMetaGenerator.generate(config.database, config.superTable, config.numOfFields, config.prefixOfFields, config.numOfTags, config.prefixOfTags);
|
||||||
|
}
|
||||||
|
/**********************************************************************************/
|
||||||
|
// 建表
|
||||||
|
start = System.currentTimeMillis();
|
||||||
|
if (config.doCreateTable) {
|
||||||
|
superTableService.drop(superTableMeta.getDatabase(), superTableMeta.getName());
|
||||||
|
superTableService.create(superTableMeta);
|
||||||
|
if (!config.autoCreateTable) {
|
||||||
|
// 批量建子表
|
||||||
|
subTableService.createSubTable(superTableMeta, config.numOfTables, config.prefixOfTable, config.numOfThreadsForCreate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end = System.currentTimeMillis();
|
||||||
|
logger.error(">>> create table time cost : " + (end - start) + " ms.");
|
||||||
|
/**********************************************************************************/
|
||||||
|
// 插入
|
||||||
|
long tableSize = config.numOfTables;
|
||||||
|
int threadSize = config.numOfThreadsForInsert;
|
||||||
|
long startTime = getProperStartTime(config.startTime, config.keep);
|
||||||
|
|
||||||
|
if (tableSize < threadSize)
|
||||||
|
threadSize = (int) tableSize;
|
||||||
|
long gap = (long) Math.ceil((0.0d + tableSize) / threadSize);
|
||||||
|
|
||||||
|
start = System.currentTimeMillis();
|
||||||
|
// multi threads to insert
|
||||||
|
int affectedRows = subTableService.insertMultiThreads(superTableMeta, threadSize, tableSize, startTime, gap, config);
|
||||||
|
end = System.currentTimeMillis();
|
||||||
|
logger.error("insert " + affectedRows + " rows, time cost: " + (end - start) + " ms");
|
||||||
|
/**********************************************************************************/
|
||||||
|
// 删除表
|
||||||
|
if (config.dropTable) {
|
||||||
|
superTableService.drop(config.database, config.superTable);
|
||||||
|
}
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static long getProperStartTime(long startTime, int keep) {
|
||||||
|
Instant now = Instant.now();
|
||||||
|
long earliest = now.minus(Duration.ofDays(keep - 1)).toEpochMilli();
|
||||||
|
if (startTime == 0 || startTime < earliest) {
|
||||||
|
startTime = earliest;
|
||||||
|
}
|
||||||
|
return startTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -1,15 +0,0 @@
|
||||||
package com.taosdata.taosdemo;
|
|
||||||
|
|
||||||
import org.mybatis.spring.annotation.MapperScan;
|
|
||||||
import org.springframework.boot.SpringApplication;
|
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
|
||||||
|
|
||||||
@MapperScan(basePackages = {"com.taosdata.taosdemo.mapper"})
|
|
||||||
@SpringBootApplication
|
|
||||||
public class TaosdemoApplication {
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
|
||||||
SpringApplication.run(TaosdemoApplication.class, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
package com.taosdata.taosdemo.components;
|
||||||
|
|
||||||
|
import com.zaxxer.hikari.HikariConfig;
|
||||||
|
import com.zaxxer.hikari.HikariDataSource;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class DataSourceFactory {
|
||||||
|
|
||||||
|
private static DataSource instance;
|
||||||
|
|
||||||
|
public static DataSource getInstance(String host, int port, String user, String password) throws IOException {
|
||||||
|
if (instance == null) {
|
||||||
|
synchronized (DataSourceFactory.class) {
|
||||||
|
if (instance == null) {
|
||||||
|
InputStream is = DataSourceFactory.class.getClassLoader().getResourceAsStream("application.properties");
|
||||||
|
Properties properties = new Properties();
|
||||||
|
properties.load(is);
|
||||||
|
|
||||||
|
HikariConfig config = new HikariConfig();
|
||||||
|
|
||||||
|
if (properties.containsKey("jdbc.driver")) {
|
||||||
|
// String driverName = properties.getProperty("jdbc.driver");
|
||||||
|
// System.out.println(">>> load driver : " + driverName);
|
||||||
|
// try {
|
||||||
|
// Class.forName(driverName);
|
||||||
|
// } catch (ClassNotFoundException e) {
|
||||||
|
// e.printStackTrace();
|
||||||
|
// }
|
||||||
|
config.setDriverClassName(properties.getProperty("jdbc.driver"));
|
||||||
|
} else {
|
||||||
|
config.setDriverClassName("com.taosdata.jdbc.TSDBDriver");
|
||||||
|
}
|
||||||
|
if ("com.taosdata.jdbc.rs.RestfulDriver".equalsIgnoreCase(properties.getProperty("jdbc.driver")))
|
||||||
|
config.setJdbcUrl("jdbc:TAOS-RS://" + host + ":6041/?charset=UTF-8&locale=en_US.UTF-8&timezone=UTC-8");
|
||||||
|
else
|
||||||
|
config.setJdbcUrl("jdbc:TAOS://" + host + ":" + port + "/?charset=UTF-8&locale=en_US.UTF-8&timezone=UTC-8");
|
||||||
|
config.setUsername(user);
|
||||||
|
config.setPassword(password);
|
||||||
|
// maximum-pool-size
|
||||||
|
if (properties.containsKey("hikari.maximum-pool-size"))
|
||||||
|
config.setMaximumPoolSize(Integer.parseInt(properties.getProperty("hikari.maximum-pool-size")));
|
||||||
|
else
|
||||||
|
config.setMaximumPoolSize(500);
|
||||||
|
// minimum-idle
|
||||||
|
if (properties.containsKey("hikari.minimum-idle"))
|
||||||
|
config.setMinimumIdle(Integer.parseInt(properties.getProperty("hikari.minimum-idle")));
|
||||||
|
else
|
||||||
|
config.setMinimumIdle(100);
|
||||||
|
config.setMaxLifetime(0);
|
||||||
|
instance = new HikariDataSource(config);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,4 +1,6 @@
|
||||||
package com.taosdata.taosdemo.utils;
|
package com.taosdata.taosdemo.components;
|
||||||
|
|
||||||
|
import com.taosdata.taosdemo.utils.TimeStampUtil;
|
||||||
|
|
||||||
public final class JdbcTaosdemoConfig {
|
public final class JdbcTaosdemoConfig {
|
||||||
// instance
|
// instance
|
||||||
|
@ -7,10 +9,14 @@ public final class JdbcTaosdemoConfig {
|
||||||
public String user = "root"; //user
|
public String user = "root"; //user
|
||||||
public String password = "taosdata"; //password
|
public String password = "taosdata"; //password
|
||||||
// database
|
// database
|
||||||
public String database = "test"; //database
|
public String database = "jdbcdb"; //database
|
||||||
public int keep = 3650; //keep
|
public int keep = 3650; //keep
|
||||||
public int days = 30; //days
|
public int days = 30; //days
|
||||||
public int replica = 1; //replica
|
public int replica = 1; //replica
|
||||||
|
public int blocks = 16;
|
||||||
|
public int cache = 8;
|
||||||
|
public String precision = "ms";
|
||||||
|
|
||||||
//super table
|
//super table
|
||||||
public boolean doCreateTable = true;
|
public boolean doCreateTable = true;
|
||||||
public String superTable = "weather"; //super table name
|
public String superTable = "weather"; //super table name
|
||||||
|
@ -20,19 +26,19 @@ public final class JdbcTaosdemoConfig {
|
||||||
public int numOfTags;
|
public int numOfTags;
|
||||||
public String superTableSQL;
|
public String superTableSQL;
|
||||||
//sub table
|
//sub table
|
||||||
public String tablePrefix = "t";
|
public String prefixOfTable = "t";
|
||||||
public int numOfTables = 100;
|
|
||||||
public int numOfThreadsForCreate = 1;
|
|
||||||
// insert task
|
// insert task
|
||||||
public boolean autoCreateTable;
|
public boolean autoCreateTable;
|
||||||
public int numOfRowsPerTable = 100;
|
public long numOfTables = 10;
|
||||||
|
public long numOfRowsPerTable = 10;
|
||||||
|
public int numOfTablesPerSQL = 1;
|
||||||
|
public int numOfValuesPerSQL = 1;
|
||||||
|
public int numOfThreadsForCreate = 1;
|
||||||
public int numOfThreadsForInsert = 1;
|
public int numOfThreadsForInsert = 1;
|
||||||
public int numOfTablesPerSQL = 10;
|
|
||||||
public int numOfValuesPerSQL = 10;
|
|
||||||
public long startTime;
|
public long startTime;
|
||||||
public long timeGap;
|
public long timeGap = 1;
|
||||||
public int sleep = 0;
|
public int frequency;
|
||||||
public int order = 0;
|
public int order;
|
||||||
public int rate = 10;
|
public int rate = 10;
|
||||||
public long range = 1000l;
|
public long range = 1000l;
|
||||||
// select task
|
// select task
|
||||||
|
@ -48,10 +54,14 @@ public final class JdbcTaosdemoConfig {
|
||||||
System.out.println("-user The TDengine user name to use when connecting to the server. Default is 'root'");
|
System.out.println("-user The TDengine user name to use when connecting to the server. Default is 'root'");
|
||||||
System.out.println("-password The password to use when connecting to the server.Default is 'taosdata'");
|
System.out.println("-password The password to use when connecting to the server.Default is 'taosdata'");
|
||||||
// database
|
// database
|
||||||
System.out.println("-database Destination database. Default is 'test'");
|
System.out.println("-database Destination database. Default is 'jdbcdb'");
|
||||||
System.out.println("-keep database keep parameter. Default is 3650");
|
System.out.println("-keep database keep parameter. Default is 3650");
|
||||||
System.out.println("-days database days parameter. Default is 30");
|
System.out.println("-days database days parameter. Default is 30");
|
||||||
System.out.println("-replica database replica parameter. Default 1, min: 1, max: 3");
|
System.out.println("-replica database replica parameter. Default 1, min: 1, max: 3");
|
||||||
|
System.out.println("-blocks database blocks parameter. Default is 16");
|
||||||
|
System.out.println("-cache database cache parameter. Default is 8");
|
||||||
|
System.out.println("-precision database precision parameter. Default is ms");
|
||||||
|
|
||||||
// super table
|
// super table
|
||||||
System.out.println("-doCreateTable do create super table and sub table, true or false, Default true");
|
System.out.println("-doCreateTable do create super table and sub table, true or false, Default true");
|
||||||
System.out.println("-superTable super table name. Default 'weather'");
|
System.out.println("-superTable super table name. Default 'weather'");
|
||||||
|
@ -63,7 +73,7 @@ public final class JdbcTaosdemoConfig {
|
||||||
" Default is 'create table weather(ts timestamp, temperature float, humidity int) tags(location nchar(64), groupId int). \n" +
|
" Default is 'create table weather(ts timestamp, temperature float, humidity int) tags(location nchar(64), groupId int). \n" +
|
||||||
" if you use this parameter, the numOfFields and numOfTags will be invalid'");
|
" if you use this parameter, the numOfFields and numOfTags will be invalid'");
|
||||||
// sub table
|
// sub table
|
||||||
System.out.println("-tablePrefix The prefix of sub tables. Default is 't'");
|
System.out.println("-prefixOfTable The prefix of sub tables. Default is 't'");
|
||||||
System.out.println("-numOfTables The number of tables. Default is 1");
|
System.out.println("-numOfTables The number of tables. Default is 1");
|
||||||
System.out.println("-numOfThreadsForCreate The number of thread during create sub table. Default is 1");
|
System.out.println("-numOfThreadsForCreate The number of thread during create sub table. Default is 1");
|
||||||
// insert task
|
// insert task
|
||||||
|
@ -74,11 +84,10 @@ public final class JdbcTaosdemoConfig {
|
||||||
System.out.println("-numOfValuesPerSQL The number of value per SQL. Default is 1");
|
System.out.println("-numOfValuesPerSQL The number of value per SQL. Default is 1");
|
||||||
System.out.println("-startTime start time for insert task, The format is \"yyyy-MM-dd HH:mm:ss.SSS\".");
|
System.out.println("-startTime start time for insert task, The format is \"yyyy-MM-dd HH:mm:ss.SSS\".");
|
||||||
System.out.println("-timeGap the number of time gap. Default is 1000 ms");
|
System.out.println("-timeGap the number of time gap. Default is 1000 ms");
|
||||||
System.out.println("-sleep The number of milliseconds for sleep after each insert. default is 0");
|
System.out.println("-frequency the number of records per second inserted into one table. default is 0, do not control frequency");
|
||||||
System.out.println("-order Insert mode--0: In order, 1: Out of order. Default is in order");
|
System.out.println("-order Insert mode--0: In order, 1: Out of order. Default is in order");
|
||||||
System.out.println("-rate The proportion of data out of order. effective only if order is 1. min 0, max 100, default is 10");
|
System.out.println("-rate The proportion of data out of order. effective only if order is 1. min 0, max 100, default is 10");
|
||||||
System.out.println("-range The range of data out of order. effective only if order is 1. default is 1000 ms");
|
System.out.println("-range The range of data out of order. effective only if order is 1. default is 1000 ms");
|
||||||
|
|
||||||
// query task
|
// query task
|
||||||
// System.out.println("-sqlFile The select sql file");
|
// System.out.println("-sqlFile The select sql file");
|
||||||
// drop task
|
// drop task
|
||||||
|
@ -120,6 +129,15 @@ public final class JdbcTaosdemoConfig {
|
||||||
if ("-replica".equals(args[i]) && i < args.length - 1) {
|
if ("-replica".equals(args[i]) && i < args.length - 1) {
|
||||||
replica = Integer.parseInt(args[++i]);
|
replica = Integer.parseInt(args[++i]);
|
||||||
}
|
}
|
||||||
|
if ("-blocks".equals(args[i]) && i < args.length - 1) {
|
||||||
|
blocks = Integer.parseInt(args[++i]);
|
||||||
|
}
|
||||||
|
if ("-cache".equals(args[i]) && i < args.length - 1) {
|
||||||
|
cache = Integer.parseInt(args[++i]);
|
||||||
|
}
|
||||||
|
if ("-precision".equals(args[i]) && i < args.length - 1) {
|
||||||
|
precision = args[++i];
|
||||||
|
}
|
||||||
// super table
|
// super table
|
||||||
if ("-doCreateTable".equals(args[i]) && i < args.length - 1) {
|
if ("-doCreateTable".equals(args[i]) && i < args.length - 1) {
|
||||||
doCreateTable = Boolean.parseBoolean(args[++i]);
|
doCreateTable = Boolean.parseBoolean(args[++i]);
|
||||||
|
@ -143,11 +161,11 @@ public final class JdbcTaosdemoConfig {
|
||||||
superTableSQL = args[++i];
|
superTableSQL = args[++i];
|
||||||
}
|
}
|
||||||
// sub table
|
// sub table
|
||||||
if ("-tablePrefix".equals(args[i]) && i < args.length - 1) {
|
if ("-prefixOfTable".equals(args[i]) && i < args.length - 1) {
|
||||||
tablePrefix = args[++i];
|
prefixOfTable = args[++i];
|
||||||
}
|
}
|
||||||
if ("-numOfTables".equals(args[i]) && i < args.length - 1) {
|
if ("-numOfTables".equals(args[i]) && i < args.length - 1) {
|
||||||
numOfTables = Integer.parseInt(args[++i]);
|
numOfTables = Long.parseLong(args[++i]);
|
||||||
}
|
}
|
||||||
if ("-autoCreateTable".equals(args[i]) && i < args.length - 1) {
|
if ("-autoCreateTable".equals(args[i]) && i < args.length - 1) {
|
||||||
autoCreateTable = Boolean.parseBoolean(args[++i]);
|
autoCreateTable = Boolean.parseBoolean(args[++i]);
|
||||||
|
@ -157,7 +175,7 @@ public final class JdbcTaosdemoConfig {
|
||||||
}
|
}
|
||||||
// insert task
|
// insert task
|
||||||
if ("-numOfRowsPerTable".equals(args[i]) && i < args.length - 1) {
|
if ("-numOfRowsPerTable".equals(args[i]) && i < args.length - 1) {
|
||||||
numOfRowsPerTable = Integer.parseInt(args[++i]);
|
numOfRowsPerTable = Long.parseLong(args[++i]);
|
||||||
}
|
}
|
||||||
if ("-numOfThreadsForInsert".equals(args[i]) && i < args.length - 1) {
|
if ("-numOfThreadsForInsert".equals(args[i]) && i < args.length - 1) {
|
||||||
numOfThreadsForInsert = Integer.parseInt(args[++i]);
|
numOfThreadsForInsert = Integer.parseInt(args[++i]);
|
||||||
|
@ -174,8 +192,8 @@ public final class JdbcTaosdemoConfig {
|
||||||
if ("-timeGap".equals(args[i]) && i < args.length - 1) {
|
if ("-timeGap".equals(args[i]) && i < args.length - 1) {
|
||||||
timeGap = Long.parseLong(args[++i]);
|
timeGap = Long.parseLong(args[++i]);
|
||||||
}
|
}
|
||||||
if ("-sleep".equals(args[i]) && i < args.length - 1) {
|
if ("-frequency".equals(args[i]) && i < args.length - 1) {
|
||||||
sleep = Integer.parseInt(args[++i]);
|
frequency = Integer.parseInt(args[++i]);
|
||||||
}
|
}
|
||||||
if ("-order".equals(args[i]) && i < args.length - 1) {
|
if ("-order".equals(args[i]) && i < args.length - 1) {
|
||||||
order = Integer.parseInt(args[++i]);
|
order = Integer.parseInt(args[++i]);
|
||||||
|
@ -197,8 +215,4 @@ public final class JdbcTaosdemoConfig {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
|
||||||
JdbcTaosdemoConfig config = new JdbcTaosdemoConfig(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
package com.taosdata.taosdemo.components;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
|
||||||
|
public class JsonConfig {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
JsonConfig config = new JsonConfig();
|
||||||
|
String str = config.read("insert.json");
|
||||||
|
JSONObject jsonObject = JSONObject.parseObject(str);
|
||||||
|
System.out.println(jsonObject);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private String read(String fileName) {
|
||||||
|
try {
|
||||||
|
BufferedReader reader = new BufferedReader(
|
||||||
|
new InputStreamReader(JsonConfig.class.getClassLoader().getResourceAsStream(fileName))
|
||||||
|
);
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
String line = null;
|
||||||
|
while ((line = reader.readLine()) != null) {
|
||||||
|
sb.append(line);
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -1,174 +0,0 @@
|
||||||
package com.taosdata.taosdemo.components;
|
|
||||||
|
|
||||||
import com.taosdata.taosdemo.domain.*;
|
|
||||||
import com.taosdata.taosdemo.service.DatabaseService;
|
|
||||||
import com.taosdata.taosdemo.service.SubTableService;
|
|
||||||
import com.taosdata.taosdemo.service.SuperTableService;
|
|
||||||
import com.taosdata.taosdemo.service.data.SubTableMetaGenerator;
|
|
||||||
import com.taosdata.taosdemo.service.data.SubTableValueGenerator;
|
|
||||||
import com.taosdata.taosdemo.service.data.SuperTableMetaGenerator;
|
|
||||||
import com.taosdata.taosdemo.utils.JdbcTaosdemoConfig;
|
|
||||||
import org.apache.log4j.Logger;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.boot.CommandLineRunner;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
|
|
||||||
@Component
|
|
||||||
public class TaosDemoCommandLineRunner implements CommandLineRunner {
|
|
||||||
|
|
||||||
private static Logger logger = Logger.getLogger(TaosDemoCommandLineRunner.class);
|
|
||||||
@Autowired
|
|
||||||
private DatabaseService databaseService;
|
|
||||||
@Autowired
|
|
||||||
private SuperTableService superTableService;
|
|
||||||
@Autowired
|
|
||||||
private SubTableService subTableService;
|
|
||||||
|
|
||||||
private SuperTableMeta superTableMeta;
|
|
||||||
private List<SubTableMeta> subTableMetaList;
|
|
||||||
private List<SubTableValue> subTableValueList;
|
|
||||||
private List<List<SubTableValue>> dataList;
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run(String... args) throws Exception {
|
|
||||||
// 读配置参数
|
|
||||||
JdbcTaosdemoConfig config = new JdbcTaosdemoConfig(args);
|
|
||||||
boolean isHelp = Arrays.asList(args).contains("--help");
|
|
||||||
if (isHelp) {
|
|
||||||
JdbcTaosdemoConfig.printHelp();
|
|
||||||
System.exit(0);
|
|
||||||
}
|
|
||||||
// 准备数据
|
|
||||||
prepareData(config);
|
|
||||||
// 创建数据库
|
|
||||||
createDatabaseTask(config);
|
|
||||||
// 建表
|
|
||||||
createTableTask(config);
|
|
||||||
// 插入
|
|
||||||
insertTask(config);
|
|
||||||
// 查询: 1. 生成查询语句, 2. 执行查询
|
|
||||||
// 删除表
|
|
||||||
if (config.dropTable) {
|
|
||||||
superTableService.drop(config.database, config.superTable);
|
|
||||||
}
|
|
||||||
|
|
||||||
System.exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createDatabaseTask(JdbcTaosdemoConfig config) {
|
|
||||||
long start = System.currentTimeMillis();
|
|
||||||
|
|
||||||
Map<String, String> databaseParam = new HashMap<>();
|
|
||||||
databaseParam.put("database", config.database);
|
|
||||||
databaseParam.put("keep", Integer.toString(config.keep));
|
|
||||||
databaseParam.put("days", Integer.toString(config.days));
|
|
||||||
databaseParam.put("replica", Integer.toString(config.replica));
|
|
||||||
//TODO: other database parameters
|
|
||||||
databaseService.dropDatabase(config.database);
|
|
||||||
databaseService.createDatabase(databaseParam);
|
|
||||||
databaseService.useDatabase(config.database);
|
|
||||||
|
|
||||||
long end = System.currentTimeMillis();
|
|
||||||
logger.info(">>> insert time cost : " + (end - start) + " ms.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 建超级表,三种方式:1. 指定SQL,2. 指定field和tags的个数,3. 默认
|
|
||||||
private void createTableTask(JdbcTaosdemoConfig config) {
|
|
||||||
long start = System.currentTimeMillis();
|
|
||||||
if (config.doCreateTable) {
|
|
||||||
superTableService.create(superTableMeta);
|
|
||||||
// 批量建子表
|
|
||||||
subTableService.createSubTable(subTableMetaList, config.numOfThreadsForCreate);
|
|
||||||
}
|
|
||||||
long end = System.currentTimeMillis();
|
|
||||||
logger.info(">>> create table time cost : " + (end - start) + " ms.");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void insertTask(JdbcTaosdemoConfig config) {
|
|
||||||
long start = System.currentTimeMillis();
|
|
||||||
|
|
||||||
int numOfThreadsForInsert = config.numOfThreadsForInsert;
|
|
||||||
int sleep = config.sleep;
|
|
||||||
if (config.autoCreateTable) {
|
|
||||||
// 批量插入,自动建表
|
|
||||||
dataList.stream().forEach(subTableValues -> {
|
|
||||||
subTableService.insertAutoCreateTable(subTableValues, numOfThreadsForInsert);
|
|
||||||
sleep(sleep);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
dataList.stream().forEach(subTableValues -> {
|
|
||||||
subTableService.insert(subTableValues, numOfThreadsForInsert);
|
|
||||||
sleep(sleep);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
long end = System.currentTimeMillis();
|
|
||||||
logger.info(">>> insert time cost : " + (end - start) + " ms.");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void prepareData(JdbcTaosdemoConfig config) {
|
|
||||||
long start = System.currentTimeMillis();
|
|
||||||
// 超级表的meta
|
|
||||||
superTableMeta = createSupertable(config);
|
|
||||||
// 子表的meta
|
|
||||||
subTableMetaList = SubTableMetaGenerator.generate(superTableMeta, config.numOfTables, config.tablePrefix);
|
|
||||||
// 子表的data
|
|
||||||
subTableValueList = SubTableValueGenerator.generate(subTableMetaList, config.numOfRowsPerTable, config.startTime, config.timeGap);
|
|
||||||
// 如果有乱序,给数据搞乱
|
|
||||||
if (config.order != 0) {
|
|
||||||
SubTableValueGenerator.disrupt(subTableValueList, config.rate, config.range);
|
|
||||||
}
|
|
||||||
// 分割数据
|
|
||||||
int numOfTables = config.numOfTables;
|
|
||||||
int numOfTablesPerSQL = config.numOfTablesPerSQL;
|
|
||||||
int numOfRowsPerTable = config.numOfRowsPerTable;
|
|
||||||
int numOfValuesPerSQL = config.numOfValuesPerSQL;
|
|
||||||
dataList = SubTableValueGenerator.split(subTableValueList, numOfTables, numOfTablesPerSQL, numOfRowsPerTable, numOfValuesPerSQL);
|
|
||||||
long end = System.currentTimeMillis();
|
|
||||||
logger.info(">>> prepare data time cost : " + (end - start) + " ms.");
|
|
||||||
}
|
|
||||||
|
|
||||||
private SuperTableMeta createSupertable(JdbcTaosdemoConfig config) {
|
|
||||||
SuperTableMeta tableMeta;
|
|
||||||
// create super table
|
|
||||||
logger.info(">>> create super table <<<");
|
|
||||||
if (config.superTableSQL != null) {
|
|
||||||
// use a sql to create super table
|
|
||||||
tableMeta = SuperTableMetaGenerator.generate(config.superTableSQL);
|
|
||||||
} else if (config.numOfFields == 0) {
|
|
||||||
// default sql = "create table test.weather (ts timestamp, temperature float, humidity int) tags(location nchar(64), groupId int)";
|
|
||||||
SuperTableMeta superTableMeta = new SuperTableMeta();
|
|
||||||
superTableMeta.setDatabase(config.database);
|
|
||||||
superTableMeta.setName(config.superTable);
|
|
||||||
List<FieldMeta> fields = new ArrayList<>();
|
|
||||||
fields.add(new FieldMeta("ts", "timestamp"));
|
|
||||||
fields.add(new FieldMeta("temperature", "float"));
|
|
||||||
fields.add(new FieldMeta("humidity", "int"));
|
|
||||||
superTableMeta.setFields(fields);
|
|
||||||
List<TagMeta> tags = new ArrayList<>();
|
|
||||||
tags.add(new TagMeta("location", "nchar(64)"));
|
|
||||||
tags.add(new TagMeta("groupId", "int"));
|
|
||||||
superTableMeta.setTags(tags);
|
|
||||||
return superTableMeta;
|
|
||||||
} else {
|
|
||||||
// create super table with specified field size and tag size
|
|
||||||
tableMeta = SuperTableMetaGenerator.generate(config.database, config.superTable, config.numOfFields, config.prefixOfFields, config.numOfTags, config.prefixOfTags);
|
|
||||||
}
|
|
||||||
return tableMeta;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void sleep(int sleep) {
|
|
||||||
if (sleep <= 0)
|
|
||||||
return;
|
|
||||||
try {
|
|
||||||
TimeUnit.MILLISECONDS.sleep(sleep);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,40 +0,0 @@
|
||||||
package com.taosdata.taosdemo.controller;
|
|
||||||
|
|
||||||
import com.taosdata.taosdemo.service.DatabaseService;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@RestController
|
|
||||||
@RequestMapping
|
|
||||||
public class DatabaseController {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private DatabaseService databaseService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* create database
|
|
||||||
***/
|
|
||||||
@PostMapping
|
|
||||||
public int create(@RequestBody Map<String, String> map) {
|
|
||||||
return databaseService.createDatabase(map);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* drop database
|
|
||||||
**/
|
|
||||||
@DeleteMapping("/{dbname}")
|
|
||||||
public int delete(@PathVariable("dbname") String dbname) {
|
|
||||||
return databaseService.dropDatabase(dbname);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* use database
|
|
||||||
**/
|
|
||||||
@GetMapping("/{dbname}")
|
|
||||||
public int use(@PathVariable("dbname") String dbname) {
|
|
||||||
return databaseService.useDatabase(dbname);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,17 +0,0 @@
|
||||||
package com.taosdata.taosdemo.controller;
|
|
||||||
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
@RestController
|
|
||||||
public class InsertController {
|
|
||||||
|
|
||||||
//TODO:多线程写一张表, thread = 10, table = 1
|
|
||||||
//TODO:一个批次写多张表, insert into t1 using weather values() t2 using weather values()
|
|
||||||
//TODO:插入的频率,
|
|
||||||
//TODO:指定一张表内的records数量
|
|
||||||
//TODO:是否乱序,
|
|
||||||
//TODO:乱序的比例,乱序的范围
|
|
||||||
//TODO:先建表,自动建表
|
|
||||||
//TODO:一个批次写多张表
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,45 +0,0 @@
|
||||||
package com.taosdata.taosdemo.controller;
|
|
||||||
|
|
||||||
import com.taosdata.taosdemo.domain.TableValue;
|
|
||||||
import com.taosdata.taosdemo.service.SuperTableService;
|
|
||||||
import com.taosdata.taosdemo.service.TableService;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
@RestController
|
|
||||||
public class SubTableController {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private TableService tableService;
|
|
||||||
@Autowired
|
|
||||||
private SuperTableService superTableService;
|
|
||||||
|
|
||||||
//TODO: 使用supertable创建一个子表
|
|
||||||
|
|
||||||
//TODO:使用supertable创建多个子表
|
|
||||||
|
|
||||||
//TODO:使用supertable多线程创建子表
|
|
||||||
|
|
||||||
//TODO:使用supertable多线程创建子表,指定子表的name_prefix,子表的数量,使用线程的个数
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建表,超级表或者普通表
|
|
||||||
**/
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建超级表的子表
|
|
||||||
**/
|
|
||||||
@PostMapping("/{database}/{superTable}")
|
|
||||||
public int createTable(@PathVariable("database") String database,
|
|
||||||
@PathVariable("superTable") String superTable,
|
|
||||||
@RequestBody TableValue tableMetadta) {
|
|
||||||
tableMetadta.setDatabase(database);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
package com.taosdata.taosdemo.controller;
|
|
||||||
|
|
||||||
import com.taosdata.taosdemo.domain.SuperTableMeta;
|
|
||||||
import com.taosdata.taosdemo.service.SuperTableService;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
|
||||||
|
|
||||||
public class SuperTableController {
|
|
||||||
@Autowired
|
|
||||||
private SuperTableService superTableService;
|
|
||||||
|
|
||||||
|
|
||||||
@PostMapping("/{database}")
|
|
||||||
public int createTable(@PathVariable("database") String database, @RequestBody SuperTableMeta tableMetadta) {
|
|
||||||
tableMetadta.setDatabase(database);
|
|
||||||
return superTableService.create(tableMetadta);
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO: 删除超级表
|
|
||||||
|
|
||||||
//TODO:查询超级表
|
|
||||||
|
|
||||||
//TODO:统计查询表
|
|
||||||
}
|
|
|
@ -1,11 +0,0 @@
|
||||||
package com.taosdata.taosdemo.controller;
|
|
||||||
|
|
||||||
public class TableController {
|
|
||||||
|
|
||||||
//TODO:创建普通表,create table(ts timestamp, temperature float)
|
|
||||||
|
|
||||||
//TODO:创建普通表,指定表的列数,包括第一列timestamp
|
|
||||||
|
|
||||||
//TODO:创建普通表,指定表每列的name和type
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
package com.taosdata.taosdemo.dao;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public interface DatabaseMapper {
|
||||||
|
|
||||||
|
// create database if not exists XXX
|
||||||
|
void createDatabase(String dbname);
|
||||||
|
|
||||||
|
// drop database if exists XXX
|
||||||
|
void dropDatabase(String dbname);
|
||||||
|
|
||||||
|
// create database if not exists XXX keep XX days XX replica XX
|
||||||
|
void createDatabaseWithParameters(Map<String, String> map);
|
||||||
|
|
||||||
|
// use XXX
|
||||||
|
void useDatabase(String dbname);
|
||||||
|
|
||||||
|
//TODO: alter database
|
||||||
|
|
||||||
|
//TODO: show database
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
package com.taosdata.taosdemo.dao;
|
||||||
|
|
||||||
|
import com.taosdata.taosdemo.utils.SqlSpeller;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.springframework.jdbc.core.JdbcTemplate;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class DatabaseMapperImpl implements DatabaseMapper {
|
||||||
|
private static final Logger logger = Logger.getLogger(DatabaseMapperImpl.class);
|
||||||
|
|
||||||
|
private final JdbcTemplate jdbcTemplate;
|
||||||
|
|
||||||
|
public DatabaseMapperImpl(DataSource dataSource) {
|
||||||
|
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void createDatabase(String dbname) {
|
||||||
|
String sql = "create database if not exists " + dbname;
|
||||||
|
jdbcTemplate.execute(sql);
|
||||||
|
logger.info("SQL >>> " + sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dropDatabase(String dbname) {
|
||||||
|
String sql = "drop database if exists " + dbname;
|
||||||
|
jdbcTemplate.update(sql);
|
||||||
|
logger.info("SQL >>> " + sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void createDatabaseWithParameters(Map<String, String> map) {
|
||||||
|
String sql = SqlSpeller.createDatabase(map);
|
||||||
|
jdbcTemplate.execute(sql);
|
||||||
|
logger.info("SQL >>> " + sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void useDatabase(String dbname) {
|
||||||
|
String sql = "use " + dbname;
|
||||||
|
jdbcTemplate.execute(sql);
|
||||||
|
logger.info("SQL >>> " + sql);
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue