Merge branch 'develop' into feature/TD-2577
This commit is contained in:
commit
80e0d0eff1
|
@ -42,12 +42,12 @@ def pre_test(){
|
||||||
killall -9 taosd ||echo "no taosd running"
|
killall -9 taosd ||echo "no taosd running"
|
||||||
killall -9 gdb || echo "no gdb running"
|
killall -9 gdb || echo "no gdb running"
|
||||||
cd ${WKC}
|
cd ${WKC}
|
||||||
git checkout develop
|
|
||||||
git reset --hard HEAD~10 >/dev/null
|
git reset --hard HEAD~10 >/dev/null
|
||||||
|
git checkout develop
|
||||||
git pull >/dev/null
|
git pull >/dev/null
|
||||||
git fetch origin +refs/pull/${CHANGE_ID}/merge
|
git fetch origin +refs/pull/${CHANGE_ID}/merge
|
||||||
git checkout -qf FETCH_HEAD
|
git checkout -qf FETCH_HEAD
|
||||||
find ${WKC}/tests/pytest -name \'*\'.sql -exec rm -rf {} \\;
|
git clean -dfx
|
||||||
cd ${WK}
|
cd ${WK}
|
||||||
git reset --hard HEAD~10
|
git reset --hard HEAD~10
|
||||||
git checkout develop
|
git checkout develop
|
||||||
|
@ -55,7 +55,7 @@ def pre_test(){
|
||||||
cd ${WK}
|
cd ${WK}
|
||||||
export TZ=Asia/Harbin
|
export TZ=Asia/Harbin
|
||||||
date
|
date
|
||||||
rm -rf ${WK}/debug
|
git clean -dfx
|
||||||
mkdir debug
|
mkdir debug
|
||||||
cd debug
|
cd debug
|
||||||
cmake .. > /dev/null
|
cmake .. > /dev/null
|
||||||
|
@ -185,6 +185,14 @@ pipeline {
|
||||||
rm -rf /var/log/taos/*
|
rm -rf /var/log/taos/*
|
||||||
./handle_crash_gen_val_log.sh
|
./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'){
|
timeout(time: 45, unit: 'MINUTES'){
|
||||||
sh '''
|
sh '''
|
||||||
date
|
date
|
||||||
|
@ -215,6 +223,11 @@ pipeline {
|
||||||
cd ${WKC}/tests
|
cd ${WKC}/tests
|
||||||
./test-all.sh b3fq
|
./test-all.sh b3fq
|
||||||
date'''
|
date'''
|
||||||
|
sh '''
|
||||||
|
date
|
||||||
|
cd ${WKC}/tests
|
||||||
|
./test-all.sh full example
|
||||||
|
date'''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ ELSEIF (TD_WINDOWS)
|
||||||
#INSTALL(TARGETS taos RUNTIME DESTINATION driver)
|
#INSTALL(TARGETS taos RUNTIME DESTINATION driver)
|
||||||
#INSTALL(TARGETS shell RUNTIME DESTINATION .)
|
#INSTALL(TARGETS shell RUNTIME DESTINATION .)
|
||||||
IF (TD_MVN_INSTALLED)
|
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 ()
|
ENDIF ()
|
||||||
ELSEIF (TD_DARWIN)
|
ELSEIF (TD_DARWIN)
|
||||||
SET(TD_MAKE_INSTALL_SH "${TD_COMMUNITY_DIR}/packaging/tools/make_install.sh")
|
SET(TD_MAKE_INSTALL_SH "${TD_COMMUNITY_DIR}/packaging/tools/make_install.sh")
|
||||||
|
|
|
@ -179,18 +179,18 @@ taos> select avg(f1), max(f2), min(f3) from test.t10 interval(10s);
|
||||||
|
|
||||||
### TDengine服务器支持的平台列表
|
### 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 | ● | ● | | ○ | ● | ● |
|
| X64 | ● | ● | | ○ | ● | ● |
|
||||||
| 树莓派ARM32 | | ● | ● | | | |
|
| 树莓派 ARM32 | | ● | ● | | | |
|
||||||
| 龙芯MIPS64 | | | ● | | | |
|
| 龙芯 MIPS64 | | | ● | | | |
|
||||||
| 鲲鹏 ARM64 | | ○ | ○ | | ● | |
|
| 鲲鹏 ARM64 | | ○ | ○ | | ● | |
|
||||||
| 申威 Alpha64 | | | ○ | ● | | |
|
| 申威 Alpha64 | | | ○ | ● | | |
|
||||||
| 飞腾ARM64 | | ○优麒麟 | | | | |
|
| 飞腾 ARM64 | | ○ 优麒麟 | | | | |
|
||||||
| 海光X64 | ● | ● | ● | ○ | ● | ● |
|
| 海光 X64 | ● | ● | ● | ○ | ● | ● |
|
||||||
| 瑞芯微ARM64/32 | | | ○ | | | |
|
| 瑞芯微 ARM64/32 | | | ○ | | | |
|
||||||
| 全志ARM64/32 | | | ○ | | | |
|
| 全志 ARM64/32 | | | ○ | | | |
|
||||||
| 炬力ARM64/32 | | | ○ | | | |
|
| 炬力 ARM64/32 | | | ○ | | | |
|
||||||
| TI ARM32 | | | ○ | | | |
|
| TI 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** |
|
| **OS** | **Linux** | **Win64** | **Win32** | **Win32** | **Linux** | **Linux** | **Linux** | **Linux** | **Linux** |
|
||||||
| **C/C++** | ● | ● | ● | ○ | ● | ● | ● | ● | ● |
|
| **C/C++** | ● | ● | ● | ○ | ● | ● | ● | ● | ● |
|
||||||
|
|
|
@ -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推送查询的结果,也可以将结果再写回到TDengine中。每次执行的查询是一个时间窗口,时间窗口随着时间流动向前滑动。在定义连续查询的时候需要指定时间窗口(time window, 参数interval)大小和每次前向增量时间(forward sliding times, 参数sliding)。
|
||||||
针对库中的表或超级表,TDengine可提供定期自动执行的连续查询,
|
|
||||||
用户可让TDengine推送查询的结果,也可以将结果再写回到TDengine中。
|
|
||||||
每次执行的查询是一个时间窗口,时间窗口随着时间流动向前滑动。
|
|
||||||
在定义连续查询的时候需要指定时间窗口(time window, 参数interval)大小和每次前向增量时间(forward sliding times, 参数sliding)。
|
|
||||||
|
|
||||||
TDengine的连续查询采用时间驱动模式,可以直接使用TAOS SQL进行定义,不需要额外的操作。
|
TDengine的连续查询采用时间驱动模式,可以直接使用TAOS SQL进行定义,不需要额外的操作。使用连续查询,可以方便快捷地按照时间窗口生成结果,从而对原始采集数据进行降采样(down sampling)。用户通过TAOS SQL定义连续查询以后,TDengine自动在最后的一个完整的时间周期末端拉起查询,并将计算获得的结果推送给用户或者写回TDengine。
|
||||||
使用连续查询,可以方便快捷地按照时间窗口生成结果,从而对原始采集数据进行降采样(down sampling)。
|
|
||||||
用户通过TAOS SQL定义连续查询以后,TDengine自动在最后的一个完整的时间周期末端拉起查询,
|
|
||||||
并将计算获得的结果推送给用户或者写回TDengine。
|
|
||||||
|
|
||||||
TDengine提供的连续查询与普通流计算中的时间窗口计算具有以下区别:
|
TDengine提供的连续查询与普通流计算中的时间窗口计算具有以下区别:
|
||||||
|
|
||||||
- 不同于流计算的实时反馈计算结果,连续查询只在时间窗口关闭以后才开始计算。
|
- 不同于流计算的实时反馈计算结果,连续查询只在时间窗口关闭以后才开始计算。例如时间周期是1天,那么当天的结果只会在23:59:59以后才会生成。
|
||||||
例如时间周期是1天,那么当天的结果只会在23:59:59以后才会生成。
|
- 如果有历史记录写入到已经计算完成的时间区间,连续查询并不会重新进行计算,也不会重新将结果推送给用户。对于写回TDengine的模式,也不会更新已经存在的计算结果。
|
||||||
- 如果有历史记录写入到已经计算完成的时间区间,连续查询并不会重新进行计算,
|
- 使用连续查询推送结果的模式,服务端并不缓存客户端计算状态,也不提供Exactly-Once的语意保证。如果用户的应用端崩溃,再次拉起的连续查询将只会从再次拉起的时间开始重新计算最近的一个完整的时间窗口。如果使用写回模式,TDengine可确保数据写回的有效性和连续性。
|
||||||
也不会重新将结果推送给用户。对于写回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);
|
select avg(voltage) from meters interval(1m) sliding(30s);
|
||||||
```
|
```
|
||||||
|
|
||||||
每次执行这条语句,都会重新计算所有数据。
|
每次执行这条语句,都会重新计算所有数据。 如果需要每隔30秒执行一次来增量计算最近一分钟的数据,可以把上面的语句改进成下面的样子,每次使用不同的 `startTime` 并定期执行:
|
||||||
如果需要每隔30秒执行一次来增量计算最近一分钟的数据,
|
|
||||||
可以把上面的语句改进成下面的样子,每次使用不同的 `startTime` 并定期执行:
|
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
select avg(voltage) from meters where ts > {startTime} interval(1m) sliding(30s);
|
select avg(voltage) from meters where ts > {startTime} interval(1m) sliding(30s);
|
||||||
```
|
```
|
||||||
|
|
||||||
这样做没有问题,但TDengine提供了更简单的方法,
|
这样做没有问题,但TDengine提供了更简单的方法,只要在最初的查询语句前面加上 `create table {tableName} as ` 就可以了, 例如:
|
||||||
只要在最初的查询语句前面加上 `create table {tableName} as ` 就可以了, 例如:
|
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
create table avg_vol as select avg(voltage) from meters interval(1m) sliding(30s);
|
create table avg_vol as select avg(voltage) from meters interval(1m) sliding(30s);
|
||||||
```
|
```
|
||||||
|
|
||||||
会自动创建一个名为 `avg_vol` 的新表,然后每隔30秒,TDengine会增量执行 `as` 后面的 SQL 语句,
|
会自动创建一个名为 `avg_vol` 的新表,然后每隔30秒,TDengine会增量执行 `as` 后面的 SQL 语句,并将查询结果写入这个表中,用户程序后续只要从 `avg_vol` 中查询数据即可。 例如:
|
||||||
并将查询结果写入这个表中,用户程序后续只要从 `avg_vol` 中查询数据即可。 例如:
|
|
||||||
|
|
||||||
```mysql
|
```mysql
|
||||||
taos> select * from avg_vol;
|
taos> select * from avg_vol;
|
||||||
|
@ -70,43 +55,27 @@ taos> select * from avg_vol;
|
||||||
|
|
||||||
需要注意,查询时间窗口的最小值是10毫秒,没有时间窗口范围的上限。
|
需要注意,查询时间窗口的最小值是10毫秒,没有时间窗口范围的上限。
|
||||||
|
|
||||||
此外,TDengine还支持用户指定连续查询的起止时间。
|
此外,TDengine还支持用户指定连续查询的起止时间。如果不输入开始时间,连续查询将从第一条原始数据所在的时间窗口开始;如果没有输入结束时间,连续查询将永久运行;如果用户指定了结束时间,连续查询在系统时间达到指定的时间以后停止运行。比如使用下面的SQL创建的连续查询将运行一小时,之后会自动停止。
|
||||||
如果不输入开始时间,连续查询将从第一条原始数据所在的时间窗口开始;
|
|
||||||
如果没有输入结束时间,连续查询将永久运行;
|
|
||||||
如果用户指定了结束时间,连续查询在系统时间达到指定的时间以后停止运行。
|
|
||||||
比如使用下面的SQL创建的连续查询将运行一小时,之后会自动停止。
|
|
||||||
|
|
||||||
```mysql
|
```mysql
|
||||||
create table avg_vol as select avg(voltage) from meters where ts > now and ts <= now + 1h interval(1m) sliding(30s);
|
create table avg_vol as select avg(voltage) from meters where ts > now and ts <= now + 1h interval(1m) sliding(30s);
|
||||||
```
|
```
|
||||||
|
|
||||||
需要说明的是,上面例子中的 `now` 是指创建连续查询的时间,而不是查询执行的时间,否则,查询就无法自动停止了。
|
需要说明的是,上面例子中的 `now` 是指创建连续查询的时间,而不是查询执行的时间,否则,查询就无法自动停止了。另外,为了尽量避免原始数据延迟写入导致的问题,TDengine中连续查询的计算有一定的延迟。也就是说,一个时间窗口过去后,TDengine并不会立即计算这个窗口的数据,所以要稍等一会(一般不会超过1分钟)才能查到计算结果。
|
||||||
另外,为了尽量避免原始数据延迟写入导致的问题,TDengine中连续查询的计算有一定的延迟。
|
|
||||||
也就是说,一个时间窗口过去后,TDengine并不会立即计算这个窗口的数据,
|
|
||||||
所以要稍等一会(一般不会超过1分钟)才能查到计算结果。
|
|
||||||
|
|
||||||
|
|
||||||
### 管理连续查询
|
### 管理连续查询
|
||||||
|
|
||||||
用户可在控制台中通过 `show streams` 命令来查看系统中全部运行的连续查询,
|
用户可在控制台中通过 `show streams` 命令来查看系统中全部运行的连续查询,并可以通过 `kill stream` 命令杀掉对应的连续查询。后续版本会提供更细粒度和便捷的连续查询管理命令。
|
||||||
并可以通过 `kill stream` 命令杀掉对应的连续查询。
|
|
||||||
后续版本会提供更细粒度和便捷的连续查询管理命令。
|
|
||||||
|
|
||||||
|
|
||||||
## <a class="anchor" id="subscribe"></a>数据订阅(Publisher/Subscriber)
|
## <a class="anchor" id="subscribe"></a>数据订阅(Publisher/Subscriber)
|
||||||
|
|
||||||
基于数据天然的时间序列特性,TDengine的数据写入(insert)与消息系统的数据发布(pub)逻辑上一致,
|
基于数据天然的时间序列特性,TDengine的数据写入(insert)与消息系统的数据发布(pub)逻辑上一致,均可视为系统中插入一条带时间戳的新记录。同时,TDengine在内部严格按照数据时间序列单调递增的方式保存数据。本质上来说,TDengine中里每一张表均可视为一个标准的消息队列。
|
||||||
均可视为系统中插入一条带时间戳的新记录。
|
|
||||||
同时,TDengine在内部严格按照数据时间序列单调递增的方式保存数据。
|
|
||||||
本质上来说,TDengine中里每一张表均可视为一个标准的消息队列。
|
|
||||||
|
|
||||||
TDengine内嵌支持轻量级的消息订阅与推送服务。
|
TDengine内嵌支持轻量级的消息订阅与推送服务。使用系统提供的API,用户可使用普通查询语句订阅数据库中的一张或多张表。订阅的逻辑和操作状态的维护均是由客户端完成,客户端定时轮询服务器是否有新的记录到达,有新的记录到达就会将结果反馈到客户。
|
||||||
使用系统提供的API,用户可使用普通查询语句订阅数据库中的一张或多张表。
|
|
||||||
订阅的逻辑和操作状态的维护均是由客户端完成,客户端定时轮询服务器是否有新的记录到达,
|
|
||||||
有新的记录到达就会将结果反馈到客户。
|
|
||||||
|
|
||||||
TDengine的订阅与推送服务的状态是客户端维持,TDengine服务器并不维持。
|
TDengine的订阅与推送服务的状态是客户端维持,TDengine服务器并不维持。因此如果应用重启,从哪个时间点开始获取最新数据,由应用决定。
|
||||||
因此如果应用重启,从哪个时间点开始获取最新数据,由应用决定。
|
|
||||||
|
|
||||||
TDengine的API中,与订阅相关的主要有以下三个:
|
TDengine的API中,与订阅相关的主要有以下三个:
|
||||||
|
|
||||||
|
@ -116,12 +85,9 @@ taos_consume
|
||||||
taos_unsubscribe
|
taos_unsubscribe
|
||||||
```
|
```
|
||||||
|
|
||||||
这些API的文档请见 [C/C++ Connector](https://www.taosdata.com/cn/documentation/connector/),
|
这些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) 找到。
|
||||||
下面仍以智能电表场景为例介绍一下它们的具体用法(超级表和子表结构请参考上一节“连续查询”),
|
|
||||||
完整的示例代码可以在 [这里](https://github.com/taosdata/TDengine/blob/master/tests/examples/c/subscribe.c) 找到。
|
|
||||||
|
|
||||||
如果我们希望当某个电表的电流超过一定限制(比如10A)后能得到通知并进行一些处理, 有两种方法:
|
如果我们希望当某个电表的电流超过一定限制(比如10A)后能得到通知并进行一些处理, 有两种方法:一是分别对每张子表进行查询,每次查询后记录最后一条数据的时间戳,后续只查询这个时间戳之后的数据:
|
||||||
一是分别对每张子表进行查询,每次查询后记录最后一条数据的时间戳,后续只查询这个时间戳之后的数据:
|
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
select * from D1001 where ts > {last_timestamp1} and current > 10;
|
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;
|
select * from meters where ts > {last_timestamp} and current > 10;
|
||||||
```
|
```
|
||||||
|
|
||||||
但是,如何选择 `last_timestamp` 就成了一个新的问题。
|
但是,如何选择 `last_timestamp` 就成了一个新的问题。因为,一方面数据的产生时间(也就是数据时间戳)和数据入库的时间一般并不相同,有时偏差还很大;另一方面,不同电表的数据到达TDengine的时间也会有差异。所以,如果我们在查询中使用最慢的那台电表的数据的时间戳作为 `last_timestamp`,就可能重复读入其它电表的数据;如果使用最快的电表的时间戳,其它电表的数据就可能被漏掉。
|
||||||
因为,一方面数据的产生时间(也就是数据时间戳)和数据入库的时间一般并不相同,有时偏差还很大;
|
|
||||||
另一方面,不同电表的数据到达TDengine的时间也会有差异。
|
|
||||||
所以,如果我们在查询中使用最慢的那台电表的数据的时间戳作为 `last_timestamp`,
|
|
||||||
就可能重复读入其它电表的数据;
|
|
||||||
如果使用最快的电表的时间戳,其它电表的数据就可能被漏掉。
|
|
||||||
|
|
||||||
TDengine的订阅功能为上面这个问题提供了一个彻底的解决方案。
|
TDengine的订阅功能为上面这个问题提供了一个彻底的解决方案。
|
||||||
|
|
||||||
|
@ -160,47 +120,29 @@ if (async) {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
TDengine中的订阅既可以是同步的,也可以是异步的,
|
TDengine中的订阅既可以是同步的,也可以是异步的,上面的代码会根据从命令行获取的参数`async`的值来决定使用哪种方式。这里,同步的意思是用户程序要直接调用`taos_consume`来拉取数据,而异步则由API在内部的另一个线程中调用`taos_consume`,然后把拉取到的数据交给回调函数`subscribe_callback`去处理。
|
||||||
上面的代码会根据从命令行获取的参数`async`的值来决定使用哪种方式。
|
|
||||||
这里,同步的意思是用户程序要直接调用`taos_consume`来拉取数据,
|
|
||||||
而异步则由API在内部的另一个线程中调用`taos_consume`,
|
|
||||||
然后把拉取到的数据交给回调函数`subscribe_callback`去处理。
|
|
||||||
|
|
||||||
参数`taos`是一个已经建立好的数据库连接,在同步模式下无特殊要求。
|
参数`taos`是一个已经建立好的数据库连接,在同步模式下无特殊要求。但在异步模式下,需要注意它不会被其它线程使用,否则可能导致不可预计的错误,因为回调函数在API的内部线程中被调用,而TDengine的部分API不是线程安全的。
|
||||||
但在异步模式下,需要注意它不会被其它线程使用,否则可能导致不可预计的错误,
|
|
||||||
因为回调函数在API的内部线程中被调用,而TDengine的部分API不是线程安全的。
|
|
||||||
|
|
||||||
参数`sql`是查询语句,可以在其中使用where子句指定过滤条件。
|
参数`sql`是查询语句,可以在其中使用where子句指定过滤条件。在我们的例子中,如果只想订阅电流超过10A时的数据,可以这样写:
|
||||||
在我们的例子中,如果只想订阅电流超过10A时的数据,可以这样写:
|
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
select * from meters where current > 10;
|
select * from meters where current > 10;
|
||||||
```
|
```
|
||||||
|
|
||||||
注意,这里没有指定起始时间,所以会读到所有时间的数据。
|
注意,这里没有指定起始时间,所以会读到所有时间的数据。如果只想从一天前的数据开始订阅,而不需要更早的历史数据,可以再加上一个时间条件:
|
||||||
如果只想从一天前的数据开始订阅,而不需要更早的历史数据,可以再加上一个时间条件:
|
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
select * from meters where ts > now - 1d and current > 10;
|
select * from meters where ts > now - 1d and current > 10;
|
||||||
```
|
```
|
||||||
|
|
||||||
订阅的`topic`实际上是它的名字,因为订阅功能是在客户端API中实现的,
|
订阅的`topic`实际上是它的名字,因为订阅功能是在客户端API中实现的,所以没必要保证它全局唯一,但需要它在一台客户端机器上唯一。
|
||||||
所以没必要保证它全局唯一,但需要它在一台客户端机器上唯一。
|
|
||||||
|
|
||||||
如果名`topic`的订阅不存在,参数`restart`没有意义;
|
如果名`topic`的订阅不存在,参数`restart`没有意义;但如果用户程序创建这个订阅后退出,当它再次启动并重新使用这个`topic`时,`restart`就会被用于决定是从头开始读取数据,还是接续上次的位置进行读取。本例中,如果`restart`是 **true**(非零值),用户程序肯定会读到所有数据。但如果这个订阅之前就存在了,并且已经读取了一部分数据,且`restart`是 **false**(**0**),用户程序就不会读到之前已经读取的数据了。
|
||||||
但如果用户程序创建这个订阅后退出,当它再次启动并重新使用这个`topic`时,
|
|
||||||
`restart`就会被用于决定是从头开始读取数据,还是接续上次的位置进行读取。
|
|
||||||
本例中,如果`restart`是 **true**(非零值),用户程序肯定会读到所有数据。
|
|
||||||
但如果这个订阅之前就存在了,并且已经读取了一部分数据,
|
|
||||||
且`restart`是 **false**(**0**),用户程序就不会读到之前已经读取的数据了。
|
|
||||||
|
|
||||||
`taos_subscribe`的最后一个参数是以毫秒为单位的轮询周期。
|
`taos_subscribe`的最后一个参数是以毫秒为单位的轮询周期。在同步模式下,如果前后两次调用`taos_consume`的时间间隔小于此时间,`taos_consume`会阻塞,直到间隔超过此时间。异步模式下,这个时间是两次调用回调函数的最小时间间隔。
|
||||||
在同步模式下,如果前后两次调用`taos_consume`的时间间隔小于此时间,
|
|
||||||
`taos_consume`会阻塞,直到间隔超过此时间。
|
|
||||||
异步模式下,这个时间是两次调用回调函数的最小时间间隔。
|
|
||||||
|
|
||||||
`taos_subscribe`的倒数第二个参数用于用户程序向回调函数传递附加参数,
|
`taos_subscribe`的倒数第二个参数用于用户程序向回调函数传递附加参数,订阅API不对其做任何处理,只原样传递给回调函数。此参数在同步模式下无意义。
|
||||||
订阅API不对其做任何处理,只原样传递给回调函数。此参数在同步模式下无意义。
|
|
||||||
|
|
||||||
订阅创建以后,就可以消费其数据了,同步模式下,示例代码是下面的 else 部分:
|
订阅创建以后,就可以消费其数据了,同步模式下,示例代码是下面的 else 部分:
|
||||||
|
|
||||||
|
@ -219,9 +161,7 @@ if (async) {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
这里是一个 **while** 循环,用户每按一次回车键就调用一次`taos_consume`,
|
这里是一个 **while** 循环,用户每按一次回车键就调用一次`taos_consume`,而`taos_consume`的返回值是查询到的结果集,与`taos_use_result`完全相同,例子中使用这个结果集的代码是函数`print_result`:
|
||||||
而`taos_consume`的返回值是查询到的结果集,与`taos_use_result`完全相同,
|
|
||||||
例子中使用这个结果集的代码是函数`print_result`:
|
|
||||||
|
|
||||||
```c
|
```c
|
||||||
void print_result(TAOS_RES* res, int blockFetch) {
|
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
|
```c
|
||||||
void subscribe_callback(TAOS_SUB* tsub, TAOS_RES *res, void* param, int code) {
|
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);
|
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);
|
> insert into D1001 values(now, 12, 220, 1);
|
||||||
```
|
```
|
||||||
|
|
||||||
这时,因为电流超过了10A,您应该可以看到示例程序将它输出到了屏幕上。
|
这时,因为电流超过了10A,您应该可以看到示例程序将它输出到了屏幕上。您可以继续插入一些数据观察示例程序的输出。
|
||||||
您可以继续插入一些数据观察示例程序的输出。
|
|
||||||
|
|
||||||
### Java 使用数据订阅功能
|
### 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 的记录。
|
下面以一个示例程序介绍其具体使用方法。它所完成的功能与前面介绍的 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-Out,FIFO),又称为写驱动的缓存管理机制。这种策略有别于读驱动的数据缓存模式(Least-Recent-Use,LRU),直接将最近写入的数据保存在系统的缓存中。当缓存达到临界值的时候,将最早的数据批量写入磁盘。一般意义上来说,对于物联网数据的使用,用户最为关心最近产生的数据,即当前状态。TDengine充分利用了这一特性,将最近到达的(当前状态)数据保存在缓存中。
|
TDengine采用时间驱动缓存管理策略(First-In-First-Out,FIFO),又称为写驱动的缓存管理机制。这种策略有别于读驱动的数据缓存模式(Least-Recent-Use,LRU),直接将最近写入的数据保存在系统的缓存中。当缓存达到临界值的时候,将最早的数据批量写入磁盘。一般意义上来说,对于物联网数据的使用,用户最为关心最近产生的数据,即当前状态。TDengine充分利用了这一特性,将最近到达的(当前状态)数据保存在缓存中。
|
||||||
|
|
||||||
|
@ -423,7 +357,7 @@ select last_row(voltage) from meters where location='Beijing.Chaoyang';
|
||||||
该SQL语句将获取所有位于北京朝阳区的电表最后记录的电压值。
|
该SQL语句将获取所有位于北京朝阳区的电表最后记录的电压值。
|
||||||
|
|
||||||
|
|
||||||
## <a class="anchor" id="alert"></a>报警监测(Alert)
|
## <a class="anchor" id="alert"></a>报警监测(Alert)
|
||||||
|
|
||||||
在 TDengine 的应用场景中,报警监测是一个常见需求,从概念上说,它要求程序从最近一段时间的数据中筛选出符合一定条件的数据,并基于这些数据根据定义好的公式计算出一个结果,当这个结果符合某个条件且持续一定时间后,以某种形式通知用户。
|
在 TDengine 的应用场景中,报警监测是一个常见需求,从概念上说,它要求程序从最近一段时间的数据中筛选出符合一定条件的数据,并基于这些数据根据定义好的公式计算出一个结果,当这个结果符合某个条件且持续一定时间后,以某种形式通知用户。
|
||||||
|
|
||||||
|
|
|
@ -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/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBErrorNumbers.java
|
||||||
* https://github.com/taosdata/TDengine/blob/develop/src/inc/taoserror.h
|
* 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 |
|
| BIGINT | java.lang.Long |
|
||||||
| FLOAT | java.lang.Float |
|
| FLOAT | java.lang.Float |
|
||||||
| DOUBLE | java.lang.Double |
|
| DOUBLE | java.lang.Double |
|
||||||
| SMALLINT, TINYINT | java.lang.Short |
|
| SMALLINT | java.lang.Short |
|
||||||
|
| TINYINT | java.lang.Byte |
|
||||||
| BOOL | java.lang.Boolean |
|
| BOOL | java.lang.Boolean |
|
||||||
| BINARY, NCHAR | java.lang.String |
|
| BINARY | byte array |
|
||||||
|
| NCHAR | java.lang.String |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -120,17 +120,17 @@ taosd -C
|
||||||
不同应用场景的数据往往具有不同的数据特征,比如保留天数、副本数、采集频次、记录大小、采集点的数量、压缩等都可完全不同。为获得在存储上的最高效率,TDengine提供如下存储相关的系统配置参数:
|
不同应用场景的数据往往具有不同的数据特征,比如保留天数、副本数、采集频次、记录大小、采集点的数量、压缩等都可完全不同。为获得在存储上的最高效率,TDengine提供如下存储相关的系统配置参数:
|
||||||
|
|
||||||
- days:一个数据文件存储数据的时间跨度,单位为天,默认值:10。
|
- days:一个数据文件存储数据的时间跨度,单位为天,默认值:10。
|
||||||
- keep:数据库中数据保留的天数,单位为天,默认值:3650。
|
- keep:数据库中数据保留的天数,单位为天,默认值:3650。(可通过 alter database 修改)
|
||||||
- minRows:文件块中记录的最小条数,单位为条,默认值:100。
|
- minRows:文件块中记录的最小条数,单位为条,默认值:100。
|
||||||
- maxRows:文件块中记录的最大条数,单位为条,默认值:4096。
|
- maxRows:文件块中记录的最大条数,单位为条,默认值:4096。
|
||||||
- comp:文件压缩标志位,0:关闭;1:一阶段压缩;2:两阶段压缩。默认值:2。
|
- comp:文件压缩标志位,0:关闭;1:一阶段压缩;2:两阶段压缩。默认值:2。(可通过 alter database 修改)
|
||||||
- walLevel:WAL级别。1:写wal,但不执行fsync;2:写wal, 而且执行fsync。默认值:1。
|
- walLevel:WAL级别。1:写wal,但不执行fsync;2:写wal, 而且执行fsync。默认值:1。
|
||||||
- fsync:当wal设置为2时,执行fsync的周期。设置为0,表示每次写入,立即执行fsync。单位为毫秒,默认值:3000。
|
- fsync:当wal设置为2时,执行fsync的周期。设置为0,表示每次写入,立即执行fsync。单位为毫秒,默认值:3000。
|
||||||
- cache:内存块的大小,单位为兆字节(MB),默认值:16。
|
- cache:内存块的大小,单位为兆字节(MB),默认值:16。
|
||||||
- blocks:每个VNODE(TSDB)中有多少cache大小的内存块。因此一个VNODE的用的内存大小粗略为(cache * blocks)。单位为块,默认值:4。
|
- blocks:每个VNODE(TSDB)中有多少cache大小的内存块。因此一个VNODE的用的内存大小粗略为(cache * blocks)。单位为块,默认值:4。(可通过 alter database 修改)
|
||||||
- replica:副本个数,取值范围:1-3。单位为个,默认值:1
|
- replica:副本个数,取值范围:1-3。单位为个,默认值:1。(可通过 alter database 修改)
|
||||||
- precision:时间戳精度标识,ms表示毫秒,us表示微秒。默认值:ms
|
- precision:时间戳精度标识,ms表示毫秒,us表示微秒。默认值:ms。
|
||||||
- cacheLast:是否在内存中缓存子表 last_row,0:关闭;1:开启。默认值:0。(从 2.0.11 版本开始支持此参数)
|
- cacheLast:是否在内存中缓存子表 last_row,0:关闭;1:开启。默认值:0。(可通过 alter database 修改)(从 2.0.11 版本开始支持此参数)
|
||||||
|
|
||||||
对于一个应用场景,可能有多种数据特征的数据并存,最佳的设计是将具有相同数据特征的表放在一个库里,这样一个应用有多个库,而每个库可以配置不同的存储参数,从而保证系统有最优的性能。TDengine允许应用在创建库时指定上述存储参数,如果指定,该参数就将覆盖对应的系统配置参数。举例,有下述SQL:
|
对于一个应用场景,可能有多种数据特征的数据并存,最佳的设计是将具有相同数据特征的表放在一个库里,这样一个应用有多个库,而每个库可以配置不同的存储参数,从而保证系统有最优的性能。TDengine允许应用在创建库时指定上述存储参数,如果指定,该参数就将覆盖对应的系统配置参数。举例,有下述SQL:
|
||||||
|
|
||||||
|
|
|
@ -29,21 +29,21 @@ taos> DESCRIBE meters;
|
||||||
|
|
||||||
## <a class="anchor" id="data-type"></a>支持的数据类型
|
## <a class="anchor" id="data-type"></a>支持的数据类型
|
||||||
|
|
||||||
使用TDengine,最重要的是时间戳。创建并插入记录、查询历史记录的时候,均需要指定时间戳。时间戳有如下规则:
|
使用 TDengine,最重要的是时间戳。创建并插入记录、查询历史记录的时候,均需要指定时间戳。时间戳有如下规则:
|
||||||
|
|
||||||
- 时间格式为```YYYY-MM-DD HH:mm:ss.MS```, 默认时间分辨率为毫秒。比如:```2017-08-12 18:25:58.128```
|
- 时间格式为 ```YYYY-MM-DD HH:mm:ss.MS```,默认时间分辨率为毫秒。比如:```2017-08-12 18:25:58.128```
|
||||||
- 内部函数now是服务器的当前时间
|
- 内部函数 now 是客户端的当前时间
|
||||||
- 插入记录时,如果时间戳为now,插入数据时使用服务器当前时间
|
- 插入记录时,如果时间戳为 now,插入数据时使用提交这条记录的客户端的当前时间
|
||||||
- Epoch Time: 时间戳也可以是一个长整数,表示从1970-01-01 08:00:00.000开始的毫秒数
|
- 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(自然年)。
|
- 时间可以加减,比如 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种数据类型。
|
在TDengine中,普通表的数据模型中可使用以下 10 种数据类型。
|
||||||
|
|
||||||
| | 类型 | Bytes | 说明 |
|
| | 类型 | 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 |
|
| 2 | INT | 4 | 整型,范围 [-2^31+1, 2^31-1], -2^31 用作 NULL |
|
||||||
| 3 | BIGINT | 8 | 长整型,范围 [-2^63+1, 2^63-1], -2^63 用于 NULL |
|
| 3 | BIGINT | 8 | 长整型,范围 [-2^63+1, 2^63-1], -2^63 用于 NULL |
|
||||||
| 4 | FLOAT | 4 | 浮点型,有效位数 6-7,范围 [-3.4E38, 3.4E38] |
|
| 4 | FLOAT | 4 | 浮点型,有效位数 6-7,范围 [-3.4E38, 3.4E38] |
|
||||||
|
|
|
@ -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`)来书写时间戳,此时这些时间戳的取值将不再受其他时区设置的影响。
|
||||||
|
|
|
@ -29,6 +29,9 @@
|
||||||
# number of threads per CPU core
|
# number of threads per CPU core
|
||||||
# numOfThreadsPerCore 1.0
|
# numOfThreadsPerCore 1.0
|
||||||
|
|
||||||
|
# number of threads to commit cache data
|
||||||
|
# numOfCommitThreads 4
|
||||||
|
|
||||||
# the proportion of total CPU cores available for query processing
|
# the proportion of total CPU cores available for query processing
|
||||||
# 2.0: the query threads will be set to double of the CPU cores.
|
# 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].
|
# 1.0: all CPU cores are available for query processing [default].
|
||||||
|
|
|
@ -120,7 +120,7 @@ function clean_service_on_systemd() {
|
||||||
|
|
||||||
if [ "$verMode" == "cluster" ]; then
|
if [ "$verMode" == "cluster" ]; then
|
||||||
nginx_service_config="${service_config_dir}/${nginx_service_name}.service"
|
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
|
if systemctl is-active --quiet ${nginx_service_name}; then
|
||||||
echo "Nginx for TDengine is running, stopping it..."
|
echo "Nginx for TDengine is running, stopping it..."
|
||||||
${csudo} systemctl stop ${nginx_service_name} &> /dev/null || echo &> /dev/null
|
${csudo} systemctl stop ${nginx_service_name} &> /dev/null || echo &> /dev/null
|
||||||
|
|
|
@ -451,6 +451,8 @@ void tscFreeSqlResult(SSqlObj *pSql);
|
||||||
* @param pObj
|
* @param pObj
|
||||||
*/
|
*/
|
||||||
void tscFreeSqlObj(SSqlObj *pSql);
|
void tscFreeSqlObj(SSqlObj *pSql);
|
||||||
|
void tscFreeSubobj(SSqlObj* pSql);
|
||||||
|
|
||||||
void tscFreeRegisteredSqlObj(void *pSql);
|
void tscFreeRegisteredSqlObj(void *pSql);
|
||||||
|
|
||||||
void tscCloseTscObj(void *pObj);
|
void tscCloseTscObj(void *pObj);
|
||||||
|
|
|
@ -2683,7 +2683,6 @@ void tscInitMsgsFp() {
|
||||||
tscProcessMsgRsp[TSDB_SQL_SHOW_CREATE_TABLE] = tscProcessShowCreateRsp;
|
tscProcessMsgRsp[TSDB_SQL_SHOW_CREATE_TABLE] = tscProcessShowCreateRsp;
|
||||||
tscProcessMsgRsp[TSDB_SQL_SHOW_CREATE_DATABASE] = tscProcessShowCreateRsp;
|
tscProcessMsgRsp[TSDB_SQL_SHOW_CREATE_DATABASE] = tscProcessShowCreateRsp;
|
||||||
|
|
||||||
|
|
||||||
tscKeepConn[TSDB_SQL_SHOW] = 1;
|
tscKeepConn[TSDB_SQL_SHOW] = 1;
|
||||||
tscKeepConn[TSDB_SQL_RETRIEVE] = 1;
|
tscKeepConn[TSDB_SQL_RETRIEVE] = 1;
|
||||||
tscKeepConn[TSDB_SQL_SELECT] = 1;
|
tscKeepConn[TSDB_SQL_SELECT] = 1;
|
||||||
|
|
|
@ -299,6 +299,7 @@ static void tscProcessStreamRetrieveResult(void *param, TAOS_RES *res, int numOf
|
||||||
tfree(pTableMetaInfo->pTableMeta);
|
tfree(pTableMetaInfo->pTableMeta);
|
||||||
|
|
||||||
tscFreeSqlResult(pSql);
|
tscFreeSqlResult(pSql);
|
||||||
|
tscFreeSubobj(pSql);
|
||||||
tfree(pSql->pSubs);
|
tfree(pSql->pSubs);
|
||||||
pSql->subState.numOfSub = 0;
|
pSql->subState.numOfSub = 0;
|
||||||
pTableMetaInfo->vgroupList = tscVgroupInfoClear(pTableMetaInfo->vgroupList);
|
pTableMetaInfo->vgroupList = tscVgroupInfoClear(pTableMetaInfo->vgroupList);
|
||||||
|
|
|
@ -447,7 +447,7 @@ void tscFreeSqlResult(SSqlObj* pSql) {
|
||||||
memset(&pSql->res, 0, sizeof(SSqlRes));
|
memset(&pSql->res, 0, sizeof(SSqlRes));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tscFreeSubobj(SSqlObj* pSql) {
|
void tscFreeSubobj(SSqlObj* pSql) {
|
||||||
if (pSql->subState.numOfSub == 0) {
|
if (pSql->subState.numOfSub == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@ int32_t tsMaxShellConns = 50000;
|
||||||
int32_t tsMaxConnections = 5000;
|
int32_t tsMaxConnections = 5000;
|
||||||
int32_t tsShellActivityTimer = 3; // second
|
int32_t tsShellActivityTimer = 3; // second
|
||||||
float tsNumOfThreadsPerCore = 1.0f;
|
float tsNumOfThreadsPerCore = 1.0f;
|
||||||
int32_t tsNumOfCommitThreads = 1;
|
int32_t tsNumOfCommitThreads = 4;
|
||||||
float tsRatioOfQueryCores = 1.0f;
|
float tsRatioOfQueryCores = 1.0f;
|
||||||
int8_t tsDaylight = 0;
|
int8_t tsDaylight = 0;
|
||||||
char tsTimezone[TSDB_TIMEZONE_LEN] = {0};
|
char tsTimezone[TSDB_TIMEZONE_LEN] = {0};
|
||||||
|
|
|
@ -8,7 +8,7 @@ IF (TD_MVN_INSTALLED)
|
||||||
ADD_CUSTOM_COMMAND(OUTPUT ${JDBC_CMD_NAME}
|
ADD_CUSTOM_COMMAND(OUTPUT ${JDBC_CMD_NAME}
|
||||||
POST_BUILD
|
POST_BUILD
|
||||||
COMMAND mvn -Dmaven.test.skip=true install -f ${CMAKE_CURRENT_SOURCE_DIR}/pom.xml
|
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
|
COMMAND mvn -Dmaven.test.skip=true clean -f ${CMAKE_CURRENT_SOURCE_DIR}/pom.xml
|
||||||
COMMENT "build jdbc driver")
|
COMMENT "build jdbc driver")
|
||||||
ADD_CUSTOM_TARGET(${JDBC_TARGET_NAME} ALL WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH} DEPENDS ${JDBC_CMD_NAME})
|
ADD_CUSTOM_TARGET(${JDBC_TARGET_NAME} ALL WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH} DEPENDS ${JDBC_CMD_NAME})
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
<groupId>com.taosdata.jdbc</groupId>
|
<groupId>com.taosdata.jdbc</groupId>
|
||||||
<artifactId>taos-jdbcdriver</artifactId>
|
<artifactId>taos-jdbcdriver</artifactId>
|
||||||
<version>2.0.22</version>
|
<version>2.0.25</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>JDBCDriver</name>
|
<name>JDBCDriver</name>
|
||||||
|
@ -37,17 +37,6 @@
|
||||||
</developers>
|
</developers>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
|
||||||
<groupId>commons-logging</groupId>
|
|
||||||
<artifactId>commons-logging</artifactId>
|
|
||||||
<version>1.2</version>
|
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>*</groupId>
|
|
||||||
<artifactId>*</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
|
@ -61,21 +50,20 @@
|
||||||
<artifactId>httpclient</artifactId>
|
<artifactId>httpclient</artifactId>
|
||||||
<version>4.5.8</version>
|
<version>4.5.8</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.commons</groupId>
|
|
||||||
<artifactId>commons-lang3</artifactId>
|
|
||||||
<version>3.9</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.alibaba</groupId>
|
<groupId>com.alibaba</groupId>
|
||||||
<artifactId>fastjson</artifactId>
|
<artifactId>fastjson</artifactId>
|
||||||
<version>1.2.58</version>
|
<version>1.2.58</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.guava</groupId>
|
||||||
|
<artifactId>guava</artifactId>
|
||||||
|
<version>29.0-jre</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-assembly-plugin</artifactId>
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>com.taosdata.jdbc</groupId>
|
<groupId>com.taosdata.jdbc</groupId>
|
||||||
<artifactId>taos-jdbcdriver</artifactId>
|
<artifactId>taos-jdbcdriver</artifactId>
|
||||||
<version>2.0.22</version>
|
<version>2.0.25</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
<name>JDBCDriver</name>
|
<name>JDBCDriver</name>
|
||||||
<url>https://github.com/taosdata/TDengine/tree/master/src/connector/jdbc</url>
|
<url>https://github.com/taosdata/TDengine/tree/master/src/connector/jdbc</url>
|
||||||
|
@ -43,7 +43,6 @@
|
||||||
<version>4.13</version>
|
<version>4.13</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- for restful -->
|
<!-- for restful -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.httpcomponents</groupId>
|
<groupId>org.apache.httpcomponents</groupId>
|
||||||
|
@ -55,10 +54,22 @@
|
||||||
<artifactId>fastjson</artifactId>
|
<artifactId>fastjson</artifactId>
|
||||||
<version>1.2.58</version>
|
<version>1.2.58</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.guava</groupId>
|
||||||
|
<artifactId>guava</artifactId>
|
||||||
|
<version>29.0-jre</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<directory>src/main/resources</directory>
|
||||||
|
<excludes>
|
||||||
|
<exclude>**/*.md</exclude>
|
||||||
|
</excludes>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
|
|
@ -30,9 +30,12 @@ public abstract class AbstractConnection extends WrapperImpl implements Connecti
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
|
||||||
// do nothing
|
// do nothing
|
||||||
|
|
||||||
return sql;
|
return sql;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setAutoCommit(boolean autoCommit) throws SQLException {
|
public void setAutoCommit(boolean autoCommit) throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
|
@ -448,7 +451,6 @@ public abstract class AbstractConnection extends WrapperImpl implements Connecti
|
||||||
if (isClosed)
|
if (isClosed)
|
||||||
throw (SQLClientInfoException) TSDBError.createSQLException(TSDBErrorNumbers.ERROR_SQLCLIENT_EXCEPTION_ON_CONNECTION_CLOSED);
|
throw (SQLClientInfoException) TSDBError.createSQLException(TSDBErrorNumbers.ERROR_SQLCLIENT_EXCEPTION_ON_CONNECTION_CLOSED);
|
||||||
|
|
||||||
|
|
||||||
for (Enumeration<Object> enumer = properties.keys(); enumer.hasMoreElements(); ) {
|
for (Enumeration<Object> enumer = properties.keys(); enumer.hasMoreElements(); ) {
|
||||||
String name = (String) enumer.nextElement();
|
String name = (String) enumer.nextElement();
|
||||||
clientInfoProps.put(name, properties.getProperty(name));
|
clientInfoProps.put(name, properties.getProperty(name));
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,6 +11,15 @@ import java.util.Map;
|
||||||
public abstract class AbstractResultSet extends WrapperImpl implements ResultSet {
|
public abstract class AbstractResultSet extends WrapperImpl implements ResultSet {
|
||||||
private int fetchSize;
|
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
|
@Override
|
||||||
public abstract boolean next() throws SQLException;
|
public abstract boolean next() throws SQLException;
|
||||||
|
|
||||||
|
@ -46,38 +55,20 @@ public abstract class AbstractResultSet extends WrapperImpl implements ResultSet
|
||||||
@Override
|
@Override
|
||||||
public abstract double getDouble(int columnIndex) throws SQLException;
|
public abstract double getDouble(int columnIndex) throws SQLException;
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
@Override
|
@Override
|
||||||
public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException {
|
public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException {
|
||||||
if (isClosed())
|
return getBigDecimal(columnIndex);
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
|
|
||||||
|
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] getBytes(int columnIndex) throws SQLException {
|
public abstract byte[] getBytes(int columnIndex) throws SQLException;
|
||||||
if (isClosed())
|
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
|
|
||||||
|
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Date getDate(int columnIndex) throws SQLException {
|
public abstract Date getDate(int columnIndex) throws SQLException;
|
||||||
if (isClosed())
|
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
|
|
||||||
|
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Time getTime(int columnIndex) throws SQLException {
|
public abstract Time getTime(int columnIndex) throws SQLException;
|
||||||
if (isClosed())
|
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
|
|
||||||
|
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public abstract Timestamp getTimestamp(int columnIndex) throws SQLException;
|
public abstract Timestamp getTimestamp(int columnIndex) throws SQLException;
|
||||||
|
@ -147,9 +138,10 @@ public abstract class AbstractResultSet extends WrapperImpl implements ResultSet
|
||||||
return getDouble(findColumn(columnLabel));
|
return getDouble(findColumn(columnLabel));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
@Override
|
@Override
|
||||||
public BigDecimal getBigDecimal(String columnLabel, int scale) throws SQLException {
|
public BigDecimal getBigDecimal(String columnLabel, int scale) throws SQLException {
|
||||||
return getBigDecimal(findColumn(columnLabel));
|
return getBigDecimal(findColumn(columnLabel), scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -214,12 +206,7 @@ public abstract class AbstractResultSet extends WrapperImpl implements ResultSet
|
||||||
public abstract ResultSetMetaData getMetaData() throws SQLException;
|
public abstract ResultSetMetaData getMetaData() throws SQLException;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getObject(int columnIndex) throws SQLException {
|
public abstract Object getObject(int columnIndex) throws SQLException;
|
||||||
if (isClosed())
|
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
|
|
||||||
|
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getObject(String columnLabel) throws SQLException {
|
public Object getObject(String columnLabel) throws SQLException {
|
||||||
|
@ -243,12 +230,7 @@ public abstract class AbstractResultSet extends WrapperImpl implements ResultSet
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
|
public abstract BigDecimal getBigDecimal(int columnIndex) throws SQLException;
|
||||||
if (isClosed())
|
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
|
|
||||||
|
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BigDecimal getBigDecimal(String columnLabel) throws SQLException {
|
public BigDecimal getBigDecimal(String columnLabel) throws SQLException {
|
||||||
|
@ -718,9 +700,7 @@ public abstract class AbstractResultSet extends WrapperImpl implements ResultSet
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getObject(String columnLabel, Map<String, Class<?>> map) throws SQLException {
|
public Object getObject(String columnLabel, Map<String, Class<?>> map) throws SQLException {
|
||||||
if (isClosed())
|
return getObject(findColumn(columnLabel), map);
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -760,9 +740,7 @@ public abstract class AbstractResultSet extends WrapperImpl implements ResultSet
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Date getDate(String columnLabel, Calendar cal) throws SQLException {
|
public Date getDate(String columnLabel, Calendar cal) throws SQLException {
|
||||||
if (isClosed())
|
return getDate(findColumn(columnLabel), cal);
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -774,23 +752,15 @@ public abstract class AbstractResultSet extends WrapperImpl implements ResultSet
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Time getTime(String columnLabel, Calendar cal) throws SQLException {
|
public Time getTime(String columnLabel, Calendar cal) throws SQLException {
|
||||||
if (isClosed())
|
return getTime(findColumn(columnLabel), cal);
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException {
|
public abstract Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException;
|
||||||
if (isClosed())
|
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Timestamp getTimestamp(String columnLabel, Calendar cal) throws SQLException {
|
public Timestamp getTimestamp(String columnLabel, Calendar cal) throws SQLException {
|
||||||
if (isClosed())
|
return getTimestamp(findColumn(columnLabel), cal);
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1198,9 +1168,7 @@ public abstract class AbstractResultSet extends WrapperImpl implements ResultSet
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T getObject(String columnLabel, Class<T> type) throws SQLException {
|
public <T> T getObject(String columnLabel, Class<T> type) throws SQLException {
|
||||||
if (isClosed())
|
return getObject(findColumn(columnLabel), type);
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,8 @@ public abstract class AbstractStatement extends WrapperImpl implements Statement
|
||||||
protected List<String> batchedArgs;
|
protected List<String> batchedArgs;
|
||||||
private int fetchSize;
|
private int fetchSize;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public abstract ResultSet executeQuery(String sql) throws SQLException;
|
public abstract ResultSet executeQuery(String sql) throws SQLException;
|
||||||
|
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -27,10 +27,6 @@ public class TSDBConnection extends AbstractConnection {
|
||||||
return this.batchFetch;
|
return this.batchFetch;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBatchFetch(Boolean batchFetch) {
|
|
||||||
this.batchFetch = batchFetch;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TSDBConnection(Properties info, TSDBDatabaseMetaData meta) throws SQLException {
|
public TSDBConnection(Properties info, TSDBDatabaseMetaData meta) throws SQLException {
|
||||||
this.databaseMetaData = meta;
|
this.databaseMetaData = meta;
|
||||||
connect(info.getProperty(TSDBDriver.PROPERTY_KEY_HOST),
|
connect(info.getProperty(TSDBDriver.PROPERTY_KEY_HOST),
|
||||||
|
@ -61,9 +57,7 @@ public class TSDBConnection extends AbstractConnection {
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
TSDBStatement statement = new TSDBStatement(this, this.connector);
|
return new TSDBStatement(this, this.connector);
|
||||||
statement.setConnection(this);
|
|
||||||
return statement;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public TSDBSubscribe subscribe(String topic, String sql, boolean restart) throws SQLException {
|
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 {
|
public PreparedStatement prepareStatement(String sql) throws SQLException {
|
||||||
if (isClosed()) {
|
if (isClosed())
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
|
||||||
}
|
|
||||||
|
|
||||||
return new TSDBPreparedStatement(this, this.connector, sql);
|
return new TSDBPreparedStatement(this, this.connector, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,11 +96,4 @@ public class TSDBConnection extends AbstractConnection {
|
||||||
return this.databaseMetaData;
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -29,45 +29,25 @@ public class TSDBJNIConnector {
|
||||||
private static volatile Boolean isInitialized = false;
|
private static volatile Boolean isInitialized = false;
|
||||||
|
|
||||||
private TaosInfo taosInfo = TaosInfo.getInstance();
|
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 {
|
static {
|
||||||
System.loadLibrary("taos");
|
System.loadLibrary("taos");
|
||||||
System.out.println("java.library.path:" + System.getProperty("java.library.path"));
|
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() {
|
public boolean isClosed() {
|
||||||
return this.taos == TSDBConstants.JNI_NULL_POINTER;
|
return this.taos == TSDBConstants.JNI_NULL_POINTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the status of last result set in current connection
|
|
||||||
*/
|
|
||||||
public boolean isResultsetClosed() {
|
public boolean isResultsetClosed() {
|
||||||
return this.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 {
|
public static void init(String configDir, String locale, String charset, String timezone) throws SQLWarning {
|
||||||
synchronized (isInitialized) {
|
synchronized (isInitialized) {
|
||||||
if (!isInitialized) {
|
if (!isInitialized) {
|
||||||
|
@ -93,11 +73,6 @@ public class TSDBJNIConnector {
|
||||||
|
|
||||||
public static native String getTsCharset();
|
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 {
|
public boolean connect(String host, int port, String dbName, String user, String password) throws SQLException {
|
||||||
if (this.taos != TSDBConstants.JNI_NULL_POINTER) {
|
if (this.taos != TSDBConstants.JNI_NULL_POINTER) {
|
||||||
// this.closeConnectionImp(this.taos);
|
// this.closeConnectionImp(this.taos);
|
||||||
|
@ -185,13 +160,6 @@ public class TSDBJNIConnector {
|
||||||
|
|
||||||
private native String getErrMsgImp(long pSql);
|
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);
|
private native long getResultSetImp(long connection, long pSql);
|
||||||
|
|
||||||
public boolean isUpdateQuery(long pSql) {
|
public boolean isUpdateQuery(long pSql) {
|
||||||
|
@ -231,6 +199,7 @@ public class TSDBJNIConnector {
|
||||||
// }
|
// }
|
||||||
// return resCode;
|
// return resCode;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
private native int freeResultSetImp(long connection, long result);
|
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
|
* Validate if a <I>create table</I> sql statement is correct without actually creating that table
|
||||||
*/
|
*/
|
||||||
public boolean validateCreateTableSql(String sql) {
|
public boolean validateCreateTableSql(String sql) {
|
||||||
long connection = taos;
|
int res = validateCreateTableSqlImp(taos, sql.getBytes());
|
||||||
int res = validateCreateTableSqlImp(connection, sql.getBytes());
|
|
||||||
return res != 0 ? false : true;
|
return res != 0 ? false : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
package com.taosdata.jdbc;
|
||||||
|
|
||||||
|
public class TSDBParameterMetaData extends AbstractParameterMetaData {
|
||||||
|
|
||||||
|
public TSDBParameterMetaData(Object[] parameters) {
|
||||||
|
super(parameters);
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,6 +18,7 @@ import java.io.InputStream;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
import java.sql.*;
|
import java.sql.*;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
|
@ -30,36 +31,49 @@ import java.util.regex.Pattern;
|
||||||
* compatibility needs.
|
* compatibility needs.
|
||||||
*/
|
*/
|
||||||
public class TSDBPreparedStatement extends TSDBStatement implements PreparedStatement {
|
public class TSDBPreparedStatement extends TSDBStatement implements PreparedStatement {
|
||||||
protected String rawSql;
|
|
||||||
protected String sql;
|
private String rawSql;
|
||||||
protected ArrayList<Object> parameters = new ArrayList<>();
|
private String sql;
|
||||||
|
// private ArrayList<Object> parameters = new ArrayList<>();
|
||||||
|
private Object[] parameters;
|
||||||
|
private boolean isPrepared;
|
||||||
|
|
||||||
//start with insert or import and is case-insensitive
|
//start with insert or import and is case-insensitive
|
||||||
private static Pattern savePattern = Pattern.compile("(?i)^\\s*(insert|import)");
|
private static Pattern savePattern = Pattern.compile("(?i)^\\s*(insert|import)");
|
||||||
|
|
||||||
// is insert or import
|
// is insert or import
|
||||||
private boolean isSaved;
|
private boolean isSaved;
|
||||||
|
|
||||||
private SavedPreparedStatement savedPreparedStatement;
|
// private SavedPreparedStatement savedPreparedStatement;
|
||||||
private ParameterMetaData parameterMetaData;
|
private volatile TSDBParameterMetaData parameterMetaData;
|
||||||
|
|
||||||
TSDBPreparedStatement(TSDBConnection connection, TSDBJNIConnector connecter, String sql) {
|
TSDBPreparedStatement(TSDBConnection connection, TSDBJNIConnector connecter, String sql) {
|
||||||
super(connection, connecter);
|
super(connection, connecter);
|
||||||
init(sql);
|
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) {
|
private void init(String sql) {
|
||||||
this.rawSql = sql;
|
this.rawSql = sql;
|
||||||
preprocessSql();
|
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
|
@Override
|
||||||
public int[] executeBatch() throws SQLException {
|
public int[] executeBatch() throws SQLException {
|
||||||
if (isSaved) {
|
// if (isSaved) {
|
||||||
return this.savedPreparedStatement.executeBatch();
|
// return this.savedPreparedStatement.executeBatch();
|
||||||
} else {
|
// } else {
|
||||||
return super.executeBatch();
|
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
|
* @return a string of the native sql statement for TSDB
|
||||||
*/
|
*/
|
||||||
private String getNativeSql() {
|
// private String getNativeSql(String rawSql) {
|
||||||
this.sql = this.rawSql;
|
// for (int i = 0; i < parameters.length; i++) {
|
||||||
for (int i = 0; i < parameters.size(); ++i) {
|
// Object para = parameters[i];
|
||||||
Object para = parameters.get(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) {
|
if (para != null) {
|
||||||
String paraStr = para.toString();
|
String paraStr;
|
||||||
if (para instanceof Timestamp || para instanceof String) {
|
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 + "'";
|
paraStr = "'" + paraStr + "'";
|
||||||
}
|
}
|
||||||
this.sql = this.sql.replaceFirst("[?]", paraStr);
|
sql = sql.replaceFirst("[?]", paraStr);
|
||||||
} else {
|
} else {
|
||||||
this.sql = this.sql.replaceFirst("[?]", "NULL");
|
sql = sql.replaceFirst("[?]", "NULL");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
parameters.clear();
|
clearParameters();
|
||||||
return sql;
|
return sql;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResultSet executeQuery() throws SQLException {
|
public ResultSet executeQuery() throws SQLException {
|
||||||
if (isSaved) {
|
// if (isSaved) {
|
||||||
this.savedPreparedStatement.executeBatchInternal();
|
// this.savedPreparedStatement.executeBatchInternal();
|
||||||
return null;
|
// return null;
|
||||||
} else {
|
// } else {
|
||||||
return super.executeQuery(getNativeSql());
|
|
||||||
}
|
if (!isPrepared)
|
||||||
|
return executeQuery(this.rawSql);
|
||||||
|
|
||||||
|
final String sql = getNativeSql(this.rawSql);
|
||||||
|
return executeQuery(sql);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int executeUpdate() throws SQLException {
|
public int executeUpdate() throws SQLException {
|
||||||
if (isSaved) {
|
// if (isSaved) {
|
||||||
return this.savedPreparedStatement.executeBatchInternal();
|
// return this.savedPreparedStatement.executeBatchInternal();
|
||||||
} else {
|
// } else {
|
||||||
return super.executeUpdate(getNativeSql());
|
if (!isPrepared)
|
||||||
}
|
return executeUpdate(this.rawSql);
|
||||||
|
String sql = getNativeSql(this.rawSql);
|
||||||
|
return executeUpdate(sql);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isSupportedSQLType(int sqlType) {
|
private boolean isSupportedSQLType(int sqlType) {
|
||||||
|
@ -201,35 +239,6 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
|
||||||
case Types.BINARY:
|
case Types.BINARY:
|
||||||
case Types.NCHAR:
|
case Types.NCHAR:
|
||||||
return true;
|
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:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -259,7 +268,7 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
|
||||||
public void setByte(int parameterIndex, byte x) throws SQLException {
|
public void setByte(int parameterIndex, byte x) throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
|
setObject(parameterIndex,x);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -315,7 +324,8 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
|
||||||
public void setBytes(int parameterIndex, byte[] x) throws SQLException {
|
public void setBytes(int parameterIndex, byte[] x) throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
|
|
||||||
|
setObject(parameterIndex,x);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -365,45 +375,63 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
|
||||||
public void clearParameters() throws SQLException {
|
public void clearParameters() throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
||||||
parameters.clear();
|
|
||||||
|
// parameters.clear();
|
||||||
|
parameters = new Object[parameters.length];
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException {
|
public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
||||||
|
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setObject(int parameterIndex, Object x) throws SQLException {
|
public void setObject(int parameterIndex, Object x) throws SQLException {
|
||||||
if (isSaved) {
|
// if (isSaved) {
|
||||||
this.savedPreparedStatement.setParam(parameterIndex, x);
|
// this.savedPreparedStatement.setParam(parameterIndex, x);
|
||||||
} else {
|
// } else {
|
||||||
parameters.add(x);
|
if (parameterIndex < 1 && parameterIndex >= parameters.length)
|
||||||
}
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE);
|
||||||
|
|
||||||
|
parameters[parameterIndex - 1] = x;
|
||||||
|
// parameters.add(x);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean execute() throws SQLException {
|
public boolean execute() throws SQLException {
|
||||||
if (isSaved) {
|
// if (isSaved) {
|
||||||
int result = this.savedPreparedStatement.executeBatchInternal();
|
// int result = this.savedPreparedStatement.executeBatchInternal();
|
||||||
return result > 0;
|
// return result > 0;
|
||||||
} else {
|
// } else {
|
||||||
return super.execute(getNativeSql());
|
if (!isPrepared)
|
||||||
}
|
return execute(this.rawSql);
|
||||||
|
|
||||||
|
final String sql = getNativeSql(this.rawSql);
|
||||||
|
|
||||||
|
return execute(sql);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addBatch() throws SQLException {
|
public void addBatch() throws SQLException {
|
||||||
if (isSaved) {
|
// if (isSaved) {
|
||||||
this.savedPreparedStatement.addBatch();
|
// this.savedPreparedStatement.addBatch();
|
||||||
} else {
|
// } else {
|
||||||
if (this.batchedArgs == null) {
|
if (this.batchedArgs == null) {
|
||||||
batchedArgs = new ArrayList<>();
|
batchedArgs = new ArrayList<>();
|
||||||
}
|
}
|
||||||
super.addBatch(getNativeSql());
|
|
||||||
|
if (!isPrepared) {
|
||||||
|
addBatch(this.rawSql);
|
||||||
|
} else {
|
||||||
|
String sql = this.getConnection().nativeSQL(this.rawSql);
|
||||||
|
addBatch(sql);
|
||||||
}
|
}
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -491,9 +519,11 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
|
||||||
public ParameterMetaData getParameterMetaData() throws SQLException {
|
public ParameterMetaData getParameterMetaData() throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
||||||
//TODO: parameterMetaData not supported
|
|
||||||
// return null;
|
if (parameterMetaData == null) {
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
|
this.parameterMetaData = new TSDBParameterMetaData(parameters);
|
||||||
|
}
|
||||||
|
return this.parameterMetaData;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -14,9 +14,14 @@
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
package com.taosdata.jdbc;
|
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.math.BigDecimal;
|
||||||
import java.sql.*;
|
import java.sql.*;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Calendar;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class TSDBResultSet extends AbstractResultSet implements ResultSet {
|
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 {
|
public String getString(int columnIndex) throws SQLException {
|
||||||
|
checkAvailability(columnIndex, this.columnMetaDataList.size());
|
||||||
|
|
||||||
String res = null;
|
String res = null;
|
||||||
int colIndex = getTrueColumnIndex(columnIndex);
|
|
||||||
|
|
||||||
if (this.getBatchFetch())
|
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) {
|
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;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getBoolean(int columnIndex) throws SQLException {
|
public boolean getBoolean(int columnIndex) throws SQLException {
|
||||||
|
checkAvailability(columnIndex, this.columnMetaDataList.size());
|
||||||
|
|
||||||
boolean res = false;
|
boolean res = false;
|
||||||
int colIndex = getTrueColumnIndex(columnIndex);
|
|
||||||
|
|
||||||
if (this.getBatchFetch())
|
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) {
|
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;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte getByte(int columnIndex) throws SQLException {
|
public byte getByte(int columnIndex) throws SQLException {
|
||||||
|
checkAvailability(columnIndex, this.columnMetaDataList.size());
|
||||||
|
|
||||||
byte res = 0;
|
byte res = 0;
|
||||||
int colIndex = getTrueColumnIndex(columnIndex);
|
|
||||||
|
|
||||||
if (this.getBatchFetch())
|
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) {
|
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;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
public short getShort(int columnIndex) throws SQLException {
|
public short getShort(int columnIndex) throws SQLException {
|
||||||
|
checkAvailability(columnIndex, this.columnMetaDataList.size());
|
||||||
|
|
||||||
short res = 0;
|
short res = 0;
|
||||||
int colIndex = getTrueColumnIndex(columnIndex);
|
|
||||||
|
|
||||||
if (this.getBatchFetch())
|
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) {
|
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;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getInt(int columnIndex) throws SQLException {
|
public int getInt(int columnIndex) throws SQLException {
|
||||||
|
checkAvailability(columnIndex, this.columnMetaDataList.size());
|
||||||
|
|
||||||
int res = 0;
|
int res = 0;
|
||||||
int colIndex = getTrueColumnIndex(columnIndex);
|
|
||||||
|
|
||||||
if (this.getBatchFetch())
|
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) {
|
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;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getLong(int columnIndex) throws SQLException {
|
public long getLong(int columnIndex) throws SQLException {
|
||||||
|
checkAvailability(columnIndex, this.columnMetaDataList.size());
|
||||||
|
|
||||||
long res = 0L;
|
long res = 0L;
|
||||||
int colIndex = getTrueColumnIndex(columnIndex);
|
|
||||||
|
|
||||||
if (this.getBatchFetch())
|
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) {
|
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;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getFloat(int columnIndex) throws SQLException {
|
public float getFloat(int columnIndex) throws SQLException {
|
||||||
|
checkAvailability(columnIndex, this.columnMetaDataList.size());
|
||||||
|
|
||||||
float res = 0;
|
float res = 0;
|
||||||
int colIndex = getTrueColumnIndex(columnIndex);
|
|
||||||
|
|
||||||
if (this.getBatchFetch())
|
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)
|
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;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getDouble(int columnIndex) throws SQLException {
|
public double getDouble(int columnIndex) throws SQLException {
|
||||||
|
checkAvailability(columnIndex, this.columnMetaDataList.size());
|
||||||
|
|
||||||
double res = 0;
|
double res = 0;
|
||||||
int colIndex = getTrueColumnIndex(columnIndex);
|
|
||||||
|
|
||||||
if (this.getBatchFetch())
|
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) {
|
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;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
public byte[] getBytes(int columnIndex) throws SQLException {
|
||||||
public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException {
|
checkAvailability(columnIndex, this.columnMetaDataList.size());
|
||||||
return new BigDecimal(getLong(columnIndex));
|
|
||||||
|
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 {
|
@Override
|
||||||
return getString(columnIndex).getBytes();
|
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 {
|
public Timestamp getTimestamp(int columnIndex) throws SQLException {
|
||||||
|
checkAvailability(columnIndex, this.columnMetaDataList.size());
|
||||||
|
|
||||||
Timestamp res = null;
|
Timestamp res = null;
|
||||||
int colIndex = getTrueColumnIndex(columnIndex);
|
|
||||||
|
|
||||||
if (this.getBatchFetch())
|
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) {
|
if (!lastWasNull) {
|
||||||
res = this.rowData.getTimestamp(colIndex);
|
res = this.rowData.getTimestamp(columnIndex - 1);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResultSetMetaData getMetaData() throws SQLException {
|
public ResultSetMetaData getMetaData() throws SQLException {
|
||||||
|
if (isClosed())
|
||||||
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
|
||||||
|
|
||||||
return new TSDBResultSetMetaData(this.columnMetaDataList);
|
return new TSDBResultSetMetaData(this.columnMetaDataList);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getObject(int columnIndex) throws SQLException {
|
public Object getObject(int columnIndex) throws SQLException {
|
||||||
int colIndex = getTrueColumnIndex(columnIndex);
|
checkAvailability(columnIndex, this.columnMetaDataList.size());
|
||||||
|
|
||||||
|
Object res = null;
|
||||||
if (this.getBatchFetch())
|
if (this.getBatchFetch())
|
||||||
return this.blockData.get(colIndex);
|
return this.blockData.get(columnIndex - 1);
|
||||||
|
|
||||||
this.lastWasNull = this.rowData.wasNull(colIndex);
|
this.lastWasNull = this.rowData.wasNull(columnIndex - 1);
|
||||||
return this.rowData.get(colIndex);
|
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);
|
||||||
}
|
}
|
||||||
|
return res;
|
||||||
@Override
|
|
||||||
public Object getObject(String columnLabel) throws SQLException {
|
|
||||||
return this.getObject(this.findColumn(columnLabel));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int findColumn(String columnLabel) throws SQLException {
|
public int findColumn(String columnLabel) throws SQLException {
|
||||||
|
@ -285,15 +321,32 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
|
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(columnIndex - 1);
|
||||||
this.lastWasNull = this.rowData.wasNull(colIndex);
|
BigDecimal res = null;
|
||||||
return new BigDecimal(this.rowData.getLong(colIndex, this.columnMetaDataList.get(colIndex).getColType()));
|
if (!lastWasNull) {
|
||||||
} else {
|
int colType = this.columnMetaDataList.get(columnIndex - 1).getColType();
|
||||||
return new BigDecimal(this.blockData.getLong(colIndex));
|
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
|
@Override
|
||||||
public boolean isBeforeFirst() throws SQLException {
|
public boolean isBeforeFirst() throws SQLException {
|
||||||
|
@ -398,6 +451,12 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
|
||||||
return this.statement;
|
return this.statement;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException {
|
||||||
|
//TODO:did not use the specified timezone in cal
|
||||||
|
return getTimestamp(columnIndex);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isClosed() throws SQLException {
|
public boolean isClosed() throws SQLException {
|
||||||
if (isClosed)
|
if (isClosed)
|
||||||
return true;
|
return true;
|
||||||
|
@ -408,17 +467,7 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getNString(int columnIndex) throws SQLException {
|
public String getNString(int columnIndex) throws SQLException {
|
||||||
int colIndex = getTrueColumnIndex(columnIndex);
|
return getString(columnIndex);
|
||||||
return (String) rowData.get(colIndex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ import java.util.List;
|
||||||
|
|
||||||
public class TSDBResultSetMetaData extends WrapperImpl implements ResultSetMetaData {
|
public class TSDBResultSetMetaData extends WrapperImpl implements ResultSetMetaData {
|
||||||
|
|
||||||
List<ColumnMetaData> colMetaDataList = null;
|
List<ColumnMetaData> colMetaDataList;
|
||||||
|
|
||||||
public TSDBResultSetMetaData(List<ColumnMetaData> metaDataList) {
|
public TSDBResultSetMetaData(List<ColumnMetaData> metaDataList) {
|
||||||
this.colMetaDataList = metaDataList;
|
this.colMetaDataList = metaDataList;
|
||||||
|
@ -52,6 +52,9 @@ public class TSDBResultSetMetaData extends WrapperImpl implements ResultSetMetaD
|
||||||
}
|
}
|
||||||
|
|
||||||
public int isNullable(int column) throws SQLException {
|
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) {
|
if (column == 1) {
|
||||||
return columnNoNulls;
|
return columnNoNulls;
|
||||||
}
|
}
|
||||||
|
@ -59,6 +62,9 @@ public class TSDBResultSetMetaData extends WrapperImpl implements ResultSetMetaD
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSigned(int column) throws SQLException {
|
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);
|
ColumnMetaData meta = this.colMetaDataList.get(column - 1);
|
||||||
switch (meta.getColType()) {
|
switch (meta.getColType()) {
|
||||||
case TSDBConstants.TSDB_DATA_TYPE_TINYINT:
|
case TSDBConstants.TSDB_DATA_TYPE_TINYINT:
|
||||||
|
@ -74,22 +80,37 @@ public class TSDBResultSetMetaData extends WrapperImpl implements ResultSetMetaD
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getColumnDisplaySize(int column) throws SQLException {
|
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();
|
return colMetaDataList.get(column - 1).getColSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getColumnLabel(int column) throws SQLException {
|
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();
|
return colMetaDataList.get(column - 1).getColName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getColumnName(int column) throws SQLException {
|
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();
|
return colMetaDataList.get(column - 1).getColName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSchemaName(int column) throws SQLException {
|
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);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getPrecision(int column) throws SQLException {
|
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);
|
ColumnMetaData columnMetaData = this.colMetaDataList.get(column - 1);
|
||||||
switch (columnMetaData.getColType()) {
|
switch (columnMetaData.getColType()) {
|
||||||
case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
|
case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
|
||||||
|
@ -105,6 +126,9 @@ public class TSDBResultSetMetaData extends WrapperImpl implements ResultSetMetaD
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getScale(int column) throws SQLException {
|
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);
|
ColumnMetaData meta = this.colMetaDataList.get(column - 1);
|
||||||
switch (meta.getColType()) {
|
switch (meta.getColType()) {
|
||||||
case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
|
case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
|
||||||
|
|
|
@ -21,18 +21,13 @@ import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
public class TSDBResultSetRowData {
|
public class TSDBResultSetRowData {
|
||||||
private ArrayList<Object> data = null;
|
private ArrayList<Object> data;
|
||||||
private int colSize = 0;
|
private int colSize = 0;
|
||||||
|
|
||||||
public TSDBResultSetRowData(int colSize) {
|
public TSDBResultSetRowData(int colSize) {
|
||||||
this.setColSize(colSize);
|
this.setColSize(colSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TSDBResultSetRowData() {
|
|
||||||
this.data = new ArrayList<>();
|
|
||||||
this.setColSize(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clear() {
|
public void clear() {
|
||||||
if (this.data != null) {
|
if (this.data != null) {
|
||||||
this.data.clear();
|
this.data.clear();
|
||||||
|
@ -71,9 +66,9 @@ public class TSDBResultSetRowData {
|
||||||
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
|
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
|
||||||
case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
|
case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
|
||||||
return ((Long) obj) == 1L ? Boolean.TRUE : Boolean.FALSE;
|
return ((Long) obj) == 1L ? Boolean.TRUE : Boolean.FALSE;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Boolean.TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setByte(int col, byte value) {
|
public void setByte(int col, byte value) {
|
||||||
|
@ -198,7 +193,7 @@ public class TSDBResultSetRowData {
|
||||||
data.set(col, value);
|
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);
|
Object obj = data.get(col);
|
||||||
|
|
||||||
switch (srcType) {
|
switch (srcType) {
|
||||||
|
@ -226,7 +221,7 @@ public class TSDBResultSetRowData {
|
||||||
data.set(col, value);
|
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);
|
Object obj = data.get(col);
|
||||||
|
|
||||||
switch (srcType) {
|
switch (srcType) {
|
||||||
|
@ -267,9 +262,8 @@ public class TSDBResultSetRowData {
|
||||||
*
|
*
|
||||||
* @param col column index
|
* @param col column index
|
||||||
* @return
|
* @return
|
||||||
* @throws SQLException
|
|
||||||
*/
|
*/
|
||||||
public String getString(int col, int srcType) throws SQLException {
|
public String getString(int col, int srcType) {
|
||||||
switch (srcType) {
|
switch (srcType) {
|
||||||
case TSDBConstants.TSDB_DATA_TYPE_BINARY:
|
case TSDBConstants.TSDB_DATA_TYPE_BINARY:
|
||||||
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
|
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
|
||||||
|
@ -305,11 +299,11 @@ public class TSDBResultSetRowData {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTimestamp(int col, long ts) {
|
public void setTimestamp(int col, long ts) {
|
||||||
data.set(col, ts);
|
data.set(col, new Timestamp(ts));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Timestamp getTimestamp(int col) {
|
public Timestamp getTimestamp(int col) {
|
||||||
return new Timestamp((Long) data.get(col));
|
return (Timestamp) data.get(col);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object get(int col) {
|
public Object get(int col) {
|
||||||
|
@ -320,7 +314,7 @@ public class TSDBResultSetRowData {
|
||||||
return colSize;
|
return colSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setColSize(int colSize) {
|
private void setColSize(int colSize) {
|
||||||
this.colSize = colSize;
|
this.colSize = colSize;
|
||||||
this.clear();
|
this.clear();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,8 +1,14 @@
|
||||||
package com.taosdata.jdbc.rs;
|
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;
|
import java.util.Properties;
|
||||||
|
|
||||||
public class RestfulConnection extends AbstractConnection {
|
public class RestfulConnection extends AbstractConnection {
|
||||||
|
@ -55,7 +61,6 @@ public class RestfulConnection extends AbstractConnection {
|
||||||
public DatabaseMetaData getMetaData() throws SQLException {
|
public DatabaseMetaData getMetaData() throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
|
||||||
;
|
|
||||||
|
|
||||||
return this.metadata;
|
return this.metadata;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ public class RestfulDriver extends AbstractDriver {
|
||||||
|
|
||||||
static {
|
static {
|
||||||
try {
|
try {
|
||||||
DriverManager.registerDriver(new RestfulDriver());
|
java.sql.DriverManager.registerDriver(new RestfulDriver());
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
throw TSDBError.createRuntimeException(TSDBErrorNumbers.ERROR_URL_NOT_SET, e);
|
throw TSDBError.createRuntimeException(TSDBErrorNumbers.ERROR_URL_NOT_SET, e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
package com.taosdata.jdbc.rs;
|
||||||
|
|
||||||
|
import com.taosdata.jdbc.AbstractParameterMetaData;
|
||||||
|
|
||||||
|
public class RestfulParameterMetaData extends AbstractParameterMetaData {
|
||||||
|
|
||||||
|
RestfulParameterMetaData(Object[] parameters) {
|
||||||
|
super(parameters);
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,6 +7,7 @@ import java.io.InputStream;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
import java.sql.*;
|
import java.sql.*;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
|
|
||||||
|
@ -30,7 +31,9 @@ public class RestfulPreparedStatement extends RestfulStatement implements Prepar
|
||||||
parameters = new Object[parameterCnt];
|
parameters = new Object[parameterCnt];
|
||||||
this.isPrepared = true;
|
this.isPrepared = true;
|
||||||
}
|
}
|
||||||
//TODO: build parameterMetaData
|
|
||||||
|
// build parameterMetaData
|
||||||
|
this.parameterMetaData = new RestfulParameterMetaData(parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -60,8 +63,15 @@ public class RestfulPreparedStatement extends RestfulStatement implements Prepar
|
||||||
for (int i = 0; i < parameters.length; ++i) {
|
for (int i = 0; i < parameters.length; ++i) {
|
||||||
Object para = parameters[i];
|
Object para = parameters[i];
|
||||||
if (para != null) {
|
if (para != null) {
|
||||||
String paraStr = para.toString();
|
String paraStr;
|
||||||
if (para instanceof Timestamp || para instanceof String) {
|
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 + "'";
|
paraStr = "'" + paraStr + "'";
|
||||||
}
|
}
|
||||||
sql = sql.replaceFirst("[?]", 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 {
|
public void setByte(int parameterIndex, byte x) throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
|
setObject(parameterIndex, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -153,7 +163,7 @@ public class RestfulPreparedStatement extends RestfulStatement implements Prepar
|
||||||
public void setBytes(int parameterIndex, byte[] x) throws SQLException {
|
public void setBytes(int parameterIndex, byte[] x) throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
|
setObject(parameterIndex, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -210,19 +220,16 @@ public class RestfulPreparedStatement extends RestfulStatement implements Prepar
|
||||||
public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException {
|
public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
|
|
||||||
|
setObject(parameterIndex,x);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setObject(int parameterIndex, Object x) throws SQLException {
|
public void setObject(int parameterIndex, Object x) throws SQLException {
|
||||||
if (isClosed())
|
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
|
|
||||||
|
|
||||||
if (parameterIndex < 1 && parameterIndex >= parameters.length)
|
if (parameterIndex < 1 && parameterIndex >= parameters.length)
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE);
|
||||||
|
|
||||||
parameters[parameterIndex - 1] = x;
|
parameters[parameterIndex - 1] = x;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -2,13 +2,18 @@ package com.taosdata.jdbc.rs;
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson.JSONArray;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
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.AbstractResultSet;
|
||||||
import com.taosdata.jdbc.TSDBConstants;
|
import com.taosdata.jdbc.TSDBConstants;
|
||||||
import com.taosdata.jdbc.TSDBError;
|
import com.taosdata.jdbc.TSDBError;
|
||||||
import com.taosdata.jdbc.TSDBErrorNumbers;
|
import com.taosdata.jdbc.TSDBErrorNumbers;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
import java.sql.*;
|
import java.sql.*;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Calendar;
|
||||||
|
|
||||||
public class RestfulResultSet extends AbstractResultSet implements ResultSet {
|
public class RestfulResultSet extends AbstractResultSet implements ResultSet {
|
||||||
private volatile boolean isClosed;
|
private volatile boolean isClosed;
|
||||||
|
@ -16,7 +21,6 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
|
||||||
|
|
||||||
private final String database;
|
private final String database;
|
||||||
private final Statement statement;
|
private final Statement statement;
|
||||||
// private final JSONObject resultJson;
|
|
||||||
// data
|
// data
|
||||||
private final ArrayList<ArrayList<Object>> resultSet;
|
private final ArrayList<ArrayList<Object>> resultSet;
|
||||||
// meta
|
// meta
|
||||||
|
@ -32,7 +36,6 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
|
||||||
public RestfulResultSet(String database, Statement statement, JSONObject resultJson) throws SQLException {
|
public RestfulResultSet(String database, Statement statement, JSONObject resultJson) throws SQLException {
|
||||||
this.database = database;
|
this.database = database;
|
||||||
this.statement = statement;
|
this.statement = statement;
|
||||||
// this.resultJson = resultJson;
|
|
||||||
|
|
||||||
// column metadata
|
// column metadata
|
||||||
JSONArray columnMeta = resultJson.getJSONArray("column_meta");
|
JSONArray columnMeta = resultJson.getJSONArray("column_meta");
|
||||||
|
@ -73,7 +76,7 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
|
||||||
case TSDBConstants.TSDB_DATA_TYPE_INT:
|
case TSDBConstants.TSDB_DATA_TYPE_INT:
|
||||||
return row.getInteger(colIndex);
|
return row.getInteger(colIndex);
|
||||||
case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
|
case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
|
||||||
return row.getBigInteger(colIndex);
|
return row.getLong(colIndex);
|
||||||
case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
|
case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
|
||||||
return row.getFloat(colIndex);
|
return row.getFloat(colIndex);
|
||||||
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE:
|
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE:
|
||||||
|
@ -81,9 +84,11 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
|
||||||
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
|
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
|
||||||
return new Timestamp(row.getDate(colIndex).getTime());
|
return new Timestamp(row.getDate(colIndex).getTime());
|
||||||
case TSDBConstants.TSDB_DATA_TYPE_BINARY:
|
case TSDBConstants.TSDB_DATA_TYPE_BINARY:
|
||||||
|
return row.getString(colIndex) == null ? null : row.getString(colIndex).getBytes();
|
||||||
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
|
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
|
||||||
|
return row.getString(colIndex) == null ? null : row.getString(colIndex);
|
||||||
default:
|
default:
|
||||||
return row.getString(colIndex);
|
return row.get(colIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,37 +135,33 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getString(int columnIndex) throws SQLException {
|
public String getString(int columnIndex) throws SQLException {
|
||||||
if (isClosed())
|
checkAvailability(columnIndex, resultSet.get(pos).size());
|
||||||
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());
|
|
||||||
|
|
||||||
columnIndex = getTrueColumnIndex(columnIndex);
|
Object value = resultSet.get(pos).get(columnIndex - 1);
|
||||||
Object value = resultSet.get(pos).get(columnIndex);
|
if (value == null)
|
||||||
return value == null ? null : value.toString();
|
return null;
|
||||||
|
if (value instanceof byte[])
|
||||||
|
return new String((byte[]) value);
|
||||||
|
return value.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean getBoolean(int columnIndex) throws SQLException {
|
public boolean getBoolean(int columnIndex) throws SQLException {
|
||||||
if (isClosed())
|
checkAvailability(columnIndex, resultSet.get(pos).size());
|
||||||
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());
|
|
||||||
|
|
||||||
columnIndex = getTrueColumnIndex(columnIndex);
|
Object value = resultSet.get(pos).get(columnIndex - 1);
|
||||||
int result = getInt(columnIndex);
|
if (value == null)
|
||||||
return result == 0 ? false : true;
|
return false;
|
||||||
|
if (value instanceof Boolean)
|
||||||
|
return (boolean) value;
|
||||||
|
return Boolean.valueOf(value.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte getByte(int columnIndex) throws SQLException {
|
public byte getByte(int columnIndex) throws SQLException {
|
||||||
if (isClosed())
|
checkAvailability(columnIndex, resultSet.get(pos).size());
|
||||||
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());
|
|
||||||
|
|
||||||
columnIndex = getTrueColumnIndex(columnIndex);
|
Object value = resultSet.get(pos).get(columnIndex - 1);
|
||||||
Object value = resultSet.get(pos).get(columnIndex);
|
|
||||||
if (value == null)
|
if (value == null)
|
||||||
return 0;
|
return 0;
|
||||||
long valueAsLong = Long.parseLong(value.toString());
|
long valueAsLong = Long.parseLong(value.toString());
|
||||||
|
@ -179,13 +180,9 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public short getShort(int columnIndex) throws SQLException {
|
public short getShort(int columnIndex) throws SQLException {
|
||||||
if (isClosed())
|
checkAvailability(columnIndex, resultSet.get(pos).size());
|
||||||
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());
|
|
||||||
|
|
||||||
columnIndex = getTrueColumnIndex(columnIndex);
|
Object value = resultSet.get(pos).get(columnIndex - 1);
|
||||||
Object value = resultSet.get(pos).get(columnIndex);
|
|
||||||
if (value == null)
|
if (value == null)
|
||||||
return 0;
|
return 0;
|
||||||
long valueAsLong = Long.parseLong(value.toString());
|
long valueAsLong = Long.parseLong(value.toString());
|
||||||
|
@ -198,13 +195,9 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getInt(int columnIndex) throws SQLException {
|
public int getInt(int columnIndex) throws SQLException {
|
||||||
if (isClosed())
|
checkAvailability(columnIndex, resultSet.get(pos).size());
|
||||||
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());
|
|
||||||
|
|
||||||
columnIndex = getTrueColumnIndex(columnIndex);
|
Object value = resultSet.get(pos).get(columnIndex - 1);
|
||||||
Object value = resultSet.get(pos).get(columnIndex);
|
|
||||||
if (value == null)
|
if (value == null)
|
||||||
return 0;
|
return 0;
|
||||||
long valueAsLong = Long.parseLong(value.toString());
|
long valueAsLong = Long.parseLong(value.toString());
|
||||||
|
@ -217,13 +210,9 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getLong(int columnIndex) throws SQLException {
|
public long getLong(int columnIndex) throws SQLException {
|
||||||
if (isClosed())
|
checkAvailability(columnIndex, resultSet.get(pos).size());
|
||||||
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());
|
|
||||||
|
|
||||||
columnIndex = getTrueColumnIndex(columnIndex);
|
Object value = resultSet.get(pos).get(columnIndex - 1);
|
||||||
Object value = resultSet.get(pos).get(columnIndex);
|
|
||||||
if (value == null)
|
if (value == null)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -240,64 +229,99 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float getFloat(int columnIndex) throws SQLException {
|
public float getFloat(int columnIndex) throws SQLException {
|
||||||
if (isClosed())
|
checkAvailability(columnIndex, resultSet.get(pos).size());
|
||||||
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());
|
|
||||||
|
|
||||||
columnIndex = getTrueColumnIndex(columnIndex);
|
Object value = resultSet.get(pos).get(columnIndex - 1);
|
||||||
return Float.parseFloat(resultSet.get(pos).get(columnIndex).toString());
|
if (value == null)
|
||||||
|
return 0;
|
||||||
|
if (value instanceof Float || value instanceof Double)
|
||||||
|
return (float) value;
|
||||||
|
return Float.parseFloat(value.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double getDouble(int columnIndex) throws SQLException {
|
public double getDouble(int columnIndex) throws SQLException {
|
||||||
if (isClosed())
|
checkAvailability(columnIndex, resultSet.get(pos).size());
|
||||||
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());
|
|
||||||
|
|
||||||
columnIndex = getTrueColumnIndex(columnIndex);
|
Object value = resultSet.get(pos).get(columnIndex - 1);
|
||||||
return Double.parseDouble(resultSet.get(pos).get(columnIndex).toString());
|
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 {
|
@Override
|
||||||
if (columnIndex < 1) {
|
public byte[] getBytes(int columnIndex) throws SQLException {
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE
|
checkAvailability(columnIndex, resultSet.get(pos).size());
|
||||||
, "Column Index out of range, " + columnIndex + " < 1");
|
|
||||||
|
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();
|
@Override
|
||||||
if (columnIndex > numOfCols) {
|
public Date getDate(int columnIndex) throws SQLException {
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE
|
checkAvailability(columnIndex, resultSet.get(pos).size());
|
||||||
, "Column Index out of range, " + columnIndex + " > " + numOfCols);
|
|
||||||
|
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
|
@Override
|
||||||
public Timestamp getTimestamp(int columnIndex) throws SQLException {
|
public Timestamp getTimestamp(int columnIndex) throws SQLException {
|
||||||
if (isClosed())
|
checkAvailability(columnIndex, resultSet.get(pos).size());
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
|
|
||||||
|
|
||||||
columnIndex = getTrueColumnIndex(columnIndex);
|
Object value = resultSet.get(pos).get(columnIndex - 1);
|
||||||
String strDate = resultSet.get(pos).get(columnIndex).toString();
|
if (value == null)
|
||||||
// strDate = strDate.substring(1, strDate.length() - 1);
|
return null;
|
||||||
return Timestamp.valueOf(strDate);
|
if (value instanceof Timestamp)
|
||||||
|
return (Timestamp) value;
|
||||||
|
return Timestamp.valueOf(value.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************************************************************/
|
|
||||||
@Override
|
@Override
|
||||||
public ResultSetMetaData getMetaData() throws SQLException {
|
public ResultSetMetaData getMetaData() throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
|
||||||
|
|
||||||
return this.metaData;
|
return this.metaData;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getObject(String columnLabel) throws SQLException {
|
public Object getObject(int columnIndex) throws SQLException {
|
||||||
return getObject(findColumn(columnLabel));
|
checkAvailability(columnIndex, resultSet.get(pos).size());
|
||||||
|
|
||||||
|
return resultSet.get(pos).get(columnIndex - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -311,6 +335,23 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
|
||||||
return columnIndex + 1;
|
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
|
@Override
|
||||||
public boolean isBeforeFirst() throws SQLException {
|
public boolean isBeforeFirst() throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
|
@ -471,6 +512,12 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
|
||||||
return this.statement;
|
return this.statement;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException {
|
||||||
|
//TODO:did not use the specified timezone in cal
|
||||||
|
return getTimestamp(columnIndex);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isClosed() throws SQLException {
|
public boolean isClosed() throws SQLException {
|
||||||
return isClosed;
|
return isClosed;
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1 +1,2 @@
|
||||||
com.taosdata.jdbc.TSDBDriver
|
com.taosdata.jdbc.TSDBDriver
|
||||||
|
com.taosdata.jdbc.rs.RestfulDriver
|
||||||
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -233,7 +233,7 @@ public class TSDBConnectionTest {
|
||||||
int status = rs.getInt("server_status()");
|
int status = rs.getInt("server_status()");
|
||||||
Assert.assertEquals(1, 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)
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,14 +5,16 @@ import org.junit.Assert;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Serializable;
|
||||||
import java.sql.*;
|
import java.sql.*;
|
||||||
|
|
||||||
public class TSDBPreparedStatementTest {
|
public class TSDBPreparedStatementTest {
|
||||||
private static final String host = "127.0.0.1";
|
private static final String host = "127.0.0.1";
|
||||||
private static Connection conn;
|
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 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;
|
private static PreparedStatement pstmt_select;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -21,7 +23,7 @@ public class TSDBPreparedStatementTest {
|
||||||
long start = end - 1000 * 60 * 60;
|
long start = end - 1000 * 60 * 60;
|
||||||
pstmt_select.setTimestamp(1, new Timestamp(start));
|
pstmt_select.setTimestamp(1, new Timestamp(start));
|
||||||
pstmt_select.setTimestamp(2, new Timestamp(end));
|
pstmt_select.setTimestamp(2, new Timestamp(end));
|
||||||
pstmt_select.setFloat(3, 0);
|
pstmt_select.setInt(3, 0);
|
||||||
|
|
||||||
ResultSet rs = pstmt_select.executeQuery();
|
ResultSet rs = pstmt_select.executeQuery();
|
||||||
Assert.assertNotNull(rs);
|
Assert.assertNotNull(rs);
|
||||||
|
@ -37,48 +39,73 @@ public class TSDBPreparedStatementTest {
|
||||||
@Test
|
@Test
|
||||||
public void executeUpdate() throws SQLException {
|
public void executeUpdate() throws SQLException {
|
||||||
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
|
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();
|
int result = pstmt_insert.executeUpdate();
|
||||||
Assert.assertEquals(1, result);
|
Assert.assertEquals(1, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void setNull() throws SQLException {
|
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
|
@Test
|
||||||
public void setBoolean() throws SQLException {
|
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 {
|
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
|
@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
|
@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
|
@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
|
@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
|
@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)
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
@ -87,12 +114,56 @@ public class TSDBPreparedStatementTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@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)
|
class Person implements Serializable {
|
||||||
public void setBytes() throws SQLException {
|
String name;
|
||||||
pstmt_insert.setBytes(1, new byte[]{});
|
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)
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
@ -106,8 +177,10 @@ public class TSDBPreparedStatementTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void setTimestamp() {
|
public void setTimestamp() throws SQLException {
|
||||||
//TODO
|
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
|
||||||
|
int ret = pstmt_insert.executeUpdate();
|
||||||
|
Assert.assertEquals(1, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = SQLFeatureNotSupportedException.class)
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
@ -121,24 +194,69 @@ public class TSDBPreparedStatementTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void clearParameters() {
|
public void clearParameters() throws SQLException {
|
||||||
//TODO
|
pstmt_insert.clearParameters();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void setObject() throws SQLException {
|
public void setObject() throws SQLException {
|
||||||
pstmt_insert.setObject(1, System.currentTimeMillis());
|
pstmt_insert.setObject(1, new Timestamp(System.currentTimeMillis()));
|
||||||
//TODO
|
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
|
@Test
|
||||||
public void execute() {
|
public void execute() throws SQLException {
|
||||||
//TODO
|
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
|
||||||
}
|
int ret = pstmt_insert.executeUpdate();
|
||||||
|
Assert.assertEquals(1, ret);
|
||||||
|
|
||||||
@Test
|
executeQuery();
|
||||||
public void addBatch() {
|
|
||||||
//TODO:
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = SQLFeatureNotSupportedException.class)
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
@ -176,11 +294,11 @@ public class TSDBPreparedStatementTest {
|
||||||
pstmt_insert.setURL(1, null);
|
pstmt_insert.setURL(1, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = SQLFeatureNotSupportedException.class)
|
@Test
|
||||||
public void getParameterMetaData() throws SQLException {
|
public void getParameterMetaData() throws SQLException {
|
||||||
ParameterMetaData parameterMetaData = pstmt_insert.getParameterMetaData();
|
ParameterMetaData parameterMetaData = pstmt_insert.getParameterMetaData();
|
||||||
// Assert.assertNotNull(parameterMetaData);
|
Assert.assertNotNull(parameterMetaData);
|
||||||
//TODO:
|
//TODO: modify the test case
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = SQLFeatureNotSupportedException.class)
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
@ -215,10 +333,10 @@ public class TSDBPreparedStatementTest {
|
||||||
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
||||||
conn = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata");
|
conn = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata");
|
||||||
try (Statement stmt = conn.createStatement()) {
|
try (Statement stmt = conn.createStatement()) {
|
||||||
stmt.execute("drop database if exists test_pstmt");
|
stmt.execute("drop database if exists test_pstmt_jni");
|
||||||
stmt.execute("create database if not exists test_pstmt");
|
stmt.execute("create database if not exists test_pstmt_jni");
|
||||||
stmt.execute("use test_pstmt");
|
stmt.execute("use test_pstmt_jni");
|
||||||
stmt.execute("create table weather(ts timestamp, temperature float) tags(loc nchar(64))");
|
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')");
|
stmt.execute("create table t1 using weather tags('beijing')");
|
||||||
}
|
}
|
||||||
pstmt_insert = conn.prepareStatement(sql_insert);
|
pstmt_insert = conn.prepareStatement(sql_insert);
|
||||||
|
@ -231,7 +349,10 @@ public class TSDBPreparedStatementTest {
|
||||||
@AfterClass
|
@AfterClass
|
||||||
public static void afterClass() {
|
public static void afterClass() {
|
||||||
try {
|
try {
|
||||||
|
if (pstmt_insert != null)
|
||||||
|
pstmt_insert.close();
|
||||||
|
if (pstmt_select != null)
|
||||||
|
pstmt_select.close();
|
||||||
if (conn != null)
|
if (conn != null)
|
||||||
conn.close();
|
conn.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -14,7 +14,6 @@ import java.util.Random;
|
||||||
public class InsertDbwithoutUseDbTest {
|
public class InsertDbwithoutUseDbTest {
|
||||||
|
|
||||||
private static String host = "127.0.0.1";
|
private static String host = "127.0.0.1";
|
||||||
// private static String host = "master";
|
|
||||||
private static Properties properties;
|
private static Properties properties;
|
||||||
private static Random random = new Random(System.currentTimeMillis());
|
private static Random random = new Random(System.currentTimeMillis());
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,8 +10,8 @@ import java.util.Properties;
|
||||||
|
|
||||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||||
public class UnsignedNumberRestfulTest {
|
public class UnsignedNumberRestfulTest {
|
||||||
|
|
||||||
private static final String host = "127.0.0.1";
|
private static final String host = "127.0.0.1";
|
||||||
// private static final String host = "master";
|
|
||||||
private static Connection conn;
|
private static Connection conn;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -8,7 +8,6 @@ import java.sql.*;
|
||||||
public class AuthenticationTest {
|
public class AuthenticationTest {
|
||||||
|
|
||||||
private static final String host = "127.0.0.1";
|
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 user = "root";
|
||||||
private static final String password = "taos?data";
|
private static final String password = "taos?data";
|
||||||
private Connection conn;
|
private Connection conn;
|
||||||
|
|
|
@ -12,7 +12,6 @@ import java.util.Properties;
|
||||||
public class RestfulConnectionTest {
|
public class RestfulConnectionTest {
|
||||||
|
|
||||||
private static final String host = "127.0.0.1";
|
private static final String host = "127.0.0.1";
|
||||||
// private static final String host = "master";
|
|
||||||
|
|
||||||
private static Connection conn;
|
private static Connection conn;
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,6 @@ import java.sql.*;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
public class RestfulDatabaseMetaDataTest {
|
public class RestfulDatabaseMetaDataTest {
|
||||||
// private static final String host = "master";
|
|
||||||
private static final String host = "127.0.0.1";
|
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 final String url = "jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata";
|
||||||
private static Connection connection;
|
private static Connection connection;
|
||||||
|
|
|
@ -10,7 +10,6 @@ import java.util.Random;
|
||||||
public class RestfulJDBCTest {
|
public class RestfulJDBCTest {
|
||||||
|
|
||||||
private static final String host = "127.0.0.1";
|
private static final String host = "127.0.0.1";
|
||||||
// private static final String host = "master";
|
|
||||||
private static Connection connection;
|
private static Connection connection;
|
||||||
private Random random = new Random(System.currentTimeMillis());
|
private Random random = new Random(System.currentTimeMillis());
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,11 +5,12 @@ import org.junit.Assert;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Serializable;
|
||||||
import java.sql.*;
|
import java.sql.*;
|
||||||
|
|
||||||
public class RestfulPreparedStatementTest {
|
public class RestfulPreparedStatementTest {
|
||||||
private static final String host = "127.0.0.1";
|
private static final String host = "127.0.0.1";
|
||||||
// private static final String host = "master";
|
|
||||||
private static Connection conn;
|
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 PreparedStatement pstmt_insert;
|
||||||
|
@ -38,48 +39,73 @@ public class RestfulPreparedStatementTest {
|
||||||
@Test
|
@Test
|
||||||
public void executeUpdate() throws SQLException {
|
public void executeUpdate() throws SQLException {
|
||||||
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
|
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();
|
int result = pstmt_insert.executeUpdate();
|
||||||
Assert.assertEquals(1, result);
|
Assert.assertEquals(1, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void setNull() throws SQLException {
|
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
|
@Test
|
||||||
public void setBoolean() throws SQLException {
|
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 {
|
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
|
@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
|
@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
|
@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
|
@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
|
@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)
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
@ -88,12 +114,56 @@ public class RestfulPreparedStatementTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@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)
|
class Person implements Serializable {
|
||||||
public void setBytes() throws SQLException {
|
String name;
|
||||||
pstmt_insert.setBytes(1, new byte[]{});
|
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)
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
@ -107,8 +177,10 @@ public class RestfulPreparedStatementTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void setTimestamp() {
|
public void setTimestamp() throws SQLException {
|
||||||
//TODO
|
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
|
||||||
|
int ret = pstmt_insert.executeUpdate();
|
||||||
|
Assert.assertEquals(1, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = SQLFeatureNotSupportedException.class)
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
@ -122,24 +194,69 @@ public class RestfulPreparedStatementTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void clearParameters() {
|
public void clearParameters() throws SQLException {
|
||||||
//TODO
|
pstmt_insert.clearParameters();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void setObject() throws SQLException {
|
public void setObject() throws SQLException {
|
||||||
pstmt_insert.setObject(1, System.currentTimeMillis());
|
pstmt_insert.setObject(1, new Timestamp(System.currentTimeMillis()));
|
||||||
//TODO
|
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
|
@Test
|
||||||
public void execute() {
|
public void execute() throws SQLException {
|
||||||
//TODO
|
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
|
||||||
}
|
int ret = pstmt_insert.executeUpdate();
|
||||||
|
Assert.assertEquals(1, ret);
|
||||||
|
|
||||||
@Test
|
executeQuery();
|
||||||
public void addBatch() {
|
|
||||||
//TODO:
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = SQLFeatureNotSupportedException.class)
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
@ -180,8 +297,8 @@ public class RestfulPreparedStatementTest {
|
||||||
@Test
|
@Test
|
||||||
public void getParameterMetaData() throws SQLException {
|
public void getParameterMetaData() throws SQLException {
|
||||||
ParameterMetaData parameterMetaData = pstmt_insert.getParameterMetaData();
|
ParameterMetaData parameterMetaData = pstmt_insert.getParameterMetaData();
|
||||||
Assert.assertNull(parameterMetaData);
|
Assert.assertNotNull(parameterMetaData);
|
||||||
//TODO:
|
//TODO: modify the test case
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = SQLFeatureNotSupportedException.class)
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
|
|
@ -10,7 +10,6 @@ import java.sql.*;
|
||||||
public class RestfulResultSetMetaDataTest {
|
public class RestfulResultSetMetaDataTest {
|
||||||
|
|
||||||
private static final String host = "127.0.0.1";
|
private static final String host = "127.0.0.1";
|
||||||
// private static final String host = "master";
|
|
||||||
|
|
||||||
private static Connection conn;
|
private static Connection conn;
|
||||||
private static Statement stmt;
|
private static Statement stmt;
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
package com.taosdata.jdbc.rs;
|
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.AfterClass;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
|
@ -9,11 +12,12 @@ import java.io.InputStream;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.sql.*;
|
import java.sql.*;
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
|
||||||
public class RestfulResultSetTest {
|
public class RestfulResultSetTest {
|
||||||
|
|
||||||
private static final String host = "127.0.0.1";
|
private static final String host = "127.0.0.1";
|
||||||
// private static final String host = "master";
|
|
||||||
|
|
||||||
private static Connection conn;
|
private static Connection conn;
|
||||||
private static Statement stmt;
|
private static Statement stmt;
|
||||||
|
@ -88,24 +92,75 @@ public class RestfulResultSetTest {
|
||||||
Assert.assertEquals(3.1415926, f5, 0.0);
|
Assert.assertEquals(3.1415926, f5, 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = SQLFeatureNotSupportedException.class)
|
@Test
|
||||||
public void getBigDecimal() throws SQLException {
|
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 {
|
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)
|
@Test
|
||||||
public void getDate() throws SQLException {
|
public void getDate() throws SQLException, ParseException {
|
||||||
rs.getDate("f1");
|
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 {
|
public void getTime() throws SQLException {
|
||||||
rs.getTime("f1");
|
Time f1 = rs.getTime("f1");
|
||||||
|
Assert.assertEquals("00:00:00", f1.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -152,9 +207,49 @@ public class RestfulResultSetTest {
|
||||||
Assert.assertNotNull(meta);
|
Assert.assertNotNull(meta);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = SQLFeatureNotSupportedException.class)
|
@Test
|
||||||
public void getObject() throws SQLException {
|
public void getObject() throws SQLException, ParseException {
|
||||||
rs.getObject("f1");
|
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)
|
@Test(expected = SQLException.class)
|
||||||
|
|
|
@ -12,7 +12,6 @@ import java.util.UUID;
|
||||||
|
|
||||||
public class RestfulStatementTest {
|
public class RestfulStatementTest {
|
||||||
private static final String host = "127.0.0.1";
|
private static final String host = "127.0.0.1";
|
||||||
// private static final String host = "master";
|
|
||||||
private static Connection conn;
|
private static Connection conn;
|
||||||
private static Statement stmt;
|
private static Statement stmt;
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,6 @@ import java.sql.*;
|
||||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||||
public class SQLTest {
|
public class SQLTest {
|
||||||
private static final String host = "127.0.0.1";
|
private static final String host = "127.0.0.1";
|
||||||
// private static final String host = "master";
|
|
||||||
private static Connection connection;
|
private static Connection connection;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -70,13 +70,16 @@ static SStep tsDnodeSteps[] = {
|
||||||
{"dnode-vread", dnodeInitVRead, dnodeCleanupVRead},
|
{"dnode-vread", dnodeInitVRead, dnodeCleanupVRead},
|
||||||
{"dnode-vwrite", dnodeInitVWrite, dnodeCleanupVWrite},
|
{"dnode-vwrite", dnodeInitVWrite, dnodeCleanupVWrite},
|
||||||
{"dnode-vmgmt", dnodeInitVMgmt, dnodeCleanupVMgmt},
|
{"dnode-vmgmt", dnodeInitVMgmt, dnodeCleanupVMgmt},
|
||||||
{"dnode-mread", dnodeInitMRead, dnodeCleanupMRead},
|
{"dnode-mread", dnodeInitMRead, NULL},
|
||||||
{"dnode-mwrite", dnodeInitMWrite, dnodeCleanupMWrite},
|
{"dnode-mwrite", dnodeInitMWrite, NULL},
|
||||||
{"dnode-mpeer", dnodeInitMPeer, dnodeCleanupMPeer},
|
{"dnode-mpeer", dnodeInitMPeer, NULL},
|
||||||
{"dnode-client", dnodeInitClient, dnodeCleanupClient},
|
{"dnode-client", dnodeInitClient, dnodeCleanupClient},
|
||||||
{"dnode-server", dnodeInitServer, dnodeCleanupServer},
|
{"dnode-server", dnodeInitServer, dnodeCleanupServer},
|
||||||
{"dnode-vnodes", dnodeInitVnodes, dnodeCleanupVnodes},
|
{"dnode-vnodes", dnodeInitVnodes, dnodeCleanupVnodes},
|
||||||
{"dnode-modules", dnodeInitModules, dnodeCleanupModules},
|
{"dnode-modules", dnodeInitModules, dnodeCleanupModules},
|
||||||
|
{"dnode-mread", NULL, dnodeCleanupMRead},
|
||||||
|
{"dnode-mwrite", NULL, dnodeCleanupMWrite},
|
||||||
|
{"dnode-mpeer", NULL, dnodeCleanupMPeer},
|
||||||
{"dnode-shell", dnodeInitShell, dnodeCleanupShell},
|
{"dnode-shell", dnodeInitShell, dnodeCleanupShell},
|
||||||
{"dnode-statustmr", dnodeInitStatusTimer,dnodeCleanupStatusTimer},
|
{"dnode-statustmr", dnodeInitStatusTimer,dnodeCleanupStatusTimer},
|
||||||
{"dnode-telemetry", dnodeInitTelemetry, dnodeCleanupTelemetry},
|
{"dnode-telemetry", dnodeInitTelemetry, dnodeCleanupTelemetry},
|
||||||
|
@ -234,6 +237,18 @@ static int32_t dnodeInitStorage() {
|
||||||
return -1;
|
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);
|
dnodeCheckDataDirOpenned(tsDnodeDir);
|
||||||
|
|
||||||
dInfo("dnode storage is initialized at %s", tsDnodeDir);
|
dInfo("dnode storage is initialized at %s", tsDnodeDir);
|
||||||
|
|
|
@ -43,6 +43,7 @@ int32_t dnodeInitServer() {
|
||||||
|
|
||||||
dnodeProcessReqMsgFp[TSDB_MSG_TYPE_MD_CREATE_VNODE] = dnodeDispatchToVMgmtQueue;
|
dnodeProcessReqMsgFp[TSDB_MSG_TYPE_MD_CREATE_VNODE] = dnodeDispatchToVMgmtQueue;
|
||||||
dnodeProcessReqMsgFp[TSDB_MSG_TYPE_MD_ALTER_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_DROP_VNODE] = dnodeDispatchToVMgmtQueue;
|
||||||
dnodeProcessReqMsgFp[TSDB_MSG_TYPE_MD_ALTER_STREAM] = dnodeDispatchToVMgmtQueue;
|
dnodeProcessReqMsgFp[TSDB_MSG_TYPE_MD_ALTER_STREAM] = dnodeDispatchToVMgmtQueue;
|
||||||
dnodeProcessReqMsgFp[TSDB_MSG_TYPE_MD_CONFIG_DNODE] = dnodeDispatchToVMgmtQueue;
|
dnodeProcessReqMsgFp[TSDB_MSG_TYPE_MD_CONFIG_DNODE] = dnodeDispatchToVMgmtQueue;
|
||||||
|
|
|
@ -30,6 +30,7 @@ static taos_queue tsVMgmtQueue = NULL;
|
||||||
static void * dnodeProcessMgmtQueue(void *param);
|
static void * dnodeProcessMgmtQueue(void *param);
|
||||||
static int32_t dnodeProcessCreateVnodeMsg(SRpcMsg *pMsg);
|
static int32_t dnodeProcessCreateVnodeMsg(SRpcMsg *pMsg);
|
||||||
static int32_t dnodeProcessAlterVnodeMsg(SRpcMsg *pMsg);
|
static int32_t dnodeProcessAlterVnodeMsg(SRpcMsg *pMsg);
|
||||||
|
static int32_t dnodeProcessSyncVnodeMsg(SRpcMsg *pMsg);
|
||||||
static int32_t dnodeProcessDropVnodeMsg(SRpcMsg *pMsg);
|
static int32_t dnodeProcessDropVnodeMsg(SRpcMsg *pMsg);
|
||||||
static int32_t dnodeProcessAlterStreamMsg(SRpcMsg *pMsg);
|
static int32_t dnodeProcessAlterStreamMsg(SRpcMsg *pMsg);
|
||||||
static int32_t dnodeProcessConfigDnodeMsg(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() {
|
int32_t dnodeInitVMgmt() {
|
||||||
dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_MD_CREATE_VNODE] = dnodeProcessCreateVnodeMsg;
|
dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_MD_CREATE_VNODE] = dnodeProcessCreateVnodeMsg;
|
||||||
dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_MD_ALTER_VNODE] = dnodeProcessAlterVnodeMsg;
|
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_DROP_VNODE] = dnodeProcessDropVnodeMsg;
|
||||||
dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_MD_ALTER_STREAM] = dnodeProcessAlterStreamMsg;
|
dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_MD_ALTER_STREAM] = dnodeProcessAlterStreamMsg;
|
||||||
dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_MD_CONFIG_DNODE] = dnodeProcessConfigDnodeMsg;
|
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) {
|
static int32_t dnodeProcessDropVnodeMsg(SRpcMsg *rpcMsg) {
|
||||||
SDropVnodeMsg *pDrop = rpcMsg->pCont;
|
SDropVnodeMsg *pDrop = rpcMsg->pCont;
|
||||||
pDrop->vgId = htonl(pDrop->vgId);
|
pDrop->vgId = htonl(pDrop->vgId);
|
||||||
|
|
|
@ -206,6 +206,7 @@ static void dnodeProcessStatusRsp(SRpcMsg *pMsg) {
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
taosTmrReset(dnodeSendStatusMsg, tsStatusInterval * 1000, NULL, tsDnodeTmr, &tsStatusTimer);
|
taosTmrReset(dnodeSendStatusMsg, tsStatusInterval * 1000, NULL, tsDnodeTmr, &tsStatusTimer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -259,7 +259,7 @@ do { \
|
||||||
#define TSDB_MIN_TABLES 4
|
#define TSDB_MIN_TABLES 4
|
||||||
#define TSDB_MAX_TABLES 10000000
|
#define TSDB_MAX_TABLES 10000000
|
||||||
#define TSDB_DEFAULT_TABLES 1000000
|
#define TSDB_DEFAULT_TABLES 1000000
|
||||||
#define TSDB_TABLES_STEP 100
|
#define TSDB_TABLES_STEP 1000
|
||||||
|
|
||||||
#define TSDB_MIN_DAYS_PER_FILE 1
|
#define TSDB_MIN_DAYS_PER_FILE 1
|
||||||
#define TSDB_MAX_DAYS_PER_FILE 3650
|
#define TSDB_MAX_DAYS_PER_FILE 3650
|
||||||
|
|
|
@ -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_ALTER_STREAM, "alter-stream" )
|
||||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_MD_CONFIG_DNODE, "config-dnode" )
|
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_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_MD_CREATE_MNODE, "create-mnode" )
|
||||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_DUMMY6, "dummy6" )
|
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_DUMMY6, "dummy6" )
|
||||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_DUMMY7, "dummy7" )
|
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_DUMMY7, "dummy7" )
|
||||||
|
@ -389,7 +390,7 @@ typedef struct {
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int32_t vgId;
|
int32_t vgId;
|
||||||
} SDropVnodeMsg;
|
} SDropVnodeMsg, SSyncVnodeMsg;
|
||||||
|
|
||||||
typedef struct SColIndex {
|
typedef struct SColIndex {
|
||||||
int16_t colId; // column id
|
int16_t colId; // column id
|
||||||
|
|
|
@ -79,9 +79,6 @@ typedef void (*FStopSyncFile)(int32_t vgId, uint64_t fversion);
|
||||||
// get file version
|
// get file version
|
||||||
typedef int32_t (*FGetVersion)(int32_t vgId, uint64_t *fver, uint64_t *vver);
|
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 (*FSendFile)(void *tsdb, SOCKET socketFd);
|
||||||
typedef int32_t (*FRecvFile)(void *tsdb, SOCKET socketFd);
|
typedef int32_t (*FRecvFile)(void *tsdb, SOCKET socketFd);
|
||||||
|
|
||||||
|
@ -99,7 +96,6 @@ typedef struct {
|
||||||
FStartSyncFile startSyncFileFp;
|
FStartSyncFile startSyncFileFp;
|
||||||
FStopSyncFile stopSyncFileFp;
|
FStopSyncFile stopSyncFileFp;
|
||||||
FGetVersion getVersionFp;
|
FGetVersion getVersionFp;
|
||||||
FResetVersion resetVersionFp;
|
|
||||||
FSendFile sendFileFp;
|
FSendFile sendFileFp;
|
||||||
FRecvFile recvFileFp;
|
FRecvFile recvFileFp;
|
||||||
} SSyncInfo;
|
} SSyncInfo;
|
||||||
|
|
|
@ -60,6 +60,7 @@ int32_t vnodeCreate(SCreateVnodeMsg *pVnodeCfg);
|
||||||
int32_t vnodeDrop(int32_t vgId);
|
int32_t vnodeDrop(int32_t vgId);
|
||||||
int32_t vnodeOpen(int32_t vgId);
|
int32_t vnodeOpen(int32_t vgId);
|
||||||
int32_t vnodeAlter(void *pVnode, SCreateVnodeMsg *pVnodeCfg);
|
int32_t vnodeAlter(void *pVnode, SCreateVnodeMsg *pVnodeCfg);
|
||||||
|
int32_t vnodeSync(int32_t vgId);
|
||||||
int32_t vnodeClose(int32_t vgId);
|
int32_t vnodeClose(int32_t vgId);
|
||||||
|
|
||||||
// vnodeMgmt
|
// vnodeMgmt
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -49,6 +49,7 @@ void mnodeRemoveTableFromVgroup(SVgObj *pVgroup, SCTableObj *pTable);
|
||||||
void mnodeSendDropVnodeMsg(int32_t vgId, SRpcEpSet *epSet, void *ahandle);
|
void mnodeSendDropVnodeMsg(int32_t vgId, SRpcEpSet *epSet, void *ahandle);
|
||||||
void mnodeSendCreateVgroupMsg(SVgObj *pVgroup, void *ahandle);
|
void mnodeSendCreateVgroupMsg(SVgObj *pVgroup, void *ahandle);
|
||||||
void mnodeSendAlterVgroupMsg(SVgObj *pVgroup);
|
void mnodeSendAlterVgroupMsg(SVgObj *pVgroup);
|
||||||
|
void mnodeSendSyncVgroupMsg(SVgObj *pVgroup);
|
||||||
|
|
||||||
SRpcEpSet mnodeGetEpSetFromVgroup(SVgObj *pVgroup);
|
SRpcEpSet mnodeGetEpSetFromVgroup(SVgObj *pVgroup);
|
||||||
SRpcEpSet mnodeGetEpSetFromIp(char *ep);
|
SRpcEpSet mnodeGetEpSetFromIp(char *ep);
|
||||||
|
|
|
@ -1186,8 +1186,44 @@ static int32_t mnodeProcessDropDbMsg(SMnodeMsg *pMsg) {
|
||||||
return mnodeDropDb(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) {
|
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) {
|
void mnodeDropAllDbs(SAcctObj *pAcct) {
|
||||||
|
|
|
@ -722,6 +722,10 @@ int32_t mnodeDropDnode(SDnodeObj *pDnode, void *pMsg) {
|
||||||
static int32_t mnodeDropDnodeByEp(char *ep, SMnodeMsg *pMsg) {
|
static int32_t mnodeDropDnodeByEp(char *ep, SMnodeMsg *pMsg) {
|
||||||
SDnodeObj *pDnode = mnodeGetDnodeByEp(ep);
|
SDnodeObj *pDnode = mnodeGetDnodeByEp(ep);
|
||||||
if (pDnode == NULL) {
|
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);
|
int32_t dnodeId = (int32_t)strtol(ep, NULL, 10);
|
||||||
pDnode = mnodeGetDnode(dnodeId);
|
pDnode = mnodeGetDnode(dnodeId);
|
||||||
if (pDnode == NULL) {
|
if (pDnode == NULL) {
|
||||||
|
|
|
@ -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 int32_t mnodeRetrieveVgroups(SShowObj *pShow, char *data, int32_t rows, void *pConn);
|
||||||
static void mnodeProcessCreateVnodeRsp(SRpcMsg *rpcMsg);
|
static void mnodeProcessCreateVnodeRsp(SRpcMsg *rpcMsg);
|
||||||
static void mnodeProcessAlterVnodeRsp(SRpcMsg *rpcMsg);
|
static void mnodeProcessAlterVnodeRsp(SRpcMsg *rpcMsg);
|
||||||
|
static void mnodeProcessSyncVnodeRsp(SRpcMsg *rpcMsg);
|
||||||
static void mnodeProcessDropVnodeRsp(SRpcMsg *rpcMsg);
|
static void mnodeProcessDropVnodeRsp(SRpcMsg *rpcMsg);
|
||||||
static int32_t mnodeProcessVnodeCfgMsg(SMnodeMsg *pMsg) ;
|
static int32_t mnodeProcessVnodeCfgMsg(SMnodeMsg *pMsg) ;
|
||||||
static void mnodeSendDropVgroupMsg(SVgObj *pVgroup, void *ahandle);
|
static void mnodeSendDropVgroupMsg(SVgObj *pVgroup, void *ahandle);
|
||||||
|
@ -236,6 +237,7 @@ int32_t mnodeInitVgroups() {
|
||||||
mnodeAddShowFreeIterHandle(TSDB_MGMT_TABLE_VGROUP, mnodeCancelGetNextVgroup);
|
mnodeAddShowFreeIterHandle(TSDB_MGMT_TABLE_VGROUP, mnodeCancelGetNextVgroup);
|
||||||
mnodeAddPeerRspHandle(TSDB_MSG_TYPE_MD_CREATE_VNODE_RSP, mnodeProcessCreateVnodeRsp);
|
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, mnodeProcessAlterVnodeRsp);
|
||||||
|
mnodeAddPeerRspHandle(TSDB_MSG_TYPE_MD_ALTER_VNODE_RSP, mnodeProcessSyncVnodeRsp);
|
||||||
mnodeAddPeerRspHandle(TSDB_MSG_TYPE_MD_DROP_VNODE_RSP, mnodeProcessDropVnodeRsp);
|
mnodeAddPeerRspHandle(TSDB_MSG_TYPE_MD_DROP_VNODE_RSP, mnodeProcessDropVnodeRsp);
|
||||||
mnodeAddPeerMsgHandle(TSDB_MSG_TYPE_DM_CONFIG_VNODE, mnodeProcessVnodeCfgMsg);
|
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) {
|
static void mnodeSendCreateVnodeMsg(SVgObj *pVgroup, SRpcEpSet *epSet, void *ahandle) {
|
||||||
SCreateVnodeMsg *pCreate = mnodeBuildVnodeMsg(pVgroup);
|
SCreateVnodeMsg *pCreate = mnodeBuildVnodeMsg(pVgroup);
|
||||||
SRpcMsg rpcMsg = {
|
SRpcMsg rpcMsg = {
|
||||||
|
@ -994,6 +1028,10 @@ static void mnodeProcessAlterVnodeRsp(SRpcMsg *rpcMsg) {
|
||||||
mDebug("alter vnode rsp received");
|
mDebug("alter vnode rsp received");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void mnodeProcessSyncVnodeRsp(SRpcMsg *rpcMsg) {
|
||||||
|
mDebug("sync vnode rsp received");
|
||||||
|
}
|
||||||
|
|
||||||
static void mnodeProcessCreateVnodeRsp(SRpcMsg *rpcMsg) {
|
static void mnodeProcessCreateVnodeRsp(SRpcMsg *rpcMsg) {
|
||||||
if (rpcMsg->ahandle == NULL) return;
|
if (rpcMsg->ahandle == NULL) return;
|
||||||
|
|
||||||
|
|
|
@ -117,7 +117,6 @@ typedef struct SSyncNode {
|
||||||
FStartSyncFile startSyncFileFp;
|
FStartSyncFile startSyncFileFp;
|
||||||
FStopSyncFile stopSyncFileFp;
|
FStopSyncFile stopSyncFileFp;
|
||||||
FGetVersion getVersionFp;
|
FGetVersion getVersionFp;
|
||||||
FResetVersion resetVersionFp;
|
|
||||||
FSendFile sendFileFp;
|
FSendFile sendFileFp;
|
||||||
FRecvFile recvFileFp;
|
FRecvFile recvFileFp;
|
||||||
pthread_mutex_t mutex;
|
pthread_mutex_t mutex;
|
||||||
|
|
|
@ -182,7 +182,6 @@ int64_t syncStart(const SSyncInfo *pInfo) {
|
||||||
pNode->startSyncFileFp = pInfo->startSyncFileFp;
|
pNode->startSyncFileFp = pInfo->startSyncFileFp;
|
||||||
pNode->stopSyncFileFp = pInfo->stopSyncFileFp;
|
pNode->stopSyncFileFp = pInfo->stopSyncFileFp;
|
||||||
pNode->getVersionFp = pInfo->getVersionFp;
|
pNode->getVersionFp = pInfo->getVersionFp;
|
||||||
pNode->resetVersionFp = pInfo->resetVersionFp;
|
|
||||||
pNode->sendFileFp = pInfo->sendFileFp;
|
pNode->sendFileFp = pInfo->sendFileFp;
|
||||||
pNode->recvFileFp = pInfo->recvFileFp;
|
pNode->recvFileFp = pInfo->recvFileFp;
|
||||||
|
|
||||||
|
@ -410,7 +409,7 @@ void syncConfirmForward(int64_t rid, uint64_t version, int32_t code, bool force)
|
||||||
syncReleaseNode(pNode);
|
syncReleaseNode(pNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 1
|
||||||
void syncRecover(int64_t rid) {
|
void syncRecover(int64_t rid) {
|
||||||
SSyncPeer *pPeer;
|
SSyncPeer *pPeer;
|
||||||
|
|
||||||
|
|
|
@ -238,7 +238,6 @@ static int32_t syncRestoreDataStepByStep(SSyncPeer *pPeer) {
|
||||||
|
|
||||||
(*pNode->stopSyncFileFp)(pNode->vgId, fversion);
|
(*pNode->stopSyncFileFp)(pNode->vgId, fversion);
|
||||||
nodeVersion = fversion;
|
nodeVersion = fversion;
|
||||||
if (pNode->resetVersionFp) (*pNode->resetVersionFp)(pNode->vgId, fversion);
|
|
||||||
|
|
||||||
sInfo("%s, start to restore wal, fver:%" PRIu64, pPeer->id, nodeVersion);
|
sInfo("%s, start to restore wal, fver:%" PRIu64, pPeer->id, nodeVersion);
|
||||||
uint64_t wver = 0;
|
uint64_t wver = 0;
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
#define TSDB_MAX_SUBBLOCKS 8
|
#define TSDB_MAX_SUBBLOCKS 8
|
||||||
static FORCE_INLINE int TSDB_KEY_FID(TSKEY key, int32_t days, int8_t precision) {
|
static FORCE_INLINE int TSDB_KEY_FID(TSKEY key, int32_t days, int8_t precision) {
|
||||||
if (key < 0) {
|
if (key < 0) {
|
||||||
return (int)((key + 1) / tsMsPerDay[precision] / days + 1);
|
return (int)((key + 1) / tsMsPerDay[precision] / days - 1);
|
||||||
} else {
|
} else {
|
||||||
return (int)((key / tsMsPerDay[precision] / days));
|
return (int)((key / tsMsPerDay[precision] / days));
|
||||||
}
|
}
|
||||||
|
@ -452,6 +452,14 @@ static int tsdbCommitToFile(SCommitH *pCommith, SDFileSet *pSet, int fid) {
|
||||||
return -1;
|
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
|
// Close commit file
|
||||||
tsdbCloseCommitFile(pCommith, false);
|
tsdbCloseCommitFile(pCommith, false);
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@ static int tsdbScanDataDir(STsdbRepo *pRepo);
|
||||||
static bool tsdbIsTFileInFS(STsdbFS *pfs, const TFILE *pf);
|
static bool tsdbIsTFileInFS(STsdbFS *pfs, const TFILE *pf);
|
||||||
static int tsdbRestoreCurrent(STsdbRepo *pRepo);
|
static int tsdbRestoreCurrent(STsdbRepo *pRepo);
|
||||||
static int tsdbComparTFILE(const void *arg1, const void *arg2);
|
static int tsdbComparTFILE(const void *arg1, const void *arg2);
|
||||||
|
static void tsdbScanAndTryFixDFilesHeader(STsdbRepo *pRepo);
|
||||||
|
|
||||||
// ================== CURRENT file header info
|
// ================== CURRENT file header info
|
||||||
static int tsdbEncodeFSHeader(void **buf, SFSHeader *pHeader) {
|
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));
|
tsdbError("vgId:%d failed to open FS since %s", REPO_ID(pRepo), tstrerror(terrno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tsdbScanAndTryFixDFilesHeader(pRepo);
|
||||||
} else {
|
} else {
|
||||||
if (tsdbRestoreCurrent(pRepo) < 0) {
|
if (tsdbRestoreCurrent(pRepo) < 0) {
|
||||||
tsdbError("vgId:%d failed to restore current file since %s", REPO_ID(pRepo), tstrerror(terrno));
|
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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -134,14 +134,14 @@ int tsdbCreateMFile(SMFile *pMFile, bool updateHeader) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pMFile->info.size += TSDB_FILE_HEAD_SIZE;
|
||||||
|
|
||||||
if (tsdbUpdateMFileHeader(pMFile) < 0) {
|
if (tsdbUpdateMFileHeader(pMFile) < 0) {
|
||||||
tsdbCloseMFile(pMFile);
|
tsdbCloseMFile(pMFile);
|
||||||
tsdbRemoveMFile(pMFile);
|
tsdbRemoveMFile(pMFile);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pMFile->info.size += TSDB_FILE_HEAD_SIZE;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -378,14 +378,14 @@ int tsdbCreateDFile(SDFile *pDFile, bool updateHeader) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pDFile->info.size += TSDB_FILE_HEAD_SIZE;
|
||||||
|
|
||||||
if (tsdbUpdateDFileHeader(pDFile) < 0) {
|
if (tsdbUpdateDFileHeader(pDFile) < 0) {
|
||||||
tsdbCloseDFile(pDFile);
|
tsdbCloseDFile(pDFile);
|
||||||
tsdbRemoveDFile(pDFile);
|
tsdbRemoveDFile(pDFile);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pDFile->info.size += TSDB_FILE_HEAD_SIZE;
|
|
||||||
|
|
||||||
return 0;
|
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) {
|
void tsdbInitDFileSetEx(SDFileSet *pSet, SDFileSet *pOSet) {
|
||||||
|
pSet->fid = pOSet->fid;
|
||||||
for (TSDB_FILE_T ftype = 0; ftype < TSDB_FILE_MAX; ftype++) {
|
for (TSDB_FILE_T ftype = 0; ftype < TSDB_FILE_MAX; ftype++) {
|
||||||
tsdbInitDFileEx(TSDB_DFILE_IN_SET(pSet, ftype), TSDB_DFILE_IN_SET(pOSet, ftype));
|
tsdbInitDFileEx(TSDB_DFILE_IN_SET(pSet, ftype), TSDB_DFILE_IN_SET(pOSet, ftype));
|
||||||
}
|
}
|
||||||
|
|
|
@ -917,7 +917,9 @@ static int32_t loadBlockInfo(STsdbQueryHandle * pQueryHandle, int32_t index, int
|
||||||
pCheckInfo->compSize = compIndex->len;
|
pCheckInfo->compSize = compIndex->len;
|
||||||
}
|
}
|
||||||
|
|
||||||
tsdbLoadBlockInfo(&(pQueryHandle->rhelper), (void*)(pCheckInfo->pCompInfo));
|
if (tsdbLoadBlockInfo(&(pQueryHandle->rhelper), (void*)(pCheckInfo->pCompInfo)) < 0) {
|
||||||
|
return terrno;
|
||||||
|
}
|
||||||
SBlockInfo* pCompInfo = pCheckInfo->pCompInfo;
|
SBlockInfo* pCompInfo = pCheckInfo->pCompInfo;
|
||||||
|
|
||||||
TSKEY s = TSKEY_INITIAL_VAL, e = TSKEY_INITIAL_VAL;
|
TSKEY s = TSKEY_INITIAL_VAL, e = TSKEY_INITIAL_VAL;
|
||||||
|
@ -2832,7 +2834,9 @@ int32_t tsdbRetrieveDataBlockStatisInfo(TsdbQueryHandleT* pQueryHandle, SDataSta
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t stime = taosGetTimestampUs();
|
int64_t stime = taosGetTimestampUs();
|
||||||
tsdbLoadBlockStatis(&pHandle->rhelper, pBlockInfo->compBlock);
|
if (tsdbLoadBlockStatis(&pHandle->rhelper, pBlockInfo->compBlock) < 0) {
|
||||||
|
return terrno;
|
||||||
|
}
|
||||||
|
|
||||||
int16_t* colIds = pHandle->defaultLoadColumn->pData;
|
int16_t* colIds = pHandle->defaultLoadColumn->pData;
|
||||||
|
|
||||||
|
|
|
@ -194,8 +194,8 @@ static int32_t tsdbSyncRecvMeta(SSyncH *pSynch) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pLMFile == NULL || memcmp(&(pSynch->pmf->info), &(pLMFile->info), sizeof(SMFInfo)) != 0 ||
|
if (pLMFile == NULL || pSynch->pmf->info.size != pLMFile->info.size ||
|
||||||
TSDB_FILE_IS_BAD(pLMFile)) {
|
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
|
// Local has no meta file or has a different meta file, need to copy from remote
|
||||||
pSynch->mfChanged = true;
|
pSynch->mfChanged = true;
|
||||||
|
|
||||||
|
@ -536,7 +536,7 @@ static bool tsdbIsTowFSetSame(SDFileSet *pSet1, SDFileSet *pSet2) {
|
||||||
SDFile *pDFile1 = TSDB_DFILE_IN_SET(pSet1, ftype);
|
SDFile *pDFile1 = TSDB_DFILE_IN_SET(pSet1, ftype);
|
||||||
SDFile *pDFile2 = TSDB_DFILE_IN_SET(pSet2, 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;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
@ -25,6 +25,7 @@ int32_t vnodeCreate(SCreateVnodeMsg *pVnodeCfg);
|
||||||
int32_t vnodeDrop(int32_t vgId);
|
int32_t vnodeDrop(int32_t vgId);
|
||||||
int32_t vnodeOpen(int32_t vgId);
|
int32_t vnodeOpen(int32_t vgId);
|
||||||
int32_t vnodeAlter(void *pVnode, SCreateVnodeMsg *pVnodeCfg);
|
int32_t vnodeAlter(void *pVnode, SCreateVnodeMsg *pVnodeCfg);
|
||||||
|
int32_t vnodeSync(int32_t vgId);
|
||||||
int32_t vnodeClose(int32_t vgId);
|
int32_t vnodeClose(int32_t vgId);
|
||||||
void vnodeCleanUp(SVnodeObj *pVnode);
|
void vnodeCleanUp(SVnodeObj *pVnode);
|
||||||
void vnodeDestroy(SVnodeObj *pVnode);
|
void vnodeDestroy(SVnodeObj *pVnode);
|
||||||
|
|
|
@ -30,7 +30,6 @@ void vnodeStopSyncFile(int32_t vgId, uint64_t fversion);
|
||||||
void vnodeConfirmForard(int32_t vgId, void *wparam, int32_t code);
|
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 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 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);
|
void vnodeConfirmForward(void *pVnode, uint64_t version, int32_t code, bool force);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -27,6 +27,7 @@
|
||||||
#include "vnodeVersion.h"
|
#include "vnodeVersion.h"
|
||||||
#include "vnodeMgmt.h"
|
#include "vnodeMgmt.h"
|
||||||
#include "vnodeWorker.h"
|
#include "vnodeWorker.h"
|
||||||
|
#include "vnodeBackup.h"
|
||||||
#include "vnodeMain.h"
|
#include "vnodeMain.h"
|
||||||
|
|
||||||
static int32_t vnodeProcessTsdbStatus(void *arg, int32_t status, int32_t eno);
|
static int32_t vnodeProcessTsdbStatus(void *arg, int32_t status, int32_t eno);
|
||||||
|
@ -91,6 +92,23 @@ int32_t vnodeCreate(SCreateVnodeMsg *pVnodeCfg) {
|
||||||
return code;
|
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) {
|
int32_t vnodeDrop(int32_t vgId) {
|
||||||
SVnodeObj *pVnode = vnodeAcquire(vgId);
|
SVnodeObj *pVnode = vnodeAcquire(vgId);
|
||||||
if (pVnode == NULL) {
|
if (pVnode == NULL) {
|
||||||
|
@ -347,7 +365,6 @@ int32_t vnodeOpen(int32_t vgId) {
|
||||||
syncInfo.startSyncFileFp = vnodeStartSyncFile;
|
syncInfo.startSyncFileFp = vnodeStartSyncFile;
|
||||||
syncInfo.stopSyncFileFp = vnodeStopSyncFile;
|
syncInfo.stopSyncFileFp = vnodeStopSyncFile;
|
||||||
syncInfo.getVersionFp = vnodeGetVersion;
|
syncInfo.getVersionFp = vnodeGetVersion;
|
||||||
syncInfo.resetVersionFp = vnodeResetVersion;
|
|
||||||
syncInfo.sendFileFp = tsdbSyncSend;
|
syncInfo.sendFileFp = tsdbSyncSend;
|
||||||
syncInfo.recvFileFp = tsdbSyncRecv;
|
syncInfo.recvFileFp = tsdbSyncRecv;
|
||||||
syncInfo.pTsdb = pVnode->tsdb;
|
syncInfo.pTsdb = pVnode->tsdb;
|
||||||
|
@ -431,18 +448,14 @@ void vnodeDestroy(SVnodeObj *pVnode) {
|
||||||
|
|
||||||
if (pVnode->dropped) {
|
if (pVnode->dropped) {
|
||||||
char rootDir[TSDB_FILENAME_LEN] = {0};
|
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(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) {
|
tfsRename(rootDir, stagingDir);
|
||||||
vInfo("vgId:%d, vnode backup not enabled", pVnode->vgId);
|
|
||||||
} else {
|
vnodeBackup(vgId);
|
||||||
tfsRmdir(newDir);
|
|
||||||
tfsRename(rootDir, newDir);
|
|
||||||
}
|
|
||||||
|
|
||||||
tfsRmdir(rootDir);
|
|
||||||
dnodeSendStatusMsgToMnode();
|
dnodeSendStatusMsgToMnode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "dnode.h"
|
#include "dnode.h"
|
||||||
#include "vnodeStatus.h"
|
#include "vnodeStatus.h"
|
||||||
|
#include "vnodeBackup.h"
|
||||||
#include "vnodeWorker.h"
|
#include "vnodeWorker.h"
|
||||||
#include "vnodeRead.h"
|
#include "vnodeRead.h"
|
||||||
#include "vnodeWrite.h"
|
#include "vnodeWrite.h"
|
||||||
|
@ -29,6 +30,7 @@ static void vnodeCleanupHash(void);
|
||||||
static void vnodeIncRef(void *ptNode);
|
static void vnodeIncRef(void *ptNode);
|
||||||
|
|
||||||
static SStep tsVnodeSteps[] = {
|
static SStep tsVnodeSteps[] = {
|
||||||
|
{"vnode-backup", vnodeInitBackup, vnodeCleanupBackup},
|
||||||
{"vnode-worker", vnodeInitMWorker, vnodeCleanupMWorker},
|
{"vnode-worker", vnodeInitMWorker, vnodeCleanupMWorker},
|
||||||
{"vnode-write", vnodeInitWrite, vnodeCleanupWrite},
|
{"vnode-write", vnodeInitWrite, vnodeCleanupWrite},
|
||||||
{"vnode-read", vnodeInitRead, vnodeCleanupRead},
|
{"vnode-read", vnodeInitRead, vnodeCleanupRead},
|
||||||
|
|
|
@ -107,8 +107,9 @@ void vnodeStopSyncFile(int32_t vgId, uint64_t fversion) {
|
||||||
pVnode->fversion = fversion;
|
pVnode->fversion = fversion;
|
||||||
pVnode->version = fversion;
|
pVnode->version = fversion;
|
||||||
vnodeSaveVersion(pVnode);
|
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);
|
vnodeSetReadyStatus(pVnode);
|
||||||
|
|
||||||
vnodeRelease(pVnode);
|
vnodeRelease(pVnode);
|
||||||
|
@ -158,22 +159,6 @@ int32_t vnodeGetVersion(int32_t vgId, uint64_t *fver, uint64_t *wver) {
|
||||||
return code;
|
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) {
|
void vnodeConfirmForward(void *vparam, uint64_t version, int32_t code, bool force) {
|
||||||
SVnodeObj *pVnode = vparam;
|
SVnodeObj *pVnode = vparam;
|
||||||
syncConfirmForward(pVnode->sync, version, code, force);
|
syncConfirmForward(pVnode->sync, version, code, force);
|
||||||
|
|
|
@ -76,9 +76,20 @@ pipeline {
|
||||||
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
|
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
|
||||||
sh '''
|
sh '''
|
||||||
cd ${WKC}/tests/pytest
|
cd ${WKC}/tests/pytest
|
||||||
|
rm -rf /var/lib/taos/*
|
||||||
|
rm -rf /var/log/taos/*
|
||||||
./handle_crash_gen_val_log.sh
|
./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'''
|
sh'''
|
||||||
systemctl start taosd
|
systemctl start taosd
|
||||||
sleep 10
|
sleep 10
|
||||||
|
@ -163,6 +174,11 @@ pipeline {
|
||||||
cd ${WKC}/tests
|
cd ${WKC}/tests
|
||||||
./test-all.sh b3
|
./test-all.sh b3
|
||||||
date'''
|
date'''
|
||||||
|
sh '''
|
||||||
|
date
|
||||||
|
cd ${WKC}/tests
|
||||||
|
./test-all.sh full example
|
||||||
|
date'''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.taosdata.jdbc</groupId>
|
<groupId>com.taosdata.jdbc</groupId>
|
||||||
<artifactId>taos-jdbcdriver</artifactId>
|
<artifactId>taos-jdbcdriver</artifactId>
|
||||||
<version>2.0.20</version>
|
<version>2.0.22</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|
|
@ -68,12 +68,12 @@ public class JDBCDemo {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void insert() {
|
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);
|
exuete(sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void select() {
|
private void select() {
|
||||||
final String sql = "select * from test.weather";
|
final String sql = "select * from "+ dbName + "." + tbName;
|
||||||
executeQuery(sql);
|
executeQuery(sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ function buildTDengine {
|
||||||
echo "repo up-to-date"
|
echo "repo up-to-date"
|
||||||
else
|
else
|
||||||
echo "repo need to pull"
|
echo "repo need to pull"
|
||||||
git pull > /dev/null
|
git pull > /dev/null 2>&1
|
||||||
|
|
||||||
LOCAL_COMMIT=`git rev-parse --short @`
|
LOCAL_COMMIT=`git rev-parse --short @`
|
||||||
cd debug
|
cd debug
|
||||||
|
@ -72,26 +72,13 @@ function runQueryPerfTest {
|
||||||
|
|
||||||
python3 insert/insertFromCSVPerformance.py -c $LOCAL_COMMIT | tee -a $PERFORMANCE_TEST_REPORT
|
python3 insert/insertFromCSVPerformance.py -c $LOCAL_COMMIT | tee -a $PERFORMANCE_TEST_REPORT
|
||||||
|
|
||||||
yes | taosdemo -c /etc/taosperf/ -d taosdemo_insert_test -x > taosdemoperf.txt
|
python3 tools/taosdemoPerformance.py -c $LOCAL_COMMIT | tee -a $PERFORMANCE_TEST_REPORT
|
||||||
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function sendReport {
|
function sendReport {
|
||||||
echo "send report"
|
echo "send report"
|
||||||
receiver="pxiao@taosdata.com"
|
receiver="develop@taosdata.com"
|
||||||
mimebody="MIME-Version: 1.0\nContent-Type: text/html; charset=utf-8\n"
|
mimebody="MIME-Version: 1.0\nContent-Type: text/html; charset=utf-8\n"
|
||||||
|
|
||||||
cd $TDENGINE_DIR
|
cd $TDENGINE_DIR
|
||||||
|
|
|
@ -139,6 +139,18 @@ python3 ./test.py -f import_merge/importInsertThenImport.py
|
||||||
python3 ./test.py -f import_merge/importCSV.py
|
python3 ./test.py -f import_merge/importCSV.py
|
||||||
#======================p1-end===============
|
#======================p1-end===============
|
||||||
#======================p2-start===============
|
#======================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
|
# update
|
||||||
python3 ./test.py -f update/allow_update.py
|
python3 ./test.py -f update/allow_update.py
|
||||||
python3 ./test.py -f update/allow_update-0.py
|
python3 ./test.py -f update/allow_update-0.py
|
||||||
|
@ -164,6 +176,11 @@ python3 ./test.py -f user/pass_len.py
|
||||||
# stable
|
# stable
|
||||||
python3 ./test.py -f stable/query_after_reset.py
|
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
|
#query
|
||||||
python3 ./test.py -f query/filter.py
|
python3 ./test.py -f query/filter.py
|
||||||
python3 ./test.py -f query/filterCombo.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/isNullTest.py
|
||||||
python3 ./test.py -f query/queryWithTaosdKilled.py
|
python3 ./test.py -f query/queryWithTaosdKilled.py
|
||||||
python3 ./test.py -f query/floatCompare.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
|
python3 ./test.py -f query/bug3375.py
|
||||||
|
|
||||||
|
|
||||||
|
@ -242,18 +261,6 @@ python3 test.py -f subscribe/supertable.py
|
||||||
#======================p3-end===============
|
#======================p3-end===============
|
||||||
#======================p4-start===============
|
#======================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
|
python3 ./test.py -f update/merge_commit_data-0.py
|
||||||
# wal
|
# wal
|
||||||
python3 ./test.py -f wal/addOldWalTest.py
|
python3 ./test.py -f wal/addOldWalTest.py
|
||||||
|
|
|
@ -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
|
|
@ -25,6 +25,8 @@ class TDTestCase:
|
||||||
tdSql.init(conn.cursor(), logSql)
|
tdSql.init(conn.cursor(), logSql)
|
||||||
|
|
||||||
self.ts = 1538548685000
|
self.ts = 1538548685000
|
||||||
|
self.tables = 10
|
||||||
|
self.rows = 1000
|
||||||
|
|
||||||
def updateMetadata(self):
|
def updateMetadata(self):
|
||||||
self.host = "127.0.0.1"
|
self.host = "127.0.0.1"
|
||||||
|
@ -37,6 +39,29 @@ class TDTestCase:
|
||||||
self.cursor.execute("alter table db.tb add column col2 int")
|
self.cursor.execute("alter table db.tb add column col2 int")
|
||||||
print("alter table done")
|
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):
|
def run(self):
|
||||||
tdSql.prepare()
|
tdSql.prepare()
|
||||||
|
|
||||||
|
@ -59,6 +84,36 @@ class TDTestCase:
|
||||||
tdSql.query("select * from tb")
|
tdSql.query("select * from tb")
|
||||||
tdSql.checkRows(2)
|
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):
|
def stop(self):
|
||||||
tdSql.close()
|
tdSql.close()
|
||||||
tdLog.success("%s successfully executed" % __file__)
|
tdLog.success("%s successfully executed" % __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())
|
|
@ -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())
|
|
@ -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())
|
|
@ -22,25 +22,34 @@ import datetime
|
||||||
from util.log import *
|
from util.log import *
|
||||||
from util.sql import *
|
from util.sql import *
|
||||||
from util.cases import *
|
from util.cases import *
|
||||||
|
from util.dnodes import *
|
||||||
|
from util.dnodes import TDDnode
|
||||||
|
|
||||||
class TDTestCase:
|
class TDTestCase:
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.path = ""
|
||||||
|
|
||||||
def init(self, conn, logSql):
|
def init(self, conn, logSql):
|
||||||
tdLog.debug(f"start to excute {__file__}")
|
tdLog.debug(f"start to excute {__file__}")
|
||||||
tdSql.init(conn.cursor())
|
tdSql.init(conn.cursor())
|
||||||
|
|
||||||
def getCfgDir(self, path):
|
def getcfgPath(self, path):
|
||||||
binPath = os.path.dirname(os.path.realpath(__file__))
|
binPath = os.path.dirname(os.path.realpath(__file__))
|
||||||
binPath = binPath + "/../../../debug/"
|
binPath = binPath + "/../../../debug/"
|
||||||
tdLog.debug("binPath %s" % (binPath))
|
tdLog.debug(f"binPath {binPath}")
|
||||||
binPath = os.path.realpath(binPath)
|
binPath = os.path.realpath(binPath)
|
||||||
tdLog.debug("binPath real path %s" % (binPath))
|
tdLog.debug(f"binPath real path {binPath}")
|
||||||
|
|
||||||
if path == "":
|
if path == "":
|
||||||
self.path = os.path.abspath(binPath + "../../")
|
self.path = os.path.abspath(binPath + "../../")
|
||||||
else:
|
else:
|
||||||
self.path = os.path.realpath(path)
|
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
|
return self.cfgDir
|
||||||
|
|
||||||
def creatcfg(self):
|
def creatcfg(self):
|
||||||
|
@ -63,7 +72,7 @@ class TDTestCase:
|
||||||
"update": 0
|
"update": 0
|
||||||
}
|
}
|
||||||
|
|
||||||
# 设置创建的超级表格式
|
# set stable schema
|
||||||
stable1 = {
|
stable1 = {
|
||||||
"name": "stb2",
|
"name": "stb2",
|
||||||
"child_table_exists": "no",
|
"child_table_exists": "no",
|
||||||
|
@ -75,35 +84,49 @@ class TDTestCase:
|
||||||
"insert_rows": 5000,
|
"insert_rows": 5000,
|
||||||
"multi_thread_write_one_tbl": "no",
|
"multi_thread_write_one_tbl": "no",
|
||||||
"number_of_tbl_in_one_sql": 0,
|
"number_of_tbl_in_one_sql": 0,
|
||||||
"rows_per_tbl": 1000,
|
"rows_per_tbl": 1,
|
||||||
"max_sql_len": 65480,
|
"max_sql_len": 65480,
|
||||||
"disorder_ratio": 0,
|
"disorder_ratio": 0,
|
||||||
"disorder_range": 1000,
|
"disorder_range": 1000,
|
||||||
"timestamp_step": 19000000,
|
"timestamp_step": 20000,
|
||||||
"start_timestamp": "1969-01-01 00:00:00.000",
|
"start_timestamp": "1969-12-31 00:00:00.000",
|
||||||
"sample_format": "csv",
|
"sample_format": "csv",
|
||||||
"sample_file": "./sample.csv",
|
"sample_file": "./sample.csv",
|
||||||
"tags_file": "",
|
"tags_file": "",
|
||||||
"columns": [
|
"columns": [
|
||||||
{"type": "INT"},
|
{"type": "INT", "count": 2},
|
||||||
{"type": "DOUBLE", "count": 10},
|
{"type": "DOUBLE", "count": 2},
|
||||||
{"type": "BINARY", "len": 16, "count": 3},
|
{"type": "BIGINT", "count": 2},
|
||||||
{"type": "BINARY", "len": 32, "count": 6}
|
{"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": [
|
"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": "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
|
# create different stables like stable1 and add to list super_tables
|
||||||
super_tables = [stable1]
|
super_tables = []
|
||||||
|
super_tables.append(stable1)
|
||||||
database = {
|
database = {
|
||||||
"dbinfo": dbinfo,
|
"dbinfo": dbinfo,
|
||||||
"super_tables": super_tables
|
"super_tables": super_tables
|
||||||
}
|
}
|
||||||
|
|
||||||
cfgdir = self.getCfgDir("")
|
cfgdir = self.getCfgDir()
|
||||||
create_table = {
|
create_table = {
|
||||||
"filetype": "insert",
|
"filetype": "insert",
|
||||||
"cfgdir": cfgdir,
|
"cfgdir": cfgdir,
|
||||||
|
@ -121,17 +144,82 @@ class TDTestCase:
|
||||||
}
|
}
|
||||||
return create_table
|
return create_table
|
||||||
|
|
||||||
def inserttable(self):
|
def createinsertfile(self):
|
||||||
create_table = self.creatcfg()
|
create_table = self.creatcfg()
|
||||||
date = datetime.datetime.now().strftime("%Y%m%d%H%M")
|
date = datetime.datetime.now().strftime("%Y%m%d%H%M")
|
||||||
file_create_table = f"/tmp/insert_{date}.json"
|
file_create_table = f"/tmp/insert_{date}.json"
|
||||||
|
|
||||||
with open(file_create_table, 'w') as f:
|
with open(file_create_table, 'w') as f:
|
||||||
json.dump(create_table, 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")
|
_ = 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):
|
def run(self):
|
||||||
s = 'reset query cache'
|
s = 'reset query cache'
|
||||||
|
@ -142,84 +230,24 @@ class TDTestCase:
|
||||||
tdSql.execute(s)
|
tdSql.execute(s)
|
||||||
|
|
||||||
tdLog.info("==========step1:create table stable and child table,then insert data automatically")
|
tdLog.info("==========step1:create table stable and child table,then insert data automatically")
|
||||||
self.inserttable()
|
insertfile = self.createinsertfile()
|
||||||
# tdSql.execute(
|
self.inserttable(insertfile)
|
||||||
# '''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)"
|
|
||||||
# )
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
tdLog.info("==========step2:query join")
|
tdLog.info("==========step2:query join")
|
||||||
|
self.sqlsquery()
|
||||||
|
|
||||||
# stable query
|
# after wal and sync, check again
|
||||||
tdSql.query(
|
tdSql.query("show dnodes")
|
||||||
"select * from stb2 where stb2.ts < '1970-01-01 00:00:00.000' "
|
index = tdSql.getData(0, 0)
|
||||||
)
|
tdDnodes.stop(index)
|
||||||
tdSql.checkRows(16600)
|
tdDnodes.start(index)
|
||||||
|
|
||||||
tdSql.query(
|
tdLog.info("==========step3: query join again")
|
||||||
"select * from stb2 where stb2.ts >= '1970-01-01 00:00:00.000' "
|
self.sqlsquery()
|
||||||
)
|
|
||||||
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' "
|
|
||||||
)
|
|
||||||
|
|
||||||
|
# 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):
|
def stop(self):
|
||||||
tdSql.close()
|
tdSql.close()
|
||||||
|
|
|
@ -11,26 +11,16 @@
|
||||||
|
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
import sys
|
|
||||||
import taos
|
import taos
|
||||||
import time
|
|
||||||
import datetime
|
|
||||||
import csv
|
|
||||||
import random
|
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
import argparse
|
import argparse
|
||||||
import os.path
|
import os.path
|
||||||
|
import json
|
||||||
|
|
||||||
class taosdemoPerformace:
|
class taosdemoPerformace:
|
||||||
def __init__(self, commitID, dbName, createTableTime, insertRecordsTime, recordsPerSecond, avgDelay, maxDelay, minDelay):
|
def __init__(self, commitID, dbName):
|
||||||
self.commitID = commitID
|
self.commitID = commitID
|
||||||
self.dbName = dbName
|
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.host = "127.0.0.1"
|
||||||
self.user = "root"
|
self.user = "root"
|
||||||
self.password = "taosdata"
|
self.password = "taosdata"
|
||||||
|
@ -40,6 +30,95 @@ class taosdemoPerformace:
|
||||||
self.user,
|
self.user,
|
||||||
self.password,
|
self.password,
|
||||||
self.config)
|
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):
|
def createTablesAndStoreData(self):
|
||||||
cursor = self.conn.cursor()
|
cursor = self.conn.cursor()
|
||||||
|
@ -48,14 +127,15 @@ class taosdemoPerformace:
|
||||||
cursor.execute("use %s" % self.dbName)
|
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)")
|
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("==================== taosdemo performance ====================")
|
||||||
print("create tables time: %f" % self.createTableTime)
|
print("create tables time: %f" % float(self.createTableTime))
|
||||||
print("insert records time: %f" % self.insertRecordsTime)
|
print("insert records time: %f" % float(self.insertRecordsTime))
|
||||||
print("records per second: %f" % self.recordsPerSecond)
|
print("records per second: %f" % float(self.recordsPerSecond))
|
||||||
print("avg delay: %f" % self.avgDelay)
|
print("avg delay: %f" % float(self.avgDelay))
|
||||||
print("max delay: %f" % self.maxDelay)
|
print("max delay: %f" % float(self.maxDelay))
|
||||||
print("min delay: %f" % self.minDelay)
|
print("min delay: %f" % float(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("insert into taosdemo_perf values(now, %f, %f, %f, '%s', %f, %f, %f)" %
|
||||||
cursor.execute("drop database if exists taosdemo_insert_test")
|
(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()
|
cursor.close()
|
||||||
|
|
||||||
|
@ -74,46 +154,9 @@ if __name__ == '__main__':
|
||||||
default='perf',
|
default='perf',
|
||||||
type=str,
|
type=str,
|
||||||
help='Database name to be created (default: perf)')
|
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()
|
args = parser.parse_args()
|
||||||
|
|
||||||
perftest = taosdemoPerformace(args.commit_id, args.database_name, args.create_table, args.insert_records, args.records_per_second,
|
perftest = taosdemoPerformace(args.commit_id, args.database_name)
|
||||||
args.avg_delay, args.max_delay, args.min_delay)
|
perftest.insertData()
|
||||||
perftest.createTablesAndStoreData()
|
perftest.createTablesAndStoreData()
|
|
@ -29,17 +29,54 @@ class TDTestCase:
|
||||||
self.numberOfTables = 10
|
self.numberOfTables = 10
|
||||||
self.numberOfRecords = 1000000
|
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):
|
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):
|
if(threadID == 0):
|
||||||
os.system("taosdemo -y -t %d -n %d" %
|
os.system("%staosdemo -y -t %d -n %d" %
|
||||||
(self.numberOfTables, self.numberOfRecords))
|
(binPath, self.numberOfTables, self.numberOfRecords))
|
||||||
if(threadID == 1):
|
if(threadID == 1):
|
||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
print("use test")
|
print("use test")
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
tdSql.execute("use test")
|
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
|
# check if all the tables have heen created
|
||||||
while True:
|
while True:
|
||||||
|
try:
|
||||||
tdSql.query("show tables")
|
tdSql.query("show tables")
|
||||||
|
except Exception as e:
|
||||||
|
tdLog.info("show tables test failed")
|
||||||
|
time.sleep(1)
|
||||||
|
continue
|
||||||
|
|
||||||
rows = tdSql.queryRows
|
rows = tdSql.queryRows
|
||||||
print("number of tables: %d" % rows)
|
print("number of tables: %d" % rows)
|
||||||
if(rows == self.numberOfTables):
|
if(rows == self.numberOfTables):
|
||||||
|
@ -48,16 +85,23 @@ class TDTestCase:
|
||||||
# check if there are any records in the last created table
|
# check if there are any records in the last created table
|
||||||
while True:
|
while True:
|
||||||
print("query started")
|
print("query started")
|
||||||
|
try:
|
||||||
tdSql.query("select * from test.t9")
|
tdSql.query("select * from test.t9")
|
||||||
|
except Exception as e:
|
||||||
|
tdLog.info("select * test failed")
|
||||||
|
time.sleep(2)
|
||||||
|
continue
|
||||||
|
|
||||||
rows = tdSql.queryRows
|
rows = tdSql.queryRows
|
||||||
print("number of records: %d" % rows)
|
print("number of records: %d" % rows)
|
||||||
if(rows > 0):
|
if(rows > 0):
|
||||||
break
|
break
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
||||||
print("alter table test.meters add column col10 int")
|
print("alter table test.meters add column col10 int")
|
||||||
tdSql.execute("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)")
|
print("insert into test.t9 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)")
|
tdSql.execute("insert into test.t9 values (now, 1, 2, 3, 4, 0.1, 0.01,'test', '测试', TRUE, 1610000000000, 0)")
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
tdSql.prepare()
|
tdSql.prepare()
|
||||||
|
@ -70,6 +114,8 @@ class TDTestCase:
|
||||||
t1.join()
|
t1.join()
|
||||||
t2.join()
|
t2.join()
|
||||||
|
|
||||||
|
time.sleep(3)
|
||||||
|
|
||||||
tdSql.query("select count(*) from test.meters")
|
tdSql.query("select count(*) from test.meters")
|
||||||
tdSql.checkData(0, 0, self.numberOfRecords * self.numberOfTables + 1)
|
tdSql.checkData(0, 0, self.numberOfRecords * self.numberOfTables + 1)
|
||||||
|
|
|
@ -878,5 +878,7 @@ if $rows != 0 then
|
||||||
endi
|
endi
|
||||||
|
|
||||||
sql drop topic t2
|
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
|
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
Loading…
Reference in New Issue