Merge branch 'develop' into feature/TD-2577

This commit is contained in:
dapan1121 2021-04-01 16:51:01 +08:00
commit 80e0d0eff1
102 changed files with 5002 additions and 2664 deletions

19
Jenkinsfile vendored
View File

@ -42,12 +42,12 @@ def pre_test(){
killall -9 taosd ||echo "no taosd running"
killall -9 gdb || echo "no gdb running"
cd ${WKC}
git checkout develop
git reset --hard HEAD~10 >/dev/null
git checkout develop
git pull >/dev/null
git fetch origin +refs/pull/${CHANGE_ID}/merge
git checkout -qf FETCH_HEAD
find ${WKC}/tests/pytest -name \'*\'.sql -exec rm -rf {} \\;
git clean -dfx
cd ${WK}
git reset --hard HEAD~10
git checkout develop
@ -55,7 +55,7 @@ def pre_test(){
cd ${WK}
export TZ=Asia/Harbin
date
rm -rf ${WK}/debug
git clean -dfx
mkdir debug
cd debug
cmake .. > /dev/null
@ -185,6 +185,14 @@ pipeline {
rm -rf /var/log/taos/*
./handle_crash_gen_val_log.sh
'''
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
sh '''
cd ${WKC}/tests/pytest
rm -rf /var/lib/taos/*
rm -rf /var/log/taos/*
./handle_taosd_val_log.sh
'''
}
timeout(time: 45, unit: 'MINUTES'){
sh '''
date
@ -215,6 +223,11 @@ pipeline {
cd ${WKC}/tests
./test-all.sh b3fq
date'''
sh '''
date
cd ${WKC}/tests
./test-all.sh full example
date'''
}
}
}

View File

@ -32,7 +32,7 @@ ELSEIF (TD_WINDOWS)
#INSTALL(TARGETS taos RUNTIME DESTINATION driver)
#INSTALL(TARGETS shell RUNTIME DESTINATION .)
IF (TD_MVN_INSTALLED)
INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos-jdbcdriver-2.0.22-dist.jar DESTINATION connector/jdbc)
INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos-jdbcdriver-2.0.25-dist.jar DESTINATION connector/jdbc)
ENDIF ()
ELSEIF (TD_DARWIN)
SET(TD_MAKE_INSTALL_SH "${TD_COMMUNITY_DIR}/packaging/tools/make_install.sh")

View File

@ -179,7 +179,7 @@ taos> select avg(f1), max(f2), min(f3) from test.t10 interval(10s);
### TDengine服务器支持的平台列表
| | **CentOS** **6/7/8** | **Ubuntu** **16/18/20** | **Other Linux** | **统信****UOS** | **银河****/****中标麒麟** | **凝思** **V60/V80** |
| | **CentOS 6/7/8** | **Ubuntu 16/18/20** | **Other Linux** | **统信 UOS** | **银河/中标麒麟** | **凝思 V60/V80** |
| -------------- | --------------------- | ------------------------ | --------------- | --------------- | ------------------------- | --------------------- |
| X64 | ● | ● | | ○ | ● | ● |
| 树莓派 ARM32 | | ● | ● | | | |
@ -203,7 +203,7 @@ taos> select avg(f1), max(f2), min(f3) from test.t10 interval(10s);
对照矩阵如下:
| **CPU** | **X64 64bit** | | | **X86 32bit** | **ARM64** | **ARM32** | **MIPS ** **龙芯** | **Alpha ** **申威** | **X64 ** **海光** |
| **CPU** | **X64 64bit** | | | **X86 32bit** | **ARM64** | **ARM32** | **MIPS 龙芯** | **Alpha 申威** | **X64 海光** |
| ----------- | --------------- | --------- | --------- | --------------- | --------- | --------- | ------------------- | -------------------- | ------------------ |
| **OS** | **Linux** | **Win64** | **Win32** | **Win32** | **Linux** | **Linux** | **Linux** | **Linux** | **Linux** |
| **C/C++** | ● | ● | ● | ○ | ● | ● | ● | ● | ● |

View File

@ -1,27 +1,16 @@
# 高级功能
## <a class="anchor" id="continuous-query"></a>连续查询(Continuous Query)
## <a class="anchor" id="continuous-query"></a>连续查询Continuous Query
连续查询是TDengine定期自动执行的查询采用滑动窗口的方式进行计算是一种简化的时间驱动的流式计算。
针对库中的表或超级表TDengine可提供定期自动执行的连续查询
用户可让TDengine推送查询的结果也可以将结果再写回到TDengine中。
每次执行的查询是一个时间窗口,时间窗口随着时间流动向前滑动。
在定义连续查询的时候需要指定时间窗口time window, 参数interval大小和每次前向增量时间forward sliding times, 参数sliding
连续查询是TDengine定期自动执行的查询采用滑动窗口的方式进行计算是一种简化的时间驱动的流式计算。针对库中的表或超级表TDengine可提供定期自动执行的连续查询用户可让TDengine推送查询的结果也可以将结果再写回到TDengine中。每次执行的查询是一个时间窗口时间窗口随着时间流动向前滑动。在定义连续查询的时候需要指定时间窗口time window, 参数interval大小和每次前向增量时间forward sliding times, 参数sliding
TDengine的连续查询采用时间驱动模式可以直接使用TAOS SQL进行定义不需要额外的操作。
使用连续查询可以方便快捷地按照时间窗口生成结果从而对原始采集数据进行降采样down sampling
用户通过TAOS SQL定义连续查询以后TDengine自动在最后的一个完整的时间周期末端拉起查询
并将计算获得的结果推送给用户或者写回TDengine。
TDengine的连续查询采用时间驱动模式可以直接使用TAOS SQL进行定义不需要额外的操作。使用连续查询可以方便快捷地按照时间窗口生成结果从而对原始采集数据进行降采样down sampling。用户通过TAOS SQL定义连续查询以后TDengine自动在最后的一个完整的时间周期末端拉起查询并将计算获得的结果推送给用户或者写回TDengine。
TDengine提供的连续查询与普通流计算中的时间窗口计算具有以下区别
- 不同于流计算的实时反馈计算结果,连续查询只在时间窗口关闭以后才开始计算。
例如时间周期是1天那么当天的结果只会在23:59:59以后才会生成。
- 如果有历史记录写入到已经计算完成的时间区间,连续查询并不会重新进行计算,
也不会重新将结果推送给用户。对于写回TDengine的模式也不会更新已经存在的计算结果。
- 使用连续查询推送结果的模式服务端并不缓存客户端计算状态也不提供Exactly-Once的语意保证。
如果用户的应用端崩溃,再次拉起的连续查询将只会从再次拉起的时间开始重新计算最近的一个完整的时间窗口。
如果使用写回模式TDengine可确保数据写回的有效性和连续性。
- 不同于流计算的实时反馈计算结果连续查询只在时间窗口关闭以后才开始计算。例如时间周期是1天那么当天的结果只会在23:59:59以后才会生成。
- 如果有历史记录写入到已经计算完成的时间区间连续查询并不会重新进行计算也不会重新将结果推送给用户。对于写回TDengine的模式也不会更新已经存在的计算结果。
- 使用连续查询推送结果的模式服务端并不缓存客户端计算状态也不提供Exactly-Once的语意保证。如果用户的应用端崩溃再次拉起的连续查询将只会从再次拉起的时间开始重新计算最近的一个完整的时间窗口。如果使用写回模式TDengine可确保数据写回的有效性和连续性。
### 使用连续查询
@ -40,23 +29,19 @@ create table D1002 using meters tags ("Beijing.Haidian", 2);
select avg(voltage) from meters interval(1m) sliding(30s);
```
每次执行这条语句,都会重新计算所有数据。
如果需要每隔30秒执行一次来增量计算最近一分钟的数据
可以把上面的语句改进成下面的样子,每次使用不同的 `startTime` 并定期执行:
每次执行这条语句,都会重新计算所有数据。 如果需要每隔30秒执行一次来增量计算最近一分钟的数据可以把上面的语句改进成下面的样子每次使用不同的 `startTime` 并定期执行:
```sql
select avg(voltage) from meters where ts > {startTime} interval(1m) sliding(30s);
```
这样做没有问题但TDengine提供了更简单的方法
只要在最初的查询语句前面加上 `create table {tableName} as ` 就可以了, 例如:
这样做没有问题但TDengine提供了更简单的方法只要在最初的查询语句前面加上 `create table {tableName} as ` 就可以了, 例如:
```sql
create table avg_vol as select avg(voltage) from meters interval(1m) sliding(30s);
```
会自动创建一个名为 `avg_vol` 的新表然后每隔30秒TDengine会增量执行 `as` 后面的 SQL 语句,
并将查询结果写入这个表中,用户程序后续只要从 `avg_vol` 中查询数据即可。 例如:
会自动创建一个名为 `avg_vol` 的新表然后每隔30秒TDengine会增量执行 `as` 后面的 SQL 语句,并将查询结果写入这个表中,用户程序后续只要从 `avg_vol` 中查询数据即可。 例如:
```mysql
taos> select * from avg_vol;
@ -70,43 +55,27 @@ taos> select * from avg_vol;
需要注意查询时间窗口的最小值是10毫秒没有时间窗口范围的上限。
此外TDengine还支持用户指定连续查询的起止时间。
如果不输入开始时间,连续查询将从第一条原始数据所在的时间窗口开始;
如果没有输入结束时间,连续查询将永久运行;
如果用户指定了结束时间,连续查询在系统时间达到指定的时间以后停止运行。
比如使用下面的SQL创建的连续查询将运行一小时之后会自动停止。
此外TDengine还支持用户指定连续查询的起止时间。如果不输入开始时间连续查询将从第一条原始数据所在的时间窗口开始如果没有输入结束时间连续查询将永久运行如果用户指定了结束时间连续查询在系统时间达到指定的时间以后停止运行。比如使用下面的SQL创建的连续查询将运行一小时之后会自动停止。
```mysql
create table avg_vol as select avg(voltage) from meters where ts > now and ts <= now + 1h interval(1m) sliding(30s);
```
需要说明的是,上面例子中的 `now` 是指创建连续查询的时间,而不是查询执行的时间,否则,查询就无法自动停止了。
另外为了尽量避免原始数据延迟写入导致的问题TDengine中连续查询的计算有一定的延迟。
也就是说一个时间窗口过去后TDengine并不会立即计算这个窗口的数据
所以要稍等一会一般不会超过1分钟才能查到计算结果。
需要说明的是,上面例子中的 `now` 是指创建连续查询的时间而不是查询执行的时间否则查询就无法自动停止了。另外为了尽量避免原始数据延迟写入导致的问题TDengine中连续查询的计算有一定的延迟。也就是说一个时间窗口过去后TDengine并不会立即计算这个窗口的数据所以要稍等一会一般不会超过1分钟才能查到计算结果。
### 管理连续查询
用户可在控制台中通过 `show streams` 命令来查看系统中全部运行的连续查询,
并可以通过 `kill stream` 命令杀掉对应的连续查询。
后续版本会提供更细粒度和便捷的连续查询管理命令。
用户可在控制台中通过 `show streams` 命令来查看系统中全部运行的连续查询,并可以通过 `kill stream` 命令杀掉对应的连续查询。后续版本会提供更细粒度和便捷的连续查询管理命令。
## <a class="anchor" id="subscribe"></a>数据订阅(Publisher/Subscriber)
## <a class="anchor" id="subscribe"></a>数据订阅Publisher/Subscriber
基于数据天然的时间序列特性TDengine的数据写入insert与消息系统的数据发布pub逻辑上一致
均可视为系统中插入一条带时间戳的新记录。
同时TDengine在内部严格按照数据时间序列单调递增的方式保存数据。
本质上来说TDengine中里每一张表均可视为一个标准的消息队列。
基于数据天然的时间序列特性TDengine的数据写入insert与消息系统的数据发布pub逻辑上一致均可视为系统中插入一条带时间戳的新记录。同时TDengine在内部严格按照数据时间序列单调递增的方式保存数据。本质上来说TDengine中里每一张表均可视为一个标准的消息队列。
TDengine内嵌支持轻量级的消息订阅与推送服务。
使用系统提供的API用户可使用普通查询语句订阅数据库中的一张或多张表。
订阅的逻辑和操作状态的维护均是由客户端完成,客户端定时轮询服务器是否有新的记录到达,
有新的记录到达就会将结果反馈到客户。
TDengine内嵌支持轻量级的消息订阅与推送服务。使用系统提供的API用户可使用普通查询语句订阅数据库中的一张或多张表。订阅的逻辑和操作状态的维护均是由客户端完成客户端定时轮询服务器是否有新的记录到达有新的记录到达就会将结果反馈到客户。
TDengine的订阅与推送服务的状态是客户端维持TDengine服务器并不维持。
因此如果应用重启,从哪个时间点开始获取最新数据,由应用决定。
TDengine的订阅与推送服务的状态是客户端维持TDengine服务器并不维持。因此如果应用重启从哪个时间点开始获取最新数据由应用决定。
TDengine的API中与订阅相关的主要有以下三个
@ -116,12 +85,9 @@ taos_consume
taos_unsubscribe
```
这些API的文档请见 [C/C++ Connector](https://www.taosdata.com/cn/documentation/connector/)
下面仍以智能电表场景为例介绍一下它们的具体用法(超级表和子表结构请参考上一节“连续查询”),
完整的示例代码可以在 [这里](https://github.com/taosdata/TDengine/blob/master/tests/examples/c/subscribe.c) 找到。
这些API的文档请见 [C/C++ Connector](https://www.taosdata.com/cn/documentation/connector#c-cpp),下面仍以智能电表场景为例介绍一下它们的具体用法(超级表和子表结构请参考上一节“连续查询”),完整的示例代码可以在 [这里](https://github.com/taosdata/TDengine/blob/master/tests/examples/c/subscribe.c) 找到。
如果我们希望当某个电表的电流超过一定限制比如10A后能得到通知并进行一些处理 有两种方法:
一是分别对每张子表进行查询,每次查询后记录最后一条数据的时间戳,后续只查询这个时间戳之后的数据:
如果我们希望当某个电表的电流超过一定限制比如10A后能得到通知并进行一些处理 有两种方法:一是分别对每张子表进行查询,每次查询后记录最后一条数据的时间戳,后续只查询这个时间戳之后的数据:
```sql
select * from D1001 where ts > {last_timestamp1} and current > 10;
@ -129,8 +95,7 @@ select * from D1002 where ts > {last_timestamp2} and current > 10;
...
```
这确实可行,但随着电表数量的增加,查询数量也会增加,客户端和服务端的性能都会受到影响,
当电表数增长到一定的程度,系统就无法承受了。
这确实可行,但随着电表数量的增加,查询数量也会增加,客户端和服务端的性能都会受到影响,当电表数增长到一定的程度,系统就无法承受了。
另一种方法是对超级表进行查询。这样,无论有多少电表,都只需一次查询:
@ -138,12 +103,7 @@ select * from D1002 where ts > {last_timestamp2} and current > 10;
select * from meters where ts > {last_timestamp} and current > 10;
```
但是,如何选择 `last_timestamp` 就成了一个新的问题。
因为,一方面数据的产生时间(也就是数据时间戳)和数据入库的时间一般并不相同,有时偏差还很大;
另一方面不同电表的数据到达TDengine的时间也会有差异。
所以,如果我们在查询中使用最慢的那台电表的数据的时间戳作为 `last_timestamp`
就可能重复读入其它电表的数据;
如果使用最快的电表的时间戳,其它电表的数据就可能被漏掉。
但是,如何选择 `last_timestamp` 就成了一个新的问题。因为一方面数据的产生时间也就是数据时间戳和数据入库的时间一般并不相同有时偏差还很大另一方面不同电表的数据到达TDengine的时间也会有差异。所以如果我们在查询中使用最慢的那台电表的数据的时间戳作为 `last_timestamp`,就可能重复读入其它电表的数据;如果使用最快的电表的时间戳,其它电表的数据就可能被漏掉。
TDengine的订阅功能为上面这个问题提供了一个彻底的解决方案。
@ -160,47 +120,29 @@ if (async) {
}
```
TDengine中的订阅既可以是同步的也可以是异步的
上面的代码会根据从命令行获取的参数`async`的值来决定使用哪种方式。
这里,同步的意思是用户程序要直接调用`taos_consume`来拉取数据,
而异步则由API在内部的另一个线程中调用`taos_consume`
然后把拉取到的数据交给回调函数`subscribe_callback`去处理。
TDengine中的订阅既可以是同步的也可以是异步的上面的代码会根据从命令行获取的参数`async`的值来决定使用哪种方式。这里,同步的意思是用户程序要直接调用`taos_consume`来拉取数据而异步则由API在内部的另一个线程中调用`taos_consume`,然后把拉取到的数据交给回调函数`subscribe_callback`去处理。
参数`taos`是一个已经建立好的数据库连接,在同步模式下无特殊要求。
但在异步模式下,需要注意它不会被其它线程使用,否则可能导致不可预计的错误,
因为回调函数在API的内部线程中被调用而TDengine的部分API不是线程安全的。
参数`taos`是一个已经建立好的数据库连接在同步模式下无特殊要求。但在异步模式下需要注意它不会被其它线程使用否则可能导致不可预计的错误因为回调函数在API的内部线程中被调用而TDengine的部分API不是线程安全的。
参数`sql`是查询语句可以在其中使用where子句指定过滤条件。
在我们的例子中如果只想订阅电流超过10A时的数据可以这样写
参数`sql`是查询语句可以在其中使用where子句指定过滤条件。在我们的例子中如果只想订阅电流超过10A时的数据可以这样写
```sql
select * from meters where current > 10;
```
注意,这里没有指定起始时间,所以会读到所有时间的数据。
如果只想从一天前的数据开始订阅,而不需要更早的历史数据,可以再加上一个时间条件:
注意,这里没有指定起始时间,所以会读到所有时间的数据。如果只想从一天前的数据开始订阅,而不需要更早的历史数据,可以再加上一个时间条件:
```sql
select * from meters where ts > now - 1d and current > 10;
```
订阅的`topic`实际上是它的名字因为订阅功能是在客户端API中实现的
所以没必要保证它全局唯一,但需要它在一台客户端机器上唯一。
订阅的`topic`实际上是它的名字因为订阅功能是在客户端API中实现的所以没必要保证它全局唯一但需要它在一台客户端机器上唯一。
如果名`topic`的订阅不存在,参数`restart`没有意义;
但如果用户程序创建这个订阅后退出,当它再次启动并重新使用这个`topic`时,
`restart`就会被用于决定是从头开始读取数据,还是接续上次的位置进行读取。
本例中,如果`restart`是 **true**(非零值),用户程序肯定会读到所有数据。
但如果这个订阅之前就存在了,并且已经读取了一部分数据,
且`restart`是 **false****0**),用户程序就不会读到之前已经读取的数据了。
如果名`topic`的订阅不存在,参数`restart`没有意义;但如果用户程序创建这个订阅后退出,当它再次启动并重新使用这个`topic`时,`restart`就会被用于决定是从头开始读取数据,还是接续上次的位置进行读取。本例中,如果`restart`是 **true**(非零值),用户程序肯定会读到所有数据。但如果这个订阅之前就存在了,并且已经读取了一部分数据,且`restart`是 **false****0**),用户程序就不会读到之前已经读取的数据了。
`taos_subscribe`的最后一个参数是以毫秒为单位的轮询周期。
在同步模式下,如果前后两次调用`taos_consume`的时间间隔小于此时间,
`taos_consume`会阻塞,直到间隔超过此时间。
异步模式下,这个时间是两次调用回调函数的最小时间间隔。
`taos_subscribe`的最后一个参数是以毫秒为单位的轮询周期。在同步模式下,如果前后两次调用`taos_consume`的时间间隔小于此时间,`taos_consume`会阻塞,直到间隔超过此时间。异步模式下,这个时间是两次调用回调函数的最小时间间隔。
`taos_subscribe`的倒数第二个参数用于用户程序向回调函数传递附加参数,
订阅API不对其做任何处理只原样传递给回调函数。此参数在同步模式下无意义。
`taos_subscribe`的倒数第二个参数用于用户程序向回调函数传递附加参数订阅API不对其做任何处理只原样传递给回调函数。此参数在同步模式下无意义。
订阅创建以后,就可以消费其数据了,同步模式下,示例代码是下面的 else 部分:
@ -219,9 +161,7 @@ if (async) {
}
```
这里是一个 **while** 循环,用户每按一次回车键就调用一次`taos_consume`
而`taos_consume`的返回值是查询到的结果集,与`taos_use_result`完全相同,
例子中使用这个结果集的代码是函数`print_result`
这里是一个 **while** 循环,用户每按一次回车键就调用一次`taos_consume`,而`taos_consume`的返回值是查询到的结果集,与`taos_use_result`完全相同,例子中使用这个结果集的代码是函数`print_result`
```c
void print_result(TAOS_RES* res, int blockFetch) {
@ -247,8 +187,7 @@ void print_result(TAOS_RES* res, int blockFetch) {
}
```
其中的 `taos_print_row` 用于处理订阅到数据,在我们的例子中,它会打印出所有符合条件的记录。
而异步模式下,消费订阅到的数据则显得更为简单:
其中的 `taos_print_row` 用于处理订阅到数据,在我们的例子中,它会打印出所有符合条件的记录。而异步模式下,消费订阅到的数据则显得更为简单:
```c
void subscribe_callback(TAOS_SUB* tsub, TAOS_RES *res, void* param, int code) {
@ -262,11 +201,7 @@ void subscribe_callback(TAOS_SUB* tsub, TAOS_RES *res, void* param, int code) {
taos_unsubscribe(tsub, keep);
```
其第二个参数,用于决定是否在客户端保留订阅的进度信息。
如果这个参数是**false****0**),那无论下次调用`taos_subscribe`的时的`restart`参数是什么,
订阅都只能重新开始。
另外,进度信息的保存位置是 *{DataDir}/subscribe/* 这个目录下,
每个订阅有一个与其`topic`同名的文件,删掉某个文件,同样会导致下次创建其对应的订阅时只能重新开始。
其第二个参数,用于决定是否在客户端保留订阅的进度信息。如果这个参数是**false****0**),那无论下次调用`taos_subscribe`时的`restart`参数是什么,订阅都只能重新开始。另外,进度信息的保存位置是 *{DataDir}/subscribe/* 这个目录下,每个订阅有一个与其`topic`同名的文件,删掉某个文件,同样会导致下次创建其对应的订阅时只能重新开始。
代码介绍完毕,我们来看一下实际的运行效果。假设:
@ -289,12 +224,11 @@ $ taos
> insert into D1001 values(now, 12, 220, 1);
```
这时因为电流超过了10A您应该可以看到示例程序将它输出到了屏幕上。
您可以继续插入一些数据观察示例程序的输出。
这时因为电流超过了10A您应该可以看到示例程序将它输出到了屏幕上。您可以继续插入一些数据观察示例程序的输出。
### Java 使用数据订阅功能
订阅功能也提供了 Java 开发接口,相关说明请见 [Java Connector](https://www.taosdata.com/cn/documentation/connector/)。需要注意的是,目前 Java 接口没有提供异步订阅模式,但用户程序可以通过创建 `TimerTask` 等方式达到同样的效果。
订阅功能也提供了 Java 开发接口,相关说明请见 [Java Connector](https://www.taosdata.com/cn/documentation/connector/java#subscribe)。需要注意的是,目前 Java 接口没有提供异步订阅模式,但用户程序可以通过创建 `TimerTask` 等方式达到同样的效果。
下面以一个示例程序介绍其具体使用方法。它所完成的功能与前面介绍的 C 语言示例基本相同,也是订阅数据库中所有电流超过 10A 的记录。
@ -404,7 +338,7 @@ ts: 1597466400000 current: 12.4 voltage: 220 phase: 1 location: Beijing.Chaoyang
```
## <a class="anchor" id="cache"></a>缓存(Cache)
## <a class="anchor" id="cache"></a>缓存Cache
TDengine采用时间驱动缓存管理策略First-In-First-OutFIFO又称为写驱动的缓存管理机制。这种策略有别于读驱动的数据缓存模式Least-Recent-UseLRU直接将最近写入的数据保存在系统的缓存中。当缓存达到临界值的时候将最早的数据批量写入磁盘。一般意义上来说对于物联网数据的使用用户最为关心最近产生的数据即当前状态。TDengine充分利用了这一特性将最近到达的当前状态数据保存在缓存中。
@ -423,7 +357,7 @@ select last_row(voltage) from meters where location='Beijing.Chaoyang';
该SQL语句将获取所有位于北京朝阳区的电表最后记录的电压值。
## <a class="anchor" id="alert"></a>报警监测(Alert)
## <a class="anchor" id="alert"></a>报警监测Alert
在 TDengine 的应用场景中,报警监测是一个常见需求,从概念上说,它要求程序从最近一段时间的数据中筛选出符合一定条件的数据,并基于这些数据根据定义好的公式计算出一个结果,当这个结果符合某个条件且持续一定时间后,以某种形式通知用户。

View File

@ -285,7 +285,7 @@ JDBC连接器可能报错的错误码包括3种JDBC driver本身的报错
* https://github.com/taosdata/TDengine/blob/develop/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBErrorNumbers.java
* https://github.com/taosdata/TDengine/blob/develop/src/inc/taoserror.h
### 订阅
### <a class="anchor" id="subscribe"></a>订阅
#### 创建
@ -471,9 +471,11 @@ TDengine 目前支持时间戳、数字、字符、布尔类型,与 Java 对
| BIGINT | java.lang.Long |
| FLOAT | java.lang.Float |
| DOUBLE | java.lang.Double |
| SMALLINT, TINYINT | java.lang.Short |
| SMALLINT | java.lang.Short |
| TINYINT | java.lang.Byte |
| BOOL | java.lang.Boolean |
| BINARY, NCHAR | java.lang.String |
| BINARY | byte array |
| NCHAR | java.lang.String |

View File

@ -120,17 +120,17 @@ taosd -C
不同应用场景的数据往往具有不同的数据特征比如保留天数、副本数、采集频次、记录大小、采集点的数量、压缩等都可完全不同。为获得在存储上的最高效率TDengine提供如下存储相关的系统配置参数
- days一个数据文件存储数据的时间跨度单位为天默认值10。
- keep数据库中数据保留的天数单位为天默认值3650。
- keep数据库中数据保留的天数单位为天默认值3650。(可通过 alter database 修改)
- minRows文件块中记录的最小条数单位为条默认值100。
- maxRows文件块中记录的最大条数单位为条默认值4096。
- comp文件压缩标志位0关闭1一阶段压缩2两阶段压缩。默认值2。
- comp文件压缩标志位0关闭1一阶段压缩2两阶段压缩。默认值2。(可通过 alter database 修改)
- walLevelWAL级别。1写wal但不执行fsync2写wal, 而且执行fsync。默认值1。
- fsync当wal设置为2时执行fsync的周期。设置为0表示每次写入立即执行fsync。单位为毫秒默认值3000。
- cache内存块的大小单位为兆字节MB默认值16。
- blocks每个VNODETSDB中有多少cache大小的内存块。因此一个VNODE的用的内存大小粗略为cache * blocks。单位为块默认值4。
- replica副本个数取值范围1-3。单位为个默认值1
- precision时间戳精度标识ms表示毫秒us表示微秒。默认值ms
- cacheLast是否在内存中缓存子表 last_row0关闭1开启。默认值0。从 2.0.11 版本开始支持此参数)
- blocks每个VNODETSDB中有多少cache大小的内存块。因此一个VNODE的用的内存大小粗略为cache * blocks。单位为块默认值4。(可通过 alter database 修改)
- replica副本个数取值范围1-3。单位为个默认值1。(可通过 alter database 修改)
- precision时间戳精度标识ms表示毫秒us表示微秒。默认值ms
- cacheLast是否在内存中缓存子表 last_row0关闭1开启。默认值0。可通过 alter database 修改)(从 2.0.11 版本开始支持此参数)
对于一个应用场景可能有多种数据特征的数据并存最佳的设计是将具有相同数据特征的表放在一个库里这样一个应用有多个库而每个库可以配置不同的存储参数从而保证系统有最优的性能。TDengine允许应用在创建库时指定上述存储参数如果指定该参数就将覆盖对应的系统配置参数。举例有下述SQL

View File

@ -31,19 +31,19 @@ taos> DESCRIBE meters;
使用 TDengine最重要的是时间戳。创建并插入记录、查询历史记录的时候均需要指定时间戳。时间戳有如下规则
- 时间格式为```YYYY-MM-DD HH:mm:ss.MS```, 默认时间分辨率为毫秒。比如:```2017-08-12 18:25:58.128```
- 内部函数now是服务器的当前时间
- 插入记录时,如果时间戳为now插入数据时使用服务器当前时间
- Epoch Time: 时间戳也可以是一个长整数表示从1970-01-01 08:00:00.000开始的毫秒数
- 时间可以加减,比如 now-2h表明查询时刻向前推2个小时(最近2小时)。 数字后面的时间单位可以是 a(毫秒)、s(秒)、 m(分)、h(小时)、d(天)、w(周)。 比如select * from t1 where ts > now-2w and ts <= now-1w, 表示查询两周前整整一周的数据。 在指定降频操作(down sampling)的时间窗口(interval)时,时间单位还可以使用 n(自然月) 和 y(自然年)。
- 时间格式为 ```YYYY-MM-DD HH:mm:ss.MS```默认时间分辨率为毫秒。比如:```2017-08-12 18:25:58.128```
- 内部函数 now 是客户端的当前时间
- 插入记录时,如果时间戳为 now插入数据时使用提交这条记录的客户端的当前时间
- Epoch Time:时间戳也可以是一个长整数,表示从 1970-01-01 08:00:00.000 开始的毫秒数
- 时间可以加减,比如 now-2h表明查询时刻向前推 2 个小时(最近 2 小时)。数字后面的时间单位可以是 u(微秒)、a(毫秒)、s(秒)、m(分)、h(小时)、d(天)、w(周)。 比如 `select * from t1 where ts > now-2w and ts <= now-1w`表示查询两周前整整一周的数据。在指定降频操作down sampling的时间窗口interval时,时间单位还可以使用 n(自然月) 和 y(自然年)。
TDengine缺省的时间戳是毫秒精度但通过修改配置参数enableMicrosecond就可支持微秒。
TDengine 缺省的时间戳是毫秒精度,但通过修改配置参数 enableMicrosecond 就可支持微秒。
在TDengine中普通表的数据模型中可使用以下 10 种数据类型。
| | 类型 | Bytes | 说明 |
| ---- | :-------: | ------ | ------------------------------------------------------------ |
| 1 | TIMESTAMP | 8 | 时间戳。缺省精度毫秒,可支持微秒。从格林威治时间 1970-01-01 00:00:00.000 (UTC/GMT) 开始,计时不能早于该时间。 |
| 1 | TIMESTAMP | 8 | 时间戳。缺省精度毫秒,可支持微秒。从格林威治时间 1970-01-01 00:00:00.000 (UTC/GMT) 开始,计时不能早于该时间。(从 2.0.18 版本开始,已经去除了这一时间范围限制) |
| 2 | INT | 4 | 整型,范围 [-2^31+1, 2^31-1], -2^31 用作 NULL |
| 3 | BIGINT | 8 | 长整型,范围 [-2^63+1, 2^63-1], -2^63 用于 NULL |
| 4 | FLOAT | 4 | 浮点型,有效位数 6-7范围 [-3.4E38, 3.4E38] |

View File

@ -156,3 +156,13 @@ ALTER LOCAL RESETLOG;
```
其含义是,清空本机所有由客户端生成的日志文件。
## <a class="anchor" id="timezone"></a>18. 时间戳的时区信息是怎样处理的?
TDengine 中时间戳的时区总是由客户端进行处理,而与服务端无关。具体来说,客户端会对 SQL 语句中的时间戳进行时区转换,转为 UTC 时区(即 Unix 时间戳——Unix Timestamp再交由服务端进行写入和查询在读取数据时服务端也是采用 UTC 时区提供原始数据,客户端收到后再根据本地设置,把时间戳转换为本地系统所要求的时区进行显示。
客户端在处理时间戳字符串时,会采取如下逻辑:
1. 在未做特殊设置的情况下,客户端默认使用所在操作系统的时区设置。
2. 如果在 taos.cfg 中设置了 timezone 参数,则客户端会以这个配置文件中的设置为准。
3. 如果在 C/C++/Java/Python 等各种编程语言的 Connector Driver 中,在建立数据库连接时显式指定了 timezone那么会以这个指定的时区设置为准。例如 Java Connector 的 JDBC URL 中就有 timezone 参数。
4. 在书写 SQL 语句时,也可以直接使用 Unix 时间戳(例如 `1554984068000`)或带有时区的时间戳字符串,也即以 RFC 3339 格式(例如 `2013-04-12T15:52:01.123+08:00`)或 ISO-8601 格式(例如 `2013-04-12T15:52:01.123+0800`)来书写时间戳,此时这些时间戳的取值将不再受其他时区设置的影响。

View File

@ -29,6 +29,9 @@
# number of threads per CPU core
# numOfThreadsPerCore 1.0
# number of threads to commit cache data
# numOfCommitThreads 4
# the proportion of total CPU cores available for query processing
# 2.0: the query threads will be set to double of the CPU cores.
# 1.0: all CPU cores are available for query processing [default].

View File

@ -120,7 +120,7 @@ function clean_service_on_systemd() {
if [ "$verMode" == "cluster" ]; then
nginx_service_config="${service_config_dir}/${nginx_service_name}.service"
if [ -d ${bin_dir}/web ]; then
if [ -d ${install_nginxd_dir} ]; then
if systemctl is-active --quiet ${nginx_service_name}; then
echo "Nginx for TDengine is running, stopping it..."
${csudo} systemctl stop ${nginx_service_name} &> /dev/null || echo &> /dev/null

View File

@ -451,6 +451,8 @@ void tscFreeSqlResult(SSqlObj *pSql);
* @param pObj
*/
void tscFreeSqlObj(SSqlObj *pSql);
void tscFreeSubobj(SSqlObj* pSql);
void tscFreeRegisteredSqlObj(void *pSql);
void tscCloseTscObj(void *pObj);

View File

@ -2683,7 +2683,6 @@ void tscInitMsgsFp() {
tscProcessMsgRsp[TSDB_SQL_SHOW_CREATE_TABLE] = tscProcessShowCreateRsp;
tscProcessMsgRsp[TSDB_SQL_SHOW_CREATE_DATABASE] = tscProcessShowCreateRsp;
tscKeepConn[TSDB_SQL_SHOW] = 1;
tscKeepConn[TSDB_SQL_RETRIEVE] = 1;
tscKeepConn[TSDB_SQL_SELECT] = 1;

View File

@ -299,6 +299,7 @@ static void tscProcessStreamRetrieveResult(void *param, TAOS_RES *res, int numOf
tfree(pTableMetaInfo->pTableMeta);
tscFreeSqlResult(pSql);
tscFreeSubobj(pSql);
tfree(pSql->pSubs);
pSql->subState.numOfSub = 0;
pTableMetaInfo->vgroupList = tscVgroupInfoClear(pTableMetaInfo->vgroupList);

View File

@ -447,7 +447,7 @@ void tscFreeSqlResult(SSqlObj* pSql) {
memset(&pSql->res, 0, sizeof(SSqlRes));
}
static void tscFreeSubobj(SSqlObj* pSql) {
void tscFreeSubobj(SSqlObj* pSql) {
if (pSql->subState.numOfSub == 0) {
return;
}

View File

@ -51,7 +51,7 @@ int32_t tsMaxShellConns = 50000;
int32_t tsMaxConnections = 5000;
int32_t tsShellActivityTimer = 3; // second
float tsNumOfThreadsPerCore = 1.0f;
int32_t tsNumOfCommitThreads = 1;
int32_t tsNumOfCommitThreads = 4;
float tsRatioOfQueryCores = 1.0f;
int8_t tsDaylight = 0;
char tsTimezone[TSDB_TIMEZONE_LEN] = {0};

View File

@ -8,7 +8,7 @@ IF (TD_MVN_INSTALLED)
ADD_CUSTOM_COMMAND(OUTPUT ${JDBC_CMD_NAME}
POST_BUILD
COMMAND mvn -Dmaven.test.skip=true install -f ${CMAKE_CURRENT_SOURCE_DIR}/pom.xml
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/target/taos-jdbcdriver-2.0.22-dist.jar ${LIBRARY_OUTPUT_PATH}
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/target/taos-jdbcdriver-2.0.25-dist.jar ${LIBRARY_OUTPUT_PATH}
COMMAND mvn -Dmaven.test.skip=true clean -f ${CMAKE_CURRENT_SOURCE_DIR}/pom.xml
COMMENT "build jdbc driver")
ADD_CUSTOM_TARGET(${JDBC_TARGET_NAME} ALL WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH} DEPENDS ${JDBC_CMD_NAME})

View File

@ -5,7 +5,7 @@
<groupId>com.taosdata.jdbc</groupId>
<artifactId>taos-jdbcdriver</artifactId>
<version>2.0.22</version>
<version>2.0.25</version>
<packaging>jar</packaging>
<name>JDBCDriver</name>
@ -37,17 +37,6 @@
</developers>
<dependencies>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
@ -61,21 +50,20 @@
<artifactId>httpclient</artifactId>
<version>4.5.8</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.9</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.58</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>29.0-jre</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>

View File

@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.taosdata.jdbc</groupId>
<artifactId>taos-jdbcdriver</artifactId>
<version>2.0.22</version>
<version>2.0.25</version>
<packaging>jar</packaging>
<name>JDBCDriver</name>
<url>https://github.com/taosdata/TDengine/tree/master/src/connector/jdbc</url>
@ -43,7 +43,6 @@
<version>4.13</version>
<scope>test</scope>
</dependency>
<!-- for restful -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
@ -55,10 +54,22 @@
<artifactId>fastjson</artifactId>
<version>1.2.58</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>29.0-jre</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<excludes>
<exclude>**/*.md</exclude>
</excludes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>

View File

@ -30,9 +30,12 @@ public abstract class AbstractConnection extends WrapperImpl implements Connecti
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
// do nothing
return sql;
}
@Override
public void setAutoCommit(boolean autoCommit) throws SQLException {
if (isClosed())
@ -448,7 +451,6 @@ public abstract class AbstractConnection extends WrapperImpl implements Connecti
if (isClosed)
throw (SQLClientInfoException) TSDBError.createSQLException(TSDBErrorNumbers.ERROR_SQLCLIENT_EXCEPTION_ON_CONNECTION_CLOSED);
for (Enumeration<Object> enumer = properties.keys(); enumer.hasMoreElements(); ) {
String name = (String) enumer.nextElement();
clientInfoProps.put(name, properties.getProperty(name));

View File

@ -0,0 +1,138 @@
package com.taosdata.jdbc;
import java.sql.ParameterMetaData;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.sql.Types;
public abstract class AbstractParameterMetaData extends WrapperImpl implements ParameterMetaData {
private final Object[] parameters;
public AbstractParameterMetaData(Object[] parameters) {
this.parameters = parameters;
}
@Override
public int getParameterCount() throws SQLException {
return parameters == null ? 0 : parameters.length;
}
@Override
public int isNullable(int param) throws SQLException {
return ParameterMetaData.parameterNullableUnknown;
}
@Override
public boolean isSigned(int param) throws SQLException {
if (param < 1 && param >= parameters.length)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE);
if (parameters[param - 1] instanceof Byte)
return true;
if (parameters[param - 1] instanceof Short)
return true;
if (parameters[param - 1] instanceof Integer)
return true;
if (parameters[param - 1] instanceof Long)
return true;
if (parameters[param - 1] instanceof Float)
return true;
if (parameters[param - 1] instanceof Double)
return true;
return false;
}
@Override
public int getPrecision(int param) throws SQLException {
if (param < 1 && param >= parameters.length)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE);
if (parameters[param - 1] instanceof String)
return ((String) parameters[param - 1]).length();
if (parameters[param - 1] instanceof byte[])
return ((byte[]) parameters[param - 1]).length;
return 0;
}
@Override
public int getScale(int param) throws SQLException {
if (param < 1 && param >= parameters.length)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE);
return 0;
}
@Override
public int getParameterType(int param) throws SQLException {
if (param < 1 && param >= parameters.length)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE);
if (parameters[param - 1] instanceof Timestamp)
return Types.TIMESTAMP;
if (parameters[param - 1] instanceof Byte)
return Types.TINYINT;
if (parameters[param - 1] instanceof Short)
return Types.SMALLINT;
if (parameters[param - 1] instanceof Integer)
return Types.INTEGER;
if (parameters[param - 1] instanceof Long)
return Types.BIGINT;
if (parameters[param - 1] instanceof Float)
return Types.FLOAT;
if (parameters[param - 1] instanceof Double)
return Types.DOUBLE;
if (parameters[param - 1] instanceof String)
return Types.NCHAR;
if (parameters[param - 1] instanceof byte[])
return Types.BINARY;
if (parameters[param - 1] instanceof Boolean)
return Types.BOOLEAN;
return Types.OTHER;
}
@Override
public String getParameterTypeName(int param) throws SQLException {
if (param < 1 && param >= parameters.length)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE);
if (parameters[param - 1] instanceof Timestamp)
return TSDBConstants.jdbcType2TaosTypeName(Types.TIMESTAMP);
if (parameters[param - 1] instanceof Byte)
return TSDBConstants.jdbcType2TaosTypeName(Types.TINYINT);
if (parameters[param - 1] instanceof Short)
return TSDBConstants.jdbcType2TaosTypeName(Types.SMALLINT);
if (parameters[param - 1] instanceof Integer)
return TSDBConstants.jdbcType2TaosTypeName(Types.INTEGER);
if (parameters[param - 1] instanceof Long)
return TSDBConstants.jdbcType2TaosTypeName(Types.BIGINT);
if (parameters[param - 1] instanceof Float)
return TSDBConstants.jdbcType2TaosTypeName(Types.FLOAT);
if (parameters[param - 1] instanceof Double)
return TSDBConstants.jdbcType2TaosTypeName(Types.DOUBLE);
if (parameters[param - 1] instanceof String)
return TSDBConstants.jdbcType2TaosTypeName(Types.NCHAR);
if (parameters[param - 1] instanceof byte[])
return TSDBConstants.jdbcType2TaosTypeName(Types.BINARY);
if (parameters[param - 1] instanceof Boolean)
return TSDBConstants.jdbcType2TaosTypeName(Types.BOOLEAN);
return parameters[param - 1].getClass().getName();
}
@Override
public String getParameterClassName(int param) throws SQLException {
if (param < 1 && param >= parameters.length)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE);
return parameters[param - 1].getClass().getName();
}
@Override
public int getParameterMode(int param) throws SQLException {
if (param < 1 && param >= parameters.length)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE);
return ParameterMetaData.parameterModeUnknown;
}
}

View File

@ -11,6 +11,15 @@ import java.util.Map;
public abstract class AbstractResultSet extends WrapperImpl implements ResultSet {
private int fetchSize;
protected void checkAvailability(int columnIndex, int bounds) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
if (columnIndex < 1)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE, "Column Index out of range, " + columnIndex + " < 1");
if (columnIndex > bounds)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE, "Column Index out of range, " + columnIndex + " > " + bounds);
}
@Override
public abstract boolean next() throws SQLException;
@ -46,38 +55,20 @@ public abstract class AbstractResultSet extends WrapperImpl implements ResultSet
@Override
public abstract double getDouble(int columnIndex) throws SQLException;
@Deprecated
@Override
public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
return getBigDecimal(columnIndex);
}
@Override
public byte[] getBytes(int columnIndex) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public abstract byte[] getBytes(int columnIndex) throws SQLException;
@Override
public Date getDate(int columnIndex) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public abstract Date getDate(int columnIndex) throws SQLException;
@Override
public Time getTime(int columnIndex) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public abstract Time getTime(int columnIndex) throws SQLException;
@Override
public abstract Timestamp getTimestamp(int columnIndex) throws SQLException;
@ -147,9 +138,10 @@ public abstract class AbstractResultSet extends WrapperImpl implements ResultSet
return getDouble(findColumn(columnLabel));
}
@Deprecated
@Override
public BigDecimal getBigDecimal(String columnLabel, int scale) throws SQLException {
return getBigDecimal(findColumn(columnLabel));
return getBigDecimal(findColumn(columnLabel), scale);
}
@Override
@ -214,12 +206,7 @@ public abstract class AbstractResultSet extends WrapperImpl implements ResultSet
public abstract ResultSetMetaData getMetaData() throws SQLException;
@Override
public Object getObject(int columnIndex) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public abstract Object getObject(int columnIndex) throws SQLException;
@Override
public Object getObject(String columnLabel) throws SQLException {
@ -243,12 +230,7 @@ public abstract class AbstractResultSet extends WrapperImpl implements ResultSet
}
@Override
public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public abstract BigDecimal getBigDecimal(int columnIndex) throws SQLException;
@Override
public BigDecimal getBigDecimal(String columnLabel) throws SQLException {
@ -718,9 +700,7 @@ public abstract class AbstractResultSet extends WrapperImpl implements ResultSet
@Override
public Object getObject(String columnLabel, Map<String, Class<?>> map) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
return getObject(findColumn(columnLabel), map);
}
@Override
@ -760,9 +740,7 @@ public abstract class AbstractResultSet extends WrapperImpl implements ResultSet
@Override
public Date getDate(String columnLabel, Calendar cal) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
return getDate(findColumn(columnLabel), cal);
}
@Override
@ -774,23 +752,15 @@ public abstract class AbstractResultSet extends WrapperImpl implements ResultSet
@Override
public Time getTime(String columnLabel, Calendar cal) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
return getTime(findColumn(columnLabel), cal);
}
@Override
public Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public abstract Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException;
@Override
public Timestamp getTimestamp(String columnLabel, Calendar cal) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
return getTimestamp(findColumn(columnLabel), cal);
}
@Override
@ -1198,9 +1168,7 @@ public abstract class AbstractResultSet extends WrapperImpl implements ResultSet
@Override
public <T> T getObject(String columnLabel, Class<T> type) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
return getObject(findColumn(columnLabel), type);
}
}

View File

@ -9,6 +9,8 @@ public abstract class AbstractStatement extends WrapperImpl implements Statement
protected List<String> batchedArgs;
private int fetchSize;
@Override
public abstract ResultSet executeQuery(String sql) throws SQLException;

View File

@ -1,452 +0,0 @@
package com.taosdata.jdbc;
import com.taosdata.jdbc.bean.TSDBPreparedParam;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* this class is used to precompile the sql of tdengine insert or import ops
*/
public class SavedPreparedStatement {
private TSDBPreparedStatement tsdbPreparedStatement;
/**
* sql param List
*/
private List<TSDBPreparedParam> sqlParamList;
/**
* init param according the sql
*/
private TSDBPreparedParam initPreparedParam;
/**
* is table name dynamic in the prepared sql
*/
private boolean isTableNameDynamic;
/**
* insert or import sql template pattern, the template are the following:
* <p>
* insert/import into tableName [(field1, field2, ...)] [using stables tags(?, ?, ...) ] values(?, ?, ...) (?, ?, ...)
* <p>
* we split it to three part:
* 1. prefix, insert/import
* 2. middle, tableName [(field1, field2, ...)] [using stables tags(?, ?, ...) ]
* 3. valueList, the content after values, for example (?, ?, ...) (?, ?, ...)
*/
private Pattern sqlPattern = Pattern.compile("(?s)(?i)^\\s*(INSERT|IMPORT)\\s+INTO\\s+((?<tablename>\\S+)\\s*(\\(.*\\))?\\s+(USING\\s+(?<stableName>\\S+)\\s+TAGS\\s*\\((?<tagValue>.+)\\))?)\\s*VALUES\\s*(?<valueList>\\(.*\\)).*");
/**
* the raw sql template
*/
private String sql;
/**
* the prefix part of sql
*/
private String prefix;
/**
* the middle part of sql
*/
private String middle;
private int middleParamSize;
/**
* the valueList part of sql
*/
private String valueList;
private int valueListSize;
/**
* default param value
*/
private static final String DEFAULT_VALUE = "NULL";
private static final String PLACEHOLDER = "?";
private String tableName;
/**
* is the parameter add to batch list
*/
private boolean isAddBatch;
public SavedPreparedStatement(String sql, TSDBPreparedStatement tsdbPreparedStatement) throws SQLException {
this.sql = sql;
this.tsdbPreparedStatement = tsdbPreparedStatement;
this.sqlParamList = new ArrayList<>();
parsePreparedParam(this.sql);
}
/**
* parse the init param according the sql param
*
* @param sql
*/
private void parsePreparedParam(String sql) throws SQLException {
Matcher matcher = sqlPattern.matcher(sql);
if (matcher.find()) {
tableName = matcher.group("tablename");
if (tableName != null && PLACEHOLDER.equals(tableName)) {
// the table name is dynamic
this.isTableNameDynamic = true;
}
prefix = matcher.group(1);
middle = matcher.group(2);
valueList = matcher.group("valueList");
if (middle != null && !"".equals(middle)) {
middleParamSize = parsePlaceholder(middle);
}
if (valueList != null && !"".equals(valueList)) {
valueListSize = parsePlaceholder(valueList);
}
initPreparedParam = initDefaultParam(tableName, middleParamSize, valueListSize);
} else {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_SQL);
}
}
private TSDBPreparedParam initDefaultParam(String tableName, int middleParamSize, int valueListSize) {
TSDBPreparedParam tsdbPreparedParam = new TSDBPreparedParam(tableName);
tsdbPreparedParam.setMiddleParamList(getDefaultParamList(middleParamSize));
tsdbPreparedParam.setValueList(getDefaultParamList(valueListSize));
return tsdbPreparedParam;
}
/**
* generate the default param value list
*
* @param paramSize
* @return
*/
private List<Object> getDefaultParamList(int paramSize) {
List<Object> paramList = new ArrayList<>(paramSize);
if (paramSize > 0) {
for (int i = 0; i < paramSize; i++) {
paramList.add(i, DEFAULT_VALUE);
}
}
return paramList;
}
/**
* calculate the placeholder num
*
* @param value
* @return
*/
private int parsePlaceholder(String value) {
Pattern pattern = Pattern.compile("[?]");
Matcher matcher = pattern.matcher(value);
int result = 0;
while (matcher.find()) {
result++;
}
return result;
}
/**
* set current row params
*
* @param parameterIndex the first parameter is 1, the second is 2, ...
* @param x the parameter value
*/
public void setParam(int parameterIndex, Object x) throws SQLException {
int paramSize = this.middleParamSize + this.valueListSize;
String errorMsg = String.format("the parameterIndex %s out of the range [1, %s]", parameterIndex, paramSize);
if (parameterIndex < 1 || parameterIndex > paramSize) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE,errorMsg);
}
this.isAddBatch = false; //set isAddBatch to false
if (x == null) {
x = DEFAULT_VALUE; // set default null string
}
parameterIndex = parameterIndex - 1; // start from 0 in param list
if (this.middleParamSize > 0 && parameterIndex >= 0 && parameterIndex < this.middleParamSize) {
this.initPreparedParam.setMiddleParam(parameterIndex, x);
return;
}
if (this.valueListSize > 0 && parameterIndex >= this.middleParamSize && parameterIndex < paramSize) {
this.initPreparedParam.setValueParam(parameterIndex - this.middleParamSize, x);
return;
}
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE,errorMsg);
}
public void addBatch() {
addCurrentRowParamToList();
this.initPreparedParam = initDefaultParam(tableName, middleParamSize, valueListSize);
}
/**
* add current param to batch list
*/
private void addCurrentRowParamToList() {
if (initPreparedParam != null && (this.middleParamSize > 0 || this.valueListSize > 0)) {
this.sqlParamList.add(initPreparedParam); // add current param to batch list
}
this.isAddBatch = true;
}
/**
* execute the sql with batch sql
*
* @return
* @throws SQLException
*/
public int[] executeBatch() throws SQLException {
int result = executeBatchInternal();
return new int[]{result};
}
public int executeBatchInternal() throws SQLException {
if (!isAddBatch) {
addCurrentRowParamToList(); // add current param to batch list
}
//1. generate batch sql
String sql = generateExecuteSql();
//2. execute batch sql
int result = executeSql(sql);
//3. clear batch param list
this.sqlParamList.clear();
return result;
}
/**
* generate the batch sql
*
* @return
*/
private String generateExecuteSql() {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(prefix);
stringBuilder.append(" into ");
if (!isTableNameDynamic) {
// tablename will not need to be replaced
String middleValue = replaceMiddleListParam(middle, sqlParamList);
stringBuilder.append(middleValue);
stringBuilder.append(" values");
stringBuilder.append(replaceValueListParam(valueList, sqlParamList));
} else {
// need to replace tablename
if (sqlParamList.size() > 0) {
TSDBPreparedParam firstPreparedParam = sqlParamList.get(0);
//replace middle part and value part of first row
String firstRow = replaceMiddleAndValuePart(firstPreparedParam);
stringBuilder.append(firstRow);
//the first param in the middleParamList is the tableName
String lastTableName = firstPreparedParam.getMiddleParamList().get(0).toString();
if (sqlParamList.size() > 1) {
for (int i = 1; i < sqlParamList.size(); i++) {
TSDBPreparedParam currentParam = sqlParamList.get(i);
String currentTableName = currentParam.getMiddleParamList().get(0).toString();
if (lastTableName.equalsIgnoreCase(currentTableName)) {
// tablename is same with the last row ,so only need to append the part of value
String values = replaceTemplateParam(valueList, currentParam.getValueList());
stringBuilder.append(values);
} else {
// tablename difference with the last row
//need to replace middle part and value part
String row = replaceMiddleAndValuePart(currentParam);
stringBuilder.append(row);
lastTableName = currentTableName;
}
}
}
} else {
stringBuilder.append(middle);
stringBuilder.append(" values");
stringBuilder.append(valueList);
}
}
return stringBuilder.toString();
}
/**
* replace the middle and value part
*
* @param tsdbPreparedParam
* @return
*/
private String replaceMiddleAndValuePart(TSDBPreparedParam tsdbPreparedParam) {
StringBuilder stringBuilder = new StringBuilder(" ");
String middlePart = replaceTemplateParam(middle, tsdbPreparedParam.getMiddleParamList());
stringBuilder.append(middlePart);
stringBuilder.append(" values ");
String valuePart = replaceTemplateParam(valueList, tsdbPreparedParam.getValueList());
stringBuilder.append(valuePart);
stringBuilder.append(" ");
return stringBuilder.toString();
}
/**
* replace the placeholder of the middle part of sql template with TSDBPreparedParam list
*
* @param template
* @param sqlParamList
* @return
*/
private String replaceMiddleListParam(String template, List<TSDBPreparedParam> sqlParamList) {
if (sqlParamList.size() > 0) {
//becase once the subTableName is static then will be ignore the tag which after the first setTag
return replaceTemplateParam(template, sqlParamList.get(0).getMiddleParamList());
}
return template;
}
/**
* replace the placeholder of the template with TSDBPreparedParam list
*
* @param template
* @param sqlParamList
* @return
*/
private String replaceValueListParam(String template, List<TSDBPreparedParam> sqlParamList) {
StringBuilder stringBuilder = new StringBuilder();
if (sqlParamList.size() > 0) {
for (TSDBPreparedParam tsdbPreparedParam : sqlParamList) {
String tmp = replaceTemplateParam(template, tsdbPreparedParam.getValueList());
stringBuilder.append(tmp);
}
} else {
stringBuilder.append(template);
}
return stringBuilder.toString();
}
/**
* replace the placeholder of the template with paramList
*
* @param template
* @param paramList
* @return
*/
private String replaceTemplateParam(String template, List<Object> paramList) {
if (paramList.size() > 0) {
String tmp = template;
for (int i = 0; i < paramList.size(); ++i) {
String paraStr = getParamString(paramList.get(i));
tmp = tmp.replaceFirst("[" + PLACEHOLDER + "]", paraStr);
}
return tmp;
} else {
return template;
}
}
/**
* get the string of param object
*
* @param paramObj
* @return
*/
private String getParamString(Object paramObj) {
String paraStr = paramObj.toString();
if (paramObj instanceof Timestamp || (paramObj instanceof String && !DEFAULT_VALUE.equalsIgnoreCase(paraStr))) {
paraStr = "'" + paraStr + "'";
}
return paraStr;
}
private int executeSql(String sql) throws SQLException {
return tsdbPreparedStatement.executeUpdate(sql);
}
}

View File

@ -27,10 +27,6 @@ public class TSDBConnection extends AbstractConnection {
return this.batchFetch;
}
public void setBatchFetch(Boolean batchFetch) {
this.batchFetch = batchFetch;
}
public TSDBConnection(Properties info, TSDBDatabaseMetaData meta) throws SQLException {
this.databaseMetaData = meta;
connect(info.getProperty(TSDBDriver.PROPERTY_KEY_HOST),
@ -61,9 +57,7 @@ public class TSDBConnection extends AbstractConnection {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
TSDBStatement statement = new TSDBStatement(this, this.connector);
statement.setConnection(this);
return statement;
return new TSDBStatement(this, this.connector);
}
public TSDBSubscribe subscribe(String topic, String sql, boolean restart) throws SQLException {
@ -79,10 +73,8 @@ public class TSDBConnection extends AbstractConnection {
}
public PreparedStatement prepareStatement(String sql) throws SQLException {
if (isClosed()) {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
return new TSDBPreparedStatement(this, this.connector, sql);
}
@ -104,11 +96,4 @@ public class TSDBConnection extends AbstractConnection {
return this.databaseMetaData;
}
public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
}
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
}

View File

@ -29,45 +29,25 @@ public class TSDBJNIConnector {
private static volatile Boolean isInitialized = false;
private TaosInfo taosInfo = TaosInfo.getInstance();
// Connection pointer used in C
private long taos = TSDBConstants.JNI_NULL_POINTER;
// result set status in current connection
private boolean isResultsetClosed = true;
private int affectedRows = -1;
static {
System.loadLibrary("taos");
System.out.println("java.library.path:" + System.getProperty("java.library.path"));
}
/**
* Connection pointer used in C
*/
private long taos = TSDBConstants.JNI_NULL_POINTER;
/**
* Result set pointer for the current connection
*/
// private long taosResultSetPointer = TSDBConstants.JNI_NULL_POINTER;
/**
* result set status in current connection
*/
private boolean isResultsetClosed = true;
private int affectedRows = -1;
/**
* Whether the connection is closed
*/
public boolean isClosed() {
return this.taos == TSDBConstants.JNI_NULL_POINTER;
}
/**
* Returns the status of last result set in current connection
*/
public boolean isResultsetClosed() {
return this.isResultsetClosed;
}
/**
* Initialize static variables in JNI to optimize performance
*/
public static void init(String configDir, String locale, String charset, String timezone) throws SQLWarning {
synchronized (isInitialized) {
if (!isInitialized) {
@ -93,11 +73,6 @@ public class TSDBJNIConnector {
public static native String getTsCharset();
/**
* Get connection pointer
*
* @throws SQLException
*/
public boolean connect(String host, int port, String dbName, String user, String password) throws SQLException {
if (this.taos != TSDBConstants.JNI_NULL_POINTER) {
// this.closeConnectionImp(this.taos);
@ -185,13 +160,6 @@ public class TSDBJNIConnector {
private native String getErrMsgImp(long pSql);
/**
* Get resultset pointer
* Each connection should have a single open result set at a time
*/
// public long getResultSet() {
// return taosResultSetPointer;
// }
private native long getResultSetImp(long connection, long pSql);
public boolean isUpdateQuery(long pSql) {
@ -231,6 +199,7 @@ public class TSDBJNIConnector {
// }
// return resCode;
// }
private native int freeResultSetImp(long connection, long result);
/**
@ -323,8 +292,7 @@ public class TSDBJNIConnector {
* Validate if a <I>create table</I> sql statement is correct without actually creating that table
*/
public boolean validateCreateTableSql(String sql) {
long connection = taos;
int res = validateCreateTableSqlImp(connection, sql.getBytes());
int res = validateCreateTableSqlImp(taos, sql.getBytes());
return res != 0 ? false : true;
}

View File

@ -0,0 +1,8 @@
package com.taosdata.jdbc;
public class TSDBParameterMetaData extends AbstractParameterMetaData {
public TSDBParameterMetaData(Object[] parameters) {
super(parameters);
}
}

View File

@ -18,6 +18,7 @@ import java.io.InputStream;
import java.io.Reader;
import java.math.BigDecimal;
import java.net.URL;
import java.nio.charset.Charset;
import java.sql.*;
import java.util.ArrayList;
import java.util.Calendar;
@ -30,36 +31,49 @@ import java.util.regex.Pattern;
* compatibility needs.
*/
public class TSDBPreparedStatement extends TSDBStatement implements PreparedStatement {
protected String rawSql;
protected String sql;
protected ArrayList<Object> parameters = new ArrayList<>();
private String rawSql;
private String sql;
// private ArrayList<Object> parameters = new ArrayList<>();
private Object[] parameters;
private boolean isPrepared;
//start with insert or import and is case-insensitive
private static Pattern savePattern = Pattern.compile("(?i)^\\s*(insert|import)");
// is insert or import
private boolean isSaved;
private SavedPreparedStatement savedPreparedStatement;
private ParameterMetaData parameterMetaData;
// private SavedPreparedStatement savedPreparedStatement;
private volatile TSDBParameterMetaData parameterMetaData;
TSDBPreparedStatement(TSDBConnection connection, TSDBJNIConnector connecter, String sql) {
super(connection, connecter);
init(sql);
if (sql.contains("?")) {
int parameterCnt = 0;
for (int i = 0; i < sql.length(); i++) {
if ('?' == sql.charAt(i)) {
parameterCnt++;
}
}
parameters = new Object[parameterCnt];
this.isPrepared = true;
}
}
private void init(String sql) {
this.rawSql = sql;
preprocessSql();
// this.isSaved = isSavedSql(this.rawSql);
// if (this.isSaved) {
// try {
// this.savedPreparedStatement = new SavedPreparedStatement(this.rawSql, this);
// } catch (SQLException e) {
// e.printStackTrace();
// }
// }
this.isSaved = isSavedSql(this.rawSql);
if (this.isSaved) {
try {
this.savedPreparedStatement = new SavedPreparedStatement(this.rawSql, this);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
/**
@ -75,19 +89,11 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
@Override
public int[] executeBatch() throws SQLException {
if (isSaved) {
return this.savedPreparedStatement.executeBatch();
} else {
// if (isSaved) {
// return this.savedPreparedStatement.executeBatch();
// } else {
return super.executeBatch();
}
}
public ArrayList<Object> getParameters() {
return parameters;
}
public void setParameters(ArrayList<Object> parameters) {
this.parameters = parameters;
// }
}
/*
@ -151,41 +157,73 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
*
* @return a string of the native sql statement for TSDB
*/
private String getNativeSql() {
this.sql = this.rawSql;
for (int i = 0; i < parameters.size(); ++i) {
Object para = parameters.get(i);
// private String getNativeSql(String rawSql) {
// for (int i = 0; i < parameters.length; i++) {
// Object para = parameters[i];
// if (para != null) {
// String paraStr = para.toString();
// if (para instanceof Timestamp || para instanceof String) {
// paraStr = "'" + paraStr + "'";
// }
// this.sql = this.sql.replaceFirst("[?]", paraStr);
// } else {
// this.sql = this.sql.replaceFirst("[?]", "NULL");
// }
// }
// parameters = new Object[parameters.length];
// return sql;
// }
private String getNativeSql(String rawSql) throws SQLException {
String sql = rawSql;
for (int i = 0; i < parameters.length; ++i) {
Object para = parameters[i];
if (para != null) {
String paraStr = para.toString();
if (para instanceof Timestamp || para instanceof String) {
String paraStr;
if (para instanceof byte[]) {
paraStr = new String((byte[]) para, Charset.forName("UTF-8"));
} else {
paraStr = para.toString();
}
// if para is timestamp or String or byte[] need to translate ' character
if (para instanceof Timestamp || para instanceof String || para instanceof byte[]) {
paraStr = paraStr.replaceAll("'", "\\\\\\\\'");
paraStr = "'" + paraStr + "'";
}
this.sql = this.sql.replaceFirst("[?]", paraStr);
sql = sql.replaceFirst("[?]", paraStr);
} else {
this.sql = this.sql.replaceFirst("[?]", "NULL");
sql = sql.replaceFirst("[?]", "NULL");
}
}
parameters.clear();
clearParameters();
return sql;
}
@Override
public ResultSet executeQuery() throws SQLException {
if (isSaved) {
this.savedPreparedStatement.executeBatchInternal();
return null;
} else {
return super.executeQuery(getNativeSql());
}
// if (isSaved) {
// this.savedPreparedStatement.executeBatchInternal();
// return null;
// } else {
if (!isPrepared)
return executeQuery(this.rawSql);
final String sql = getNativeSql(this.rawSql);
return executeQuery(sql);
// }
}
@Override
public int executeUpdate() throws SQLException {
if (isSaved) {
return this.savedPreparedStatement.executeBatchInternal();
} else {
return super.executeUpdate(getNativeSql());
}
// if (isSaved) {
// return this.savedPreparedStatement.executeBatchInternal();
// } else {
if (!isPrepared)
return executeUpdate(this.rawSql);
String sql = getNativeSql(this.rawSql);
return executeUpdate(sql);
// }
}
private boolean isSupportedSQLType(int sqlType) {
@ -201,35 +239,6 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
case Types.BINARY:
case Types.NCHAR:
return true;
case Types.ARRAY:
case Types.BIT:
case Types.BLOB:
case Types.CHAR:
case Types.CLOB:
case Types.DATALINK:
case Types.DATE:
case Types.DECIMAL:
case Types.DISTINCT:
case Types.JAVA_OBJECT:
case Types.LONGNVARCHAR:
case Types.LONGVARBINARY:
case Types.LONGVARCHAR:
case Types.NCLOB:
case Types.NULL:
case Types.NUMERIC:
case Types.NVARCHAR:
case Types.OTHER:
case Types.REAL:
case Types.REF:
case Types.REF_CURSOR:
case Types.ROWID:
case Types.SQLXML:
case Types.STRUCT:
case Types.TIME:
case Types.TIME_WITH_TIMEZONE:
case Types.TIMESTAMP_WITH_TIMEZONE:
case Types.VARBINARY:
case Types.VARCHAR:
default:
return false;
}
@ -259,7 +268,7 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
public void setByte(int parameterIndex, byte x) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
setObject(parameterIndex,x);
}
@Override
@ -315,7 +324,8 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
public void setBytes(int parameterIndex, byte[] x) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
setObject(parameterIndex,x);
}
@Override
@ -365,45 +375,63 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
public void clearParameters() throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
parameters.clear();
// parameters.clear();
parameters = new Object[parameters.length];
}
@Override
public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override
public void setObject(int parameterIndex, Object x) throws SQLException {
if (isSaved) {
this.savedPreparedStatement.setParam(parameterIndex, x);
} else {
parameters.add(x);
}
// if (isSaved) {
// this.savedPreparedStatement.setParam(parameterIndex, x);
// } else {
if (parameterIndex < 1 && parameterIndex >= parameters.length)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE);
parameters[parameterIndex - 1] = x;
// parameters.add(x);
// }
}
@Override
public boolean execute() throws SQLException {
if (isSaved) {
int result = this.savedPreparedStatement.executeBatchInternal();
return result > 0;
} else {
return super.execute(getNativeSql());
}
// if (isSaved) {
// int result = this.savedPreparedStatement.executeBatchInternal();
// return result > 0;
// } else {
if (!isPrepared)
return execute(this.rawSql);
final String sql = getNativeSql(this.rawSql);
return execute(sql);
// }
}
@Override
public void addBatch() throws SQLException {
if (isSaved) {
this.savedPreparedStatement.addBatch();
} else {
// if (isSaved) {
// this.savedPreparedStatement.addBatch();
// } else {
if (this.batchedArgs == null) {
batchedArgs = new ArrayList<>();
}
super.addBatch(getNativeSql());
if (!isPrepared) {
addBatch(this.rawSql);
} else {
String sql = this.getConnection().nativeSQL(this.rawSql);
addBatch(sql);
}
// }
}
@Override
@ -491,9 +519,11 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
public ParameterMetaData getParameterMetaData() throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
//TODO: parameterMetaData not supported
// return null;
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
if (parameterMetaData == null) {
this.parameterMetaData = new TSDBParameterMetaData(parameters);
}
return this.parameterMetaData;
}
@Override

View File

@ -14,9 +14,14 @@
*****************************************************************************/
package com.taosdata.jdbc;
import com.google.common.primitives.Ints;
import com.google.common.primitives.Longs;
import com.google.common.primitives.Shorts;
import java.math.BigDecimal;
import java.sql.*;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
public class TSDBResultSet extends AbstractResultSet implements ResultSet {
@ -120,158 +125,189 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
}
public String getString(int columnIndex) throws SQLException {
checkAvailability(columnIndex, this.columnMetaDataList.size());
String res = null;
int colIndex = getTrueColumnIndex(columnIndex);
if (this.getBatchFetch())
return this.blockData.getString(colIndex);
return this.blockData.getString(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(colIndex);
this.lastWasNull = this.rowData.wasNull(columnIndex - 1);
if (!lastWasNull) {
res = this.rowData.getString(colIndex, this.columnMetaDataList.get(colIndex).getColType());
res = this.rowData.getString(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType());
}
return res;
}
public boolean getBoolean(int columnIndex) throws SQLException {
checkAvailability(columnIndex, this.columnMetaDataList.size());
boolean res = false;
int colIndex = getTrueColumnIndex(columnIndex);
if (this.getBatchFetch())
return this.blockData.getBoolean(colIndex);
return this.blockData.getBoolean(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(colIndex);
this.lastWasNull = this.rowData.wasNull(columnIndex - 1);
if (!lastWasNull) {
res = this.rowData.getBoolean(colIndex, this.columnMetaDataList.get(colIndex).getColType());
res = this.rowData.getBoolean(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType());
}
return res;
}
public byte getByte(int columnIndex) throws SQLException {
checkAvailability(columnIndex, this.columnMetaDataList.size());
byte res = 0;
int colIndex = getTrueColumnIndex(columnIndex);
if (this.getBatchFetch())
return (byte) this.blockData.getInt(colIndex);
return (byte) this.blockData.getInt(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(colIndex);
this.lastWasNull = this.rowData.wasNull(columnIndex - 1);
if (!lastWasNull) {
res = (byte) this.rowData.getInt(colIndex, this.columnMetaDataList.get(colIndex).getColType());
res = (byte) this.rowData.getInt(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType());
}
return res;
}
public short getShort(int columnIndex) throws SQLException {
checkAvailability(columnIndex, this.columnMetaDataList.size());
short res = 0;
int colIndex = getTrueColumnIndex(columnIndex);
if (this.getBatchFetch())
return (short) this.blockData.getInt(colIndex);
return (short) this.blockData.getInt(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(colIndex);
this.lastWasNull = this.rowData.wasNull(columnIndex - 1);
if (!lastWasNull) {
res = (short) this.rowData.getInt(colIndex, this.columnMetaDataList.get(colIndex).getColType());
res = (short) this.rowData.getInt(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType());
}
return res;
}
public int getInt(int columnIndex) throws SQLException {
checkAvailability(columnIndex, this.columnMetaDataList.size());
int res = 0;
int colIndex = getTrueColumnIndex(columnIndex);
if (this.getBatchFetch())
return this.blockData.getInt(colIndex);
return this.blockData.getInt(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(colIndex);
this.lastWasNull = this.rowData.wasNull(columnIndex - 1);
if (!lastWasNull) {
res = this.rowData.getInt(colIndex, this.columnMetaDataList.get(colIndex).getColType());
res = this.rowData.getInt(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType());
}
return res;
}
public long getLong(int columnIndex) throws SQLException {
checkAvailability(columnIndex, this.columnMetaDataList.size());
long res = 0L;
int colIndex = getTrueColumnIndex(columnIndex);
if (this.getBatchFetch())
return this.blockData.getLong(colIndex);
return this.blockData.getLong(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(colIndex);
this.lastWasNull = this.rowData.wasNull(columnIndex - 1);
if (!lastWasNull) {
res = this.rowData.getLong(colIndex, this.columnMetaDataList.get(colIndex).getColType());
res = this.rowData.getLong(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType());
}
return res;
}
public float getFloat(int columnIndex) throws SQLException {
checkAvailability(columnIndex, this.columnMetaDataList.size());
float res = 0;
int colIndex = getTrueColumnIndex(columnIndex);
if (this.getBatchFetch())
return (float) this.blockData.getDouble(colIndex);
return (float) this.blockData.getDouble(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(colIndex);
this.lastWasNull = this.rowData.wasNull(columnIndex - 1);
if (!lastWasNull)
res = this.rowData.getFloat(colIndex, this.columnMetaDataList.get(colIndex).getColType());
res = this.rowData.getFloat(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType());
return res;
}
public double getDouble(int columnIndex) throws SQLException {
checkAvailability(columnIndex, this.columnMetaDataList.size());
double res = 0;
int colIndex = getTrueColumnIndex(columnIndex);
if (this.getBatchFetch())
return this.blockData.getDouble(colIndex);
return this.blockData.getDouble(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(colIndex);
this.lastWasNull = this.rowData.wasNull(columnIndex - 1);
if (!lastWasNull) {
res = this.rowData.getDouble(colIndex, this.columnMetaDataList.get(colIndex).getColType());
res = this.rowData.getDouble(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType());
}
return res;
}
@Deprecated
public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException {
return new BigDecimal(getLong(columnIndex));
public byte[] getBytes(int columnIndex) throws SQLException {
checkAvailability(columnIndex, this.columnMetaDataList.size());
Object value = this.rowData.get(columnIndex - 1);
if (value == null)
return null;
int colType = this.columnMetaDataList.get(columnIndex - 1).getColType();
switch (colType) {
case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
return Longs.toByteArray((Long) value);
case TSDBConstants.TSDB_DATA_TYPE_INT:
return Ints.toByteArray((int) value);
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT:
return Shorts.toByteArray((Short) value);
case TSDBConstants.TSDB_DATA_TYPE_TINYINT:
return new byte[]{(byte) value};
}
return value.toString().getBytes();
}
public byte[] getBytes(int columnIndex) throws SQLException {
return getString(columnIndex).getBytes();
@Override
public Date getDate(int columnIndex) throws SQLException {
Timestamp timestamp = getTimestamp(columnIndex);
return timestamp == null ? null : new Date(timestamp.getTime());
}
@Override
public Time getTime(int columnIndex) throws SQLException {
Timestamp timestamp = getTimestamp(columnIndex);
return timestamp == null ? null : new Time(timestamp.getTime());
}
public Timestamp getTimestamp(int columnIndex) throws SQLException {
checkAvailability(columnIndex, this.columnMetaDataList.size());
Timestamp res = null;
int colIndex = getTrueColumnIndex(columnIndex);
if (this.getBatchFetch())
return this.blockData.getTimestamp(columnIndex);
return this.blockData.getTimestamp(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(colIndex);
this.lastWasNull = this.rowData.wasNull(columnIndex - 1);
if (!lastWasNull) {
res = this.rowData.getTimestamp(colIndex);
res = this.rowData.getTimestamp(columnIndex - 1);
}
return res;
}
public ResultSetMetaData getMetaData() throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
return new TSDBResultSetMetaData(this.columnMetaDataList);
}
@Override
public Object getObject(int columnIndex) throws SQLException {
int colIndex = getTrueColumnIndex(columnIndex);
checkAvailability(columnIndex, this.columnMetaDataList.size());
Object res = null;
if (this.getBatchFetch())
return this.blockData.get(colIndex);
return this.blockData.get(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(colIndex);
return this.rowData.get(colIndex);
this.lastWasNull = this.rowData.wasNull(columnIndex - 1);
if (!lastWasNull) {
int colType = this.columnMetaDataList.get(columnIndex - 1).getColType();
if (colType == TSDBConstants.TSDB_DATA_TYPE_BINARY)
res = ((String) this.rowData.get(columnIndex - 1)).getBytes();
else
res = this.rowData.get(columnIndex - 1);
}
@Override
public Object getObject(String columnLabel) throws SQLException {
return this.getObject(this.findColumn(columnLabel));
return res;
}
public int findColumn(String columnLabel) throws SQLException {
@ -285,15 +321,32 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
@Override
public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
int colIndex = getTrueColumnIndex(columnIndex);
if (this.getBatchFetch())
return new BigDecimal(this.blockData.getLong(columnIndex - 1));
if (!this.getBatchFetch()) {
this.lastWasNull = this.rowData.wasNull(colIndex);
return new BigDecimal(this.rowData.getLong(colIndex, this.columnMetaDataList.get(colIndex).getColType()));
} else {
return new BigDecimal(this.blockData.getLong(colIndex));
this.lastWasNull = this.rowData.wasNull(columnIndex - 1);
BigDecimal res = null;
if (!lastWasNull) {
int colType = this.columnMetaDataList.get(columnIndex - 1).getColType();
switch (colType) {
case TSDBConstants.TSDB_DATA_TYPE_TINYINT:
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT:
case TSDBConstants.TSDB_DATA_TYPE_INT:
case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
res = new BigDecimal(Long.valueOf(this.rowData.get(columnIndex - 1).toString()));
break;
case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE:
res = new BigDecimal(Double.valueOf(this.rowData.get(columnIndex - 1).toString()));
break;
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
return new BigDecimal(((Timestamp) this.rowData.get(columnIndex - 1)).getTime());
default:
res = new BigDecimal(this.rowData.get(columnIndex - 1).toString());
}
}
return res;
}
@Override
public boolean isBeforeFirst() throws SQLException {
@ -398,6 +451,12 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
return this.statement;
}
@Override
public Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException {
//TODOdid not use the specified timezone in cal
return getTimestamp(columnIndex);
}
public boolean isClosed() throws SQLException {
if (isClosed)
return true;
@ -408,17 +467,7 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
}
public String getNString(int columnIndex) throws SQLException {
int colIndex = getTrueColumnIndex(columnIndex);
return (String) rowData.get(colIndex);
return getString(columnIndex);
}
private int getTrueColumnIndex(int columnIndex) throws SQLException {
if (columnIndex < 1)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE, "columnIndex(" + columnIndex + "): < 1");
int numOfCols = this.columnMetaDataList.size();
if (columnIndex > numOfCols)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE, "columnIndex: " + columnIndex);
return columnIndex - 1;
}
}

View File

@ -22,7 +22,7 @@ import java.util.List;
public class TSDBResultSetMetaData extends WrapperImpl implements ResultSetMetaData {
List<ColumnMetaData> colMetaDataList = null;
List<ColumnMetaData> colMetaDataList;
public TSDBResultSetMetaData(List<ColumnMetaData> metaDataList) {
this.colMetaDataList = metaDataList;
@ -52,6 +52,9 @@ public class TSDBResultSetMetaData extends WrapperImpl implements ResultSetMetaD
}
public int isNullable(int column) throws SQLException {
if (column < 1 && column >= colMetaDataList.size())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE);
if (column == 1) {
return columnNoNulls;
}
@ -59,6 +62,9 @@ public class TSDBResultSetMetaData extends WrapperImpl implements ResultSetMetaD
}
public boolean isSigned(int column) throws SQLException {
if (column < 1 && column >= colMetaDataList.size())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE);
ColumnMetaData meta = this.colMetaDataList.get(column - 1);
switch (meta.getColType()) {
case TSDBConstants.TSDB_DATA_TYPE_TINYINT:
@ -74,22 +80,37 @@ public class TSDBResultSetMetaData extends WrapperImpl implements ResultSetMetaD
}
public int getColumnDisplaySize(int column) throws SQLException {
if (column < 1 && column >= colMetaDataList.size())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE);
return colMetaDataList.get(column - 1).getColSize();
}
public String getColumnLabel(int column) throws SQLException {
if (column < 1 && column >= colMetaDataList.size())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE);
return colMetaDataList.get(column - 1).getColName();
}
public String getColumnName(int column) throws SQLException {
if (column < 1 && column >= colMetaDataList.size())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE);
return colMetaDataList.get(column - 1).getColName();
}
public String getSchemaName(int column) throws SQLException {
if (column < 1 && column >= colMetaDataList.size())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
public int getPrecision(int column) throws SQLException {
if (column < 1 && column >= colMetaDataList.size())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE);
ColumnMetaData columnMetaData = this.colMetaDataList.get(column - 1);
switch (columnMetaData.getColType()) {
case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
@ -105,6 +126,9 @@ public class TSDBResultSetMetaData extends WrapperImpl implements ResultSetMetaD
}
public int getScale(int column) throws SQLException {
if (column < 1 && column >= colMetaDataList.size())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE);
ColumnMetaData meta = this.colMetaDataList.get(column - 1);
switch (meta.getColType()) {
case TSDBConstants.TSDB_DATA_TYPE_FLOAT:

View File

@ -21,18 +21,13 @@ import java.util.ArrayList;
import java.util.Collections;
public class TSDBResultSetRowData {
private ArrayList<Object> data = null;
private ArrayList<Object> data;
private int colSize = 0;
public TSDBResultSetRowData(int colSize) {
this.setColSize(colSize);
}
public TSDBResultSetRowData() {
this.data = new ArrayList<>();
this.setColSize(0);
}
public void clear() {
if (this.data != null) {
this.data.clear();
@ -71,9 +66,9 @@ public class TSDBResultSetRowData {
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
return ((Long) obj) == 1L ? Boolean.TRUE : Boolean.FALSE;
default:
return false;
}
return Boolean.TRUE;
}
public void setByte(int col, byte value) {
@ -198,7 +193,7 @@ public class TSDBResultSetRowData {
data.set(col, value);
}
public float getFloat(int col, int srcType) throws SQLException {
public float getFloat(int col, int srcType) {
Object obj = data.get(col);
switch (srcType) {
@ -226,7 +221,7 @@ public class TSDBResultSetRowData {
data.set(col, value);
}
public double getDouble(int col, int srcType) throws SQLException {
public double getDouble(int col, int srcType) {
Object obj = data.get(col);
switch (srcType) {
@ -267,9 +262,8 @@ public class TSDBResultSetRowData {
*
* @param col column index
* @return
* @throws SQLException
*/
public String getString(int col, int srcType) throws SQLException {
public String getString(int col, int srcType) {
switch (srcType) {
case TSDBConstants.TSDB_DATA_TYPE_BINARY:
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
@ -305,11 +299,11 @@ public class TSDBResultSetRowData {
}
public void setTimestamp(int col, long ts) {
data.set(col, ts);
data.set(col, new Timestamp(ts));
}
public Timestamp getTimestamp(int col) {
return new Timestamp((Long) data.get(col));
return (Timestamp) data.get(col);
}
public Object get(int col) {
@ -320,7 +314,7 @@ public class TSDBResultSetRowData {
return colSize;
}
public void setColSize(int colSize) {
private void setColSize(int colSize) {
this.colSize = colSize;
this.clear();
}

View File

@ -1,62 +0,0 @@
package com.taosdata.jdbc.bean;
import java.util.List;
/**
* tdengine batch insert or import param object
*/
public class TSDBPreparedParam {
/**
* tableName, if sTable Name is not null, and this is sub table name.
*/
private String tableName;
/**
* sub middle param list
*/
private List<Object> middleParamList;
/**
* value list
*/
private List<Object> valueList;
public TSDBPreparedParam(String tableName) {
this.tableName = tableName;
}
public String getTableName() {
return tableName;
}
public void setTableName(String tableName) {
this.tableName = tableName;
}
public List<Object> getMiddleParamList() {
return middleParamList;
}
public void setMiddleParamList(List<Object> middleParamList) {
this.middleParamList = middleParamList;
}
public void setMiddleParam(int parameterIndex, Object x) {
this.middleParamList.set(parameterIndex, x);
}
public List<Object> getValueList() {
return valueList;
}
public void setValueList(List<Object> valueList) {
this.valueList = valueList;
}
public void setValueParam(int parameterIndex, Object x) {
this.valueList.set(parameterIndex, x);
}
}

View File

@ -1,8 +1,14 @@
package com.taosdata.jdbc.rs;
import com.taosdata.jdbc.*;
import com.taosdata.jdbc.AbstractConnection;
import com.taosdata.jdbc.TSDBDriver;
import com.taosdata.jdbc.TSDBError;
import com.taosdata.jdbc.TSDBErrorNumbers;
import java.sql.*;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
public class RestfulConnection extends AbstractConnection {
@ -55,7 +61,6 @@ public class RestfulConnection extends AbstractConnection {
public DatabaseMetaData getMetaData() throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
;
return this.metadata;
}

View File

@ -17,7 +17,7 @@ public class RestfulDriver extends AbstractDriver {
static {
try {
DriverManager.registerDriver(new RestfulDriver());
java.sql.DriverManager.registerDriver(new RestfulDriver());
} catch (SQLException e) {
throw TSDBError.createRuntimeException(TSDBErrorNumbers.ERROR_URL_NOT_SET, e);
}

View File

@ -0,0 +1,10 @@
package com.taosdata.jdbc.rs;
import com.taosdata.jdbc.AbstractParameterMetaData;
public class RestfulParameterMetaData extends AbstractParameterMetaData {
RestfulParameterMetaData(Object[] parameters) {
super(parameters);
}
}

View File

@ -7,6 +7,7 @@ import java.io.InputStream;
import java.io.Reader;
import java.math.BigDecimal;
import java.net.URL;
import java.nio.charset.Charset;
import java.sql.*;
import java.util.Calendar;
@ -30,7 +31,9 @@ public class RestfulPreparedStatement extends RestfulStatement implements Prepar
parameters = new Object[parameterCnt];
this.isPrepared = true;
}
//TODO: build parameterMetaData
// build parameterMetaData
this.parameterMetaData = new RestfulParameterMetaData(parameters);
}
@Override
@ -60,8 +63,15 @@ public class RestfulPreparedStatement extends RestfulStatement implements Prepar
for (int i = 0; i < parameters.length; ++i) {
Object para = parameters[i];
if (para != null) {
String paraStr = para.toString();
if (para instanceof Timestamp || para instanceof String) {
String paraStr;
if (para instanceof byte[]) {
paraStr = new String((byte[]) para, Charset.forName("UTF-8"));
} else {
paraStr = para.toString();
}
// if para is timestamp or String or byte[] need to translate ' character
if (para instanceof Timestamp || para instanceof String || para instanceof byte[]) {
paraStr = paraStr.replaceAll("'", "\\\\\\\\'");
paraStr = "'" + paraStr + "'";
}
sql = sql.replaceFirst("[?]", paraStr);
@ -92,7 +102,7 @@ public class RestfulPreparedStatement extends RestfulStatement implements Prepar
public void setByte(int parameterIndex, byte x) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
setObject(parameterIndex, x);
}
@Override
@ -153,7 +163,7 @@ public class RestfulPreparedStatement extends RestfulStatement implements Prepar
public void setBytes(int parameterIndex, byte[] x) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
setObject(parameterIndex, x);
}
@Override
@ -210,19 +220,16 @@ public class RestfulPreparedStatement extends RestfulStatement implements Prepar
public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
setObject(parameterIndex,x);
}
@Override
public void setObject(int parameterIndex, Object x) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
if (parameterIndex < 1 && parameterIndex >= parameters.length)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE);
parameters[parameterIndex - 1] = x;
}
@Override

View File

@ -2,13 +2,18 @@ package com.taosdata.jdbc.rs;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.primitives.Ints;
import com.google.common.primitives.Longs;
import com.google.common.primitives.Shorts;
import com.taosdata.jdbc.AbstractResultSet;
import com.taosdata.jdbc.TSDBConstants;
import com.taosdata.jdbc.TSDBError;
import com.taosdata.jdbc.TSDBErrorNumbers;
import java.math.BigDecimal;
import java.sql.*;
import java.util.ArrayList;
import java.util.Calendar;
public class RestfulResultSet extends AbstractResultSet implements ResultSet {
private volatile boolean isClosed;
@ -16,7 +21,6 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
private final String database;
private final Statement statement;
// private final JSONObject resultJson;
// data
private final ArrayList<ArrayList<Object>> resultSet;
// meta
@ -32,7 +36,6 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
public RestfulResultSet(String database, Statement statement, JSONObject resultJson) throws SQLException {
this.database = database;
this.statement = statement;
// this.resultJson = resultJson;
// column metadata
JSONArray columnMeta = resultJson.getJSONArray("column_meta");
@ -73,7 +76,7 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
case TSDBConstants.TSDB_DATA_TYPE_INT:
return row.getInteger(colIndex);
case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
return row.getBigInteger(colIndex);
return row.getLong(colIndex);
case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
return row.getFloat(colIndex);
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE:
@ -81,9 +84,11 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
return new Timestamp(row.getDate(colIndex).getTime());
case TSDBConstants.TSDB_DATA_TYPE_BINARY:
return row.getString(colIndex) == null ? null : row.getString(colIndex).getBytes();
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
return row.getString(colIndex) == null ? null : row.getString(colIndex);
default:
return row.getString(colIndex);
return row.get(colIndex);
}
}
@ -130,37 +135,33 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
@Override
public String getString(int columnIndex) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
if (columnIndex > resultSet.get(pos).size())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE, "Column Index out of range, " + columnIndex + " > " + resultSet.get(pos).size());
checkAvailability(columnIndex, resultSet.get(pos).size());
columnIndex = getTrueColumnIndex(columnIndex);
Object value = resultSet.get(pos).get(columnIndex);
return value == null ? null : value.toString();
Object value = resultSet.get(pos).get(columnIndex - 1);
if (value == null)
return null;
if (value instanceof byte[])
return new String((byte[]) value);
return value.toString();
}
@Override
public boolean getBoolean(int columnIndex) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
if (columnIndex > resultSet.get(pos).size())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE, "Column Index out of range, " + columnIndex + " > " + resultSet.get(pos).size());
checkAvailability(columnIndex, resultSet.get(pos).size());
columnIndex = getTrueColumnIndex(columnIndex);
int result = getInt(columnIndex);
return result == 0 ? false : true;
Object value = resultSet.get(pos).get(columnIndex - 1);
if (value == null)
return false;
if (value instanceof Boolean)
return (boolean) value;
return Boolean.valueOf(value.toString());
}
@Override
public byte getByte(int columnIndex) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
if (columnIndex > resultSet.get(pos).size())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE, "Column Index out of range, " + columnIndex + " > " + resultSet.get(pos).size());
checkAvailability(columnIndex, resultSet.get(pos).size());
columnIndex = getTrueColumnIndex(columnIndex);
Object value = resultSet.get(pos).get(columnIndex);
Object value = resultSet.get(pos).get(columnIndex - 1);
if (value == null)
return 0;
long valueAsLong = Long.parseLong(value.toString());
@ -179,13 +180,9 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
@Override
public short getShort(int columnIndex) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
if (columnIndex > resultSet.get(pos).size())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE, "Column Index out of range, " + columnIndex + " > " + resultSet.get(pos).size());
checkAvailability(columnIndex, resultSet.get(pos).size());
columnIndex = getTrueColumnIndex(columnIndex);
Object value = resultSet.get(pos).get(columnIndex);
Object value = resultSet.get(pos).get(columnIndex - 1);
if (value == null)
return 0;
long valueAsLong = Long.parseLong(value.toString());
@ -198,13 +195,9 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
@Override
public int getInt(int columnIndex) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
if (columnIndex > resultSet.get(pos).size())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE, "Column Index out of range, " + columnIndex + " > " + resultSet.get(pos).size());
checkAvailability(columnIndex, resultSet.get(pos).size());
columnIndex = getTrueColumnIndex(columnIndex);
Object value = resultSet.get(pos).get(columnIndex);
Object value = resultSet.get(pos).get(columnIndex - 1);
if (value == null)
return 0;
long valueAsLong = Long.parseLong(value.toString());
@ -217,13 +210,9 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
@Override
public long getLong(int columnIndex) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
if (columnIndex > resultSet.get(pos).size())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE, "Column Index out of range, " + columnIndex + " > " + resultSet.get(pos).size());
checkAvailability(columnIndex, resultSet.get(pos).size());
columnIndex = getTrueColumnIndex(columnIndex);
Object value = resultSet.get(pos).get(columnIndex);
Object value = resultSet.get(pos).get(columnIndex - 1);
if (value == null)
return 0;
@ -240,64 +229,99 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
@Override
public float getFloat(int columnIndex) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
if (columnIndex > resultSet.get(pos).size())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE, "Column Index out of range, " + columnIndex + " > " + resultSet.get(pos).size());
checkAvailability(columnIndex, resultSet.get(pos).size());
columnIndex = getTrueColumnIndex(columnIndex);
return Float.parseFloat(resultSet.get(pos).get(columnIndex).toString());
Object value = resultSet.get(pos).get(columnIndex - 1);
if (value == null)
return 0;
if (value instanceof Float || value instanceof Double)
return (float) value;
return Float.parseFloat(value.toString());
}
@Override
public double getDouble(int columnIndex) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
if (columnIndex > resultSet.get(pos).size())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE, "Column Index out of range, " + columnIndex + " > " + resultSet.get(pos).size());
checkAvailability(columnIndex, resultSet.get(pos).size());
columnIndex = getTrueColumnIndex(columnIndex);
return Double.parseDouble(resultSet.get(pos).get(columnIndex).toString());
Object value = resultSet.get(pos).get(columnIndex - 1);
if (value == null)
return 0;
if (value instanceof Double || value instanceof Float)
return (double) value;
return Double.parseDouble(value.toString());
}
private int getTrueColumnIndex(int columnIndex) throws SQLException {
if (columnIndex < 1) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE
, "Column Index out of range, " + columnIndex + " < 1");
@Override
public byte[] getBytes(int columnIndex) throws SQLException {
checkAvailability(columnIndex, resultSet.get(pos).size());
Object value = resultSet.get(pos).get(columnIndex - 1);
if (value == null)
return null;
if (value instanceof byte[])
return (byte[]) value;
if (value instanceof String)
return ((String) value).getBytes();
if (value instanceof Long)
return Longs.toByteArray((long) value);
if (value instanceof Integer)
return Ints.toByteArray((int) value);
if (value instanceof Short)
return Shorts.toByteArray((short) value);
if (value instanceof Byte)
return new byte[]{(byte) value};
return value.toString().getBytes();
}
int numOfCols = resultSet.get(pos).size();
if (columnIndex > numOfCols) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE
, "Column Index out of range, " + columnIndex + " > " + numOfCols);
@Override
public Date getDate(int columnIndex) throws SQLException {
checkAvailability(columnIndex, resultSet.get(pos).size());
Object value = resultSet.get(pos).get(columnIndex - 1);
if (value == null)
return null;
if (value instanceof Timestamp)
return new Date(((Timestamp) value).getTime());
return Date.valueOf(value.toString());
}
return columnIndex - 1;
@Override
public Time getTime(int columnIndex) throws SQLException {
checkAvailability(columnIndex, resultSet.get(pos).size());
Object value = resultSet.get(pos).get(columnIndex - 1);
if (value == null)
return null;
if (value instanceof Timestamp)
return new Time(((Timestamp) value).getTime());
return Time.valueOf(value.toString());
}
@Override
public Timestamp getTimestamp(int columnIndex) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
checkAvailability(columnIndex, resultSet.get(pos).size());
columnIndex = getTrueColumnIndex(columnIndex);
String strDate = resultSet.get(pos).get(columnIndex).toString();
// strDate = strDate.substring(1, strDate.length() - 1);
return Timestamp.valueOf(strDate);
Object value = resultSet.get(pos).get(columnIndex - 1);
if (value == null)
return null;
if (value instanceof Timestamp)
return (Timestamp) value;
return Timestamp.valueOf(value.toString());
}
/*************************************************************************************************************/
@Override
public ResultSetMetaData getMetaData() throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
return this.metaData;
}
@Override
public Object getObject(String columnLabel) throws SQLException {
return getObject(findColumn(columnLabel));
public Object getObject(int columnIndex) throws SQLException {
checkAvailability(columnIndex, resultSet.get(pos).size());
return resultSet.get(pos).get(columnIndex - 1);
}
@Override
@ -311,6 +335,23 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
return columnIndex + 1;
}
@Override
public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
checkAvailability(columnIndex, resultSet.get(pos).size());
Object value = resultSet.get(pos).get(columnIndex - 1);
if (value == null)
return null;
if (value instanceof Long || value instanceof Integer || value instanceof Short || value instanceof Byte)
return new BigDecimal(Long.valueOf(value.toString()));
if (value instanceof Double || value instanceof Float)
return new BigDecimal(Double.valueOf(value.toString()));
if (value instanceof Timestamp)
return new BigDecimal(((Timestamp) value).getTime());
return new BigDecimal(value.toString());
}
@Override
public boolean isBeforeFirst() throws SQLException {
if (isClosed())
@ -471,6 +512,12 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
return this.statement;
}
@Override
public Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException {
//TODOdid not use the specified timezone in cal
return getTimestamp(columnIndex);
}
@Override
public boolean isClosed() throws SQLException {
return isClosed;

View File

@ -0,0 +1,17 @@
package com.taosdata.jdbc.utils;
public class OSUtils {
private static final String OS = System.getProperty("os.name").toLowerCase();
public static boolean isWindows() {
return OS.indexOf("win") >= 0;
}
public static boolean isMac() {
return OS.indexOf("mac") >= 0;
}
public static boolean isLinux() {
return OS.indexOf("nux") >= 0;
}
}

View File

@ -1 +1,2 @@
com.taosdata.jdbc.TSDBDriver
com.taosdata.jdbc.rs.RestfulDriver

View File

@ -1,266 +0,0 @@
package com.taosdata.jdbc;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import javax.sql.rowset.serial.SerialBlob;
import javax.sql.rowset.serial.SerialClob;
import java.io.UnsupportedEncodingException;
import java.sql.*;
import java.util.HashMap;
import java.util.Properties;
import static org.junit.Assert.assertEquals;
public class ResultSetTest {
static Connection connection;
static Statement statement;
static String dbName = "test";
static String tName = "t0";
static String host = "localhost";
static ResultSet resSet;
@BeforeClass
public static void createDatabaseAndTable() {
try {
Class.forName("com.taosdata.jdbc.TSDBDriver");
Properties properties = new Properties();
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
connection = DriverManager.getConnection("jdbc:TAOS://" + host + ":0/", properties);
statement = connection.createStatement();
statement.executeUpdate("drop database if exists " + dbName);
statement.executeUpdate("create database if not exists " + dbName);
statement.execute("use " + dbName);
statement.executeUpdate("create table if not exists " + dbName + "." + tName + " (ts timestamp, k1 int, k2 bigint, k3 float, k4 double, k5 binary(30), k6 smallint, k7 bool, k8 nchar(20))");
} catch (ClassNotFoundException | SQLException e) {
return;
}
}
@Test
public void testResultSet() {
String sql;
long ts = 1496732686000l;
int v1 = 2147483600;
long v2 = ts + 1000;
float v3 = 3.1415926f;
double v4 = 3.1415926535897;
String v5 = "涛思数据,强~";
short v6 = 12;
boolean v7 = false;
String v8 = "TDengine is powerful";
sql = "insert into " + dbName + "." + tName + " values (" + ts + "," + v1 + "," + v2 + "," + v3 + "," + v4
+ ",\"" + v5 + "\"," + v6 + "," + v7 + ",\"" + v8 + "\")";
try {
statement.executeUpdate(sql);
assertEquals(1, statement.getUpdateCount());
} catch (SQLException e) {
assert false : "insert error " + e.getMessage();
}
try {
statement.execute("select * from " + dbName + "." + tName + " where ts = " + ts);
resSet = statement.getResultSet();
System.out.println(((TSDBResultSet) resSet).getRowData());
while (resSet.next()) {
assertEquals(ts, resSet.getLong(1));
assertEquals(ts, resSet.getLong("ts"));
System.out.println(resSet.getTimestamp(1));
assertEquals(v1, resSet.getInt(2));
assertEquals(v1, resSet.getInt("k1"));
assertEquals(v2, resSet.getLong(3));
assertEquals(v2, resSet.getLong("k2"));
assertEquals(v3, resSet.getFloat(4), 7);
assertEquals(v3, resSet.getFloat("k3"), 7);
assertEquals(v4, resSet.getDouble(5), 13);
assertEquals(v4, resSet.getDouble("k4"), 13);
assertEquals(v5, resSet.getString(6));
assertEquals(v5, resSet.getString("k5"));
assertEquals(v6, resSet.getShort(7));
assertEquals(v6, resSet.getShort("k6"));
assertEquals(v7, resSet.getBoolean(8));
assertEquals(v7, resSet.getBoolean("k7"));
assertEquals(v8, resSet.getString(9));
assertEquals(v8, resSet.getString("k8"));
resSet.getBytes(9);
resSet.getObject(6);
resSet.getObject("k8");
}
if (!resSet.isClosed()) {
resSet.close();
}
} catch (SQLException e) {
assert false : "insert error " + e.getMessage();
}
}
@Test(expected = SQLException.class)
public void testUnsupport() throws SQLException, UnsupportedEncodingException {
statement.execute("show databases");
resSet = statement.getResultSet();
Assert.assertNotNull(resSet.unwrap(TSDBResultSet.class));
Assert.assertTrue(resSet.isWrapperFor(TSDBResultSet.class));
resSet.getUnicodeStream(null);
resSet.getBinaryStream(null);
resSet.getAsciiStream("");
resSet.getUnicodeStream(null);
resSet.getBinaryStream(null);
resSet.getWarnings();
resSet.clearWarnings();
resSet.getCursorName();
resSet.getCharacterStream(null);
resSet.getCharacterStream(null);
resSet.isBeforeFirst();
resSet.isAfterLast();
resSet.isFirst();
resSet.isLast();
resSet.beforeFirst();
resSet.afterLast();
resSet.first();
resSet.last();
resSet.getRow();
resSet.absolute(1);
resSet.relative(1);
resSet.previous();
resSet.setFetchDirection(0);
resSet.getFetchDirection();
resSet.setFetchSize(0);
resSet.getFetchSize();
resSet.getConcurrency();
resSet.rowUpdated();
resSet.rowInserted();
resSet.rowDeleted();
resSet.updateNull(null);
resSet.updateBoolean(0, true);
resSet.updateByte(0, (byte) 2);
resSet.updateShort(0, (short) 1);
resSet.updateInt(0, 0);
resSet.updateLong(0, 0l);
resSet.updateFloat(0, 3.14f);
resSet.updateDouble(0, 3.1415);
resSet.updateBigDecimal(null, null);
resSet.updateString(null, null);
resSet.updateBytes(null, null);
resSet.updateDate(null, null);
resSet.updateTime(null, null);
resSet.updateTimestamp(null, null);
resSet.updateAsciiStream(null, null);
resSet.updateBinaryStream(null, null);
resSet.updateCharacterStream(null, null);
resSet.updateObject(null, null);
resSet.updateObject(null, null);
resSet.updateNull(null);
resSet.updateBoolean("", false);
resSet.updateByte("", (byte) 1);
resSet.updateShort("", (short) 1);
resSet.updateInt("", 0);
resSet.updateLong("", 0l);
resSet.updateFloat("", 3.14f);
resSet.updateDouble("", 3.1415);
resSet.updateBigDecimal(null, null);
resSet.updateString(null, null);
resSet.updateBytes(null, null);
resSet.updateDate(null, null);
resSet.updateTime(null, null);
resSet.updateTimestamp(null, null);
resSet.updateAsciiStream(null, null);
resSet.updateBinaryStream(null, null);
resSet.updateCharacterStream(null, null);
resSet.updateObject(null, null);
resSet.updateObject(null, null);
resSet.insertRow();
resSet.updateRow();
resSet.deleteRow();
resSet.refreshRow();
resSet.cancelRowUpdates();
resSet.moveToInsertRow();
resSet.moveToCurrentRow();
resSet.getStatement();
resSet.getObject(0, new HashMap<>());
resSet.getRef(null);
resSet.getBlob(null);
resSet.getClob(null);
resSet.getArray(null);
resSet.getObject("", new HashMap<>());
resSet.getRef(null);
resSet.getBlob(null);
resSet.getClob(null);
resSet.getArray(null);
resSet.getDate(null, null);
resSet.getDate(null, null);
resSet.getTime(null, null);
resSet.getTime(null, null);
resSet.getTimestamp(null, null);
resSet.getTimestamp(null, null);
resSet.getURL(null);
resSet.getURL(null);
resSet.updateRef(null, null);
resSet.updateRef(null, null);
resSet.updateBlob(0, new SerialBlob("".getBytes("UTF8")));
resSet.updateBlob("", new SerialBlob("".getBytes("UTF8")));
resSet.updateClob("", new SerialClob("".toCharArray()));
resSet.updateClob(0, new SerialClob("".toCharArray()));
resSet.updateArray(null, null);
resSet.updateArray(null, null);
resSet.getRowId(null);
resSet.getRowId(null);
resSet.updateRowId(null, null);
resSet.updateRowId(null, null);
resSet.getHoldability();
resSet.updateNString(null, null);
resSet.updateNString(null, null);
resSet.getNClob(null);
resSet.getNClob(null);
resSet.getSQLXML(null);
resSet.getSQLXML(null);
resSet.updateSQLXML(null, null);
resSet.updateSQLXML(null, null);
resSet.getNCharacterStream(null);
resSet.getNCharacterStream(null);
resSet.updateNCharacterStream(null, null);
resSet.updateNCharacterStream(null, null);
resSet.updateAsciiStream(null, null);
resSet.updateBinaryStream(null, null);
resSet.updateCharacterStream(null, null);
resSet.updateAsciiStream(null, null);
resSet.updateBinaryStream(null, null);
resSet.updateCharacterStream(null, null);
resSet.updateNCharacterStream(null, null);
resSet.updateNCharacterStream(null, null);
resSet.updateAsciiStream(null, null);
resSet.updateBinaryStream(null, null);
resSet.updateCharacterStream(null, null);
resSet.updateAsciiStream(null, null);
resSet.updateBinaryStream(null, null);
resSet.updateCharacterStream(null, null);
}
@Test
public void testBatch() throws SQLException {
String[] sqls = new String[]{"insert into test.t0 values (1496732686001,2147483600,1496732687000,3.1415925,3.1415926535897," +
"'涛思数据,强~',12,0,'TDengine is powerful')", "insert into test.t0 values (1496732686002,2147483600,1496732687000,3.1415925,3.1415926535897," +
"'涛思数据,强~',12,1,'TDengine is powerful')"};
for (String sql : sqls) {
statement.addBatch(sql);
}
int[] res = statement.executeBatch();
assertEquals(res.length, 2);
statement.clearBatch();
}
@AfterClass
public static void close() {
try {
statement.executeUpdate("drop database " + dbName);
if (statement != null)
statement.close();
if (connection != null)
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}

View File

@ -233,7 +233,7 @@ public class TSDBConnectionTest {
int status = rs.getInt("server_status()");
Assert.assertEquals(1, status);
conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT);
conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT);
}
@Test(expected = SQLFeatureNotSupportedException.class)

View File

@ -0,0 +1,194 @@
package com.taosdata.jdbc;
import com.taosdata.jdbc.rs.RestfulParameterMetaData;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import java.sql.*;
public class TSDBParameterMetaDataTest {
private static final String host = "127.0.0.1";
private static Connection conn;
private static final String sql_insert = "insert into t1 values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
private static PreparedStatement pstmt_insert;
private static final String sql_select = "select * from t1 where ts > ? and ts <= ? and f1 >= ?";
private static PreparedStatement pstmt_select;
private static ParameterMetaData parameterMetaData_insert;
private static ParameterMetaData parameterMetaData_select;
@Test
public void getParameterCount() throws SQLException {
Assert.assertEquals(10, parameterMetaData_insert.getParameterCount());
}
@Test
public void isNullable() throws SQLException {
Assert.assertEquals(ParameterMetaData.parameterNullableUnknown, parameterMetaData_insert.isNullable(1));
Assert.assertEquals(ParameterMetaData.parameterNullableUnknown, parameterMetaData_insert.isNullable(2));
Assert.assertEquals(ParameterMetaData.parameterNullableUnknown, parameterMetaData_insert.isNullable(3));
Assert.assertEquals(ParameterMetaData.parameterNullableUnknown, parameterMetaData_insert.isNullable(4));
Assert.assertEquals(ParameterMetaData.parameterNullableUnknown, parameterMetaData_insert.isNullable(5));
Assert.assertEquals(ParameterMetaData.parameterNullableUnknown, parameterMetaData_insert.isNullable(6));
Assert.assertEquals(ParameterMetaData.parameterNullableUnknown, parameterMetaData_insert.isNullable(7));
Assert.assertEquals(ParameterMetaData.parameterNullableUnknown, parameterMetaData_insert.isNullable(8));
Assert.assertEquals(ParameterMetaData.parameterNullableUnknown, parameterMetaData_insert.isNullable(9));
Assert.assertEquals(ParameterMetaData.parameterNullableUnknown, parameterMetaData_insert.isNullable(10));
}
@Test
public void isSigned() throws SQLException {
Assert.assertEquals(false, parameterMetaData_insert.isSigned(1));
Assert.assertEquals(true, parameterMetaData_insert.isSigned(2));
Assert.assertEquals(true, parameterMetaData_insert.isSigned(3));
Assert.assertEquals(true, parameterMetaData_insert.isSigned(4));
Assert.assertEquals(true, parameterMetaData_insert.isSigned(5));
Assert.assertEquals(true, parameterMetaData_insert.isSigned(6));
Assert.assertEquals(true, parameterMetaData_insert.isSigned(7));
Assert.assertEquals(false, parameterMetaData_insert.isSigned(8));
Assert.assertEquals(false, parameterMetaData_insert.isSigned(9));
Assert.assertEquals(false, parameterMetaData_insert.isSigned(10));
}
@Test
public void getPrecision() throws SQLException {
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(1));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(2));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(3));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(4));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(5));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(6));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(7));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(8));
Assert.assertEquals(5, parameterMetaData_insert.getPrecision(9));
Assert.assertEquals(5, parameterMetaData_insert.getPrecision(10));
}
@Test
public void getScale() throws SQLException {
Assert.assertEquals(0, parameterMetaData_insert.getScale(1));
Assert.assertEquals(0, parameterMetaData_insert.getScale(2));
Assert.assertEquals(0, parameterMetaData_insert.getScale(3));
Assert.assertEquals(0, parameterMetaData_insert.getScale(4));
Assert.assertEquals(0, parameterMetaData_insert.getScale(5));
Assert.assertEquals(0, parameterMetaData_insert.getScale(6));
Assert.assertEquals(0, parameterMetaData_insert.getScale(7));
Assert.assertEquals(0, parameterMetaData_insert.getScale(8));
Assert.assertEquals(0, parameterMetaData_insert.getScale(9));
Assert.assertEquals(0, parameterMetaData_insert.getScale(10));
}
@Test
public void getParameterType() throws SQLException {
Assert.assertEquals(Types.TIMESTAMP, parameterMetaData_insert.getParameterType(1));
Assert.assertEquals(Types.INTEGER, parameterMetaData_insert.getParameterType(2));
Assert.assertEquals(Types.BIGINT, parameterMetaData_insert.getParameterType(3));
Assert.assertEquals(Types.FLOAT, parameterMetaData_insert.getParameterType(4));
Assert.assertEquals(Types.DOUBLE, parameterMetaData_insert.getParameterType(5));
Assert.assertEquals(Types.SMALLINT, parameterMetaData_insert.getParameterType(6));
Assert.assertEquals(Types.TINYINT, parameterMetaData_insert.getParameterType(7));
Assert.assertEquals(Types.BOOLEAN, parameterMetaData_insert.getParameterType(8));
Assert.assertEquals(Types.BINARY, parameterMetaData_insert.getParameterType(9));
Assert.assertEquals(Types.NCHAR, parameterMetaData_insert.getParameterType(10));
}
@Test
public void getParameterTypeName() throws SQLException {
Assert.assertEquals(TSDBConstants.jdbcType2TaosTypeName(Types.TIMESTAMP), parameterMetaData_insert.getParameterTypeName(1));
Assert.assertEquals(TSDBConstants.jdbcType2TaosTypeName(Types.INTEGER), parameterMetaData_insert.getParameterTypeName(2));
Assert.assertEquals(TSDBConstants.jdbcType2TaosTypeName(Types.BIGINT), parameterMetaData_insert.getParameterTypeName(3));
Assert.assertEquals(TSDBConstants.jdbcType2TaosTypeName(Types.FLOAT), parameterMetaData_insert.getParameterTypeName(4));
Assert.assertEquals(TSDBConstants.jdbcType2TaosTypeName(Types.DOUBLE), parameterMetaData_insert.getParameterTypeName(5));
Assert.assertEquals(TSDBConstants.jdbcType2TaosTypeName(Types.SMALLINT), parameterMetaData_insert.getParameterTypeName(6));
Assert.assertEquals(TSDBConstants.jdbcType2TaosTypeName(Types.TINYINT), parameterMetaData_insert.getParameterTypeName(7));
Assert.assertEquals(TSDBConstants.jdbcType2TaosTypeName(Types.BOOLEAN), parameterMetaData_insert.getParameterTypeName(8));
Assert.assertEquals(TSDBConstants.jdbcType2TaosTypeName(Types.BINARY), parameterMetaData_insert.getParameterTypeName(9));
Assert.assertEquals(TSDBConstants.jdbcType2TaosTypeName(Types.NCHAR), parameterMetaData_insert.getParameterTypeName(10));
}
@Test
public void getParameterClassName() throws SQLException {
Assert.assertEquals(Timestamp.class.getName(), parameterMetaData_insert.getParameterClassName(1));
Assert.assertEquals(Integer.class.getName(), parameterMetaData_insert.getParameterClassName(2));
Assert.assertEquals(Long.class.getName(), parameterMetaData_insert.getParameterClassName(3));
Assert.assertEquals(Float.class.getName(), parameterMetaData_insert.getParameterClassName(4));
Assert.assertEquals(Double.class.getName(), parameterMetaData_insert.getParameterClassName(5));
Assert.assertEquals(Short.class.getName(), parameterMetaData_insert.getParameterClassName(6));
Assert.assertEquals(Byte.class.getName(), parameterMetaData_insert.getParameterClassName(7));
Assert.assertEquals(Boolean.class.getName(), parameterMetaData_insert.getParameterClassName(8));
Assert.assertEquals(byte[].class.getName(), parameterMetaData_insert.getParameterClassName(9));
Assert.assertEquals(String.class.getName(), parameterMetaData_insert.getParameterClassName(10));
}
@Test
public void getParameterMode() throws SQLException {
for (int i = 1; i <= parameterMetaData_insert.getParameterCount(); i++) {
int parameterMode = parameterMetaData_insert.getParameterMode(i);
Assert.assertEquals(ParameterMetaData.parameterModeUnknown, parameterMode);
}
}
@Test
public void unwrap() throws SQLException {
TSDBParameterMetaData unwrap = parameterMetaData_insert.unwrap(TSDBParameterMetaData.class);
Assert.assertNotNull(unwrap);
}
@Test
public void isWrapperFor() throws SQLException {
Assert.assertTrue(parameterMetaData_insert.isWrapperFor(TSDBParameterMetaData.class));
}
@BeforeClass
public static void beforeClass() {
try {
Class.forName("com.taosdata.jdbc.TSDBDriver");
conn = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata");
try (Statement stmt = conn.createStatement()) {
stmt.execute("drop database if exists test_pstmt");
stmt.execute("create database if not exists test_pstmt");
stmt.execute("use test_pstmt");
stmt.execute("create table weather(ts timestamp, f1 int, f2 bigint, f3 float, f4 double, f5 smallint, f6 tinyint, f7 bool, f8 binary(64), f9 nchar(64)) tags(loc nchar(64))");
stmt.execute("create table t1 using weather tags('beijing')");
}
pstmt_insert = conn.prepareStatement(sql_insert);
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setObject(2, 111);
pstmt_insert.setObject(3, Long.MAX_VALUE);
pstmt_insert.setObject(4, 3.14159265354f);
pstmt_insert.setObject(5, Double.MAX_VALUE);
pstmt_insert.setObject(6, Short.MAX_VALUE);
pstmt_insert.setObject(7, Byte.MAX_VALUE);
pstmt_insert.setObject(8, true);
pstmt_insert.setObject(9, "hello".getBytes());
pstmt_insert.setObject(10, "Hello");
parameterMetaData_insert = pstmt_insert.getParameterMetaData();
pstmt_select = conn.prepareStatement(sql_select);
pstmt_select.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_select.setTimestamp(2, new Timestamp(System.currentTimeMillis() + 10000));
pstmt_select.setInt(3, 0);
parameterMetaData_select = pstmt_select.getParameterMetaData();
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
}
@AfterClass
public static void afterClass() {
try {
if (pstmt_insert != null)
pstmt_insert.close();
if (pstmt_select != null)
pstmt_select.close();
if (conn != null)
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}

View File

@ -5,14 +5,16 @@ import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import java.io.IOException;
import java.io.Serializable;
import java.sql.*;
public class TSDBPreparedStatementTest {
private static final String host = "127.0.0.1";
private static Connection conn;
private static final String sql_insert = "insert into t1 values(?, ?)";
private static final String sql_insert = "insert into t1 values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
private static PreparedStatement pstmt_insert;
private static final String sql_select = "select * from t1 where ts > ? and ts <= ? and temperature >= ?";
private static final String sql_select = "select * from t1 where ts > ? and ts <= ? and f1 >= ?";
private static PreparedStatement pstmt_select;
@Test
@ -21,7 +23,7 @@ public class TSDBPreparedStatementTest {
long start = end - 1000 * 60 * 60;
pstmt_select.setTimestamp(1, new Timestamp(start));
pstmt_select.setTimestamp(2, new Timestamp(end));
pstmt_select.setFloat(3, 0);
pstmt_select.setInt(3, 0);
ResultSet rs = pstmt_select.executeQuery();
Assert.assertNotNull(rs);
@ -37,48 +39,73 @@ public class TSDBPreparedStatementTest {
@Test
public void executeUpdate() throws SQLException {
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setFloat(2, 3.14f);
pstmt_insert.setFloat(4, 3.14f);
int result = pstmt_insert.executeUpdate();
Assert.assertEquals(1, result);
}
@Test
public void setNull() throws SQLException {
pstmt_insert.setNull(2, Types.FLOAT);
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setNull(2, Types.INTEGER);
int result = pstmt_insert.executeUpdate();
Assert.assertEquals(1, result);
}
@Test
public void setBoolean() throws SQLException {
pstmt_insert.setBoolean(2, true);
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setBoolean(8, true);
int ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
}
@Test(expected = SQLFeatureNotSupportedException.class)
@Test
public void setByte() throws SQLException {
pstmt_insert.setByte(1, (byte) 0x001);
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setByte(7, (byte) 0x001);
int ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
}
@Test
public void setShort() {
public void setShort() throws SQLException {
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setShort(6, (short) 2);
int ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
}
@Test
public void setInt() {
public void setInt() throws SQLException {
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setInt(2, 10086);
int ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
}
@Test
public void setLong() {
public void setLong() throws SQLException {
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setLong(3, Long.MAX_VALUE);
int ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
}
@Test
public void setFloat() {
public void setFloat() throws SQLException {
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setFloat(4, 3.14f);
int ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
}
@Test
public void setDouble() {
public void setDouble() throws SQLException {
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setDouble(5, 3.14444);
int ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
}
@Test(expected = SQLFeatureNotSupportedException.class)
@ -87,12 +114,56 @@ public class TSDBPreparedStatementTest {
}
@Test
public void setString() {
public void setString() throws SQLException {
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setString(10, "aaaa");
boolean execute = pstmt_insert.execute();
Assert.assertFalse(execute);
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setString(10, new Person("john", 33, true).toString());
Assert.assertFalse(pstmt_insert.execute());
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setString(10, new Person("john", 33, true).toString().replaceAll("'", "\""));
Assert.assertFalse(pstmt_insert.execute());
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void setBytes() throws SQLException {
pstmt_insert.setBytes(1, new byte[]{});
class Person implements Serializable {
String name;
int age;
boolean sex;
public Person(String name, int age, boolean sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", sex=" + sex +
'}';
}
}
@Test
public void setBytes() throws SQLException, IOException {
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
// ByteArrayOutputStream baos = new ByteArrayOutputStream();
// ObjectOutputStream oos = new ObjectOutputStream(baos);
// oos.writeObject(new Person("john", 33, true));
// oos.flush();
// byte[] bytes = baos.toByteArray();
// pstmt_insert.setBytes(9, bytes);
pstmt_insert.setBytes(9, new Person("john", 33, true).toString().getBytes());
int ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
}
@Test(expected = SQLFeatureNotSupportedException.class)
@ -106,8 +177,10 @@ public class TSDBPreparedStatementTest {
}
@Test
public void setTimestamp() {
//TODO
public void setTimestamp() throws SQLException {
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
int ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
}
@Test(expected = SQLFeatureNotSupportedException.class)
@ -121,24 +194,69 @@ public class TSDBPreparedStatementTest {
}
@Test
public void clearParameters() {
//TODO
public void clearParameters() throws SQLException {
pstmt_insert.clearParameters();
}
@Test
public void setObject() throws SQLException {
pstmt_insert.setObject(1, System.currentTimeMillis());
//TODO
pstmt_insert.setObject(1, new Timestamp(System.currentTimeMillis()));
int ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setObject(2, 111);
ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setObject(3, Long.MAX_VALUE);
ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setObject(4, 3.14159265354f);
ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setObject(5, Double.MAX_VALUE);
ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setObject(6, Short.MAX_VALUE);
ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setObject(7, Byte.MAX_VALUE);
ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setObject(8, true);
ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setObject(9, "hello".getBytes());
ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setObject(10, "Hello");
ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
}
@Test
public void execute() {
//TODO
}
public void execute() throws SQLException {
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
int ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
@Test
public void addBatch() {
//TODO:
executeQuery();
}
@Test(expected = SQLFeatureNotSupportedException.class)
@ -176,11 +294,11 @@ public class TSDBPreparedStatementTest {
pstmt_insert.setURL(1, null);
}
@Test(expected = SQLFeatureNotSupportedException.class)
@Test
public void getParameterMetaData() throws SQLException {
ParameterMetaData parameterMetaData = pstmt_insert.getParameterMetaData();
// Assert.assertNotNull(parameterMetaData);
//TODO:
Assert.assertNotNull(parameterMetaData);
//TODO: modify the test case
}
@Test(expected = SQLFeatureNotSupportedException.class)
@ -215,10 +333,10 @@ public class TSDBPreparedStatementTest {
Class.forName("com.taosdata.jdbc.TSDBDriver");
conn = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata");
try (Statement stmt = conn.createStatement()) {
stmt.execute("drop database if exists test_pstmt");
stmt.execute("create database if not exists test_pstmt");
stmt.execute("use test_pstmt");
stmt.execute("create table weather(ts timestamp, temperature float) tags(loc nchar(64))");
stmt.execute("drop database if exists test_pstmt_jni");
stmt.execute("create database if not exists test_pstmt_jni");
stmt.execute("use test_pstmt_jni");
stmt.execute("create table weather(ts timestamp, f1 int, f2 bigint, f3 float, f4 double, f5 smallint, f6 tinyint, f7 bool, f8 binary(64), f9 nchar(64)) tags(loc nchar(64))");
stmt.execute("create table t1 using weather tags('beijing')");
}
pstmt_insert = conn.prepareStatement(sql_insert);
@ -231,7 +349,10 @@ public class TSDBPreparedStatementTest {
@AfterClass
public static void afterClass() {
try {
if (pstmt_insert != null)
pstmt_insert.close();
if (pstmt_select != null)
pstmt_select.close();
if (conn != null)
conn.close();
} catch (SQLException e) {

View File

@ -0,0 +1,678 @@
package com.taosdata.jdbc;
import com.google.common.primitives.Ints;
import com.google.common.primitives.Longs;
import com.google.common.primitives.Shorts;
import com.taosdata.jdbc.rs.RestfulResultSet;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import java.io.InputStream;
import java.io.Reader;
import java.math.BigDecimal;
import java.sql.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
public class TSDBResultSetTest {
private static final String host = "127.0.0.1";
private static Connection conn;
private static Statement stmt;
private static ResultSet rs;
@Test
public void wasNull() throws SQLException {
Assert.assertFalse(rs.wasNull());
}
@Test
public void getString() throws SQLException {
String f10 = rs.getString("f10");
Assert.assertEquals("涛思数据", f10);
f10 = rs.getString(10);
Assert.assertEquals("涛思数据", f10);
}
@Test
public void getBoolean() throws SQLException {
Boolean f9 = rs.getBoolean("f9");
Assert.assertEquals(true, f9);
f9 = rs.getBoolean(9);
Assert.assertEquals(true, f9);
}
@Test
public void getByte() throws SQLException {
byte f8 = rs.getByte("f8");
Assert.assertEquals(10, f8);
f8 = rs.getByte(8);
Assert.assertEquals(10, f8);
}
@Test
public void getShort() throws SQLException {
short f7 = rs.getShort("f7");
Assert.assertEquals(10, f7);
f7 = rs.getShort(7);
Assert.assertEquals(10, f7);
}
@Test
public void getInt() throws SQLException {
int f2 = rs.getInt("f2");
Assert.assertEquals(1, f2);
f2 = rs.getInt(2);
Assert.assertEquals(1, f2);
}
@Test
public void getLong() throws SQLException {
long f3 = rs.getLong("f3");
Assert.assertEquals(100, f3);
f3 = rs.getLong(3);
Assert.assertEquals(100, f3);
}
@Test
public void getFloat() throws SQLException {
float f4 = rs.getFloat("f4");
Assert.assertEquals(3.1415f, f4, 0f);
f4 = rs.getFloat(4);
Assert.assertEquals(3.1415f, f4, 0f);
}
@Test
public void getDouble() throws SQLException {
double f5 = rs.getDouble("f5");
Assert.assertEquals(3.1415926, f5, 0.0);
f5 = rs.getDouble(5);
Assert.assertEquals(3.1415926, f5, 0.0);
}
@Test
public void getBigDecimal() throws SQLException {
BigDecimal f1 = rs.getBigDecimal("f1");
Assert.assertEquals(1609430400000l, f1.longValue());
BigDecimal f2 = rs.getBigDecimal("f2");
Assert.assertEquals(1, f2.intValue());
BigDecimal f3 = rs.getBigDecimal("f3");
Assert.assertEquals(100l, f3.longValue());
BigDecimal f4 = rs.getBigDecimal("f4");
Assert.assertEquals(3.1415f, f4.floatValue(), 0.00000f);
BigDecimal f5 = rs.getBigDecimal("f5");
Assert.assertEquals(3.1415926, f5.doubleValue(), 0.0000000);
BigDecimal f7 = rs.getBigDecimal("f7");
Assert.assertEquals(10, f7.intValue());
BigDecimal f8 = rs.getBigDecimal("f8");
Assert.assertEquals(10, f8.intValue());
}
@Test
public void getBytes() throws SQLException {
byte[] f1 = rs.getBytes("f1");
Assert.assertEquals("2021-01-01 00:00:00.0", new String(f1));
byte[] f2 = rs.getBytes("f2");
Assert.assertEquals(1, Ints.fromByteArray(f2));
byte[] f3 = rs.getBytes("f3");
Assert.assertEquals(100l, Longs.fromByteArray(f3));
byte[] f4 = rs.getBytes("f4");
Assert.assertEquals(3.1415f, Float.valueOf(new String(f4)), 0.000000f);
byte[] f5 = rs.getBytes("f5");
Assert.assertEquals(3.1415926, Double.valueOf(new String(f5)), 0.000000f);
byte[] f6 = rs.getBytes("f6");
Assert.assertEquals("abc", new String(f6));
byte[] f7 = rs.getBytes("f7");
Assert.assertEquals((short) 10, Shorts.fromByteArray(f7));
byte[] f8 = rs.getBytes("f8");
Assert.assertEquals(1, f8.length);
Assert.assertEquals((byte) 10, f8[0]);
byte[] f9 = rs.getBytes("f9");
Assert.assertEquals("true", new String(f9));
byte[] f10 = rs.getBytes("f10");
Assert.assertEquals("涛思数据", new String(f10));
}
@Test
public void getDate() throws SQLException, ParseException {
Date f1 = rs.getDate("f1");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Assert.assertEquals(sdf.parse("2021-01-01"), f1);
}
@Test
public void getTime() throws SQLException {
Time f1 = rs.getTime("f1");
Assert.assertEquals("00:00:00", f1.toString());
}
@Test
public void getTimestamp() throws SQLException {
Timestamp f1 = rs.getTimestamp("f1");
Assert.assertEquals("2021-01-01 00:00:00.0", f1.toString());
f1 = rs.getTimestamp(1);
Assert.assertEquals("2021-01-01 00:00:00.0", f1.toString());
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void getAsciiStream() throws SQLException {
rs.getAsciiStream("f1");
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void getUnicodeStream() throws SQLException {
rs.getUnicodeStream("f1");
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void getBinaryStream() throws SQLException {
rs.getBinaryStream("f1");
}
@Test
public void getWarnings() throws SQLException {
Assert.assertNull(rs.getWarnings());
}
@Test
public void clearWarnings() throws SQLException {
rs.clearWarnings();
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void getCursorName() throws SQLException {
rs.getCursorName();
}
@Test
public void getMetaData() throws SQLException {
ResultSetMetaData meta = rs.getMetaData();
Assert.assertNotNull(meta);
}
@Test
public void getObject() throws SQLException, ParseException {
Object f1 = rs.getObject("f1");
Assert.assertEquals(Timestamp.class, f1.getClass());
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.sss");
java.util.Date date = sdf.parse("2021-01-01 00:00:00.000");
Assert.assertEquals(new Timestamp(date.getTime()), f1);
Object f2 = rs.getObject("f2");
Assert.assertEquals(Integer.class, f2.getClass());
Assert.assertEquals(1, f2);
Object f3 = rs.getObject("f3");
Assert.assertEquals(Long.class, f3.getClass());
Assert.assertEquals(100l, f3);
Object f4 = rs.getObject("f4");
Assert.assertEquals(Float.class, f4.getClass());
Assert.assertEquals(3.1415f, f4);
Object f5 = rs.getObject("f5");
Assert.assertEquals(Double.class, f5.getClass());
Assert.assertEquals(3.1415926, f5);
Object f6 = rs.getObject("f6");
Assert.assertEquals(byte[].class, f6.getClass());
Assert.assertEquals("abc", new String((byte[]) f6));
Object f7 = rs.getObject("f7");
Assert.assertEquals(Short.class, f7.getClass());
Assert.assertEquals((short) 10, f7);
Object f8 = rs.getObject("f8");
Assert.assertEquals(Byte.class, f8.getClass());
Assert.assertEquals((byte) 10, f8);
Object f9 = rs.getObject("f9");
Assert.assertEquals(Boolean.class, f9.getClass());
Assert.assertEquals(true, f9);
Object f10 = rs.getObject("f10");
Assert.assertEquals(String.class, f10.getClass());
Assert.assertEquals("涛思数据", f10);
}
@Test(expected = SQLException.class)
public void findColumn() throws SQLException {
int columnIndex = rs.findColumn("f1");
Assert.assertEquals(1, columnIndex);
columnIndex = rs.findColumn("f2");
Assert.assertEquals(2, columnIndex);
columnIndex = rs.findColumn("f3");
Assert.assertEquals(3, columnIndex);
columnIndex = rs.findColumn("f4");
Assert.assertEquals(4, columnIndex);
columnIndex = rs.findColumn("f5");
Assert.assertEquals(5, columnIndex);
columnIndex = rs.findColumn("f6");
Assert.assertEquals(6, columnIndex);
columnIndex = rs.findColumn("f7");
Assert.assertEquals(7, columnIndex);
columnIndex = rs.findColumn("f8");
Assert.assertEquals(8, columnIndex);
columnIndex = rs.findColumn("f9");
Assert.assertEquals(9, columnIndex);
columnIndex = rs.findColumn("f10");
Assert.assertEquals(10, columnIndex);
rs.findColumn("f11");
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void getCharacterStream() throws SQLException {
rs.getCharacterStream(1);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void isBeforeFirst() throws SQLException {
rs.isBeforeFirst();
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void isAfterLast() throws SQLException {
rs.isAfterLast();
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void isFirst() throws SQLException {
rs.isFirst();
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void isLast() throws SQLException {
rs.isLast();
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void beforeFirst() throws SQLException {
rs.beforeFirst();
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void afterLast() throws SQLException {
rs.afterLast();
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void first() throws SQLException {
rs.first();
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void last() throws SQLException {
rs.last();
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void getRow() throws SQLException {
int row = rs.getRow();
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void absolute() throws SQLException {
rs.absolute(-1);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void relative() throws SQLException {
rs.relative(-1);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void previous() throws SQLException {
rs.previous();
}
@Test
public void setFetchDirection() throws SQLException {
rs.setFetchDirection(ResultSet.FETCH_FORWARD);
Assert.assertEquals(ResultSet.FETCH_FORWARD, rs.getFetchDirection());
rs.setFetchDirection(ResultSet.FETCH_UNKNOWN);
Assert.assertEquals(ResultSet.FETCH_FORWARD, rs.getFetchDirection());
}
@Test
public void getFetchDirection() throws SQLException {
Assert.assertEquals(ResultSet.FETCH_FORWARD, rs.getFetchDirection());
}
@Test
public void setFetchSize() throws SQLException {
rs.setFetchSize(0);
Assert.assertEquals(0, rs.getFetchSize());
}
@Test
public void getFetchSize() throws SQLException {
Assert.assertEquals(0, rs.getFetchSize());
}
@Test
public void getType() throws SQLException {
Assert.assertEquals(ResultSet.TYPE_FORWARD_ONLY, rs.getType());
}
@Test
public void getConcurrency() throws SQLException {
Assert.assertEquals(ResultSet.CONCUR_READ_ONLY, rs.getConcurrency());
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void rowUpdated() throws SQLException {
rs.rowUpdated();
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void rowInserted() throws SQLException {
rs.rowInserted();
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void rowDeleted() throws SQLException {
rs.rowDeleted();
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void updateNull() throws SQLException {
rs.updateNull("f1");
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void updateBoolean() throws SQLException {
rs.updateBoolean(1, false);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void updateByte() throws SQLException {
rs.updateByte(1, new Byte("0"));
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void updateShort() throws SQLException {
rs.updateShort(1, new Short("0"));
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void updateInt() throws SQLException {
rs.updateInt(1, 1);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void updateLong() throws SQLException {
rs.updateLong(1, 1l);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void updateFloat() throws SQLException {
rs.updateFloat(1, 1f);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void updateDouble() throws SQLException {
rs.updateDouble(1, 1.0);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void updateBigDecimal() throws SQLException {
rs.updateBigDecimal(1, new BigDecimal(1));
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void updateString() throws SQLException {
rs.updateString(1, "abc");
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void updateBytes() throws SQLException {
rs.updateBytes(1, new byte[]{});
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void updateDate() throws SQLException {
rs.updateDate(1, new Date(System.currentTimeMillis()));
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void updateTime() throws SQLException {
rs.updateTime(1, new Time(System.currentTimeMillis()));
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void updateTimestamp() throws SQLException {
rs.updateTimestamp(1, new Timestamp(System.currentTimeMillis()));
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void updateAsciiStream() throws SQLException {
rs.updateAsciiStream(1, null);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void updateBinaryStream() throws SQLException {
rs.updateBinaryStream(1, null);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void updateCharacterStream() throws SQLException {
rs.updateCharacterStream(1, null);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void updateObject() throws SQLException {
rs.updateObject(1, null);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void insertRow() throws SQLException {
rs.insertRow();
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void updateRow() throws SQLException {
rs.updateRow();
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void deleteRow() throws SQLException {
rs.deleteRow();
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void refreshRow() throws SQLException {
rs.refreshRow();
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void cancelRowUpdates() throws SQLException {
rs.cancelRowUpdates();
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void moveToInsertRow() throws SQLException {
rs.moveToInsertRow();
}
@Test
public void getStatement() throws SQLException {
Statement stmt = rs.getStatement();
Assert.assertNotNull(stmt);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void moveToCurrentRow() throws SQLException {
rs.moveToCurrentRow();
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void getRef() throws SQLException {
rs.getRef(1);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void getBlob() throws SQLException {
rs.getBlob("f1");
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void getClob() throws SQLException {
rs.getClob("f1");
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void getArray() throws SQLException {
rs.getArray("f1");
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void getURL() throws SQLException {
rs.getURL("f1");
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void updateRef() throws SQLException {
rs.updateRef("f1", null);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void updateBlob() throws SQLException {
rs.updateBlob(1, (InputStream) null);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void updateClob() throws SQLException {
rs.updateClob(1, (Reader) null);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void updateArray() throws SQLException {
rs.updateArray(1, null);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void getRowId() throws SQLException {
rs.getRowId("f1");
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void updateRowId() throws SQLException {
rs.updateRowId(1, null);
}
@Test
public void getHoldability() throws SQLException {
Assert.assertEquals(ResultSet.HOLD_CURSORS_OVER_COMMIT, rs.getHoldability());
}
@Test
public void isClosed() throws SQLException {
Assert.assertFalse(rs.isClosed());
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void updateNString() throws SQLException {
rs.updateNString(1, null);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void updateNClob() throws SQLException {
rs.updateNClob(1, (Reader) null);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void getNClob() throws SQLException {
rs.getNClob("f1");
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void getSQLXML() throws SQLException {
rs.getSQLXML("f1");
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void updateSQLXML() throws SQLException {
rs.updateSQLXML(1, null);
}
@Test
public void getNString() throws SQLException {
String f10 = rs.getNString("f10");
Assert.assertEquals("涛思数据", f10);
f10 = rs.getNString(10);
Assert.assertEquals("涛思数据", f10);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void getNCharacterStream() throws SQLException {
rs.getNCharacterStream("f1");
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void updateNCharacterStream() throws SQLException {
rs.updateNCharacterStream(1, null);
}
@Test
public void unwrap() throws SQLException {
TSDBResultSet unwrap = rs.unwrap(TSDBResultSet.class);
Assert.assertNotNull(unwrap);
}
@Test
public void isWrapperFor() throws SQLException {
Assert.assertTrue(rs.isWrapperFor(TSDBResultSet.class));
}
@BeforeClass
public static void beforeClass() {
try {
Class.forName("com.taosdata.jdbc.TSDBDriver");
conn = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata");
stmt = conn.createStatement();
stmt.execute("create database if not exists restful_test");
stmt.execute("use restful_test");
stmt.execute("drop table if exists weather");
stmt.execute("create table if not exists weather(f1 timestamp, f2 int, f3 bigint, f4 float, f5 double, f6 binary(64), f7 smallint, f8 tinyint, f9 bool, f10 nchar(64))");
stmt.execute("insert into restful_test.weather values('2021-01-01 00:00:00.000', 1, 100, 3.1415, 3.1415926, 'abc', 10, 10, true, '涛思数据')");
rs = stmt.executeQuery("select * from restful_test.weather");
rs.next();
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
}
@AfterClass
public static void afterClass() {
try {
if (rs != null)
rs.close();
if (stmt != null)
stmt.close();
if (conn != null)
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,41 @@
package com.taosdata.jdbc.cases;
import com.taosdata.jdbc.TSDBDriver;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
public class DriverAutoloadTest {
private Properties properties;
private String host = "127.0.0.1";
@Test
public void testRestful() throws SQLException {
final String url = "jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata";
Connection conn = DriverManager.getConnection(url, properties);
Assert.assertNotNull(conn);
}
@Test
public void testJni() throws SQLException {
final String url = "jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata";
Connection conn = DriverManager.getConnection(url, properties);
Assert.assertNotNull(conn);
}
@Before
public void before() {
properties = new Properties();
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
}
}

View File

@ -14,7 +14,6 @@ import java.util.Random;
public class InsertDbwithoutUseDbTest {
private static String host = "127.0.0.1";
// private static String host = "master";
private static Properties properties;
private static Random random = new Random(System.currentTimeMillis());

View File

@ -0,0 +1,64 @@
package com.taosdata.jdbc.cases;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.sql.*;
public class NullValueInResultSetForJdbcRestfulTest {
private static final String host = "127.0.0.1";
Connection conn;
@Test
public void test() {
try (Statement stmt = conn.createStatement()) {
ResultSet rs = stmt.executeQuery("select * from weather");
ResultSetMetaData meta = rs.getMetaData();
while (rs.next()) {
for (int i = 1; i <= meta.getColumnCount(); i++) {
Object value = rs.getObject(i);
System.out.print(meta.getColumnLabel(i) + ": " + value + "\t");
}
System.out.println();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
@Before
public void before() throws SQLException {
final String url = "jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata";
conn = DriverManager.getConnection(url);
try (Statement stmt = conn.createStatement()) {
stmt.execute("drop database if exists test_null");
stmt.execute("create database if not exists test_null");
stmt.execute("use test_null");
stmt.execute("create table weather(ts timestamp, f1 int, f2 bigint, f3 float, f4 double, f5 smallint, f6 tinyint, f7 bool, f8 binary(64), f9 nchar(64))");
stmt.executeUpdate("insert into weather(ts, f1) values(now+1s, 1)");
stmt.executeUpdate("insert into weather(ts, f2) values(now+2s, 2)");
stmt.executeUpdate("insert into weather(ts, f3) values(now+3s, 3.0)");
stmt.executeUpdate("insert into weather(ts, f4) values(now+4s, 4.0)");
stmt.executeUpdate("insert into weather(ts, f5) values(now+5s, 5)");
stmt.executeUpdate("insert into weather(ts, f6) values(now+6s, 6)");
stmt.executeUpdate("insert into weather(ts, f7) values(now+7s, true)");
stmt.executeUpdate("insert into weather(ts, f8) values(now+8s, 'hello')");
stmt.executeUpdate("insert into weather(ts, f9) values(now+9s, '涛思数据')");
} catch (SQLException e) {
e.printStackTrace();
}
}
@After
public void after() {
try {
if (conn != null)
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}

View File

@ -10,8 +10,8 @@ import java.util.Properties;
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class UnsignedNumberRestfulTest {
private static final String host = "127.0.0.1";
// private static final String host = "master";
private static Connection conn;
@Test

View File

@ -8,7 +8,6 @@ import java.sql.*;
public class AuthenticationTest {
private static final String host = "127.0.0.1";
// private static final String host = "master";
private static final String user = "root";
private static final String password = "taos?data";
private Connection conn;

View File

@ -12,7 +12,6 @@ import java.util.Properties;
public class RestfulConnectionTest {
private static final String host = "127.0.0.1";
// private static final String host = "master";
private static Connection conn;

View File

@ -10,7 +10,6 @@ import java.sql.*;
import java.util.Properties;
public class RestfulDatabaseMetaDataTest {
// private static final String host = "master";
private static final String host = "127.0.0.1";
private static final String url = "jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata";
private static Connection connection;

View File

@ -10,7 +10,6 @@ import java.util.Random;
public class RestfulJDBCTest {
private static final String host = "127.0.0.1";
// private static final String host = "master";
private static Connection connection;
private Random random = new Random(System.currentTimeMillis());

View File

@ -0,0 +1,194 @@
package com.taosdata.jdbc.rs;
import com.taosdata.jdbc.TSDBConstants;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import java.sql.*;
public class RestfulParameterMetaDataTest {
private static final String host = "127.0.0.1";
private static Connection conn;
private static final String sql_insert = "insert into t1 values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
private static PreparedStatement pstmt_insert;
private static final String sql_select = "select * from t1 where ts > ? and ts <= ? and f1 >= ?";
private static PreparedStatement pstmt_select;
private static ParameterMetaData parameterMetaData_insert;
private static ParameterMetaData parameterMetaData_select;
@Test
public void getParameterCount() throws SQLException {
Assert.assertEquals(10, parameterMetaData_insert.getParameterCount());
}
@Test
public void isNullable() throws SQLException {
Assert.assertEquals(ParameterMetaData.parameterNullableUnknown, parameterMetaData_insert.isNullable(1));
Assert.assertEquals(ParameterMetaData.parameterNullableUnknown, parameterMetaData_insert.isNullable(2));
Assert.assertEquals(ParameterMetaData.parameterNullableUnknown, parameterMetaData_insert.isNullable(3));
Assert.assertEquals(ParameterMetaData.parameterNullableUnknown, parameterMetaData_insert.isNullable(4));
Assert.assertEquals(ParameterMetaData.parameterNullableUnknown, parameterMetaData_insert.isNullable(5));
Assert.assertEquals(ParameterMetaData.parameterNullableUnknown, parameterMetaData_insert.isNullable(6));
Assert.assertEquals(ParameterMetaData.parameterNullableUnknown, parameterMetaData_insert.isNullable(7));
Assert.assertEquals(ParameterMetaData.parameterNullableUnknown, parameterMetaData_insert.isNullable(8));
Assert.assertEquals(ParameterMetaData.parameterNullableUnknown, parameterMetaData_insert.isNullable(9));
Assert.assertEquals(ParameterMetaData.parameterNullableUnknown, parameterMetaData_insert.isNullable(10));
}
@Test
public void isSigned() throws SQLException {
Assert.assertEquals(false, parameterMetaData_insert.isSigned(1));
Assert.assertEquals(true, parameterMetaData_insert.isSigned(2));
Assert.assertEquals(true, parameterMetaData_insert.isSigned(3));
Assert.assertEquals(true, parameterMetaData_insert.isSigned(4));
Assert.assertEquals(true, parameterMetaData_insert.isSigned(5));
Assert.assertEquals(true, parameterMetaData_insert.isSigned(6));
Assert.assertEquals(true, parameterMetaData_insert.isSigned(7));
Assert.assertEquals(false, parameterMetaData_insert.isSigned(8));
Assert.assertEquals(false, parameterMetaData_insert.isSigned(9));
Assert.assertEquals(false, parameterMetaData_insert.isSigned(10));
}
@Test
public void getPrecision() throws SQLException {
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(1));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(2));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(3));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(4));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(5));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(6));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(7));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(8));
Assert.assertEquals(5, parameterMetaData_insert.getPrecision(9));
Assert.assertEquals(5, parameterMetaData_insert.getPrecision(10));
}
@Test
public void getScale() throws SQLException {
Assert.assertEquals(0, parameterMetaData_insert.getScale(1));
Assert.assertEquals(0, parameterMetaData_insert.getScale(2));
Assert.assertEquals(0, parameterMetaData_insert.getScale(3));
Assert.assertEquals(0, parameterMetaData_insert.getScale(4));
Assert.assertEquals(0, parameterMetaData_insert.getScale(5));
Assert.assertEquals(0, parameterMetaData_insert.getScale(6));
Assert.assertEquals(0, parameterMetaData_insert.getScale(7));
Assert.assertEquals(0, parameterMetaData_insert.getScale(8));
Assert.assertEquals(0, parameterMetaData_insert.getScale(9));
Assert.assertEquals(0, parameterMetaData_insert.getScale(10));
}
@Test
public void getParameterType() throws SQLException {
Assert.assertEquals(Types.TIMESTAMP, parameterMetaData_insert.getParameterType(1));
Assert.assertEquals(Types.INTEGER, parameterMetaData_insert.getParameterType(2));
Assert.assertEquals(Types.BIGINT, parameterMetaData_insert.getParameterType(3));
Assert.assertEquals(Types.FLOAT, parameterMetaData_insert.getParameterType(4));
Assert.assertEquals(Types.DOUBLE, parameterMetaData_insert.getParameterType(5));
Assert.assertEquals(Types.SMALLINT, parameterMetaData_insert.getParameterType(6));
Assert.assertEquals(Types.TINYINT, parameterMetaData_insert.getParameterType(7));
Assert.assertEquals(Types.BOOLEAN, parameterMetaData_insert.getParameterType(8));
Assert.assertEquals(Types.BINARY, parameterMetaData_insert.getParameterType(9));
Assert.assertEquals(Types.NCHAR, parameterMetaData_insert.getParameterType(10));
}
@Test
public void getParameterTypeName() throws SQLException {
Assert.assertEquals(TSDBConstants.jdbcType2TaosTypeName(Types.TIMESTAMP), parameterMetaData_insert.getParameterTypeName(1));
Assert.assertEquals(TSDBConstants.jdbcType2TaosTypeName(Types.INTEGER), parameterMetaData_insert.getParameterTypeName(2));
Assert.assertEquals(TSDBConstants.jdbcType2TaosTypeName(Types.BIGINT), parameterMetaData_insert.getParameterTypeName(3));
Assert.assertEquals(TSDBConstants.jdbcType2TaosTypeName(Types.FLOAT), parameterMetaData_insert.getParameterTypeName(4));
Assert.assertEquals(TSDBConstants.jdbcType2TaosTypeName(Types.DOUBLE), parameterMetaData_insert.getParameterTypeName(5));
Assert.assertEquals(TSDBConstants.jdbcType2TaosTypeName(Types.SMALLINT), parameterMetaData_insert.getParameterTypeName(6));
Assert.assertEquals(TSDBConstants.jdbcType2TaosTypeName(Types.TINYINT), parameterMetaData_insert.getParameterTypeName(7));
Assert.assertEquals(TSDBConstants.jdbcType2TaosTypeName(Types.BOOLEAN), parameterMetaData_insert.getParameterTypeName(8));
Assert.assertEquals(TSDBConstants.jdbcType2TaosTypeName(Types.BINARY), parameterMetaData_insert.getParameterTypeName(9));
Assert.assertEquals(TSDBConstants.jdbcType2TaosTypeName(Types.NCHAR), parameterMetaData_insert.getParameterTypeName(10));
}
@Test
public void getParameterClassName() throws SQLException {
Assert.assertEquals(Timestamp.class.getName(), parameterMetaData_insert.getParameterClassName(1));
Assert.assertEquals(Integer.class.getName(), parameterMetaData_insert.getParameterClassName(2));
Assert.assertEquals(Long.class.getName(), parameterMetaData_insert.getParameterClassName(3));
Assert.assertEquals(Float.class.getName(), parameterMetaData_insert.getParameterClassName(4));
Assert.assertEquals(Double.class.getName(), parameterMetaData_insert.getParameterClassName(5));
Assert.assertEquals(Short.class.getName(), parameterMetaData_insert.getParameterClassName(6));
Assert.assertEquals(Byte.class.getName(), parameterMetaData_insert.getParameterClassName(7));
Assert.assertEquals(Boolean.class.getName(), parameterMetaData_insert.getParameterClassName(8));
Assert.assertEquals(byte[].class.getName(), parameterMetaData_insert.getParameterClassName(9));
Assert.assertEquals(String.class.getName(), parameterMetaData_insert.getParameterClassName(10));
}
@Test
public void getParameterMode() throws SQLException {
for (int i = 1; i <= parameterMetaData_insert.getParameterCount(); i++) {
int parameterMode = parameterMetaData_insert.getParameterMode(i);
Assert.assertEquals(ParameterMetaData.parameterModeUnknown, parameterMode);
}
}
@Test
public void unwrap() throws SQLException {
RestfulParameterMetaData unwrap = parameterMetaData_insert.unwrap(RestfulParameterMetaData.class);
Assert.assertNotNull(unwrap);
}
@Test
public void isWrapperFor() throws SQLException {
Assert.assertTrue(parameterMetaData_insert.isWrapperFor(RestfulParameterMetaData.class));
}
@BeforeClass
public static void beforeClass() {
try {
Class.forName("com.taosdata.jdbc.rs.RestfulDriver");
conn = DriverManager.getConnection("jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata");
try (Statement stmt = conn.createStatement()) {
stmt.execute("drop database if exists test_pstmt");
stmt.execute("create database if not exists test_pstmt");
stmt.execute("use test_pstmt");
stmt.execute("create table weather(ts timestamp, f1 int, f2 bigint, f3 float, f4 double, f5 smallint, f6 tinyint, f7 bool, f8 binary(64), f9 nchar(64)) tags(loc nchar(64))");
stmt.execute("create table t1 using weather tags('beijing')");
}
pstmt_insert = conn.prepareStatement(sql_insert);
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setObject(2, 111);
pstmt_insert.setObject(3, Long.MAX_VALUE);
pstmt_insert.setObject(4, 3.14159265354f);
pstmt_insert.setObject(5, Double.MAX_VALUE);
pstmt_insert.setObject(6, Short.MAX_VALUE);
pstmt_insert.setObject(7, Byte.MAX_VALUE);
pstmt_insert.setObject(8, true);
pstmt_insert.setObject(9, "hello".getBytes());
pstmt_insert.setObject(10, "Hello");
parameterMetaData_insert = pstmt_insert.getParameterMetaData();
pstmt_select = conn.prepareStatement(sql_select);
pstmt_select.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_select.setTimestamp(2, new Timestamp(System.currentTimeMillis() + 10000));
pstmt_select.setInt(3, 0);
parameterMetaData_select = pstmt_select.getParameterMetaData();
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
}
@AfterClass
public static void afterClass() {
try {
if (pstmt_insert != null)
pstmt_insert.close();
if (pstmt_select != null)
pstmt_select.close();
if (conn != null)
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}

View File

@ -5,11 +5,12 @@ import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import java.io.IOException;
import java.io.Serializable;
import java.sql.*;
public class RestfulPreparedStatementTest {
private static final String host = "127.0.0.1";
// private static final String host = "master";
private static Connection conn;
private static final String sql_insert = "insert into t1 values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
private static PreparedStatement pstmt_insert;
@ -38,48 +39,73 @@ public class RestfulPreparedStatementTest {
@Test
public void executeUpdate() throws SQLException {
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setFloat(2, 3.14f);
pstmt_insert.setFloat(4, 3.14f);
int result = pstmt_insert.executeUpdate();
Assert.assertEquals(1, result);
}
@Test
public void setNull() throws SQLException {
pstmt_insert.setNull(2, Types.FLOAT);
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setNull(2, Types.INTEGER);
int result = pstmt_insert.executeUpdate();
Assert.assertEquals(1, result);
}
@Test
public void setBoolean() throws SQLException {
pstmt_insert.setBoolean(2, true);
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setBoolean(8, true);
int ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
}
@Test(expected = SQLFeatureNotSupportedException.class)
@Test
public void setByte() throws SQLException {
pstmt_insert.setByte(1, (byte) 0x001);
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setByte(7, (byte) 0x001);
int ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
}
@Test
public void setShort() {
public void setShort() throws SQLException {
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setShort(6, (short) 2);
int ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
}
@Test
public void setInt() {
public void setInt() throws SQLException {
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setInt(2, 10086);
int ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
}
@Test
public void setLong() {
public void setLong() throws SQLException {
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setLong(3, Long.MAX_VALUE);
int ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
}
@Test
public void setFloat() {
public void setFloat() throws SQLException {
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setFloat(4, 3.14f);
int ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
}
@Test
public void setDouble() {
public void setDouble() throws SQLException {
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setDouble(5, 3.14444);
int ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
}
@Test(expected = SQLFeatureNotSupportedException.class)
@ -88,12 +114,56 @@ public class RestfulPreparedStatementTest {
}
@Test
public void setString() {
public void setString() throws SQLException {
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setString(10, "aaaa");
boolean execute = pstmt_insert.execute();
Assert.assertFalse(execute);
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setString(10, new Person("john", 33, true).toString());
Assert.assertFalse(pstmt_insert.execute());
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setString(10, new Person("john", 33, true).toString().replaceAll("'", "\""));
Assert.assertFalse(pstmt_insert.execute());
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void setBytes() throws SQLException {
pstmt_insert.setBytes(1, new byte[]{});
class Person implements Serializable {
String name;
int age;
boolean sex;
public Person(String name, int age, boolean sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", sex=" + sex +
'}';
}
}
@Test
public void setBytes() throws SQLException, IOException {
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
// ByteArrayOutputStream baos = new ByteArrayOutputStream();
// ObjectOutputStream oos = new ObjectOutputStream(baos);
// oos.writeObject(new Person("john", 33, true));
// oos.flush();
// byte[] bytes = baos.toByteArray();
// pstmt_insert.setBytes(9, bytes);
pstmt_insert.setBytes(9, new Person("john", 33, true).toString().getBytes());
int ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
}
@Test(expected = SQLFeatureNotSupportedException.class)
@ -107,8 +177,10 @@ public class RestfulPreparedStatementTest {
}
@Test
public void setTimestamp() {
//TODO
public void setTimestamp() throws SQLException {
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
int ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
}
@Test(expected = SQLFeatureNotSupportedException.class)
@ -122,24 +194,69 @@ public class RestfulPreparedStatementTest {
}
@Test
public void clearParameters() {
//TODO
public void clearParameters() throws SQLException {
pstmt_insert.clearParameters();
}
@Test
public void setObject() throws SQLException {
pstmt_insert.setObject(1, System.currentTimeMillis());
//TODO
pstmt_insert.setObject(1, new Timestamp(System.currentTimeMillis()));
int ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setObject(2, 111);
ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setObject(3, Long.MAX_VALUE);
ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setObject(4, 3.14159265354f);
ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setObject(5, Double.MAX_VALUE);
ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setObject(6, Short.MAX_VALUE);
ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setObject(7, Byte.MAX_VALUE);
ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setObject(8, true);
ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setObject(9, "hello".getBytes());
ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setObject(10, "Hello");
ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
}
@Test
public void execute() {
//TODO
}
public void execute() throws SQLException {
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
int ret = pstmt_insert.executeUpdate();
Assert.assertEquals(1, ret);
@Test
public void addBatch() {
//TODO:
executeQuery();
}
@Test(expected = SQLFeatureNotSupportedException.class)
@ -180,8 +297,8 @@ public class RestfulPreparedStatementTest {
@Test
public void getParameterMetaData() throws SQLException {
ParameterMetaData parameterMetaData = pstmt_insert.getParameterMetaData();
Assert.assertNull(parameterMetaData);
//TODO:
Assert.assertNotNull(parameterMetaData);
//TODO: modify the test case
}
@Test(expected = SQLFeatureNotSupportedException.class)

View File

@ -10,7 +10,6 @@ import java.sql.*;
public class RestfulResultSetMetaDataTest {
private static final String host = "127.0.0.1";
// private static final String host = "master";
private static Connection conn;
private static Statement stmt;

View File

@ -1,5 +1,8 @@
package com.taosdata.jdbc.rs;
import com.google.common.primitives.Ints;
import com.google.common.primitives.Longs;
import com.google.common.primitives.Shorts;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
@ -9,11 +12,12 @@ import java.io.InputStream;
import java.io.Reader;
import java.math.BigDecimal;
import java.sql.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
public class RestfulResultSetTest {
private static final String host = "127.0.0.1";
// private static final String host = "master";
private static Connection conn;
private static Statement stmt;
@ -88,24 +92,75 @@ public class RestfulResultSetTest {
Assert.assertEquals(3.1415926, f5, 0.0);
}
@Test(expected = SQLFeatureNotSupportedException.class)
@Test
public void getBigDecimal() throws SQLException {
rs.getBigDecimal("f1");
BigDecimal f1 = rs.getBigDecimal("f1");
Assert.assertEquals(1609430400000l, f1.longValue());
BigDecimal f2 = rs.getBigDecimal("f2");
Assert.assertEquals(1, f2.intValue());
BigDecimal f3 = rs.getBigDecimal("f3");
Assert.assertEquals(100l, f3.longValue());
BigDecimal f4 = rs.getBigDecimal("f4");
Assert.assertEquals(3.1415f, f4.floatValue(), 0.00000f);
BigDecimal f5 = rs.getBigDecimal("f5");
Assert.assertEquals(3.1415926, f5.doubleValue(), 0.0000000);
BigDecimal f7 = rs.getBigDecimal("f7");
Assert.assertEquals(10, f7.intValue());
BigDecimal f8 = rs.getBigDecimal("f8");
Assert.assertEquals(10, f8.intValue());
}
@Test(expected = SQLFeatureNotSupportedException.class)
@Test
public void getBytes() throws SQLException {
rs.getBytes("f1");
byte[] f1 = rs.getBytes("f1");
Assert.assertEquals("2021-01-01 00:00:00.0", new String(f1));
byte[] f2 = rs.getBytes("f2");
Assert.assertEquals(1, Ints.fromByteArray(f2));
byte[] f3 = rs.getBytes("f3");
Assert.assertEquals(100l, Longs.fromByteArray(f3));
byte[] f4 = rs.getBytes("f4");
Assert.assertEquals(3.1415f, Float.valueOf(new String(f4)), 0.000000f);
byte[] f5 = rs.getBytes("f5");
Assert.assertEquals(3.1415926, Double.valueOf(new String(f5)), 0.000000f);
byte[] f6 = rs.getBytes("f6");
Assert.assertEquals("abc", new String(f6));
byte[] f7 = rs.getBytes("f7");
Assert.assertEquals((short) 10, Shorts.fromByteArray(f7));
byte[] f8 = rs.getBytes("f8");
Assert.assertEquals(1, f8.length);
Assert.assertEquals((byte) 10, f8[0]);
byte[] f9 = rs.getBytes("f9");
Assert.assertEquals("true", new String(f9));
byte[] f10 = rs.getBytes("f10");
Assert.assertEquals("涛思数据", new String(f10));
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void getDate() throws SQLException {
rs.getDate("f1");
@Test
public void getDate() throws SQLException, ParseException {
Date f1 = rs.getDate("f1");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Assert.assertEquals(sdf.parse("2021-01-01"), f1);
}
@Test(expected = SQLFeatureNotSupportedException.class)
@Test
public void getTime() throws SQLException {
rs.getTime("f1");
Time f1 = rs.getTime("f1");
Assert.assertEquals("00:00:00", f1.toString());
}
@Test
@ -152,9 +207,49 @@ public class RestfulResultSetTest {
Assert.assertNotNull(meta);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void getObject() throws SQLException {
rs.getObject("f1");
@Test
public void getObject() throws SQLException, ParseException {
Object f1 = rs.getObject("f1");
Assert.assertEquals(Timestamp.class, f1.getClass());
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.sss");
java.util.Date date = sdf.parse("2021-01-01 00:00:00.000");
Assert.assertEquals(new Timestamp(date.getTime()), f1);
Object f2 = rs.getObject("f2");
Assert.assertEquals(Integer.class, f2.getClass());
Assert.assertEquals(1, f2);
Object f3 = rs.getObject("f3");
Assert.assertEquals(Long.class, f3.getClass());
Assert.assertEquals(100l, f3);
Object f4 = rs.getObject("f4");
Assert.assertEquals(Float.class, f4.getClass());
Assert.assertEquals(3.1415f, f4);
Object f5 = rs.getObject("f5");
Assert.assertEquals(Double.class, f5.getClass());
Assert.assertEquals(3.1415926, f5);
Object f6 = rs.getObject("f6");
Assert.assertEquals(byte[].class, f6.getClass());
Assert.assertEquals("abc", new String((byte[]) f6));
Object f7 = rs.getObject("f7");
Assert.assertEquals(Short.class, f7.getClass());
Assert.assertEquals((short) 10, f7);
Object f8 = rs.getObject("f8");
Assert.assertEquals(Byte.class, f8.getClass());
Assert.assertEquals((byte) 10, f8);
Object f9 = rs.getObject("f9");
Assert.assertEquals(Boolean.class, f9.getClass());
Assert.assertEquals(true, f9);
Object f10 = rs.getObject("f10");
Assert.assertEquals(String.class, f10.getClass());
Assert.assertEquals("涛思数据", f10);
}
@Test(expected = SQLException.class)

View File

@ -12,7 +12,6 @@ import java.util.UUID;
public class RestfulStatementTest {
private static final String host = "127.0.0.1";
// private static final String host = "master";
private static Connection conn;
private static Statement stmt;

View File

@ -12,7 +12,6 @@ import java.sql.*;
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class SQLTest {
private static final String host = "127.0.0.1";
// private static final String host = "master";
private static Connection connection;
@Test

View File

@ -0,0 +1,30 @@
package com.taosdata.jdbc.utils;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class OSUtilsTest {
private String OS;
@Test
public void inWindows() {
Assert.assertEquals(OS.indexOf("win") >= 0, OSUtils.isWindows());
}
@Test
public void isMac() {
Assert.assertEquals(OS.indexOf("mac") >= 0, OSUtils.isMac());
}
@Test
public void isLinux() {
Assert.assertEquals(OS.indexOf("nux") >= 0, OSUtils.isLinux());
}
@Before
public void before() {
OS = System.getProperty("os.name").toLowerCase();
}
}

View File

@ -70,13 +70,16 @@ static SStep tsDnodeSteps[] = {
{"dnode-vread", dnodeInitVRead, dnodeCleanupVRead},
{"dnode-vwrite", dnodeInitVWrite, dnodeCleanupVWrite},
{"dnode-vmgmt", dnodeInitVMgmt, dnodeCleanupVMgmt},
{"dnode-mread", dnodeInitMRead, dnodeCleanupMRead},
{"dnode-mwrite", dnodeInitMWrite, dnodeCleanupMWrite},
{"dnode-mpeer", dnodeInitMPeer, dnodeCleanupMPeer},
{"dnode-mread", dnodeInitMRead, NULL},
{"dnode-mwrite", dnodeInitMWrite, NULL},
{"dnode-mpeer", dnodeInitMPeer, NULL},
{"dnode-client", dnodeInitClient, dnodeCleanupClient},
{"dnode-server", dnodeInitServer, dnodeCleanupServer},
{"dnode-vnodes", dnodeInitVnodes, dnodeCleanupVnodes},
{"dnode-modules", dnodeInitModules, dnodeCleanupModules},
{"dnode-mread", NULL, dnodeCleanupMRead},
{"dnode-mwrite", NULL, dnodeCleanupMWrite},
{"dnode-mpeer", NULL, dnodeCleanupMPeer},
{"dnode-shell", dnodeInitShell, dnodeCleanupShell},
{"dnode-statustmr", dnodeInitStatusTimer,dnodeCleanupStatusTimer},
{"dnode-telemetry", dnodeInitTelemetry, dnodeCleanupTelemetry},
@ -234,6 +237,18 @@ static int32_t dnodeInitStorage() {
return -1;
}
TDIR *tdir = tfsOpendir("vnode_bak/.staging");
if (tfsReaddir(tdir) != NULL) {
dError("vnode_bak/.staging dir not empty, fix it first.");
tfsClosedir(tdir);
return -1;
}
if (tfsMkdir("vnode_bak/.staging") < 0) {
dError("failed to create vnode_bak/.staging dir since %s", tstrerror(terrno));
return -1;
}
dnodeCheckDataDirOpenned(tsDnodeDir);
dInfo("dnode storage is initialized at %s", tsDnodeDir);

View File

@ -43,6 +43,7 @@ int32_t dnodeInitServer() {
dnodeProcessReqMsgFp[TSDB_MSG_TYPE_MD_CREATE_VNODE] = dnodeDispatchToVMgmtQueue;
dnodeProcessReqMsgFp[TSDB_MSG_TYPE_MD_ALTER_VNODE] = dnodeDispatchToVMgmtQueue;
dnodeProcessReqMsgFp[TSDB_MSG_TYPE_MD_SYNC_VNODE] = dnodeDispatchToVMgmtQueue;
dnodeProcessReqMsgFp[TSDB_MSG_TYPE_MD_DROP_VNODE] = dnodeDispatchToVMgmtQueue;
dnodeProcessReqMsgFp[TSDB_MSG_TYPE_MD_ALTER_STREAM] = dnodeDispatchToVMgmtQueue;
dnodeProcessReqMsgFp[TSDB_MSG_TYPE_MD_CONFIG_DNODE] = dnodeDispatchToVMgmtQueue;

View File

@ -30,6 +30,7 @@ static taos_queue tsVMgmtQueue = NULL;
static void * dnodeProcessMgmtQueue(void *param);
static int32_t dnodeProcessCreateVnodeMsg(SRpcMsg *pMsg);
static int32_t dnodeProcessAlterVnodeMsg(SRpcMsg *pMsg);
static int32_t dnodeProcessSyncVnodeMsg(SRpcMsg *pMsg);
static int32_t dnodeProcessDropVnodeMsg(SRpcMsg *pMsg);
static int32_t dnodeProcessAlterStreamMsg(SRpcMsg *pMsg);
static int32_t dnodeProcessConfigDnodeMsg(SRpcMsg *pMsg);
@ -39,6 +40,7 @@ static int32_t (*dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_MAX])(SRpcMsg *pMsg);
int32_t dnodeInitVMgmt() {
dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_MD_CREATE_VNODE] = dnodeProcessCreateVnodeMsg;
dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_MD_ALTER_VNODE] = dnodeProcessAlterVnodeMsg;
dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_MD_SYNC_VNODE] = dnodeProcessSyncVnodeMsg;
dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_MD_DROP_VNODE] = dnodeProcessDropVnodeMsg;
dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_MD_ALTER_STREAM] = dnodeProcessAlterStreamMsg;
dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_MD_CONFIG_DNODE] = dnodeProcessConfigDnodeMsg;
@ -179,6 +181,13 @@ static int32_t dnodeProcessAlterVnodeMsg(SRpcMsg *rpcMsg) {
}
}
static int32_t dnodeProcessSyncVnodeMsg(SRpcMsg *rpcMsg) {
SSyncVnodeMsg *pSyncVnode = rpcMsg->pCont;
pSyncVnode->vgId = htonl(pSyncVnode->vgId);
return vnodeSync(pSyncVnode->vgId);
}
static int32_t dnodeProcessDropVnodeMsg(SRpcMsg *rpcMsg) {
SDropVnodeMsg *pDrop = rpcMsg->pCont;
pDrop->vgId = htonl(pDrop->vgId);

View File

@ -206,6 +206,7 @@ static void dnodeProcessStatusRsp(SRpcMsg *pMsg) {
exit(EXIT_FAILURE);
}
}
taosTmrReset(dnodeSendStatusMsg, tsStatusInterval * 1000, NULL, tsDnodeTmr, &tsStatusTimer);
return;
}

View File

@ -259,7 +259,7 @@ do { \
#define TSDB_MIN_TABLES 4
#define TSDB_MAX_TABLES 10000000
#define TSDB_DEFAULT_TABLES 1000000
#define TSDB_TABLES_STEP 100
#define TSDB_TABLES_STEP 1000
#define TSDB_MIN_DAYS_PER_FILE 1
#define TSDB_MAX_DAYS_PER_FILE 3650

View File

@ -59,6 +59,7 @@ TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_MD_DROP_STABLE, "drop-stable" )
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_MD_ALTER_STREAM, "alter-stream" )
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_MD_CONFIG_DNODE, "config-dnode" )
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_MD_ALTER_VNODE, "alter-vnode" )
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_MD_SYNC_VNODE, "sync-vnode" )
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_MD_CREATE_MNODE, "create-mnode" )
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_DUMMY6, "dummy6" )
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_DUMMY7, "dummy7" )
@ -389,7 +390,7 @@ typedef struct {
typedef struct {
int32_t vgId;
} SDropVnodeMsg;
} SDropVnodeMsg, SSyncVnodeMsg;
typedef struct SColIndex {
int16_t colId; // column id

View File

@ -79,9 +79,6 @@ typedef void (*FStopSyncFile)(int32_t vgId, uint64_t fversion);
// get file version
typedef int32_t (*FGetVersion)(int32_t vgId, uint64_t *fver, uint64_t *vver);
// reset version
typedef int32_t (*FResetVersion)(int32_t vgId, uint64_t fver);
typedef int32_t (*FSendFile)(void *tsdb, SOCKET socketFd);
typedef int32_t (*FRecvFile)(void *tsdb, SOCKET socketFd);
@ -99,7 +96,6 @@ typedef struct {
FStartSyncFile startSyncFileFp;
FStopSyncFile stopSyncFileFp;
FGetVersion getVersionFp;
FResetVersion resetVersionFp;
FSendFile sendFileFp;
FRecvFile recvFileFp;
} SSyncInfo;

View File

@ -60,6 +60,7 @@ int32_t vnodeCreate(SCreateVnodeMsg *pVnodeCfg);
int32_t vnodeDrop(int32_t vgId);
int32_t vnodeOpen(int32_t vgId);
int32_t vnodeAlter(void *pVnode, SCreateVnodeMsg *pVnodeCfg);
int32_t vnodeSync(int32_t vgId);
int32_t vnodeClose(int32_t vgId);
// vnodeMgmt

File diff suppressed because it is too large Load Diff

View File

@ -49,6 +49,7 @@ void mnodeRemoveTableFromVgroup(SVgObj *pVgroup, SCTableObj *pTable);
void mnodeSendDropVnodeMsg(int32_t vgId, SRpcEpSet *epSet, void *ahandle);
void mnodeSendCreateVgroupMsg(SVgObj *pVgroup, void *ahandle);
void mnodeSendAlterVgroupMsg(SVgObj *pVgroup);
void mnodeSendSyncVgroupMsg(SVgObj *pVgroup);
SRpcEpSet mnodeGetEpSetFromVgroup(SVgObj *pVgroup);
SRpcEpSet mnodeGetEpSetFromIp(char *ep);

View File

@ -1186,8 +1186,44 @@ static int32_t mnodeProcessDropDbMsg(SMnodeMsg *pMsg) {
return mnodeDropDb(pMsg);
}
static int32_t mnodeSyncDb(SDbObj *pDb, SMnodeMsg *pMsg) {
void *pIter = NULL;
SVgObj *pVgroup = NULL;
while (1) {
pIter = mnodeGetNextVgroup(pIter, &pVgroup);
if (pVgroup == NULL) break;
if (pVgroup->pDb == pDb) {
mnodeSendSyncVgroupMsg(pVgroup);
}
mnodeDecVgroupRef(pVgroup);
}
mLInfo("db:%s, is synced by %s", pDb->name, mnodeGetUserFromMsg(pMsg));
return TSDB_CODE_SUCCESS;
}
static int32_t mnodeProcessSyncDbMsg(SMnodeMsg *pMsg) {
return 0;
SSyncDbMsg *pSyncDb = pMsg->rpcMsg.pCont;
mDebug("db:%s, syncdb is received from thandle:%p, ignore:%d", pSyncDb->db, pMsg->rpcMsg.handle, pSyncDb->ignoreNotExists);
if (pMsg->pDb == NULL) pMsg->pDb = mnodeGetDb(pSyncDb->db);
if (pMsg->pDb == NULL) {
if (pSyncDb->ignoreNotExists) {
mDebug("db:%s, db is not exist, treat as success", pSyncDb->db);
return TSDB_CODE_SUCCESS;
} else {
mError("db:%s, failed to sync, invalid db", pSyncDb->db);
return TSDB_CODE_MND_INVALID_DB;
}
}
if (pMsg->pDb->status != TSDB_DB_STATUS_READY) {
mError("db:%s, status:%d, in dropping", pSyncDb->db, pMsg->pDb->status);
return TSDB_CODE_MND_DB_IN_DROPPING;
}
return mnodeSyncDb(pMsg->pDb, pMsg);
}
void mnodeDropAllDbs(SAcctObj *pAcct) {

View File

@ -722,6 +722,10 @@ int32_t mnodeDropDnode(SDnodeObj *pDnode, void *pMsg) {
static int32_t mnodeDropDnodeByEp(char *ep, SMnodeMsg *pMsg) {
SDnodeObj *pDnode = mnodeGetDnodeByEp(ep);
if (pDnode == NULL) {
if (strspn(ep, "0123456789 ;") != strlen(ep)) {
return TSDB_CODE_MND_DNODE_NOT_EXIST;
}
int32_t dnodeId = (int32_t)strtol(ep, NULL, 10);
pDnode = mnodeGetDnode(dnodeId);
if (pDnode == NULL) {

View File

@ -60,6 +60,7 @@ static int32_t mnodeGetVgroupMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *p
static int32_t mnodeRetrieveVgroups(SShowObj *pShow, char *data, int32_t rows, void *pConn);
static void mnodeProcessCreateVnodeRsp(SRpcMsg *rpcMsg);
static void mnodeProcessAlterVnodeRsp(SRpcMsg *rpcMsg);
static void mnodeProcessSyncVnodeRsp(SRpcMsg *rpcMsg);
static void mnodeProcessDropVnodeRsp(SRpcMsg *rpcMsg);
static int32_t mnodeProcessVnodeCfgMsg(SMnodeMsg *pMsg) ;
static void mnodeSendDropVgroupMsg(SVgObj *pVgroup, void *ahandle);
@ -236,6 +237,7 @@ int32_t mnodeInitVgroups() {
mnodeAddShowFreeIterHandle(TSDB_MGMT_TABLE_VGROUP, mnodeCancelGetNextVgroup);
mnodeAddPeerRspHandle(TSDB_MSG_TYPE_MD_CREATE_VNODE_RSP, mnodeProcessCreateVnodeRsp);
mnodeAddPeerRspHandle(TSDB_MSG_TYPE_MD_ALTER_VNODE_RSP, mnodeProcessAlterVnodeRsp);
mnodeAddPeerRspHandle(TSDB_MSG_TYPE_MD_ALTER_VNODE_RSP, mnodeProcessSyncVnodeRsp);
mnodeAddPeerRspHandle(TSDB_MSG_TYPE_MD_DROP_VNODE_RSP, mnodeProcessDropVnodeRsp);
mnodeAddPeerMsgHandle(TSDB_MSG_TYPE_DM_CONFIG_VNODE, mnodeProcessVnodeCfgMsg);
@ -967,6 +969,38 @@ void mnodeSendAlterVgroupMsg(SVgObj *pVgroup) {
}
}
static SSyncVnodeMsg *mnodeBuildSyncVnodeMsg(int32_t vgId) {
SSyncVnodeMsg *pSyncVnode = rpcMallocCont(sizeof(SSyncVnodeMsg));
if (pSyncVnode == NULL) return NULL;
pSyncVnode->vgId = htonl(vgId);
return pSyncVnode;
}
static void mnodeSendSyncVnodeMsg(SVgObj *pVgroup, SRpcEpSet *epSet) {
SSyncVnodeMsg *pSyncVnode = mnodeBuildSyncVnodeMsg(pVgroup->vgId);
SRpcMsg rpcMsg = {
.ahandle = NULL,
.pCont = pSyncVnode,
.contLen = pSyncVnode ? sizeof(SSyncVnodeMsg) : 0,
.code = 0,
.msgType = TSDB_MSG_TYPE_MD_SYNC_VNODE
};
dnodeSendMsgToDnode(epSet, &rpcMsg);
}
void mnodeSendSyncVgroupMsg(SVgObj *pVgroup) {
mDebug("vgId:%d, send sync all vnodes msg, numOfVnodes:%d db:%s", pVgroup->vgId, pVgroup->numOfVnodes,
pVgroup->dbName);
for (int32_t i = 0; i < pVgroup->numOfVnodes; ++i) {
SRpcEpSet epSet = mnodeGetEpSetFromIp(pVgroup->vnodeGid[i].pDnode->dnodeEp);
mDebug("vgId:%d, index:%d, send sync vnode msg to dnode %s", pVgroup->vgId, i,
pVgroup->vnodeGid[i].pDnode->dnodeEp);
mnodeSendSyncVnodeMsg(pVgroup, &epSet);
}
}
static void mnodeSendCreateVnodeMsg(SVgObj *pVgroup, SRpcEpSet *epSet, void *ahandle) {
SCreateVnodeMsg *pCreate = mnodeBuildVnodeMsg(pVgroup);
SRpcMsg rpcMsg = {
@ -994,6 +1028,10 @@ static void mnodeProcessAlterVnodeRsp(SRpcMsg *rpcMsg) {
mDebug("alter vnode rsp received");
}
static void mnodeProcessSyncVnodeRsp(SRpcMsg *rpcMsg) {
mDebug("sync vnode rsp received");
}
static void mnodeProcessCreateVnodeRsp(SRpcMsg *rpcMsg) {
if (rpcMsg->ahandle == NULL) return;

View File

@ -117,7 +117,6 @@ typedef struct SSyncNode {
FStartSyncFile startSyncFileFp;
FStopSyncFile stopSyncFileFp;
FGetVersion getVersionFp;
FResetVersion resetVersionFp;
FSendFile sendFileFp;
FRecvFile recvFileFp;
pthread_mutex_t mutex;

View File

@ -182,7 +182,6 @@ int64_t syncStart(const SSyncInfo *pInfo) {
pNode->startSyncFileFp = pInfo->startSyncFileFp;
pNode->stopSyncFileFp = pInfo->stopSyncFileFp;
pNode->getVersionFp = pInfo->getVersionFp;
pNode->resetVersionFp = pInfo->resetVersionFp;
pNode->sendFileFp = pInfo->sendFileFp;
pNode->recvFileFp = pInfo->recvFileFp;
@ -410,7 +409,7 @@ void syncConfirmForward(int64_t rid, uint64_t version, int32_t code, bool force)
syncReleaseNode(pNode);
}
#if 0
#if 1
void syncRecover(int64_t rid) {
SSyncPeer *pPeer;

View File

@ -238,7 +238,6 @@ static int32_t syncRestoreDataStepByStep(SSyncPeer *pPeer) {
(*pNode->stopSyncFileFp)(pNode->vgId, fversion);
nodeVersion = fversion;
if (pNode->resetVersionFp) (*pNode->resetVersionFp)(pNode->vgId, fversion);
sInfo("%s, start to restore wal, fver:%" PRIu64, pPeer->id, nodeVersion);
uint64_t wver = 0;

View File

@ -17,7 +17,7 @@
#define TSDB_MAX_SUBBLOCKS 8
static FORCE_INLINE int TSDB_KEY_FID(TSKEY key, int32_t days, int8_t precision) {
if (key < 0) {
return (int)((key + 1) / tsMsPerDay[precision] / days + 1);
return (int)((key + 1) / tsMsPerDay[precision] / days - 1);
} else {
return (int)((key / tsMsPerDay[precision] / days));
}
@ -452,6 +452,14 @@ static int tsdbCommitToFile(SCommitH *pCommith, SDFileSet *pSet, int fid) {
return -1;
}
if (tsdbUpdateDFileSetHeader(&(pCommith->wSet)) < 0) {
tsdbError("vgId:%d failed to update FSET %d header since %s", REPO_ID(pRepo), fid, tstrerror(terrno));
tsdbCloseCommitFile(pCommith, true);
// revert the file change
tsdbApplyDFileSetChange(TSDB_COMMIT_WRITE_FSET(pCommith), pSet);
return -1;
}
// Close commit file
tsdbCloseCommitFile(pCommith, false);

View File

@ -33,6 +33,7 @@ static int tsdbScanDataDir(STsdbRepo *pRepo);
static bool tsdbIsTFileInFS(STsdbFS *pfs, const TFILE *pf);
static int tsdbRestoreCurrent(STsdbRepo *pRepo);
static int tsdbComparTFILE(const void *arg1, const void *arg2);
static void tsdbScanAndTryFixDFilesHeader(STsdbRepo *pRepo);
// ================== CURRENT file header info
static int tsdbEncodeFSHeader(void **buf, SFSHeader *pHeader) {
@ -246,6 +247,8 @@ int tsdbOpenFS(STsdbRepo *pRepo) {
tsdbError("vgId:%d failed to open FS since %s", REPO_ID(pRepo), tstrerror(terrno));
return -1;
}
tsdbScanAndTryFixDFilesHeader(pRepo);
} else {
if (tsdbRestoreCurrent(pRepo) < 0) {
tsdbError("vgId:%d failed to restore current file since %s", REPO_ID(pRepo), tstrerror(terrno));
@ -1202,3 +1205,40 @@ static int tsdbComparTFILE(const void *arg1, const void *arg2) {
}
}
}
static void tsdbScanAndTryFixDFilesHeader(STsdbRepo *pRepo) {
STsdbFS * pfs = REPO_FS(pRepo);
SFSStatus *pStatus = pfs->cstatus;
SDFInfo info;
for (size_t i = 0; i < taosArrayGetSize(pStatus->df); i++) {
SDFileSet fset;
tsdbInitDFileSetEx(&fset, (SDFileSet *)taosArrayGet(pStatus->df, i));
tsdbDebug("vgId:%d scan DFileSet %d header", REPO_ID(pRepo), fset.fid);
if (tsdbOpenDFileSet(&fset, O_RDWR) < 0) {
tsdbError("vgId:%d failed to open DFileSet %d since %s, continue", REPO_ID(pRepo), fset.fid, tstrerror(terrno));
continue;
}
for (TSDB_FILE_T ftype = 0; ftype < TSDB_FILE_MAX; ftype++) {
SDFile *pDFile = TSDB_DFILE_IN_SET(&fset, ftype);
if ((tsdbLoadDFileHeader(pDFile, &info) < 0) || pDFile->info.size != info.size ||
pDFile->info.magic != info.magic) {
if (tsdbUpdateDFileHeader(pDFile) < 0) {
tsdbError("vgId:%d failed to update DFile header of %s since %s, continue", REPO_ID(pRepo),
TSDB_FILE_FULL_NAME(pDFile), tstrerror(terrno));
} else {
tsdbInfo("vgId:%d DFile header of %s is updated", REPO_ID(pRepo), TSDB_FILE_FULL_NAME(pDFile));
TSDB_FILE_FSYNC(pDFile);
}
} else {
tsdbDebug("vgId:%d DFile header of %s is correct", REPO_ID(pRepo), TSDB_FILE_FULL_NAME(pDFile));
}
}
tsdbCloseDFileSet(&fset);
}
}

View File

@ -134,14 +134,14 @@ int tsdbCreateMFile(SMFile *pMFile, bool updateHeader) {
return 0;
}
pMFile->info.size += TSDB_FILE_HEAD_SIZE;
if (tsdbUpdateMFileHeader(pMFile) < 0) {
tsdbCloseMFile(pMFile);
tsdbRemoveMFile(pMFile);
return -1;
}
pMFile->info.size += TSDB_FILE_HEAD_SIZE;
return 0;
}
@ -378,14 +378,14 @@ int tsdbCreateDFile(SDFile *pDFile, bool updateHeader) {
return 0;
}
pDFile->info.size += TSDB_FILE_HEAD_SIZE;
if (tsdbUpdateDFileHeader(pDFile) < 0) {
tsdbCloseDFile(pDFile);
tsdbRemoveDFile(pDFile);
return -1;
}
pDFile->info.size += TSDB_FILE_HEAD_SIZE;
return 0;
}
@ -567,6 +567,7 @@ void tsdbInitDFileSet(SDFileSet *pSet, SDiskID did, int vid, int fid, uint32_t v
}
void tsdbInitDFileSetEx(SDFileSet *pSet, SDFileSet *pOSet) {
pSet->fid = pOSet->fid;
for (TSDB_FILE_T ftype = 0; ftype < TSDB_FILE_MAX; ftype++) {
tsdbInitDFileEx(TSDB_DFILE_IN_SET(pSet, ftype), TSDB_DFILE_IN_SET(pOSet, ftype));
}

View File

@ -917,7 +917,9 @@ static int32_t loadBlockInfo(STsdbQueryHandle * pQueryHandle, int32_t index, int
pCheckInfo->compSize = compIndex->len;
}
tsdbLoadBlockInfo(&(pQueryHandle->rhelper), (void*)(pCheckInfo->pCompInfo));
if (tsdbLoadBlockInfo(&(pQueryHandle->rhelper), (void*)(pCheckInfo->pCompInfo)) < 0) {
return terrno;
}
SBlockInfo* pCompInfo = pCheckInfo->pCompInfo;
TSKEY s = TSKEY_INITIAL_VAL, e = TSKEY_INITIAL_VAL;
@ -2832,7 +2834,9 @@ int32_t tsdbRetrieveDataBlockStatisInfo(TsdbQueryHandleT* pQueryHandle, SDataSta
}
int64_t stime = taosGetTimestampUs();
tsdbLoadBlockStatis(&pHandle->rhelper, pBlockInfo->compBlock);
if (tsdbLoadBlockStatis(&pHandle->rhelper, pBlockInfo->compBlock) < 0) {
return terrno;
}
int16_t* colIds = pHandle->defaultLoadColumn->pData;

View File

@ -194,8 +194,8 @@ static int32_t tsdbSyncRecvMeta(SSyncH *pSynch) {
return 0;
}
if (pLMFile == NULL || memcmp(&(pSynch->pmf->info), &(pLMFile->info), sizeof(SMFInfo)) != 0 ||
TSDB_FILE_IS_BAD(pLMFile)) {
if (pLMFile == NULL || pSynch->pmf->info.size != pLMFile->info.size ||
pSynch->pmf->info.magic != pLMFile->info.magic || TSDB_FILE_IS_BAD(pLMFile)) {
// Local has no meta file or has a different meta file, need to copy from remote
pSynch->mfChanged = true;
@ -536,7 +536,7 @@ static bool tsdbIsTowFSetSame(SDFileSet *pSet1, SDFileSet *pSet2) {
SDFile *pDFile1 = TSDB_DFILE_IN_SET(pSet1, ftype);
SDFile *pDFile2 = TSDB_DFILE_IN_SET(pSet2, ftype);
if (memcmp((void *)(TSDB_FILE_INFO(pDFile1)), (void *)(TSDB_FILE_INFO(pDFile2)), sizeof(SDFInfo)) != 0) {
if (pDFile1->info.size != pDFile2->info.size || pDFile1->info.magic != pDFile2->info.magic) {
return false;
}
}

View File

@ -0,0 +1,32 @@
/*
* 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/>.
*/
#ifndef TDENGINE_VNODE_BACKUP_H
#define TDENGINE_VNODE_BACKUP_H
#ifdef __cplusplus
extern "C" {
#endif
#include "vnodeInt.h"
int32_t vnodeInitBackup();
void vnodeCleanupBackup();
int32_t vnodeBackup(int32_t vgId);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -25,6 +25,7 @@ int32_t vnodeCreate(SCreateVnodeMsg *pVnodeCfg);
int32_t vnodeDrop(int32_t vgId);
int32_t vnodeOpen(int32_t vgId);
int32_t vnodeAlter(void *pVnode, SCreateVnodeMsg *pVnodeCfg);
int32_t vnodeSync(int32_t vgId);
int32_t vnodeClose(int32_t vgId);
void vnodeCleanUp(SVnodeObj *pVnode);
void vnodeDestroy(SVnodeObj *pVnode);

View File

@ -30,7 +30,6 @@ void vnodeStopSyncFile(int32_t vgId, uint64_t fversion);
void vnodeConfirmForard(int32_t vgId, void *wparam, int32_t code);
int32_t vnodeWriteToCache(int32_t vgId, void *wparam, int32_t qtype, void *rparam);
int32_t vnodeGetVersion(int32_t vgId, uint64_t *fver, uint64_t *wver);
int32_t vnodeResetVersion(int32_t vgId, uint64_t fver);
void vnodeConfirmForward(void *pVnode, uint64_t version, int32_t code, bool force);

172
src/vnode/src/vnodeBackup.c Normal file
View File

@ -0,0 +1,172 @@
/*
* 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/>.
*/
#define _DEFAULT_SOURCE
#include "os.h"
#include "taoserror.h"
#include "taosmsg.h"
#include "tutil.h"
#include "tqueue.h"
#include "tglobal.h"
#include "tfs.h"
#include "vnodeBackup.h"
#include "vnodeMain.h"
typedef struct {
int32_t vgId;
} SVBackupMsg;
typedef struct {
pthread_t thread;
int32_t workerId;
} SVBackupWorker;
typedef struct {
int32_t num;
SVBackupWorker *worker;
} SVBackupWorkerPool;
static SVBackupWorkerPool tsVBackupPool;
static taos_qset tsVBackupQset;
static taos_queue tsVBackupQueue;
static void vnodeProcessBackupMsg(SVBackupMsg *pMsg) {
int32_t vgId = pMsg->vgId;
char newDir[TSDB_FILENAME_LEN] = {0};
char stagingDir[TSDB_FILENAME_LEN] = {0};
sprintf(newDir, "%s/vnode%d", "vnode_bak", vgId);
sprintf(stagingDir, "%s/.staging/vnode%d", "vnode_bak", vgId);
if (tsEnableVnodeBak) {
tfsRmdir(newDir);
tfsRename(stagingDir, newDir);
} else {
vInfo("vgId:%d, vnode backup not enabled", vgId);
tfsRmdir(stagingDir);
}
}
static void *vnodeBackupFunc(void *param) {
while (1) {
SVBackupMsg *pMsg = NULL;
if (taosReadQitemFromQset(tsVBackupQset, NULL, (void **)&pMsg, NULL) == 0) {
vDebug("qset:%p, vbackup got no message from qset, exiting", tsVBackupQset);
break;
}
vTrace("vgId:%d, will be processed in vbackup queue", pMsg->vgId);
vnodeProcessBackupMsg(pMsg);
vTrace("vgId:%d, disposed in vbackup worker", pMsg->vgId);
taosFreeQitem(pMsg);
}
return NULL;
}
static int32_t vnodeStartBackup() {
tsVBackupQueue = taosOpenQueue();
if (tsVBackupQueue == NULL) return TSDB_CODE_DND_OUT_OF_MEMORY;
taosAddIntoQset(tsVBackupQset, tsVBackupQueue, NULL);
for (int32_t i = 0; i < tsVBackupPool.num; ++i) {
SVBackupWorker *pWorker = tsVBackupPool.worker + i;
pWorker->workerId = i;
pthread_attr_t thAttr;
pthread_attr_init(&thAttr);
pthread_attr_setdetachstate(&thAttr, PTHREAD_CREATE_JOINABLE);
if (pthread_create(&pWorker->thread, &thAttr, vnodeBackupFunc, pWorker) != 0) {
vError("failed to create thread to process vbackup queue, reason:%s", strerror(errno));
}
pthread_attr_destroy(&thAttr);
vDebug("vbackup:%d is launched, total:%d", pWorker->workerId, tsVBackupPool.num);
}
vDebug("vbackup queue:%p is allocated", tsVBackupQueue);
return TSDB_CODE_SUCCESS;
}
static int32_t vnodeWriteIntoBackupWorker(int32_t vgId) {
SVBackupMsg *pMsg = taosAllocateQitem(sizeof(SVBackupMsg));
if (pMsg == NULL) return TSDB_CODE_VND_OUT_OF_MEMORY;
pMsg->vgId = vgId;
int32_t code = taosWriteQitem(tsVBackupQueue, TAOS_QTYPE_RPC, pMsg);
if (code == 0) code = TSDB_CODE_DND_ACTION_IN_PROGRESS;
return code;
}
int32_t vnodeBackup(int32_t vgId) {
vTrace("vgId:%d, will backup", vgId);
return vnodeWriteIntoBackupWorker(vgId);
}
int32_t vnodeInitBackup() {
tsVBackupQset = taosOpenQset();
tsVBackupPool.num = 1;
tsVBackupPool.worker = calloc(sizeof(SVBackupWorker), tsVBackupPool.num);
if (tsVBackupPool.worker == NULL) return -1;
for (int32_t i = 0; i < tsVBackupPool.num; ++i) {
SVBackupWorker *pWorker = tsVBackupPool.worker + i;
pWorker->workerId = i;
vDebug("vbackup:%d is created", i);
}
vDebug("vbackup is initialized, num:%d qset:%p", tsVBackupPool.num, tsVBackupQset);
return vnodeStartBackup();
}
void vnodeCleanupBackup() {
for (int32_t i = 0; i < tsVBackupPool.num; ++i) {
SVBackupWorker *pWorker = tsVBackupPool.worker + i;
if (taosCheckPthreadValid(pWorker->thread)) {
taosQsetThreadResume(tsVBackupQset);
}
vDebug("vbackup:%d is closed", i);
}
for (int32_t i = 0; i < tsVBackupPool.num; ++i) {
SVBackupWorker *pWorker = tsVBackupPool.worker + i;
vDebug("vbackup:%d start to join", i);
if (taosCheckPthreadValid(pWorker->thread)) {
pthread_join(pWorker->thread, NULL);
}
vDebug("vbackup:%d join success", i);
}
vDebug("vbackup is closed, qset:%p", tsVBackupQset);
taosCloseQset(tsVBackupQset);
tsVBackupQset = NULL;
tfree(tsVBackupPool.worker);
vDebug("vbackup queue:%p is freed", tsVBackupQueue);
taosCloseQueue(tsVBackupQueue);
tsVBackupQueue = NULL;
}

View File

@ -27,6 +27,7 @@
#include "vnodeVersion.h"
#include "vnodeMgmt.h"
#include "vnodeWorker.h"
#include "vnodeBackup.h"
#include "vnodeMain.h"
static int32_t vnodeProcessTsdbStatus(void *arg, int32_t status, int32_t eno);
@ -91,6 +92,23 @@ int32_t vnodeCreate(SCreateVnodeMsg *pVnodeCfg) {
return code;
}
int32_t vnodeSync(int32_t vgId) {
SVnodeObj *pVnode = vnodeAcquire(vgId);
if (pVnode == NULL) {
vDebug("vgId:%d, failed to sync, vnode not find", vgId);
return TSDB_CODE_VND_INVALID_VGROUP_ID;
}
if (pVnode->role != TAOS_SYNC_ROLE_MASTER) {
vInfo("vgId:%d, vnode will sync, refCount:%d pVnode:%p", pVnode->vgId, pVnode->refCount, pVnode);
syncRecover(pVnode->sync);
}
vnodeRelease(pVnode);
return TSDB_CODE_SUCCESS;
}
int32_t vnodeDrop(int32_t vgId) {
SVnodeObj *pVnode = vnodeAcquire(vgId);
if (pVnode == NULL) {
@ -347,7 +365,6 @@ int32_t vnodeOpen(int32_t vgId) {
syncInfo.startSyncFileFp = vnodeStartSyncFile;
syncInfo.stopSyncFileFp = vnodeStopSyncFile;
syncInfo.getVersionFp = vnodeGetVersion;
syncInfo.resetVersionFp = vnodeResetVersion;
syncInfo.sendFileFp = tsdbSyncSend;
syncInfo.recvFileFp = tsdbSyncRecv;
syncInfo.pTsdb = pVnode->tsdb;
@ -431,18 +448,14 @@ void vnodeDestroy(SVnodeObj *pVnode) {
if (pVnode->dropped) {
char rootDir[TSDB_FILENAME_LEN] = {0};
char newDir[TSDB_FILENAME_LEN] = {0};
char stagingDir[TSDB_FILENAME_LEN] = {0};
sprintf(rootDir, "%s/vnode%d", "vnode", vgId);
sprintf(newDir, "%s/vnode%d", "vnode_bak", vgId);
sprintf(stagingDir, "%s/.staging/vnode%d", "vnode_bak", vgId);
if (0 == tsEnableVnodeBak) {
vInfo("vgId:%d, vnode backup not enabled", pVnode->vgId);
} else {
tfsRmdir(newDir);
tfsRename(rootDir, newDir);
}
tfsRename(rootDir, stagingDir);
vnodeBackup(vgId);
tfsRmdir(rootDir);
dnodeSendStatusMsgToMnode();
}

View File

@ -17,6 +17,7 @@
#include "os.h"
#include "dnode.h"
#include "vnodeStatus.h"
#include "vnodeBackup.h"
#include "vnodeWorker.h"
#include "vnodeRead.h"
#include "vnodeWrite.h"
@ -29,6 +30,7 @@ static void vnodeCleanupHash(void);
static void vnodeIncRef(void *ptNode);
static SStep tsVnodeSteps[] = {
{"vnode-backup", vnodeInitBackup, vnodeCleanupBackup},
{"vnode-worker", vnodeInitMWorker, vnodeCleanupMWorker},
{"vnode-write", vnodeInitWrite, vnodeCleanupWrite},
{"vnode-read", vnodeInitRead, vnodeCleanupRead},

View File

@ -107,8 +107,9 @@ void vnodeStopSyncFile(int32_t vgId, uint64_t fversion) {
pVnode->fversion = fversion;
pVnode->version = fversion;
vnodeSaveVersion(pVnode);
walResetVersion(pVnode->wal, fversion);
vDebug("vgId:%d, datafile is synced, fver:%" PRIu64 " vver:%" PRIu64, vgId, fversion, fversion);
vInfo("vgId:%d, datafile is synced, fver:%" PRIu64 " vver:%" PRIu64, vgId, fversion, fversion);
vnodeSetReadyStatus(pVnode);
vnodeRelease(pVnode);
@ -158,22 +159,6 @@ int32_t vnodeGetVersion(int32_t vgId, uint64_t *fver, uint64_t *wver) {
return code;
}
int32_t vnodeResetVersion(int32_t vgId, uint64_t fver) {
SVnodeObj *pVnode = vnodeAcquire(vgId);
if (pVnode == NULL) {
vError("vgId:%d, vnode not found while reset version", vgId);
return -1;
}
pVnode->fversion = fver;
pVnode->version = fver;
walResetVersion(pVnode->wal, fver);
vInfo("vgId:%d, version reset to %" PRIu64, vgId, fver);
vnodeRelease(pVnode);
return 0;
}
void vnodeConfirmForward(void *vparam, uint64_t version, int32_t code, bool force) {
SVnodeObj *pVnode = vparam;
syncConfirmForward(pVnode->sync, version, code, force);

16
tests/Jenkinsfile vendored
View File

@ -76,9 +76,20 @@ pipeline {
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
sh '''
cd ${WKC}/tests/pytest
rm -rf /var/lib/taos/*
rm -rf /var/log/taos/*
./handle_crash_gen_val_log.sh
'''
}
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
sh '''
cd ${WKC}/tests/pytest
rm -rf /var/lib/taos/*
rm -rf /var/log/taos/*
./handle_taosd_val_log.sh
'''
}
sh'''
systemctl start taosd
sleep 10
@ -163,6 +174,11 @@ pipeline {
cd ${WKC}/tests
./test-all.sh b3
date'''
sh '''
date
cd ${WKC}/tests
./test-all.sh full example
date'''
}
}

View File

@ -13,7 +13,7 @@
<dependency>
<groupId>com.taosdata.jdbc</groupId>
<artifactId>taos-jdbcdriver</artifactId>
<version>2.0.20</version>
<version>2.0.22</version>
</dependency>
</dependencies>

View File

@ -68,12 +68,12 @@ public class JDBCDemo {
}
private void insert() {
final String sql = "insert into test.weather (ts, temperature, humidity) values(now, 20.5, 34)";
final String sql = "insert into " + dbName + "." + tbName + " (ts, temperature, humidity) values(now, 20.5, 34)";
exuete(sql);
}
private void select() {
final String sql = "select * from test.weather";
final String sql = "select * from "+ dbName + "." + tbName;
executeQuery(sql);
}

View File

@ -50,7 +50,7 @@ function buildTDengine {
echo "repo up-to-date"
else
echo "repo need to pull"
git pull > /dev/null
git pull > /dev/null 2>&1
LOCAL_COMMIT=`git rev-parse --short @`
cd debug
@ -72,26 +72,13 @@ function runQueryPerfTest {
python3 insert/insertFromCSVPerformance.py -c $LOCAL_COMMIT | tee -a $PERFORMANCE_TEST_REPORT
yes | taosdemo -c /etc/taosperf/ -d taosdemo_insert_test -x > taosdemoperf.txt
CREATETABLETIME=`grep 'Spent' taosdemoperf.txt | awk 'NR==1{print $2}'`
INSERTRECORDSTIME=`grep 'Spent' taosdemoperf.txt | awk 'NR==2{print $2}'`
REQUESTSPERSECOND=`grep 'Spent' taosdemoperf.txt | awk 'NR==2{print $13}'`
delay=`grep 'delay' taosdemoperf.txt | awk '{print $4}'`
AVGDELAY=`echo ${delay:0:${#delay}-3}`
delay=`grep 'delay' taosdemoperf.txt | awk '{print $6}'`
MAXDELAY=`echo ${delay:0:${#delay}-3}`
delay=`grep 'delay' taosdemoperf.txt | awk '{print $8}'`
MINDELAY=`echo ${delay:0:${#delay}-2}`
python3 tools/taosdemoPerformance.py -c $LOCAL_COMMIT -t $CREATETABLETIME -i $INSERTRECORDSTIME -r $REQUESTSPERSECOND -avg $AVGDELAY -max $MAXDELAY -min $MINDELAY | tee -a $PERFORMANCE_TEST_REPORT
[ -f taosdemoperf.txt ] && rm taosdemoperf.txt
python3 tools/taosdemoPerformance.py -c $LOCAL_COMMIT | tee -a $PERFORMANCE_TEST_REPORT
}
function sendReport {
echo "send report"
receiver="pxiao@taosdata.com"
receiver="develop@taosdata.com"
mimebody="MIME-Version: 1.0\nContent-Type: text/html; charset=utf-8\n"
cd $TDENGINE_DIR

View File

@ -139,6 +139,18 @@ python3 ./test.py -f import_merge/importInsertThenImport.py
python3 ./test.py -f import_merge/importCSV.py
#======================p1-end===============
#======================p2-start===============
# tools
python3 test.py -f tools/taosdumpTest.py
python3 test.py -f tools/taosdemoTest.py
python3 test.py -f tools/taosdemoTestWithoutMetric.py
python3 test.py -f tools/taosdemoTestWithJson.py
python3 test.py -f tools/taosdemoTestLimitOffset.py
python3 test.py -f tools/taosdemoTestTblAlt.py
python3 test.py -f tools/taosdemoTestSampleData.py
python3 test.py -f tools/taosdemoTestInterlace.py
python3 test.py -f tools/taosdemoTestQuery.py
# update
python3 ./test.py -f update/allow_update.py
python3 ./test.py -f update/allow_update-0.py
@ -164,6 +176,11 @@ python3 ./test.py -f user/pass_len.py
# stable
python3 ./test.py -f stable/query_after_reset.py
# perfbenchmark
python3 ./test.py -f perfbenchmark/bug3433.py
python3 ./test.py -f perfbenchmark/bug3589.py
#query
python3 ./test.py -f query/filter.py
python3 ./test.py -f query/filterCombo.py
@ -196,6 +213,8 @@ python3 ./test.py -f query/bug2119.py
python3 ./test.py -f query/isNullTest.py
python3 ./test.py -f query/queryWithTaosdKilled.py
python3 ./test.py -f query/floatCompare.py
python3 ./test.py -f query/query1970YearsAf.py
python3 ./test.py -f query/bug3351.py
python3 ./test.py -f query/bug3375.py
@ -242,18 +261,6 @@ python3 test.py -f subscribe/supertable.py
#======================p3-end===============
#======================p4-start===============
# tools
python3 test.py -f tools/taosdumpTest.py
python3 test.py -f tools/taosdemoTest.py
python3 test.py -f tools/taosdemoTestWithoutMetric.py
python3 test.py -f tools/taosdemoTestWithJson.py
python3 test.py -f tools/taosdemoTestLimitOffset.py
python3 test.py -f tools/taosdemoTest2.py
python3 test.py -f tools/taosdemoTestSampleData.py
python3 test.py -f tools/taosdemoTestInterlace.py
python3 test.py -f tools/taosdemoTestQuery.py
python3 ./test.py -f update/merge_commit_data-0.py
# wal
python3 ./test.py -f wal/addOldWalTest.py

View File

@ -0,0 +1,68 @@
#!/bin/bash
# Color setting
RED='\033[0;31m'
GREEN='\033[1;32m'
GREEN_DARK='\033[0;32m'
GREEN_UNDERLINE='\033[4;32m'
NC='\033[0m'
IN_TDINTERNAL="community"
TDIR=`pwd`
if [[ "$tests_dir" == *"$IN_TDINTERNAL"* ]]; then
cd ../..
else
cd ../../..
fi
TOP_DIR=`pwd`
TAOSD_DIR=`find . -name "taosd"|grep -v community|grep debug|head -n1`
VALGRIND_OUT=taosd_valgrind.out
VALGRIND_ERR=taosd_valgrind.err
rm -rf /var/lib/taos/*
# nohup valgrind --tool=memcheck --leak-check=yes $TAOSD_DIR > $TDIR/$VALGRIND_OUT 2> $TDIR/$VALGRIND_ERR &
nohup valgrind --leak-check=yes $TAOSD_DIR > $TDIR/$VALGRIND_OUT 2> $TDIR/$VALGRIND_ERR &
sleep 20
cd -
./crash_gen.sh -p -t 10 -s 200
ps -ef |grep valgrind|grep -v grep|awk '{print $2}'|xargs kill -term
while true
do
monitoring=` ps -ef|grep valgrind |grep -v grep| wc -l`
if [ $monitoring -eq 0 ]
then
echo "Manipulator is not running "
break
else
sleep 1
fi
done
grep 'start to execute\|ERROR SUMMARY' $VALGRIND_ERR | grep -v 'grep' | uniq | tee taosd_mem_err.log
for memError in `grep 'ERROR SUMMARY' taosd_mem_err.log | awk '{print $4}'`
do
memError=(${memError//,/})
if [ -n "$memError" ]; then
if [ "$memError" -gt 12 ]; then
echo -e "${RED} ## Memory errors number valgrind reports is $memError.\
More than our threshold! ## ${NC}"
fi
fi
done
grep 'start to execute\|definitely lost:' $VALGRIND_ERR|grep -v 'grep'|uniq|tee taosd-definitely-lost-out.log
for defiMemError in `grep 'definitely lost:' taosd-definitely-lost-out.log | awk '{print $7}'`
do
defiMemError=(${defiMemError//,/})
if [ -n "$defiMemError" ]; then
if [ "$defiMemError" -gt 0 -a "$defiMemError" -lt 1013 ]; then
cat $VALGRIND_ERR
echo -e "${RED} ## Memory errors number valgrind reports \
Definitely lost is $defiMemError. More than our threshold! ## ${NC}"
exit 8
elif [ "$defiMemError" -gt 1013 ];then #add for azure
cat $VALGRIND_ERR
echo -e "${RED} ## Memory errors number valgrind reports \
Definitely lost is $defiMemError. More than our threshold! ## ${NC}"
exit 8
fi
fi
done

View File

@ -25,6 +25,8 @@ class TDTestCase:
tdSql.init(conn.cursor(), logSql)
self.ts = 1538548685000
self.tables = 10
self.rows = 1000
def updateMetadata(self):
self.host = "127.0.0.1"
@ -37,6 +39,29 @@ class TDTestCase:
self.cursor.execute("alter table db.tb add column col2 int")
print("alter table done")
def deleteTableAndRecreate(self):
self.host = "127.0.0.1"
self.user = "root"
self.password = "taosdata"
self.config = tdDnodes.getSimCfgPath()
self.conn = taos.connect(host = self.host, user = self.user, password = self.password, config = self.config)
self.cursor = self.conn.cursor()
self.cursor.execute("use test")
print("drop table stb")
self.cursor.execute("drop table stb")
print("create table stb")
self.cursor.execute("create table if not exists stb (ts timestamp, col1 int) tags(areaid int, city nchar(20))")
print("insert data")
for i in range(self.tables):
city = "beijing" if i % 2 == 0 else "shanghai"
self.cursor.execute("create table tb%d using stb tags(%d, '%s')" % (i, i, city))
for j in range(self.rows):
self.cursor.execute("insert into tb%d values(%d, %d)" % (i, self.ts + j, j * 100000))
def run(self):
tdSql.prepare()
@ -59,6 +84,36 @@ class TDTestCase:
tdSql.query("select * from tb")
tdSql.checkRows(2)
# Add test case: https://jira.taosdata.com:18080/browse/TD-3474
print("==============step1")
tdSql.execute("create database test")
tdSql.execute("use test")
tdSql.execute("create table if not exists stb (ts timestamp, col1 int) tags(areaid int, city nchar(20))")
for i in range(self.tables):
city = "beijing" if i % 2 == 0 else "shanghai"
tdSql.execute("create table tb%d using stb tags(%d, '%s')" % (i, i, city))
for j in range(self.rows):
tdSql.execute("insert into tb%d values(%d, %d)" % (i, self.ts + j, j * 100000))
tdSql.query("select count(*) from stb")
tdSql.checkData(0, 0, 10000)
tdSql.query("select count(*) from tb1")
tdSql.checkData(0, 0, 1000)
p = Process(target=self.deleteTableAndRecreate, args=())
p.start()
p.join()
p.terminate()
tdSql.query("select count(*) from stb")
tdSql.checkData(0, 0, 10000)
tdSql.query("select count(*) from tb1")
tdSql.checkData(0, 0, 1000)
def stop(self):
tdSql.close()
tdLog.success("%s successfully executed" % __file__)

View File

@ -0,0 +1,245 @@
###################################################################
# Copyright (c) 2016 by TAOS Technologies, Inc.
# All rights reserved.
#
# This file is proprietary and confidential to TAOS Technologies.
# No part of this file may be reproduced, stored, transmitted,
# disclosed or used in any form or by any means other than as
# expressly provided by the written permission from Jianhui Tao
#
###################################################################
# -*- coding: utf-8 -*-
import sys
import json
from util.log import *
from util.cases import *
from util.sql import *
from util.dnodes import *
class TDTestCase:
def __init__(self):
self.path = ""
def init(self, conn, logSql):
tdLog.debug(f"start to execute {__file__}")
tdSql.init(conn.cursor(), logSql)
def getBuildPath(self):
selfPath = os.path.dirname(os.path.realpath(__file__))
if ("community" in selfPath):
projPath = selfPath[:selfPath.find("community")]
else:
projPath = selfPath[:selfPath.find("tests")]
for root, dirs, files in os.walk(projPath):
if ("taosd" in files):
rootRealPath = os.path.dirname(os.path.realpath(root))
if ("packaging" not in rootRealPath):
buildPath = root[:len(root) - len("/build/bin")]
break
return buildPath
def getcfgPath(self, path):
binPath = os.path.dirname(os.path.realpath(__file__))
binPath = binPath + "/../../../debug/"
tdLog.debug(f"binPath {binPath}")
binPath = os.path.realpath(binPath)
tdLog.debug(f"binPath real path {binPath}")
if path == "":
self.path = os.path.abspath(binPath + "../../")
else:
self.path = os.path.realpath(path)
return self.path
def getCfgDir(self):
self.getcfgPath(self.path)
self.cfgDir = f"{self.path}/sim/psim/cfg"
return self.cfgDir
def creatcfg(self):
dbinfo = {
"name": "db",
"drop": "yes",
"replica": 1,
"days": 10,
"cache": 16,
"blocks": 8,
"precision": "ms",
"keep": 3650,
"minRows": 100,
"maxRows": 4096,
"comp": 2,
"walLevel": 1,
"cachelast": 0,
"quorum": 1,
"fsync": 3000,
"update": 0
}
# set stable schema
stable1 = {
"name": "stb1",
"child_table_exists": "no",
"childtable_count": 1000,
"childtable_prefix": "t1",
"auto_create_table": "no",
"data_source": "rand",
"insert_mode": "taosc",
"insert_rows": 1,
"multi_thread_write_one_tbl": "no",
"number_of_tbl_in_one_sql": 0,
"rows_per_tbl": 1,
"max_sql_len": 65480,
"disorder_ratio": 0,
"disorder_range": 1000,
"timestamp_step": 20000,
"start_timestamp": "2020-12-31 00:00:00.000",
"sample_format": "csv",
"sample_file": "./sample.csv",
"tags_file": "",
"columns": [
{"type": "INT", "count": 2},
{"type": "DOUBLE", "count": 2},
{"type": "BIGINT", "count": 2},
{"type": "FLOAT", "count": 2},
{"type": "SMALLINT", "count": 2},
{"type": "TINYINT", "count": 2},
{"type": "BOOL", "count": 2},
{"type": "NCHAR", "len": 3, "count": 1},
{"type": "BINARY", "len": 8, "count": 1}
],
"tags": [
{"type": "INT", "count": 2},
{"type": "DOUBLE", "count": 2},
{"type": "BIGINT", "count": 2},
{"type": "FLOAT", "count": 2},
{"type": "SMALLINT", "count": 2},
{"type": "TINYINT", "count": 2},
{"type": "BOOL", "count": 2},
{"type": "NCHAR", "len": 3, "count": 1},
{"type": "BINARY", "len": 8, "count": 1}
]
}
stable2 = {
"name": "stb2",
"child_table_exists": "no",
"childtable_count": 1000,
"childtable_prefix": "t2",
"auto_create_table": "no",
"data_source": "rand",
"insert_mode": "taosc",
"insert_rows": 1,
"multi_thread_write_one_tbl": "no",
"number_of_tbl_in_one_sql": 0,
"rows_per_tbl": 1,
"max_sql_len": 65480,
"disorder_ratio": 0,
"disorder_range": 1000,
"timestamp_step": 20000,
"start_timestamp": "2020-12-31 00:00:00.000",
"sample_format": "csv",
"sample_file": "./sample.csv",
"tags_file": "",
"columns": [
{"type": "INT", "count": 2},
{"type": "DOUBLE", "count": 2},
{"type": "BIGINT", "count": 2},
{"type": "FLOAT", "count": 2},
{"type": "SMALLINT", "count": 2},
{"type": "TINYINT", "count": 2},
{"type": "BOOL", "count": 2},
{"type": "NCHAR", "len": 3, "count": 1},
{"type": "BINARY", "len": 8, "count": 1}
],
"tags": [
{"type": "INT", "count": 2},
{"type": "DOUBLE", "count": 2},
{"type": "BIGINT", "count": 2},
{"type": "FLOAT", "count": 2},
{"type": "SMALLINT", "count": 2},
{"type": "TINYINT", "count": 2},
{"type": "BOOL", "count": 2},
{"type": "NCHAR", "len": 3, "count": 1},
{"type": "BINARY", "len": 8, "count": 1}
]
}
# create different stables like stable1 and add to list super_tables
super_tables = []
super_tables.append(stable1)
super_tables.append(stable2)
database = {
"dbinfo": dbinfo,
"super_tables": super_tables
}
cfgdir = self.getCfgDir()
create_table = {
"filetype": "insert",
"cfgdir": cfgdir,
"host": "127.0.0.1",
"port": 6030,
"user": "root",
"password": "taosdata",
"thread_count": 4,
"thread_count_create_tbl": 4,
"result_file": "/tmp/insert_res.txt",
"confirm_parameter_prompt": "no",
"insert_interval": 0,
"num_of_records_per_req": 100,
"databases": [database]
}
return create_table
def createinsertfile(self):
create_table = self.creatcfg()
date = datetime.datetime.now().strftime("%Y%m%d%H%M")
file_create_table = f"/tmp/insert_{date}.json"
with open(file_create_table, 'w') as f:
json.dump(create_table, f)
return file_create_table
def inserttable(self, filepath):
buildPath = self.getBuildPath()
if (buildPath == ""):
tdLog.exit("taosd not found!")
else:
tdLog.info(f"taosd found in {buildPath}")
binPath = buildPath + "/build/bin/"
create_table_cmd = f"{binPath}taosdemo -f {filepath} > /dev/null 2>&1"
_ = subprocess.check_output(create_table_cmd, shell=True).decode("utf-8")
def droptmpfile(self):
drop_file_cmd = "rm -f /tmp/insert_* "
_ = subprocess.check_output(drop_file_cmd, shell=True).decode("utf-8")
def run(self):
tdLog.printNoPrefix("==========step1:create database and insert records")
file_create_table = self.createinsertfile()
self.inserttable(file_create_table)
tdLog.printNoPrefix("==========step2:check database and stable records")
tdSql.query("show databases")
tdSql.checkData(0, 2, 2000)
tdSql.execute("use db")
tdSql.query("show stables")
tdSql.checkData(0, 4, 1000)
tdSql.checkData(1, 4, 1000)
self.droptmpfile()
def stop(self):
tdSql.close()
tdLog.success(f"{__file__} successfully executed")
tdCases.addLinux(__file__, TDTestCase())
tdCases.addWindows(__file__, TDTestCase())

View File

@ -0,0 +1,156 @@
###################################################################
# Copyright (c) 2016 by TAOS Technologies, Inc.
# All rights reserved.
#
# This file is proprietary and confidential to TAOS Technologies.
# No part of this file may be reproduced, stored, transmitted,
# disclosed or used in any form or by any means other than as
# expressly provided by the written permission from Jianhui Tao
#
###################################################################
# -*- coding: utf-8 -*-
import sys
import json
from util.log import *
from util.cases import *
from util.sql import *
from util.dnodes import *
class TDTestCase:
def __init__(self):
self.path = ""
def init(self, conn, logSql):
tdLog.debug("start to execute %s" % __file__)
tdSql.init(conn.cursor(), logSql)
def getBuildPath(self):
selfPath = os.path.dirname(os.path.realpath(__file__))
if ("community" in selfPath):
projPath = selfPath[:selfPath.find("community")]
else:
projPath = selfPath[:selfPath.find("tests")]
for root, dirs, files in os.walk(projPath):
if ("taosd" in files):
rootRealPath = os.path.dirname(os.path.realpath(root))
if ("packaging" not in rootRealPath):
buildPath = root[:len(root) - len("/debug/build/bin")]
break
return buildPath
def getCfgDir(self):
return self.getBuildPath() + "/sim/psim/cfg"
def querycfg(self):
cfgdir = self.getCfgDir()
querycfg={
"filetype": "query",
"cfgdir": cfgdir,
"host": "127.0.0.1",
"port": 6030,
"user": "root",
"password": "taosdata",
"confirm_parameter_prompt": "yes",
"databases": "db",
"specified_table_query": {
"query_interval": 0,
"concurrent": 1,
"sqls": [
{
"sql": "select * from t10, t11 where t10.ts=t11.ts"
}
]
}
}
return querycfg
def querycfgfile(self):
querycfg = self.querycfg()
date = datetime.datetime.now().strftime("%Y%m%d%H%M")
querycfg.get("specified_table_query").get("sqls")[0]["result"] = f"/tmp/query_{date}.log"
file_query_table = f"/tmp/query_{date}.json"
with open(file_query_table, "w") as f:
json.dump(querycfg, f)
return [file_query_table, querycfg]
def querytable(self, filepath):
buildPath = self.getBuildPath()
if (buildPath == ""):
tdLog.exit("taosd not found!")
else:
tdLog.info(f"taosd found in {buildPath}")
binPath = buildPath + "/debug/build/bin/"
query_table_cmd = f"yes | {binPath}taosdemo -f {filepath}"
_ = subprocess.check_output(query_table_cmd, shell=True).decode("utf-8")
def checkqueryresult(self, expectrows):
querycfg = self.querycfgfile()[1]
result_file = querycfg.get("specified_table_query").get("sqls")[0].get("result") + "-0"
if result_file:
check_cmd = f"wc -l {result_file}"
check_data_init = subprocess.check_output(check_cmd, shell=True).decode("utf-8")
check_data = int(check_data_init[0])
if check_data == expectrows:
tdLog.info(f"queryResultRows:{check_data} == expect:{expectrows}")
else:
caller = inspect.getframeinfo(inspect.stack()[1][0])
args = (caller.filename, caller.lineno, check_data, expectrows)
tdLog.exit(f"{args[0]}({args[1]}) failed: result:{args[2]} != expect:{args[3]}")
def droptmpfile(self):
drop_file_cmd = "rm -f /tmp/query_* "
_ = subprocess.check_output(drop_file_cmd, shell=True).decode("utf-8")
drop_file_cmd = "rm -f querySystemInfo-*"
_ = subprocess.check_output(drop_file_cmd, shell=True).decode("utf-8")
def run(self):
tdSql.prepare()
tdLog.printNoPrefix("==========step1:create table && insert data")
tdSql.execute("alter database db keep 36500")
tdSql.execute(
"create table stb1 (ts timestamp, c1 int) TAGS(t1 int)"
)
tdSql.execute("create table t10 using stb1 tags(1)")
tdSql.execute("create table t11 using stb1 tags(2)")
tdSql.execute("insert into t10 values (-865000000, 1)")
tdSql.execute("insert into t11 values (-865000000, 2)")
tdSql.execute("insert into t10 values ('1969-12-31 23:59:59.000', 2)")
tdSql.execute("insert into t11 values ('1969-12-31 23:59:59.000', 3)")
tdSql.execute("insert into t10 values ('1970-01-01 00:00:00.000', 3)")
tdSql.execute("insert into t11 values ('1970-01-01 00:00:00.000', 4)")
tdSql.execute("insert into t10 values (-15230000, 4)")
tdSql.execute("insert into t11 values (-15230000, 5)")
tdSql.execute("insert into t10 values (-15220000, 5)")
tdSql.execute("insert into t11 values (-15220000, 6)")
tdSql.execute("insert into t10 values (-15210000, 6)")
tdSql.execute("insert into t11 values (-15210000, 7)")
tdSql.execute("insert into t10 values (0, 7)")
tdSql.execute("insert into t11 values (0, 8)")
tdSql.execute("insert into t10 values ('2020-10-01 00:00:00.000', 8)")
tdSql.execute("insert into t11 values ('2020-10-01 00:00:00.000', 9)")
tdLog.printNoPrefix("==========step2:query")
query_file = self.querycfgfile()[0]
self.querytable(query_file)
self.checkqueryresult(8)
self.droptmpfile()
def stop(self):
tdSql.close()
tdLog.success("%s successfully executed" % __file__)
tdCases.addWindows(__file__, TDTestCase())
tdCases.addLinux(__file__, TDTestCase())

View File

@ -0,0 +1,74 @@
###################################################################
# Copyright (c) 2016 by TAOS Technologies, Inc.
# All rights reserved.
#
# This file is proprietary and confidential to TAOS Technologies.
# No part of this file may be reproduced, stored, transmitted,
# disclosed or used in any form or by any means other than as
# expressly provided by the written permission from Jianhui Tao
#
###################################################################
# -*- coding: utf-8 -*-
import sys
from util.log import *
from util.cases import *
from util.sql import *
from util.dnodes import *
class TDTestCase:
def init(self, conn, logSql):
tdLog.debug("start to execute %s" % __file__)
tdSql.init(conn.cursor(), logSql)
def run(self):
tdSql.prepare()
tdSql.execute("drop database if exists db")
tdSql.execute("create database if not exists db keep 36500")
tdSql.execute("use db")
tdLog.printNoPrefix("==========step1:create table && insert data")
tdSql.execute(
"create table stb1 (ts timestamp, c1 int) TAGS(t1 int)"
)
tdSql.execute("create table t0 using stb1 tags(1)")
tdSql.execute("insert into t0 values (-865000000, 1)")
tdSql.execute("insert into t0 values (-864000000, 2)")
tdSql.execute("insert into t0 values (-863000000, 3)")
tdSql.execute("insert into t0 values (-15230000, 4)")
tdSql.execute("insert into t0 values (-15220000, 5)")
tdSql.execute("insert into t0 values (-15210000, 6)")
tdLog.printNoPrefix("==========step2:query")
# bug1:when ts > -864000000, return 0 rows;
# bug2:when ts = -15220000, return 0 rows.
tdSql.query('select * from t0 where ts < -864000000')
tdSql.checkRows(1)
tdSql.query('select * from t0 where ts <= -864000000')
tdSql.checkRows(2)
tdSql.query('select * from t0 where ts = -864000000')
tdSql.checkRows(1)
tdSql.query('select * from t0 where ts > -864000000')
tdSql.checkRows(4)
tdSql.query('select * from t0 where ts >= -864000000')
tdSql.checkRows(5)
tdSql.query('select * from t0 where ts < -15220000')
tdSql.checkRows(4)
tdSql.query('select * from t0 where ts <= -15220000')
tdSql.checkRows(5)
tdSql.query('select * from t0 where ts = -15220000')
tdSql.checkRows(1)
tdSql.query('select * from t0 where ts > -15220000')
tdSql.checkRows(1)
tdSql.query('select * from t0 where ts >= -15220000')
tdSql.checkRows(2)
def stop(self):
tdSql.close()
tdLog.success("%s successfully executed" % __file__)
tdCases.addWindows(__file__, TDTestCase())
tdCases.addLinux(__file__, TDTestCase())

View File

@ -22,25 +22,34 @@ import datetime
from util.log import *
from util.sql import *
from util.cases import *
from util.dnodes import *
from util.dnodes import TDDnode
class TDTestCase:
def __init__(self):
self.path = ""
def init(self, conn, logSql):
tdLog.debug(f"start to excute {__file__}")
tdSql.init(conn.cursor())
def getCfgDir(self, path):
def getcfgPath(self, path):
binPath = os.path.dirname(os.path.realpath(__file__))
binPath = binPath + "/../../../debug/"
tdLog.debug("binPath %s" % (binPath))
tdLog.debug(f"binPath {binPath}")
binPath = os.path.realpath(binPath)
tdLog.debug("binPath real path %s" % (binPath))
tdLog.debug(f"binPath real path {binPath}")
if path == "":
self.path = os.path.abspath(binPath + "../../")
else:
self.path = os.path.realpath(path)
return self.path
self.cfgDir = "%s/sim/psim/cfg" % (self.path)
def getCfgDir(self):
self.getcfgPath(self.path)
self.cfgDir = f"{self.path}/sim/psim/cfg"
return self.cfgDir
def creatcfg(self):
@ -63,7 +72,7 @@ class TDTestCase:
"update": 0
}
# 设置创建的超级表格式
# set stable schema
stable1 = {
"name": "stb2",
"child_table_exists": "no",
@ -75,35 +84,49 @@ class TDTestCase:
"insert_rows": 5000,
"multi_thread_write_one_tbl": "no",
"number_of_tbl_in_one_sql": 0,
"rows_per_tbl": 1000,
"rows_per_tbl": 1,
"max_sql_len": 65480,
"disorder_ratio": 0,
"disorder_range": 1000,
"timestamp_step": 19000000,
"start_timestamp": "1969-01-01 00:00:00.000",
"timestamp_step": 20000,
"start_timestamp": "1969-12-31 00:00:00.000",
"sample_format": "csv",
"sample_file": "./sample.csv",
"tags_file": "",
"columns": [
{"type": "INT"},
{"type": "DOUBLE", "count": 10},
{"type": "BINARY", "len": 16, "count": 3},
{"type": "BINARY", "len": 32, "count": 6}
{"type": "INT", "count": 2},
{"type": "DOUBLE", "count": 2},
{"type": "BIGINT", "count": 2},
{"type": "FLOAT", "count": 2},
{"type": "SMALLINT", "count": 2},
{"type": "TINYINT", "count": 2},
{"type": "BOOL", "count": 2},
{"type": "NCHAR", "len": 3, "count": 1},
{"type": "BINARY", "len": 8, "count": 1}
],
"tags": [
{"type": "INT", "count": 2},
{"type": "DOUBLE", "count": 2},
{"type": "BIGINT", "count": 2},
{"type": "FLOAT", "count": 2},
{"type": "SMALLINT", "count": 2},
{"type": "TINYINT", "count": 2},
{"type": "BINARY", "len": 16, "count": 5}
{"type": "BOOL", "count": 2},
{"type": "NCHAR", "len": 3, "count": 1},
{"type": "BINARY", "len": 8, "count": 1}
]
}
# 需要创建多个超级表时只需创建不同的超级表格式并添加至super_tables
super_tables = [stable1]
# create different stables like stable1 and add to list super_tables
super_tables = []
super_tables.append(stable1)
database = {
"dbinfo": dbinfo,
"super_tables": super_tables
}
cfgdir = self.getCfgDir("")
cfgdir = self.getCfgDir()
create_table = {
"filetype": "insert",
"cfgdir": cfgdir,
@ -121,17 +144,82 @@ class TDTestCase:
}
return create_table
def inserttable(self):
def createinsertfile(self):
create_table = self.creatcfg()
date = datetime.datetime.now().strftime("%Y%m%d%H%M")
file_create_table = f"/tmp/insert_{date}.json"
with open(file_create_table, 'w') as f:
json.dump(create_table, f)
return file_create_table
create_table_cmd = f"taosdemo -f {file_create_table}"
def inserttable(self, filepath):
create_table_cmd = f"taosdemo -f {filepath} > /dev/null 2>&1"
_ = subprocess.check_output(create_table_cmd, shell=True).decode("utf-8")
def sqlsquery(self):
# stable query
tdSql.query(
"select * from stb2 where stb2.ts < '1970-01-01 00:00:00.000' "
)
tdSql.checkRows(43200)
tdSql.query(
"select * from stb2 where stb2.ts >= '1970-01-01 00:00:00.000' "
)
tdSql.checkRows(6800)
tdSql.query(
"select * from stb2 where stb2.ts > '1969-12-31 23:00:00.000' and stb2.ts <'1970-01-01 01:00:00.000' "
)
tdSql.checkRows(3590)
# child-tables query
tdSql.query(
"select * from t0 where t0.ts < '1970-01-01 00:00:00.000' "
)
tdSql.checkRows(4320)
tdSql.query(
"select * from t1 where t1.ts >= '1970-01-01 00:00:00.000' "
)
tdSql.checkRows(680)
tdSql.query(
"select * from t9 where t9.ts > '1969-12-31 22:00:00.000' and t9.ts <'1970-01-01 02:00:00.000' "
)
tdSql.checkRows(719)
tdSql.query(
"select * from t0,t1 where t0.ts=t1.ts and t1.ts >= '1970-01-01 00:00:00.000' "
)
tdSql.checkRows(680)
tdSql.query(
"select diff(col1) from t0 where t0.ts >= '1970-01-01 00:00:00.000' "
)
tdSql.checkRows(679)
tdSql.query(
"select t0,col1 from stb2 where stb2.ts < '1970-01-01 00:00:00.000' order by ts"
)
tdSql.checkRows(43200)
# query with timestamp in 'where ...'
tdSql.query(
"select * from stb2 where stb2.ts > -28800000 "
)
tdSql.checkRows(6790)
tdSql.query(
"select * from stb2 where stb2.ts > -28800000 and stb2.ts < '1970-01-01 08:00:00.000' "
)
tdSql.checkRows(6790)
tdSql.query(
"select * from stb2 where stb2.ts < -28800000 and stb2.ts > '1969-12-31 22:00:00.000' "
)
tdSql.checkRows(3590)
def run(self):
s = 'reset query cache'
@ -142,84 +230,24 @@ class TDTestCase:
tdSql.execute(s)
tdLog.info("==========step1:create table stable and child table,then insert data automatically")
self.inserttable()
# tdSql.execute(
# '''create table if not exists supt
# (ts timestamp, c1 int, c2 float, c3 bigint, c4 double, c5 smallint, c6 tinyint)
# tags(location binary(64), type int, isused bool , family nchar(64))'''
# )
# tdSql.execute("create table t1 using supt tags('beijing', 1, 1, '自行车')")
# tdSql.execute("create table t2 using supt tags('shanghai', 2, 0, '拖拉机')")
# tdSql.execute(
# f"insert into t1 values (-31564800000, 6, 5, 4, 3, 2, 1)"
# )
insertfile = self.createinsertfile()
self.inserttable(insertfile)
tdLog.info("==========step2:query join")
self.sqlsquery()
# stable query
tdSql.query(
"select * from stb2 where stb2.ts < '1970-01-01 00:00:00.000' "
)
tdSql.checkRows(16600)
# after wal and sync, check again
tdSql.query("show dnodes")
index = tdSql.getData(0, 0)
tdDnodes.stop(index)
tdDnodes.start(index)
tdSql.query(
"select * from stb2 where stb2.ts >= '1970-01-01 00:00:00.000' "
)
tdSql.checkRows(33400)
tdSql.query(
"select * from stb2 where stb2.ts > '1969-12-01 00:00:00.000' and stb2.ts <'1970-01-31 00:00:00.000' "
)
tdSql.checkRows(2780)
# child-table query
tdSql.query(
"select * from t0 where t0.ts < '1970-01-01 00:00:00.000' "
)
tdSql.checkRows(1660)
tdSql.query(
"select * from t1 where t1.ts >= '1970-01-01 00:00:00.000' "
)
tdSql.checkRows(3340)
tdSql.query(
"select * from t9 where t9.ts > '1969-12-01 00:00:00.000' and t9.ts <'1970-01-31 00:00:00.000' "
)
tdSql.checkRows(278)
tdSql.query(
"select * from t0,t1 where t0.ts=t1.ts and t1.ts >= '1970-01-01 00:00:00.000' "
)
tdSql.checkRows(3340)
tdSql.query(
"select diff(col1) from t0 where t0.ts >= '1970-01-01 00:00:00.000' "
)
tdSql.checkRows(3339)
tdSql.query(
"select t0,col1 from stb2 where stb2.ts < '1970-01-01 00:00:00.000' order by ts"
)
tdSql.checkRows(16600)
# query with timestamp in 'where ...'
tdSql.query(
"select * from stb2 where stb2.ts > -28800000 "
)
tdSql.checkRows(33400)
tdSql.query(
"select * from stb2 where stb2.ts > -28800000 and stb2.ts < '1970-01-01 08:00:00.000' "
)
tdSql.checkRows(20)
tdSql.query(
"select * from stb2 where stb2.ts < -28800000 and stb2.ts > '1969-12-31 16:00:00.000' "
)
tdLog.info("==========step3: query join again")
self.sqlsquery()
# delete temporary file
rm_cmd = f"rm -f /tmp/insert* > /dev/null 2>&1"
_ = subprocess.check_output(rm_cmd, shell=True).decode("utf-8")
def stop(self):
tdSql.close()

View File

@ -11,26 +11,16 @@
# -*- coding: utf-8 -*-
import sys
import taos
import time
import datetime
import csv
import random
import pandas as pd
import argparse
import os.path
import json
class taosdemoPerformace:
def __init__(self, commitID, dbName, createTableTime, insertRecordsTime, recordsPerSecond, avgDelay, maxDelay, minDelay):
def __init__(self, commitID, dbName):
self.commitID = commitID
self.dbName = dbName
self.createTableTime = createTableTime
self.insertRecordsTime = insertRecordsTime
self.recordsPerSecond = recordsPerSecond
self.avgDelay = avgDelay
self.maxDelay = maxDelay
self.minDelay = minDelay
self.host = "127.0.0.1"
self.user = "root"
self.password = "taosdata"
@ -40,6 +30,95 @@ class taosdemoPerformace:
self.user,
self.password,
self.config)
self.insertDB = "insertDB";
def generateJson(self):
db = {
"name": "%s" % self.insertDB,
"drop": "yes",
"replica": 1
}
stb = {
"name": "meters",
"child_table_exists":"no",
"childtable_count": 10000,
"childtable_prefix": "stb_",
"auto_create_table": "no",
"data_source": "rand",
"batch_create_tbl_num": 10,
"insert_mode": "taosc",
"insert_rows": 100000,
"multi_thread_write_one_tbl": "no",
"number_of_tbl_in_one_sql": 0,
"rows_per_tbl": 100,
"max_sql_len": 1024000,
"disorder_ratio": 0,
"disorder_range": 1000,
"timestamp_step": 1,
"start_timestamp": "2020-10-01 00:00:00.000",
"sample_format": "csv",
"sample_file": "./sample.csv",
"tags_file": "",
"columns": [
{"type": "INT", "count": 4}
],
"tags": [
{"type": "INT", "count":1},
{"type": "BINARY", "len": 16}
]
}
stables = []
stables.append(stb)
db = {
"dbinfo": db,
"super_tables": stables
}
insert_data = {
"filetype": "insert",
"cfgdir": "/etc/taosperf",
"host": "127.0.0.1",
"port": 6030,
"user": "root",
"password": "taosdata",
"thread_count": 10,
"thread_count_create_tbl": 10,
"result_file": "./insert_res.txt",
"confirm_parameter_prompt": "no",
"insert_interval": 0,
"num_of_records_per_req": 30000,
"databases": [db]
}
insert_json_file = f"/tmp/insert.json"
with open(insert_json_file, 'w') as f:
json.dump(insert_data, f)
return insert_json_file
def getCMDOutput(self, cmd):
cmd = os.popen(cmd)
output = cmd.read()
cmd.close()
return output
def insertData(self):
os.system("taosdemo -f %s > taosdemoperf.txt" % self.generateJson())
self.createTableTime = self.getCMDOutput("grep 'Spent' taosdemoperf.txt | awk 'NR==1{print $2}'")
self.insertRecordsTime = self.getCMDOutput("grep 'Spent' taosdemoperf.txt | awk 'NR==2{print $2}'")
self.recordsPerSecond = self.getCMDOutput("grep 'Spent' taosdemoperf.txt | awk 'NR==2{print $16}'")
self.commitID = self.getCMDOutput("git rev-parse --short HEAD")
delay = self.getCMDOutput("grep 'delay' taosdemoperf.txt | awk '{print $4}'")
self.avgDelay = delay[:-4]
delay = self.getCMDOutput("grep 'delay' taosdemoperf.txt | awk '{print $6}'")
self.maxDelay = delay[:-4]
delay = self.getCMDOutput("grep 'delay' taosdemoperf.txt | awk '{print $8}'")
self.minDelay = delay[:-3]
os.system("[ -f taosdemoperf.txt ] && rm taosdemoperf.txt")
def createTablesAndStoreData(self):
cursor = self.conn.cursor()
@ -48,14 +127,15 @@ class taosdemoPerformace:
cursor.execute("use %s" % self.dbName)
cursor.execute("create table if not exists taosdemo_perf (ts timestamp, create_table_time float, insert_records_time float, records_per_second float, commit_id binary(50), avg_delay float, max_delay float, min_delay float)")
print("==================== taosdemo performance ====================")
print("create tables time: %f" % self.createTableTime)
print("insert records time: %f" % self.insertRecordsTime)
print("records per second: %f" % self.recordsPerSecond)
print("avg delay: %f" % self.avgDelay)
print("max delay: %f" % self.maxDelay)
print("min delay: %f" % self.minDelay)
cursor.execute("insert into taosdemo_perf values(now, %f, %f, %f, '%s', %f, %f, %f)" % (self.createTableTime, self.insertRecordsTime, self.recordsPerSecond, self.commitID, self.avgDelay, self.maxDelay, self.minDelay))
cursor.execute("drop database if exists taosdemo_insert_test")
print("create tables time: %f" % float(self.createTableTime))
print("insert records time: %f" % float(self.insertRecordsTime))
print("records per second: %f" % float(self.recordsPerSecond))
print("avg delay: %f" % float(self.avgDelay))
print("max delay: %f" % float(self.maxDelay))
print("min delay: %f" % float(self.minDelay))
cursor.execute("insert into taosdemo_perf values(now, %f, %f, %f, '%s', %f, %f, %f)" %
(float(self.createTableTime), float(self.insertRecordsTime), float(self.recordsPerSecond), self.commitID, float(self.avgDelay), float(self.maxDelay), float(self.minDelay)))
cursor.execute("drop database if exists %s" % self.insertDB)
cursor.close()
@ -74,46 +154,9 @@ if __name__ == '__main__':
default='perf',
type=str,
help='Database name to be created (default: perf)')
parser.add_argument(
'-t',
'--create-table',
action='store',
type=float,
help='create table time')
parser.add_argument(
'-i',
'--insert-records',
action='store',
type=float,
help='insert records time')
parser.add_argument(
'-r',
'---records-per-second',
action='store',
type=float,
help='records per request')
parser.add_argument(
'-avg',
'---avg-delay',
action='store',
type=float,
help='avg delay')
parser.add_argument(
'-max',
'---max-delay',
action='store',
type=float,
help='max delay')
parser.add_argument(
'-min',
'---min-delay',
action='store',
type=float,
help='min delay')
args = parser.parse_args()
perftest = taosdemoPerformace(args.commit_id, args.database_name, args.create_table, args.insert_records, args.records_per_second,
args.avg_delay, args.max_delay, args.min_delay)
perftest = taosdemoPerformace(args.commit_id, args.database_name)
perftest.insertData()
perftest.createTablesAndStoreData()

View File

@ -29,17 +29,54 @@ class TDTestCase:
self.numberOfTables = 10
self.numberOfRecords = 1000000
def getBuildPath(self):
selfPath = os.path.dirname(os.path.realpath(__file__))
if ("community" in selfPath):
projPath = selfPath[:selfPath.find("community")]
else:
projPath = selfPath[:selfPath.find("tests")]
for root, dirs, files in os.walk(projPath):
if ("taosd" in files):
rootRealPath = os.path.dirname(os.path.realpath(root))
if ("packaging" not in rootRealPath):
buildPath = root[:len(root) - len("/build/bin")]
break
return buildPath
def insertDataAndAlterTable(self, threadID):
buildPath = self.getBuildPath()
if (buildPath == ""):
tdLog.exit("taosd not found!")
else:
tdLog.info("taosd found in %s" % buildPath)
binPath = buildPath + "/build/bin/"
if(threadID == 0):
os.system("taosdemo -y -t %d -n %d" %
(self.numberOfTables, self.numberOfRecords))
os.system("%staosdemo -y -t %d -n %d" %
(binPath, self.numberOfTables, self.numberOfRecords))
if(threadID == 1):
time.sleep(2)
print("use test")
while True:
try:
tdSql.execute("use test")
break
except Exception as e:
tdLog.info("use database test failed")
time.sleep(1)
continue
# check if all the tables have heen created
while True:
try:
tdSql.query("show tables")
except Exception as e:
tdLog.info("show tables test failed")
time.sleep(1)
continue
rows = tdSql.queryRows
print("number of tables: %d" % rows)
if(rows == self.numberOfTables):
@ -48,16 +85,23 @@ class TDTestCase:
# check if there are any records in the last created table
while True:
print("query started")
try:
tdSql.query("select * from test.t9")
except Exception as e:
tdLog.info("select * test failed")
time.sleep(2)
continue
rows = tdSql.queryRows
print("number of records: %d" % rows)
if(rows > 0):
break
time.sleep(1)
print("alter table test.meters add column col10 int")
tdSql.execute("alter table test.meters add column col10 int")
print("insert into test.t0 values (now, 1, 2, 3, 4, 0.1, 0.01,'test', '测试', TRUE, 1610000000000, 0)")
tdSql.execute("insert into test.t0 values (now, 1, 2, 3, 4, 0.1, 0.01,'test', '测试', TRUE, 1610000000000, 0)")
print("insert into test.t9 values (now, 1, 2, 3, 4, 0.1, 0.01,'test', '测试', TRUE, 1610000000000, 0)")
tdSql.execute("insert into test.t9 values (now, 1, 2, 3, 4, 0.1, 0.01,'test', '测试', TRUE, 1610000000000, 0)")
def run(self):
tdSql.prepare()
@ -70,6 +114,8 @@ class TDTestCase:
t1.join()
t2.join()
time.sleep(3)
tdSql.query("select count(*) from test.meters")
tdSql.checkData(0, 0, self.numberOfRecords * self.numberOfTables + 1)

View File

@ -878,5 +878,7 @@ if $rows != 0 then
endi
sql drop topic t2
sql_error drop topic abc
sql drop topic if exists abc;
system sh/exec.sh -n dnode1 -s stop -x SIGINT

Some files were not shown because too many files have changed in this diff Show More