提交 3e890bac 编写于 作者: D dapan1121

Merge branch 'develop' into feature/TD-3188

...@@ -171,6 +171,8 @@ matrix: ...@@ -171,6 +171,8 @@ matrix:
- build-essential - build-essential
- cmake - cmake
- binutils-2.26 - binutils-2.26
- unixodbc
- unixodbc-dev
env: env:
- DESC="trusty/gcc-4.8/bintuils-2.26 build" - DESC="trusty/gcc-4.8/bintuils-2.26 build"
...@@ -198,6 +200,8 @@ matrix: ...@@ -198,6 +200,8 @@ matrix:
packages: packages:
- build-essential - build-essential
- cmake - cmake
- unixodbc
- unixodbc-dev
before_script: before_script:
- export TZ=Asia/Harbin - export TZ=Asia/Harbin
...@@ -252,6 +256,8 @@ matrix: ...@@ -252,6 +256,8 @@ matrix:
packages: packages:
- build-essential - build-essential
- cmake - cmake
- unixodbc
- unixodbc-dev
env: env:
- DESC="arm64 xenial build" - DESC="arm64 xenial build"
...@@ -280,6 +286,7 @@ matrix: ...@@ -280,6 +286,7 @@ matrix:
addons: addons:
homebrew: homebrew:
- cmake - cmake
- unixodbc
script: script:
- cd ${TRAVIS_BUILD_DIR} - cd ${TRAVIS_BUILD_DIR}
......
...@@ -32,25 +32,24 @@ def abort_previous(){ ...@@ -32,25 +32,24 @@ def abort_previous(){
milestone(buildNumber) milestone(buildNumber)
} }
def pre_test(){ def pre_test(){
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
sh ''' sh '''
sudo rmtaos sudo rmtaos || echo "taosd has not installed"
''' '''
}
sh ''' sh '''
cd ${WKC} cd ${WKC}
git checkout develop git checkout develop
git reset --hard HEAD~10 >/dev/null git reset --hard HEAD~10 >/dev/null
git pull 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
git --no-pager diff --name-only FETCH_HEAD $(git merge-base FETCH_HEAD develop)|grep -v -E '.*md|//src//connector|Jenkinsfile' || exit 0 git --no-pager diff --name-only FETCH_HEAD $(git merge-base FETCH_HEAD develop)|grep -v -E '.*md|//src//connector|Jenkinsfile'
find ${WKC}/tests/pytest -name \'*\'.sql -exec rm -rf {} \\; find ${WKC}/tests/pytest -name \'*\'.sql -exec rm -rf {} \\;
cd ${WK} cd ${WK}
git reset --hard HEAD~10 git reset --hard HEAD~10
git checkout develop git checkout develop
git pull git pull >/dev/null
cd ${WK} cd ${WK}
export TZ=Asia/Harbin export TZ=Asia/Harbin
date date
......
[![Build Status](https://travis-ci.org/taosdata/TDengine.svg?branch=master)](https://travis-ci.org/taosdata/TDengine)
[![Build status](https://ci.appveyor.com/api/projects/status/kf3pwh2or5afsgl9/branch/master?svg=true)](https://ci.appveyor.com/project/sangshuduo/tdengine-2n8ge/branch/master)
[![Coverage Status](https://coveralls.io/repos/github/taosdata/TDengine/badge.svg?branch=develop)](https://coveralls.io/github/taosdata/TDengine?branch=develop)
[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/4201/badge)](https://bestpractices.coreinfrastructure.org/projects/4201)
[![tdengine](https://snapcraft.io//tdengine/badge.svg)](https://snapcraft.io/tdengine)
[![TDengine](TDenginelogo.png)](https://www.taosdata.com)
简体中文 | [English](./README.md)
# TDengine 简介
TDengine是涛思数据专为物联网、车联网、工业互联网、IT运维等设计和优化的大数据平台。除核心的快10倍以上的时序数据库功能外,还提供缓存、数据订阅、流式计算等功能,最大程度减少研发和运维的复杂度,且核心代码,包括集群功能全部开源(开源协议,AGPL v3.0)。
- 10 倍以上性能提升。定义了创新的数据存储结构,单核每秒就能处理至少2万次请求,插入数百万个数据点,读出一千万以上数据点,比现有通用数据库快了十倍以上。
- 硬件或云服务成本降至1/5。由于超强性能,计算资源不到通用大数据方案的1/5;通过列式存储和先进的压缩算法,存储空间不到通用数据库的1/10。
- 全栈时序数据处理引擎。将数据库、消息队列、缓存、流式计算等功能融合一起,应用无需再集成Kafka/Redis/HBase/Spark等软件,大幅降低应用开发和维护成本。
- 强大的分析功能。无论是十年前还是一秒钟前的数据,指定时间范围即可查询。数据可在时间轴上或多个设备上进行聚合。即席查询可通过Shell/Python/R/Matlab随时进行。
- 与第三方工具无缝连接。不用一行代码,即可与Telegraf, Grafana, EMQ X, Prometheus, Matlab, R集成。后续还将支持MQTT, OPC, Hadoop,Spark等, BI工具也将无缝连接。
- 零运维成本、零学习成本。安装、集群一秒搞定,无需分库分表,实时备份。标准SQL,支持JDBC,RESTful,支持Python/Java/C/C++/Go/Node.JS, 与MySQL相似,零学习成本。
# 文档
TDengine是一个高效的存储、查询、分析时序大数据的平台,专为物联网、车联网、工业互联网、运维监测等优化而设计。您可以像使用关系型数据库MySQL一样来使用它,但建议您在使用前仔细阅读一遍下面的文档,特别是 [数据模型](https://www.taosdata.com/cn/documentation/architecture)[数据建模](https://www.taosdata.com/cn/documentation/model)。除本文档之外,欢迎 [下载产品白皮书](https://www.taosdata.com/downloads/TDengine%20White%20Paper.pdf)
# 生成
TDengine目前2.0版服务器仅能在Linux系统上安装和运行,后续会支持Windows、macOS等系统。客户端可以在Windows或Linux上安装和运行。任何OS的应用也可以选择RESTful接口连接服务器taosd。CPU支持X64/ARM64/MIPS64/Alpha64,后续会支持ARM32、RISC-V等CPU架构。用户可根据需求选择通过[源码](https://www.taosdata.com/cn/getting-started/#通过源码安装)或者[安装包](https://www.taosdata.com/cn/getting-started/#通过安装包安装)来安装。本快速指南仅适用于通过源码安装。
## 安装工具
### Ubuntu 16.04 及以上版本 & Debian:
```bash
sudo apt-get install -y gcc cmake build-essential git
```
### Ubuntu 14.04:
```bash
sudo apt-get install -y gcc cmake3 build-essential git binutils-2.26
export PATH=/usr/lib/binutils-2.26/bin:$PATH
```
编译或打包 JDBC 驱动源码,需安装 Java JDK 8 或以上版本和 Apache Maven 2.7 或以上版本。
安装 OpenJDK 8:
```bash
sudo apt-get install -y openjdk-8-jdk
```
安装 Apache Maven:
```bash
sudo apt-get install -y maven
```
### CentOS 7:
```bash
sudo yum install -y gcc gcc-c++ make cmake git
```
安装 OpenJDK 8:
```bash
sudo yum install -y java-1.8.0-openjdk
```
安装 Apache Maven:
```bash
sudo yum install -y maven
```
### CentOS 8 & Fedora:
```bash
sudo dnf install -y gcc gcc-c++ make cmake epel-release git
```
安装 OpenJDK 8:
```bash
sudo dnf install -y java-1.8.0-openjdk
```
安装 Apache Maven:
```bash
sudo dnf install -y maven
```
## 获取源码
首先,你需要从 GitHub 克隆源码:
```bash
git clone https://github.com/taosdata/TDengine.git
cd TDengine
```
Go 连接器和 Grafana 插件在其他独立仓库,如果安装它们的话,需要在 TDengine 目录下通过此命令安装:
```bash
git submodule update --init --recursive
```
## 生成 TDengine
### Linux 系统
```bash
mkdir debug && cd debug
cmake .. && cmake --build .
```
在X86-64、X86、arm64 和 arm32 平台上,TDengine 生成脚本可以自动检测机器架构。也可以手动配置 CPUTYPE 参数来指定 CPU 类型,如 aarch64 或 aarch32 等。
aarch64:
```bash
cmake .. -DCPUTYPE=aarch64 && cmake --build .
```
aarch32:
```bash
cmake .. -DCPUTYPE=aarch32 && cmake --build .
```
### Windows 系统
如果你使用的是 Visual Studio 2013 版本:
打开 cmd.exe,执行 vcvarsall.bat 时,为 64 位操作系统指定“x86_amd64”,为 32 位操作系统指定“x86”。
```bash
mkdir debug && cd debug
"C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" < x86_amd64 | x86 >
cmake .. -G "NMake Makefiles"
nmake
```
如果你使用的是 Visual Studio 2019 或 2017 版本:
打开cmd.exe,执行 vcvarsall.bat 时,为 64 位操作系统指定“x64”,为 32 位操作系统指定“x86”。
```bash
mkdir debug && cd debug
"c:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat" < x64 | x86 >
cmake .. -G "NMake Makefiles"
nmake
```
你也可以从开始菜单中找到"Visual Studio < 2019 | 2017 >"菜单项,根据你的系统选择"x64 Native Tools Command Prompt for VS < 2019 | 2017 >"或"x86 Native Tools Command Prompt for VS < 2019 | 2017 >",打开命令行窗口,执行:
```bash
mkdir debug && cd debug
cmake .. -G "NMake Makefiles"
nmake
```
### Mac OS X 系统
安装 Xcode 命令行工具和 cmake. 在 Catalina 和 Big Sur 操作系统上,需要安装 XCode 11.4+ 版本。
```bash
mkdir debug && cd debug
cmake .. && cmake --build .
```
# 安装
如果你不想安装,可以直接在shell中运行。生成完成后,安装 TDengine:
```bash
make install
```
用户可以在[文件目录结构](https://www.taosdata.com/cn/documentation/administrator#directories)中了解更多在操作系统中生成的目录或文件。
安装成功后,在终端中启动 TDengine 服务:
```bash
taosd
```
用户可以使用 TDengine Shell 来连接 TDengine 服务,在终端中,输入:
```bash
taos
```
如果 TDengine Shell 连接服务成功,将会打印出欢迎消息和版本信息。如果失败,则会打印出错误消息。
## 快速运行
TDengine 生成后,在终端执行以下命令:
```bash
./build/bin/taosd -c test/cfg
```
在另一个终端,使用 TDengine shell 连接服务器:
```bash
./build/bin/taos -c test/cfg
```
"-c test/cfg"指定系统配置文件所在目录。
# 体验 TDengine
在TDengine终端中,用户可以通过SQL命令来创建/删除数据库、表等,并进行插入查询操作。
```bash
create database demo;
use demo;
create table t (ts timestamp, speed int);
insert into t values ('2019-07-15 00:00:00', 10);
insert into t values ('2019-07-15 01:00:00', 20);
select * from t;
ts | speed |
===================================
19-07-15 00:00:00.000| 10|
19-07-15 01:00:00.000| 20|
Query OK, 2 row(s) in set (0.001700s)
```
# 应用开发
## 官方连接器
TDengine 提供了丰富的应用程序开发接口,其中包括C/C++、Java、Python、Go、Node.js、C# 、RESTful 等,便于用户快速开发应用:
- Java
- C/C++
- Python
- Go
- RESTful API
- Node.js
## 第三方连接器
TDengine 社区生态中也有一些非常友好的第三方连接器,可以通过以下链接访问它们的源码。
- [Rust Connector](https://github.com/taosdata/TDengine/tree/master/tests/examples/rust)
- [.Net Core Connector](https://github.com/maikebing/Maikebing.EntityFrameworkCore.Taos)
- [Lua Connector](https://github.com/taosdata/TDengine/tree/develop/tests/examples/lua)
# 运行和添加测试例
TDengine 的测试框架和所有测试例全部开源。
点击[这里](tests/How-To-Run-Test-And-How-To-Add-New-Test-Case.md),了解如何运行测试例和添加新的测试例。
# 成为社区贡献者
点击[这里](https://www.taosdata.com/cn/contributor/),了解如何成为 TDengine 的贡献者。
#加入技术交流群
TDengine官方社群「物联网大数据群」对外开放,欢迎您加入讨论。搜索微信号 "tdengine",加小T为好友,即可入群。
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
[![TDengine](TDenginelogo.png)](https://www.taosdata.com) [![TDengine](TDenginelogo.png)](https://www.taosdata.com)
English | [简体中文](./README-CN.md)
# What is TDengine? # What is TDengine?
TDengine is an open-sourced big data platform under [GNU AGPL v3.0](http://www.gnu.org/licenses/agpl-3.0.html), designed and optimized for the Internet of Things (IoT), Connected Cars, Industrial IoT, and IT Infrastructure and Application Monitoring. Besides the 10x faster time-series database, it provides caching, stream computing, message queuing and other functionalities to reduce the complexity and cost of development and operation. TDengine is an open-sourced big data platform under [GNU AGPL v3.0](http://www.gnu.org/licenses/agpl-3.0.html), designed and optimized for the Internet of Things (IoT), Connected Cars, Industrial IoT, and IT Infrastructure and Application Monitoring. Besides the 10x faster time-series database, it provides caching, stream computing, message queuing and other functionalities to reduce the complexity and cost of development and operation.
...@@ -29,7 +31,7 @@ For user manual, system design and architecture, engineering blogs, refer to [TD ...@@ -29,7 +31,7 @@ For user manual, system design and architecture, engineering blogs, refer to [TD
# Building # Building
At the moment, TDengine only supports building and running on Linux systems. You can choose to [install from packages](https://www.taosdata.com/en/getting-started/#Install-from-Package) or from the source code. This quick guide is for installation from the source only. At the moment, TDengine only supports building and running on Linux systems. You can choose to [install from packages](https://www.taosdata.com/en/getting-started/#Install-from-Package) or from the source code. This quick guide is for installation from the source only.
To build TDengine, use [CMake](https://cmake.org/) 3.5 or higher versions in the project directory. To build TDengine, use [CMake](https://cmake.org/) 2.8.12.x or higher versions in the project directory.
## Install tools ## Install tools
...@@ -160,39 +162,42 @@ mkdir debug && cd debug ...@@ -160,39 +162,42 @@ mkdir debug && cd debug
cmake .. && cmake --build . cmake .. && cmake --build .
``` ```
# Quick Run
# Quick Run
To quickly start a TDengine server after building, run the command below in terminal:
```bash
./build/bin/taosd -c test/cfg
```
In another terminal, use the TDengine shell to connect the server:
```bash
./build/bin/taos -c test/cfg
```
option "-c test/cfg" specifies the system configuration file directory.
# Installing # Installing
After building successfully, TDengine can be installed by: After building successfully, TDengine can be installed by:
```bash ```bash
make install sudo make install
``` ```
Users can find more information about directories installed on the system in the [directory and files](https://www.taosdata.com/en/documentation/administrator/#Directory-and-Files) section. It should be noted that installing from source code does not configure service management for TDengine.
Users can find more information about directories installed on the system in the [directory and files](https://www.taosdata.com/en/documentation/administrator/#Directory-and-Files) section. Since version 2.0, installing from source code will also configure service management for TDengine.
Users can also choose to [install from packages](https://www.taosdata.com/en/getting-started/#Install-from-Package) for it. Users can also choose to [install from packages](https://www.taosdata.com/en/getting-started/#Install-from-Package) for it.
To start the service after installation, in a terminal, use: To start the service after installation, in a terminal, use:
```cmd ```bash
taosd sudo systemctl start taosd
``` ```
Then users can use the [TDengine shell](https://www.taosdata.com/en/getting-started/#TDengine-Shell) to connect the TDengine server. In a terminal, use: Then users can use the [TDengine shell](https://www.taosdata.com/en/getting-started/#TDengine-Shell) to connect the TDengine server. In a terminal, use:
```cmd ```bash
taos taos
``` ```
If TDengine shell connects the server successfully, welcome messages and version info are printed. Otherwise, an error message is shown. If TDengine shell connects the server successfully, welcome messages and version info are printed. Otherwise, an error message is shown.
## Quick Run
If you don't want to run TDengine as a service, you can run it in current shell. For example, to quickly start a TDengine server after building, run the command below in terminal:
```bash
./build/bin/taosd -c test/cfg
```
In another terminal, use the TDengine shell to connect the server:
```bash
./build/bin/taos -c test/cfg
```
option "-c test/cfg" specifies the system configuration file directory.
# Try TDengine # Try TDengine
It is easy to run SQL commands from TDengine shell which is the same as other SQL databases. It is easy to run SQL commands from TDengine shell which is the same as other SQL databases.
```sql ```sql
......
...@@ -32,7 +32,7 @@ ELSEIF (TD_WINDOWS) ...@@ -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.21-dist.jar DESTINATION connector/jdbc) INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos-jdbcdriver-2.0.22-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")
......
...@@ -4,7 +4,7 @@ PROJECT(TDengine) ...@@ -4,7 +4,7 @@ PROJECT(TDengine)
IF (DEFINED VERNUMBER) IF (DEFINED VERNUMBER)
SET(TD_VER_NUMBER ${VERNUMBER}) SET(TD_VER_NUMBER ${VERNUMBER})
ELSE () ELSE ()
SET(TD_VER_NUMBER "2.0.17.0") SET(TD_VER_NUMBER "2.0.18.0")
ENDIF () ENDIF ()
IF (DEFINED VERCOMPATIBLE) IF (DEFINED VERCOMPATIBLE)
......
...@@ -145,7 +145,7 @@ TDengine 建议用数据采集点的名字(如上表中的D1001)来做表名。 ...@@ -145,7 +145,7 @@ TDengine 建议用数据采集点的名字(如上表中的D1001)来做表名。
在TDengine的设计里,**表用来代表一个具体的数据采集点,超级表用来代表一组相同类型的数据采集点集合**。当为某个具体数据采集点创建表时,用户使用超级表的定义做模板,同时指定该具体采集点(表)的标签值。与传统的关系型数据库相比,表(一个数据采集点)是带有静态标签的,而且这些标签可以事后增加、删除、修改。**一张超级表包含有多张表,这些表具有相同的时序数据schema,但带有不同的标签值** 在TDengine的设计里,**表用来代表一个具体的数据采集点,超级表用来代表一组相同类型的数据采集点集合**。当为某个具体数据采集点创建表时,用户使用超级表的定义做模板,同时指定该具体采集点(表)的标签值。与传统的关系型数据库相比,表(一个数据采集点)是带有静态标签的,而且这些标签可以事后增加、删除、修改。**一张超级表包含有多张表,这些表具有相同的时序数据schema,但带有不同的标签值**
当对多个具有相同数据类型的数据采集点进行聚合操作时,TDengine将先把满足标签过滤条件的表从超级表的中查找出来,然后再扫描这些表的时序数据,进行聚合操作,这样能将需要扫描的数据集大幅减少,从而大幅提高聚合计算的性能。 当对多个具有相同数据类型的数据采集点进行聚合操作时,TDengine会先把满足标签过滤条件的表从超级表中找出来,然后再扫描这些表的时序数据,进行聚合操作,这样需要扫描的数据集会大幅减少,从而显著提高聚合计算的性能。
## <a class="anchor" id="cluster"></a>集群与基本逻辑单元 ## <a class="anchor" id="cluster"></a>集群与基本逻辑单元
......
...@@ -451,7 +451,8 @@ Query OK, 1 row(s) in set (0.000141s) ...@@ -451,7 +451,8 @@ Query OK, 1 row(s) in set (0.000141s)
| taos-jdbcdriver 版本 | TDengine 版本 | JDK 版本 | | taos-jdbcdriver 版本 | TDengine 版本 | JDK 版本 |
| -------------------- | ----------------- | -------- | | -------------------- | ----------------- | -------- |
| 2.0.12 及以上 | 2.0.8.0 及以上 | 1.8.x | | 2.0.22 | 2.0.18.0 及以上 | 1.8.x |
| 2.0.12 - 2.0.21 | 2.0.8.0 - 2.0.17.0 | 1.8.x |
| 2.0.4 - 2.0.11 | 2.0.0.0 - 2.0.7.x | 1.8.x | | 2.0.4 - 2.0.11 | 2.0.0.0 - 2.0.7.x | 1.8.x |
| 1.0.3 | 1.6.1.x 及以上 | 1.8.x | | 1.0.3 | 1.6.1.x 及以上 | 1.8.x |
| 1.0.2 | 1.6.1.x 及以上 | 1.8.x | | 1.0.2 | 1.6.1.x 及以上 | 1.8.x |
......
...@@ -14,6 +14,8 @@ Memory Size = maxVgroupsPerDb * (blocks * cache + 10MB) + numOfTables * (tagSize ...@@ -14,6 +14,8 @@ Memory Size = maxVgroupsPerDb * (blocks * cache + 10MB) + numOfTables * (tagSize
示例:假设是 4 核机器,cache 是缺省大小 16M, blocks 是缺省值 6,假设有 10 万张表,标签总长度是 256 字节,则总的内存需求为:4 \* (16 \* 6 + 10) + 100000 \* (0.25 + 0.5) / 1000 = 499M。 示例:假设是 4 核机器,cache 是缺省大小 16M, blocks 是缺省值 6,假设有 10 万张表,标签总长度是 256 字节,则总的内存需求为:4 \* (16 \* 6 + 10) + 100000 \* (0.25 + 0.5) / 1000 = 499M。
注意:从这个公式计算得到的内存容量,应理解为系统的“必要需求”,而不是“内存总数”。在实际运行的生产系统中,由于操作系统缓存、资源管理调度等方面的需要,内存规划应当在计算结果的基础上保留一定冗余,以维持系统状态和系统性能的稳定性。
实际运行的系统往往会根据数据特点的不同,将数据存放在不同的 DB 里。因此做规划时,也需要考虑。 实际运行的系统往往会根据数据特点的不同,将数据存放在不同的 DB 里。因此做规划时,也需要考虑。
如果内存充裕,可以加大 Blocks 的配置,这样更多数据将保存在内存里,提高查询速度。 如果内存充裕,可以加大 Blocks 的配置,这样更多数据将保存在内存里,提高查询速度。
......
...@@ -125,7 +125,7 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic ...@@ -125,7 +125,7 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic
```mysql ```mysql
ALTER DATABASE db_name CACHELAST 0; ALTER DATABASE db_name CACHELAST 0;
``` ```
CACHELAST 参数控制是否在内存中缓存数据子表的 last_row。缺省值为 0,取值范围 [0, 1]。其中 0 表示不启用、1 表示启用。(从 2.0.11 版本开始支持) CACHELAST 参数控制是否在内存中缓存数据子表的 last_row。缺省值为 0,取值范围 [0, 1]。其中 0 表示不启用、1 表示启用。(从 2.0.11 版本开始支持,修改后需要重启服务器生效。
**Tips**: 以上所有参数修改后都可以用show databases来确认是否修改成功。 **Tips**: 以上所有参数修改后都可以用show databases来确认是否修改成功。
...@@ -249,7 +249,7 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic ...@@ -249,7 +249,7 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic
3) TAGS 列名不能为预留关键字; 3) TAGS 列名不能为预留关键字;
4) TAGS 最多允许128个,至少1个,总长度不超过16k个字符 4) TAGS 最多允许 128 个,至少 1 个,总长度不超过 16 KB
- **删除超级表** - **删除超级表**
...@@ -331,7 +331,8 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic ...@@ -331,7 +331,8 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic
```mysql ```mysql
INSERT INTO tb_name VALUES (field1_value1, ...) (field1_value2, ...) ...; INSERT INTO tb_name VALUES (field1_value1, ...) (field1_value2, ...) ...;
``` ```
向表tb_name中插入多条记录 向表tb_name中插入多条记录
**注意**:在使用“插入多条记录”方式写入数据时,不能把第一列的时间戳取值都设为now,否则会导致语句中的多条记录使用相同的时间戳,于是就可能出现相互覆盖以致这些数据行无法全部被正确保存。
- **按指定的列插入多条记录** - **按指定的列插入多条记录**
```mysql ```mysql
......
...@@ -16,13 +16,13 @@ ...@@ -16,13 +16,13 @@
## 1. TDengine2.0之前的版本升级到2.0及以上的版本应该注意什么?☆☆☆ ## 1. TDengine2.0之前的版本升级到2.0及以上的版本应该注意什么?☆☆☆
2.0版在之前版本的基础上,进行了完全的重构,配置文件和数据文件是不兼容的。在升级之前务必进行如下操作: 2.0版在之前版本的基础上,进行了完全的重构,配置文件和数据文件是不兼容的。在升级之前务必进行如下操作:
1. 删除配置文件,执行 <code> sudo rm -rf /etc/taos/taos.cfg </code> 1. 删除配置文件,执行 `sudo rm -rf /etc/taos/taos.cfg`
2. 删除日志文件,执行 <code> sudo rm -rf /var/log/taos/ </code> 2. 删除日志文件,执行 `sudo rm -rf /var/log/taos/`
3. 确保数据已经不再需要的前提下,删除数据文件,执行 <code> sudo rm -rf /var/lib/taos/ </code> 3. 确保数据已经不再需要的前提下,删除数据文件,执行 `sudo rm -rf /var/lib/taos/`
4. 安装最新稳定版本的TDengine 4. 安装最新稳定版本的 TDengine
5. 如果数据需要迁移数据或者数据文件损坏,请联系涛思数据官方技术支持团队,进行协助解决 5. 如果需要迁移数据或者数据文件损坏,请联系涛思数据官方技术支持团队,进行协助解决
## 2. Windows平台下JDBCDriver找不到动态链接库,怎么办? ## 2. Windows平台下JDBCDriver找不到动态链接库,怎么办?
......
...@@ -213,10 +213,10 @@ fi ...@@ -213,10 +213,10 @@ fi
if echo $osinfo | grep -qwi "ubuntu" ; then if echo $osinfo | grep -qwi "ubuntu" ; then
# echo "this is ubuntu system" # echo "this is ubuntu system"
${csudo} rm -f /var/lib/dpkg/info/tdengine* || : ${csudo} dpkg --force-all -P tdengine || :
elif echo $osinfo | grep -qwi "debian" ; then elif echo $osinfo | grep -qwi "debian" ; then
# echo "this is debian system" # echo "this is debian system"
${csudo} rm -f /var/lib/dpkg/info/tdengine* || : ${csudo} dpkg --force-all -P tdengine || :
elif echo $osinfo | grep -qwi "centos" ; then elif echo $osinfo | grep -qwi "centos" ; then
# echo "this is centos system" # echo "this is centos system"
${csudo} rpm -e --noscripts tdengine || : ${csudo} rpm -e --noscripts tdengine || :
......
name: tdengine name: tdengine
base: core18 base: core18
version: '2.0.17.0' version: '2.0.18.0'
icon: snap/gui/t-dengine.svg icon: snap/gui/t-dengine.svg
summary: an open-source big data platform designed and optimized for IoT. summary: an open-source big data platform designed and optimized for IoT.
description: | description: |
...@@ -72,7 +72,7 @@ parts: ...@@ -72,7 +72,7 @@ parts:
- usr/bin/taosd - usr/bin/taosd
- usr/bin/taos - usr/bin/taos
- usr/bin/taosdemo - usr/bin/taosdemo
- usr/lib/libtaos.so.2.0.17.0 - usr/lib/libtaos.so.2.0.18.0
- usr/lib/libtaos.so.1 - usr/lib/libtaos.so.1
- usr/lib/libtaos.so - usr/lib/libtaos.so
......
...@@ -19,6 +19,6 @@ ADD_SUBDIRECTORY(tsdb) ...@@ -19,6 +19,6 @@ ADD_SUBDIRECTORY(tsdb)
ADD_SUBDIRECTORY(wal) ADD_SUBDIRECTORY(wal)
ADD_SUBDIRECTORY(cq) ADD_SUBDIRECTORY(cq)
ADD_SUBDIRECTORY(dnode) ADD_SUBDIRECTORY(dnode)
#ADD_SUBDIRECTORY(connector/odbc) ADD_SUBDIRECTORY(connector/odbc)
ADD_SUBDIRECTORY(connector/jdbc) ADD_SUBDIRECTORY(connector/jdbc)
...@@ -425,7 +425,7 @@ static bool bnMonitorVgroups() { ...@@ -425,7 +425,7 @@ static bool bnMonitorVgroups() {
while (1) { while (1) {
pIter = mnodeGetNextVgroup(pIter, &pVgroup); pIter = mnodeGetNextVgroup(pIter, &pVgroup);
if (pVgroup == NULL) break; if (pVgroup == NULL || pVgroup->pDb == NULL) break;
int32_t dbReplica = pVgroup->pDb->cfg.replications; int32_t dbReplica = pVgroup->pDb->cfg.replications;
int32_t vgReplica = pVgroup->numOfVnodes; int32_t vgReplica = pVgroup->numOfVnodes;
...@@ -721,4 +721,4 @@ int32_t bnAlterDnode(struct SDnodeObj *pSrcDnode, int32_t vnodeId, int32_t dnode ...@@ -721,4 +721,4 @@ int32_t bnAlterDnode(struct SDnodeObj *pSrcDnode, int32_t vnodeId, int32_t dnode
mnodeDecDnodeRef(pDestDnode); mnodeDecDnodeRef(pDestDnode);
return code; return code;
} }
\ No newline at end of file
...@@ -47,9 +47,6 @@ enum { ...@@ -47,9 +47,6 @@ enum {
DATA_FROM_DATA_FILE = 2, DATA_FROM_DATA_FILE = 2,
}; };
#define TSDB_UDF_TYPE_SCALAR 1
#define TSDB_UDF_TYPE_AGGREGATE 2
typedef void (*__async_cb_func_t)(void *param, TAOS_RES *tres, int32_t numOfRows); typedef void (*__async_cb_func_t)(void *param, TAOS_RES *tres, int32_t numOfRows);
typedef struct STableComInfo { typedef struct STableComInfo {
......
...@@ -481,15 +481,19 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_fetchRowImp(JNIEn ...@@ -481,15 +481,19 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_fetchRowImp(JNIEn
case TSDB_DATA_TYPE_BOOL: case TSDB_DATA_TYPE_BOOL:
(*env)->CallVoidMethod(env, rowobj, g_rowdataSetBooleanFp, i, (jboolean)(*((char *)row[i]) == 1)); (*env)->CallVoidMethod(env, rowobj, g_rowdataSetBooleanFp, i, (jboolean)(*((char *)row[i]) == 1));
break; break;
case TSDB_DATA_TYPE_UTINYINT:
case TSDB_DATA_TYPE_TINYINT: case TSDB_DATA_TYPE_TINYINT:
(*env)->CallVoidMethod(env, rowobj, g_rowdataSetByteFp, i, (jbyte) * ((int8_t *)row[i])); (*env)->CallVoidMethod(env, rowobj, g_rowdataSetByteFp, i, (jbyte) * ((int8_t *)row[i]));
break; break;
case TSDB_DATA_TYPE_USMALLINT:
case TSDB_DATA_TYPE_SMALLINT: case TSDB_DATA_TYPE_SMALLINT:
(*env)->CallVoidMethod(env, rowobj, g_rowdataSetShortFp, i, (jshort) * ((int16_t *)row[i])); (*env)->CallVoidMethod(env, rowobj, g_rowdataSetShortFp, i, (jshort) * ((int16_t *)row[i]));
break; break;
case TSDB_DATA_TYPE_UINT:
case TSDB_DATA_TYPE_INT: case TSDB_DATA_TYPE_INT:
(*env)->CallVoidMethod(env, rowobj, g_rowdataSetIntFp, i, (jint) * (int32_t *)row[i]); (*env)->CallVoidMethod(env, rowobj, g_rowdataSetIntFp, i, (jint) * (int32_t *)row[i]);
break; break;
case TSDB_DATA_TYPE_UBIGINT:
case TSDB_DATA_TYPE_BIGINT: case TSDB_DATA_TYPE_BIGINT:
(*env)->CallVoidMethod(env, rowobj, g_rowdataSetLongFp, i, (jlong) * ((int64_t *)row[i])); (*env)->CallVoidMethod(env, rowobj, g_rowdataSetLongFp, i, (jlong) * ((int64_t *)row[i]));
break; break;
......
...@@ -281,7 +281,7 @@ void tscQueueAsyncError(void(*fp), void *param, int32_t code) { ...@@ -281,7 +281,7 @@ void tscQueueAsyncError(void(*fp), void *param, int32_t code) {
} }
static void tscAsyncResultCallback(SSchedMsg *pMsg) { static void tscAsyncResultCallback(SSchedMsg *pMsg) {
SSqlObj* pSql = pMsg->ahandle; SSqlObj* pSql = (SSqlObj*)taosAcquireRef(tscObjRef, (int64_t)pMsg->ahandle);
if (pSql == NULL || pSql->signature != pSql) { if (pSql == NULL || pSql->signature != pSql) {
tscDebug("%p SqlObj is freed, not add into queue async res", pSql); tscDebug("%p SqlObj is freed, not add into queue async res", pSql);
return; return;
...@@ -292,23 +292,26 @@ static void tscAsyncResultCallback(SSchedMsg *pMsg) { ...@@ -292,23 +292,26 @@ static void tscAsyncResultCallback(SSchedMsg *pMsg) {
SSqlRes *pRes = &pSql->res; SSqlRes *pRes = &pSql->res;
if (pSql->fp == NULL || pSql->fetchFp == NULL){ if (pSql->fp == NULL || pSql->fetchFp == NULL){
taosReleaseRef(tscObjRef, pSql->self);
return; return;
} }
pSql->fp = pSql->fetchFp; pSql->fp = pSql->fetchFp;
(*pSql->fp)(pSql->param, pSql, pRes->code); (*pSql->fp)(pSql->param, pSql, pRes->code);
taosReleaseRef(tscObjRef, pSql->self);
} }
void tscAsyncResultOnError(SSqlObj* pSql) { void tscAsyncResultOnError(SSqlObj* pSql) {
SSchedMsg schedMsg = {0}; SSchedMsg schedMsg = {0};
schedMsg.fp = tscAsyncResultCallback; schedMsg.fp = tscAsyncResultCallback;
schedMsg.ahandle = pSql; schedMsg.ahandle = (void *)pSql->self;
schedMsg.thandle = (void *)1; schedMsg.thandle = (void *)1;
schedMsg.msg = 0; schedMsg.msg = 0;
taosScheduleTask(tscQhandle, &schedMsg); taosScheduleTask(tscQhandle, &schedMsg);
} }
int tscSendMsgToServer(SSqlObj *pSql); int tscSendMsgToServer(SSqlObj *pSql);
void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) { void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) {
......
...@@ -394,7 +394,7 @@ static int32_t tsCheckTimestamp(STableDataBlocks *pDataBlocks, const char *start ...@@ -394,7 +394,7 @@ static int32_t tsCheckTimestamp(STableDataBlocks *pDataBlocks, const char *start
TSKEY k = *(TSKEY *)start; TSKEY k = *(TSKEY *)start;
if (k == 0) { if (k == INT64_MIN) {
if (pDataBlocks->tsSource == TSDB_USE_CLI_TS) { if (pDataBlocks->tsSource == TSDB_USE_CLI_TS) {
return -1; return -1;
} else if (pDataBlocks->tsSource == -1) { } else if (pDataBlocks->tsSource == -1) {
...@@ -1360,7 +1360,7 @@ int tsParseSql(SSqlObj *pSql, bool initial) { ...@@ -1360,7 +1360,7 @@ int tsParseSql(SSqlObj *pSql, bool initial) {
} }
} }
} else { } else {
SSqlInfo SQLInfo = qSQLParse(pSql->sqlstr); SSqlInfo SQLInfo = qSqlParse(pSql->sqlstr);
ret = tscToSQLCmd(pSql, &SQLInfo); ret = tscToSQLCmd(pSql, &SQLInfo);
if (ret == TSDB_CODE_TSC_INVALID_SQL && pSql->parseRetry == 0 && SQLInfo.type == TSDB_SQL_NULL) { if (ret == TSDB_CODE_TSC_INVALID_SQL && pSql->parseRetry == 0 && SQLInfo.type == TSDB_SQL_NULL) {
tscResetSqlCmd(pCmd, true); tscResetSqlCmd(pCmd, true);
......
...@@ -261,7 +261,7 @@ static int doBindParam(char* data, SParamInfo* param, TAOS_BIND* bind) { ...@@ -261,7 +261,7 @@ static int doBindParam(char* data, SParamInfo* param, TAOS_BIND* bind) {
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
if (1) { if (0) {
// allow user bind param data with different type // allow user bind param data with different type
union { union {
int8_t v1; int8_t v1;
...@@ -1057,14 +1057,28 @@ int taos_stmt_get_param(TAOS_STMT *stmt, int idx, int *type, int *bytes) { ...@@ -1057,14 +1057,28 @@ int taos_stmt_get_param(TAOS_STMT *stmt, int idx, int *type, int *bytes) {
} }
if (pStmt->isInsert) { if (pStmt->isInsert) {
SSqlObj* pSql = pStmt->pSql; SSqlCmd* pCmd = &pStmt->pSql->cmd;
SSqlCmd *pCmd = &pSql->cmd; STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0, 0);
STableDataBlocks* pBlock = taosArrayGetP(pCmd->pDataBlocks, 0); STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
if (pCmd->pTableBlockHashList == NULL) {
pCmd->pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
}
STableDataBlocks* pBlock = NULL;
assert(pCmd->numOfParams == pBlock->numOfParams); int32_t ret =
if (idx < 0 || idx >= pBlock->numOfParams) return -1; tscGetDataBlockFromList(pCmd->pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk),
pTableMeta->tableInfo.rowSize, &pTableMetaInfo->name, pTableMeta, &pBlock, NULL);
if (ret != 0) {
// todo handle error
}
if (idx<0 || idx>=pBlock->numOfParams) {
tscError("param %d: out of range", idx);
abort();
}
SParamInfo* param = pBlock->params + idx; SParamInfo* param = &pBlock->params[idx];
if (type) *type = param->type; if (type) *type = param->type;
if (bytes) *bytes = param->bytes; if (bytes) *bytes = param->bytes;
......
此差异已折叠。
...@@ -1159,7 +1159,7 @@ SSqlExpr* tscSqlExprInsert(SQueryInfo* pQueryInfo, int32_t index, int16_t functi ...@@ -1159,7 +1159,7 @@ SSqlExpr* tscSqlExprInsert(SQueryInfo* pQueryInfo, int32_t index, int16_t functi
} }
SSqlExpr* tscSqlExprAppend(SQueryInfo* pQueryInfo, int16_t functionId, SColumnIndex* pColIndex, int16_t type, SSqlExpr* tscSqlExprAppend(SQueryInfo* pQueryInfo, int16_t functionId, SColumnIndex* pColIndex, int16_t type,
int16_t size, int16_t resColId, int16_t interSize, bool isTagCol) { int16_t size, int16_t resColId, int16_t interSize, bool isTagCol) {
SSqlExpr* pExpr = doCreateSqlExpr(pQueryInfo, functionId, pColIndex, type, size, resColId, interSize, isTagCol); SSqlExpr* pExpr = doCreateSqlExpr(pQueryInfo, functionId, pColIndex, type, size, resColId, interSize, isTagCol);
taosArrayPush(pQueryInfo->exprList, &pExpr); taosArrayPush(pQueryInfo->exprList, &pExpr);
return pExpr; return pExpr;
......
...@@ -163,6 +163,7 @@ extern float tsTotalDataDirGB; ...@@ -163,6 +163,7 @@ extern float tsTotalDataDirGB;
extern float tsAvailLogDirGB; extern float tsAvailLogDirGB;
extern float tsAvailTmpDirectorySpace; extern float tsAvailTmpDirectorySpace;
extern float tsAvailDataDirGB; extern float tsAvailDataDirGB;
extern float tsUsedDataDirGB;
extern float tsMinimalLogDirGB; extern float tsMinimalLogDirGB;
extern float tsReservedTmpDirectorySpace; extern float tsReservedTmpDirectorySpace;
extern float tsMinimalDataDirGB; extern float tsMinimalDataDirGB;
......
...@@ -41,41 +41,46 @@ static uint8_t UNUSED_FUNC isQueryOnPrimaryKey(const char *primaryColumnName, co ...@@ -41,41 +41,46 @@ static uint8_t UNUSED_FUNC isQueryOnPrimaryKey(const char *primaryColumnName, co
static void reverseCopy(char* dest, const char* src, int16_t type, int32_t numOfRows) { static void reverseCopy(char* dest, const char* src, int16_t type, int32_t numOfRows) {
switch(type) { switch(type) {
case TSDB_DATA_TYPE_TINYINT: { case TSDB_DATA_TYPE_TINYINT:
case TSDB_DATA_TYPE_UTINYINT:{
int8_t* p = (int8_t*) dest; int8_t* p = (int8_t*) dest;
int8_t* pSrc = (int8_t*) src; int8_t* pSrc = (int8_t*) src;
for(int32_t i = 0; i < numOfRows; ++i) { for(int32_t i = 0; i < numOfRows; ++i) {
p[i] = pSrc[numOfRows - i - 1]; p[i] = pSrc[numOfRows - i - 1];
} }
break; return;
} }
case TSDB_DATA_TYPE_SMALLINT: {
case TSDB_DATA_TYPE_SMALLINT:
case TSDB_DATA_TYPE_USMALLINT:{
int16_t* p = (int16_t*) dest; int16_t* p = (int16_t*) dest;
int16_t* pSrc = (int16_t*) src; int16_t* pSrc = (int16_t*) src;
for(int32_t i = 0; i < numOfRows; ++i) { for(int32_t i = 0; i < numOfRows; ++i) {
p[i] = pSrc[numOfRows - i - 1]; p[i] = pSrc[numOfRows - i - 1];
} }
break; return;
} }
case TSDB_DATA_TYPE_INT: { case TSDB_DATA_TYPE_INT:
case TSDB_DATA_TYPE_UINT: {
int32_t* p = (int32_t*) dest; int32_t* p = (int32_t*) dest;
int32_t* pSrc = (int32_t*) src; int32_t* pSrc = (int32_t*) src;
for(int32_t i = 0; i < numOfRows; ++i) { for(int32_t i = 0; i < numOfRows; ++i) {
p[i] = pSrc[numOfRows - i - 1]; p[i] = pSrc[numOfRows - i - 1];
} }
break; return;
} }
case TSDB_DATA_TYPE_BIGINT: { case TSDB_DATA_TYPE_BIGINT:
case TSDB_DATA_TYPE_UBIGINT: {
int64_t* p = (int64_t*) dest; int64_t* p = (int64_t*) dest;
int64_t* pSrc = (int64_t*) src; int64_t* pSrc = (int64_t*) src;
for(int32_t i = 0; i < numOfRows; ++i) { for(int32_t i = 0; i < numOfRows; ++i) {
p[i] = pSrc[numOfRows - i - 1]; p[i] = pSrc[numOfRows - i - 1];
} }
break; return;
} }
case TSDB_DATA_TYPE_FLOAT: { case TSDB_DATA_TYPE_FLOAT: {
float* p = (float*) dest; float* p = (float*) dest;
...@@ -84,7 +89,7 @@ static void reverseCopy(char* dest, const char* src, int16_t type, int32_t numOf ...@@ -84,7 +89,7 @@ static void reverseCopy(char* dest, const char* src, int16_t type, int32_t numOf
for(int32_t i = 0; i < numOfRows; ++i) { for(int32_t i = 0; i < numOfRows; ++i) {
p[i] = pSrc[numOfRows - i - 1]; p[i] = pSrc[numOfRows - i - 1];
} }
break; return;
} }
case TSDB_DATA_TYPE_DOUBLE: { case TSDB_DATA_TYPE_DOUBLE: {
double* p = (double*) dest; double* p = (double*) dest;
...@@ -93,7 +98,7 @@ static void reverseCopy(char* dest, const char* src, int16_t type, int32_t numOf ...@@ -93,7 +98,7 @@ static void reverseCopy(char* dest, const char* src, int16_t type, int32_t numOf
for(int32_t i = 0; i < numOfRows; ++i) { for(int32_t i = 0; i < numOfRows; ++i) {
p[i] = pSrc[numOfRows - i - 1]; p[i] = pSrc[numOfRows - i - 1];
} }
break; return;
} }
default: assert(0); default: assert(0);
} }
......
...@@ -210,6 +210,7 @@ float tsTotalTmpDirGB = 0; ...@@ -210,6 +210,7 @@ float tsTotalTmpDirGB = 0;
float tsTotalDataDirGB = 0; float tsTotalDataDirGB = 0;
float tsAvailTmpDirectorySpace = 0; float tsAvailTmpDirectorySpace = 0;
float tsAvailDataDirGB = 0; float tsAvailDataDirGB = 0;
float tsUsedDataDirGB = 0;
float tsReservedTmpDirectorySpace = 1.0f; float tsReservedTmpDirectorySpace = 1.0f;
float tsMinimalDataDirGB = 1.0f; float tsMinimalDataDirGB = 1.0f;
int32_t tsTotalMemoryMB = 0; int32_t tsTotalMemoryMB = 0;
......
...@@ -8,7 +8,7 @@ IF (TD_MVN_INSTALLED) ...@@ -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.21-dist.jar ${LIBRARY_OUTPUT_PATH} COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/target/taos-jdbcdriver-2.0.22-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 @@ ...@@ -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.21</version> <version>2.0.22</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>JDBCDriver</name> <name>JDBCDriver</name>
......
...@@ -3,7 +3,7 @@ ...@@ -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.21</version> <version>2.0.22</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>
...@@ -102,6 +102,8 @@ ...@@ -102,6 +102,8 @@
<include>**/*Test.java</include> <include>**/*Test.java</include>
</includes> </includes>
<excludes> <excludes>
<exclude>**/TSDBJNIConnectorTest.java</exclude>
<exclude>**/UnsignedNumberJniTest.java</exclude>
<exclude>**/DatetimeBefore1970Test.java</exclude> <exclude>**/DatetimeBefore1970Test.java</exclude>
<exclude>**/AppMemoryLeakTest.java</exclude> <exclude>**/AppMemoryLeakTest.java</exclude>
<exclude>**/AuthenticationTest.java</exclude> <exclude>**/AuthenticationTest.java</exclude>
......
...@@ -12,7 +12,7 @@ public abstract class AbstractDriver implements Driver { ...@@ -12,7 +12,7 @@ public abstract class AbstractDriver implements Driver {
hostProp.required = false; hostProp.required = false;
hostProp.description = "Hostname"; hostProp.description = "Hostname";
DriverPropertyInfo portProp = new DriverPropertyInfo(TSDBDriver.PROPERTY_KEY_PORT, info.getProperty(TSDBDriver.PROPERTY_KEY_PORT, TSDBConstants.DEFAULT_PORT)); DriverPropertyInfo portProp = new DriverPropertyInfo(TSDBDriver.PROPERTY_KEY_PORT, info.getProperty(TSDBDriver.PROPERTY_KEY_PORT));
portProp.required = false; portProp.required = false;
portProp.description = "Port"; portProp.description = "Port";
...@@ -40,11 +40,11 @@ public abstract class AbstractDriver implements Driver { ...@@ -40,11 +40,11 @@ public abstract class AbstractDriver implements Driver {
protected Properties parseURL(String url, Properties defaults) { protected Properties parseURL(String url, Properties defaults) {
Properties urlProps = (defaults != null) ? defaults : new Properties(); Properties urlProps = (defaults != null) ? defaults : new Properties();
// parse properties // parse properties in url
int beginningOfSlashes = url.indexOf("//"); int beginningOfSlashes = url.indexOf("//");
int index = url.indexOf("?"); int index = url.indexOf("?");
if (index != -1) { if (index != -1) {
String paramString = url.substring(index + 1, url.length()); String paramString = url.substring(index + 1);
url = url.substring(0, index); url = url.substring(0, index);
StringTokenizer queryParams = new StringTokenizer(paramString, "&"); StringTokenizer queryParams = new StringTokenizer(paramString, "&");
while (queryParams.hasMoreElements()) { while (queryParams.hasMoreElements()) {
...@@ -68,6 +68,7 @@ public abstract class AbstractDriver implements Driver { ...@@ -68,6 +68,7 @@ public abstract class AbstractDriver implements Driver {
String dbProductName = url.substring(0, beginningOfSlashes); String dbProductName = url.substring(0, beginningOfSlashes);
dbProductName = dbProductName.substring(dbProductName.indexOf(":") + 1); dbProductName = dbProductName.substring(dbProductName.indexOf(":") + 1);
dbProductName = dbProductName.substring(0, dbProductName.indexOf(":")); dbProductName = dbProductName.substring(0, dbProductName.indexOf(":"));
urlProps.setProperty(TSDBDriver.PROPERTY_KEY_PRODUCT_NAME,dbProductName);
// parse dbname // parse dbname
url = url.substring(beginningOfSlashes + 2); url = url.substring(beginningOfSlashes + 2);
int indexOfSlash = url.indexOf("/"); int indexOfSlash = url.indexOf("/");
......
...@@ -29,12 +29,7 @@ public abstract class AbstractResultSet extends WrapperImpl implements ResultSet ...@@ -29,12 +29,7 @@ public abstract class AbstractResultSet extends WrapperImpl implements ResultSet
public abstract boolean getBoolean(int columnIndex) throws SQLException; public abstract boolean getBoolean(int columnIndex) throws SQLException;
@Override @Override
public byte getByte(int columnIndex) throws SQLException { public abstract byte getByte(int columnIndex) throws SQLException;
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
}
@Override @Override
public abstract short getShort(int columnIndex) throws SQLException; public abstract short getShort(int columnIndex) throws SQLException;
...@@ -1205,6 +1200,7 @@ public abstract class AbstractResultSet extends WrapperImpl implements ResultSet ...@@ -1205,6 +1200,7 @@ public abstract class AbstractResultSet extends WrapperImpl implements ResultSet
public <T> T getObject(String columnLabel, Class<T> type) throws SQLException { public <T> T getObject(String columnLabel, Class<T> type) 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);
}
} }
...@@ -122,8 +122,7 @@ public class SavedPreparedStatement { ...@@ -122,8 +122,7 @@ public class SavedPreparedStatement {
initPreparedParam = initDefaultParam(tableName, middleParamSize, valueListSize); initPreparedParam = initDefaultParam(tableName, middleParamSize, valueListSize);
} else { } else {
// not match throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_SQL);
throw new SQLException(TSDBConstants.WrapErrMsg("the sql is not complete!"));
} }
} }
...@@ -189,7 +188,7 @@ public class SavedPreparedStatement { ...@@ -189,7 +188,7 @@ public class SavedPreparedStatement {
String errorMsg = String.format("the parameterIndex %s out of the range [1, %s]", parameterIndex, paramSize); String errorMsg = String.format("the parameterIndex %s out of the range [1, %s]", parameterIndex, paramSize);
if (parameterIndex < 1 || parameterIndex > paramSize) { if (parameterIndex < 1 || parameterIndex > paramSize) {
throw new SQLException(TSDBConstants.WrapErrMsg(errorMsg)); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE,errorMsg);
} }
this.isAddBatch = false; //set isAddBatch to false this.isAddBatch = false; //set isAddBatch to false
...@@ -212,7 +211,7 @@ public class SavedPreparedStatement { ...@@ -212,7 +211,7 @@ public class SavedPreparedStatement {
return; return;
} }
throw new SQLException(TSDBConstants.WrapErrMsg(errorMsg)); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE,errorMsg);
} }
public void addBatch() { public void addBatch() {
......
...@@ -16,16 +16,11 @@ package com.taosdata.jdbc; ...@@ -16,16 +16,11 @@ package com.taosdata.jdbc;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Types; import java.sql.Types;
import java.util.HashMap;
import java.util.Map;
public abstract class TSDBConstants { public abstract class TSDBConstants {
public static final String DEFAULT_PORT = "6200";
public static Map<Integer, String> DATATYPE_MAP = null;
public static final long JNI_NULL_POINTER = 0L; public static final long JNI_NULL_POINTER = 0L;
// JNI_ERROR_NUMBER
public static final int JNI_SUCCESS = 0; public static final int JNI_SUCCESS = 0;
public static final int JNI_TDENGINE_ERROR = -1; public static final int JNI_TDENGINE_ERROR = -1;
public static final int JNI_CONNECTION_NULL = -2; public static final int JNI_CONNECTION_NULL = -2;
...@@ -34,8 +29,7 @@ public abstract class TSDBConstants { ...@@ -34,8 +29,7 @@ public abstract class TSDBConstants {
public static final int JNI_SQL_NULL = -5; public static final int JNI_SQL_NULL = -5;
public static final int JNI_FETCH_END = -6; public static final int JNI_FETCH_END = -6;
public static final int JNI_OUT_OF_MEMORY = -7; public static final int JNI_OUT_OF_MEMORY = -7;
// TSDB Data Types
public static final int TSDB_DATA_TYPE_NULL = 0;
public static final int TSDB_DATA_TYPE_BOOL = 1; public static final int TSDB_DATA_TYPE_BOOL = 1;
public static final int TSDB_DATA_TYPE_TINYINT = 2; public static final int TSDB_DATA_TYPE_TINYINT = 2;
public static final int TSDB_DATA_TYPE_SMALLINT = 3; public static final int TSDB_DATA_TYPE_SMALLINT = 3;
...@@ -46,46 +40,36 @@ public abstract class TSDBConstants { ...@@ -46,46 +40,36 @@ public abstract class TSDBConstants {
public static final int TSDB_DATA_TYPE_BINARY = 8; public static final int TSDB_DATA_TYPE_BINARY = 8;
public static final int TSDB_DATA_TYPE_TIMESTAMP = 9; public static final int TSDB_DATA_TYPE_TIMESTAMP = 9;
public static final int TSDB_DATA_TYPE_NCHAR = 10; public static final int TSDB_DATA_TYPE_NCHAR = 10;
/*
// nchar field's max length 系统增加新的无符号数据类型,分别是:
unsigned tinyint, 数值范围:0-254, NULL 为255
unsigned smallint,数值范围: 0-65534, NULL 为65535
unsigned int,数值范围:0-4294967294,NULL 为4294967295u
unsigned bigint,数值范围:0-18446744073709551614u,NULL 为18446744073709551615u。
example:
create table tb(ts timestamp, a tinyint unsigned, b smallint unsigned, c int unsigned, d bigint unsigned);
*/
public static final int TSDB_DATA_TYPE_UTINYINT = 11; //unsigned tinyint
public static final int TSDB_DATA_TYPE_USMALLINT = 12; //unsigned smallint
public static final int TSDB_DATA_TYPE_UINT = 13; //unsigned int
public static final int TSDB_DATA_TYPE_UBIGINT = 14; //unsigned bigint
// nchar column max length
public static final int maxFieldSize = 16 * 1024; public static final int maxFieldSize = 16 * 1024;
public static String WrapErrMsg(String msg) {
return "TDengine Error: " + msg;
}
public static String FixErrMsg(int code) {
switch (code) {
case JNI_TDENGINE_ERROR:
return WrapErrMsg("internal error of database!");
case JNI_CONNECTION_NULL:
return WrapErrMsg("invalid tdengine connection!");
case JNI_RESULT_SET_NULL:
return WrapErrMsg("invalid resultset pointer!");
case JNI_NUM_OF_FIELDS_0:
return WrapErrMsg("invalid num of fields!");
case JNI_SQL_NULL:
return WrapErrMsg("can't execute empty sql!");
case JNI_FETCH_END:
return WrapErrMsg("fetch to the end of resultset");
default:
break;
}
return WrapErrMsg("unkown error!");
}
public static int taosType2JdbcType(int taosType) throws SQLException { public static int taosType2JdbcType(int taosType) throws SQLException {
switch (taosType) { switch (taosType) {
case TSDBConstants.TSDB_DATA_TYPE_NULL:
return Types.NULL;
case TSDBConstants.TSDB_DATA_TYPE_BOOL: case TSDBConstants.TSDB_DATA_TYPE_BOOL:
return Types.BOOLEAN; return Types.BOOLEAN;
case TSDBConstants.TSDB_DATA_TYPE_TINYINT: case TSDBConstants.TSDB_DATA_TYPE_TINYINT:
case TSDBConstants.TSDB_DATA_TYPE_UTINYINT:
return Types.TINYINT; return Types.TINYINT;
case TSDBConstants.TSDB_DATA_TYPE_USMALLINT:
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: case TSDBConstants.TSDB_DATA_TYPE_SMALLINT:
return Types.SMALLINT; return Types.SMALLINT;
case TSDBConstants.TSDB_DATA_TYPE_UINT:
case TSDBConstants.TSDB_DATA_TYPE_INT: case TSDBConstants.TSDB_DATA_TYPE_INT:
return Types.INTEGER; return Types.INTEGER;
case TSDBConstants.TSDB_DATA_TYPE_UBIGINT:
case TSDBConstants.TSDB_DATA_TYPE_BIGINT: case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
return Types.BIGINT; return Types.BIGINT;
case TSDBConstants.TSDB_DATA_TYPE_FLOAT: case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
...@@ -99,13 +83,42 @@ public abstract class TSDBConstants { ...@@ -99,13 +83,42 @@ public abstract class TSDBConstants {
case TSDBConstants.TSDB_DATA_TYPE_NCHAR: case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
return Types.NCHAR; return Types.NCHAR;
} }
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN_SQL_TYPE_IN_TDENGINE); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN_TAOS_TYPE_IN_TDENGINE);
}
public static String taosType2JdbcTypeName(int taosType) throws SQLException {
switch (taosType){
case TSDBConstants.TSDB_DATA_TYPE_BOOL:
return "BOOL";
case TSDBConstants.TSDB_DATA_TYPE_UTINYINT:
case TSDBConstants.TSDB_DATA_TYPE_TINYINT:
return "TINYINT";
case TSDBConstants.TSDB_DATA_TYPE_USMALLINT:
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT:
return "SMALLINT";
case TSDBConstants.TSDB_DATA_TYPE_UINT:
case TSDBConstants.TSDB_DATA_TYPE_INT:
return "INT";
case TSDBConstants.TSDB_DATA_TYPE_UBIGINT:
case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
return "BIGINT";
case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
return "FLOAT";
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE:
return "DOUBLE";
case TSDBConstants.TSDB_DATA_TYPE_BINARY:
return "BINARY";
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
return "TIMESTAMP";
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
return "NCHAR";
default:
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN_TAOS_TYPE_IN_TDENGINE);
}
} }
public static int jdbcType2TaosType(int jdbcType) throws SQLException { public static int jdbcType2TaosType(int jdbcType) throws SQLException {
switch (jdbcType){ switch (jdbcType){
case Types.NULL:
return TSDBConstants.TSDB_DATA_TYPE_NULL;
case Types.BOOLEAN: case Types.BOOLEAN:
return TSDBConstants.TSDB_DATA_TYPE_BOOL; return TSDBConstants.TSDB_DATA_TYPE_BOOL;
case Types.TINYINT: case Types.TINYINT:
...@@ -130,22 +143,31 @@ public abstract class TSDBConstants { ...@@ -130,22 +143,31 @@ public abstract class TSDBConstants {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN_SQL_TYPE_IN_TDENGINE); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN_SQL_TYPE_IN_TDENGINE);
} }
static { public static String jdbcType2TaosTypeName(int jdbcType) throws SQLException {
DATATYPE_MAP = new HashMap<>(); switch (jdbcType){
DATATYPE_MAP.put(0, "NULL"); case Types.BOOLEAN:
DATATYPE_MAP.put(1, "BOOL"); return "BOOL";
DATATYPE_MAP.put(2, "TINYINT"); case Types.TINYINT:
DATATYPE_MAP.put(3, "SMALLINT"); return "TINYINT";
DATATYPE_MAP.put(4, "INT"); case Types.SMALLINT:
DATATYPE_MAP.put(5, "BIGINT"); return "SMALLINT";
DATATYPE_MAP.put(6, "FLOAT"); case Types.INTEGER:
DATATYPE_MAP.put(7, "DOUBLE"); return "INT";
DATATYPE_MAP.put(8, "BINARY"); case Types.BIGINT:
DATATYPE_MAP.put(9, "TIMESTAMP"); return "BIGINT";
DATATYPE_MAP.put(10, "NCHAR"); case Types.FLOAT:
return "FLOAT";
case Types.DOUBLE:
return "DOUBLE";
case Types.BINARY:
return "BINARY";
case Types.TIMESTAMP:
return "TIMESTAMP";
case Types.NCHAR:
return "NCHAR";
default:
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN_SQL_TYPE_IN_TDENGINE);
}
} }
public static String jdbcType2TaosTypeName(int type) throws SQLException {
return DATATYPE_MAP.get(jdbcType2TaosType(type));
}
} }
...@@ -44,6 +44,10 @@ public class TSDBDriver extends AbstractDriver { ...@@ -44,6 +44,10 @@ public class TSDBDriver extends AbstractDriver {
private static final String URL_PREFIX = "jdbc:TAOS://"; private static final String URL_PREFIX = "jdbc:TAOS://";
/**
* PRODUCT_NAME
*/
public static final String PROPERTY_KEY_PRODUCT_NAME = "productName";
/** /**
* Key used to retrieve the host value from the properties instance passed to * Key used to retrieve the host value from the properties instance passed to
* the driver. * the driver.
...@@ -96,38 +100,34 @@ public class TSDBDriver extends AbstractDriver { ...@@ -96,38 +100,34 @@ public class TSDBDriver extends AbstractDriver {
static { static {
try { try {
java.sql.DriverManager.registerDriver(new TSDBDriver()); java.sql.DriverManager.registerDriver(new TSDBDriver());
} catch (SQLException E) { } catch (SQLException e) {
throw new RuntimeException(TSDBConstants.WrapErrMsg("can't register tdengine jdbc driver!")); throw TSDBError.createRuntimeException(TSDBErrorNumbers.ERROR_CANNOT_REGISTER_JNI_DRIVER, e);
} }
} }
public Connection connect(String url, Properties info) throws SQLException { public Connection connect(String url, Properties info) throws SQLException {
if (url == null) if (url == null)
throw new SQLException(TSDBConstants.WrapErrMsg("url is not set!")); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_URL_NOT_SET);
if (!acceptsURL(url)) if (!acceptsURL(url))
return null; return null;
Properties props = null; Properties props = parseURL(url, info);
if ((props = parseURL(url, info)) == null) { if (props == null) {
return null; return null;
} }
try { try {
TSDBJNIConnector.init((String) props.get(PROPERTY_KEY_CONFIG_DIR), (String) props.get(PROPERTY_KEY_LOCALE), TSDBJNIConnector.init((String) props.get(PROPERTY_KEY_CONFIG_DIR), (String) props.get(PROPERTY_KEY_LOCALE),
(String) props.get(PROPERTY_KEY_CHARSET), (String) props.get(PROPERTY_KEY_TIME_ZONE)); (String) props.get(PROPERTY_KEY_CHARSET), (String) props.get(PROPERTY_KEY_TIME_ZONE));
Connection newConn = new TSDBConnection(props, this.dbMetaData); return new TSDBConnection(props, this.dbMetaData);
return newConn;
} catch (SQLWarning sqlWarning) { } catch (SQLWarning sqlWarning) {
sqlWarning.printStackTrace(); sqlWarning.printStackTrace();
Connection newConn = new TSDBConnection(props, this.dbMetaData); return new TSDBConnection(props, this.dbMetaData);
return newConn;
} catch (SQLException sqlEx) { } catch (SQLException sqlEx) {
throw sqlEx; throw sqlEx;
} catch (Exception ex) { } catch (Exception ex) {
SQLException sqlEx = new SQLException("SQLException:" + ex.toString()); throw new SQLException("SQLException:" + ex.toString(), ex);
sqlEx.initCause(ex);
throw sqlEx;
} }
} }
...@@ -139,8 +139,8 @@ public class TSDBDriver extends AbstractDriver { ...@@ -139,8 +139,8 @@ public class TSDBDriver extends AbstractDriver {
*/ */
public boolean acceptsURL(String url) throws SQLException { public boolean acceptsURL(String url) throws SQLException {
if (url == null) if (url == null)
throw new SQLException(TSDBConstants.WrapErrMsg("url is null")); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_URL_NOT_SET);
return (url != null && url.length() > 0 && url.trim().length() > 0) && (url.startsWith(URL_PREFIX) || url.startsWith(URL_PREFIX1)); return url.length() > 0 && url.trim().length() > 0 && (url.startsWith(URL_PREFIX) || url.startsWith(URL_PREFIX1));
} }
public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException { public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException {
......
...@@ -3,6 +3,7 @@ package com.taosdata.jdbc; ...@@ -3,6 +3,7 @@ package com.taosdata.jdbc;
import java.sql.SQLClientInfoException; import java.sql.SQLClientInfoException;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException; import java.sql.SQLFeatureNotSupportedException;
import java.sql.SQLWarning;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
...@@ -18,18 +19,25 @@ public class TSDBError { ...@@ -18,18 +19,25 @@ public class TSDBError {
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_BATCH_IS_EMPTY, "Batch is empty!"); TSDBErrorMap.put(TSDBErrorNumbers.ERROR_BATCH_IS_EMPTY, "Batch is empty!");
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_INVALID_WITH_EXECUTEQUERY, "Can not issue data manipulation statements with executeQuery()"); TSDBErrorMap.put(TSDBErrorNumbers.ERROR_INVALID_WITH_EXECUTEQUERY, "Can not issue data manipulation statements with executeQuery()");
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_INVALID_WITH_EXECUTEUPDATE, "Can not issue SELECT via executeUpdate()"); TSDBErrorMap.put(TSDBErrorNumbers.ERROR_INVALID_WITH_EXECUTEUPDATE, "Can not issue SELECT via executeUpdate()");
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_INVALID_FOR_EXECUTE_QUERY, "not a valid sql for executeQuery: (?)"); TSDBErrorMap.put(TSDBErrorNumbers.ERROR_INVALID_FOR_EXECUTE_QUERY, "invalid sql for executeQuery: (?)");
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_DATABASE_NOT_SPECIFIED_OR_AVAILABLE, "Database not specified or available"); TSDBErrorMap.put(TSDBErrorNumbers.ERROR_DATABASE_NOT_SPECIFIED_OR_AVAILABLE, "Database not specified or available");
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_INVALID_FOR_EXECUTE_UPDATE, "not a valid sql for executeUpdate: (?)"); TSDBErrorMap.put(TSDBErrorNumbers.ERROR_INVALID_FOR_EXECUTE_UPDATE, "invalid sql for executeUpdate: (?)");
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_INVALID_FOR_EXECUTE, "not a valid sql for execute: (?)"); TSDBErrorMap.put(TSDBErrorNumbers.ERROR_INVALID_FOR_EXECUTE, "invalid sql for execute: (?)");
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE, "parameter index out of range"); TSDBErrorMap.put(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE, "parameter index out of range");
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_SQLCLIENT_EXCEPTION_ON_CONNECTION_CLOSED, "connection already closed"); TSDBErrorMap.put(TSDBErrorNumbers.ERROR_SQLCLIENT_EXCEPTION_ON_CONNECTION_CLOSED, "connection already closed");
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_UNKNOWN_SQL_TYPE_IN_TDENGINE, "unknown sql type in tdengine");
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_CANNOT_REGISTER_JNI_DRIVER, "can't register JDBC-JNI driver");
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_CANNOT_REGISTER_RESTFUL_DRIVER, "can't register JDBC-RESTful driver");
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_URL_NOT_SET, "url is not set");
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_INVALID_SQL, "invalid sql");
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE, "numeric value out of range");
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_UNKNOWN_TAOS_TYPE_IN_TDENGINE, "unknown taos type in tdengine");
/**************************************************/ /**************************************************/
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_UNKNOWN, "unknown error"); TSDBErrorMap.put(TSDBErrorNumbers.ERROR_UNKNOWN, "unknown error");
/**************************************************/ /**************************************************/
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_SUBSCRIBE_FAILED, "failed to create subscription"); TSDBErrorMap.put(TSDBErrorNumbers.ERROR_SUBSCRIBE_FAILED, "failed to create subscription");
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_UNSUPPORTED_ENCODING, "Unsupported encoding"); TSDBErrorMap.put(TSDBErrorNumbers.ERROR_UNSUPPORTED_ENCODING, "Unsupported encoding");
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_JNI_TDENGINE_ERROR, "internal error of database"); TSDBErrorMap.put(TSDBErrorNumbers.ERROR_JNI_TDENGINE_ERROR, "internal error of database");
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL, "JNI connection is NULL"); TSDBErrorMap.put(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL, "JNI connection is NULL");
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_JNI_RESULT_SET_NULL, "JNI result set is NULL"); TSDBErrorMap.put(TSDBErrorNumbers.ERROR_JNI_RESULT_SET_NULL, "JNI result set is NULL");
...@@ -65,4 +73,12 @@ public class TSDBError { ...@@ -65,4 +73,12 @@ public class TSDBError {
return new SQLException("TDengine ERROR (" + Integer.toHexString(errorCode) + "): " + message, "", errorCode); return new SQLException("TDengine ERROR (" + Integer.toHexString(errorCode) + "): " + message, "", errorCode);
} }
} public static RuntimeException createRuntimeException(int errorCode, Throwable t) {
String message = TSDBErrorMap.get(errorCode);
return new RuntimeException("ERROR (" + Integer.toHexString(errorCode) + "): " + message, t);
}
public static SQLWarning createSQLWarning(String message) {
return new SQLWarning(message);
}
}
\ No newline at end of file
...@@ -16,15 +16,20 @@ public class TSDBErrorNumbers { ...@@ -16,15 +16,20 @@ public class TSDBErrorNumbers {
public static final int ERROR_DATABASE_NOT_SPECIFIED_OR_AVAILABLE = 0x230a; //Database not specified or available public static final int ERROR_DATABASE_NOT_SPECIFIED_OR_AVAILABLE = 0x230a; //Database not specified or available
public static final int ERROR_INVALID_FOR_EXECUTE_UPDATE = 0x230b; //not a valid sql for executeUpdate: (SQL) public static final int ERROR_INVALID_FOR_EXECUTE_UPDATE = 0x230b; //not a valid sql for executeUpdate: (SQL)
public static final int ERROR_INVALID_FOR_EXECUTE = 0x230c; //not a valid sql for execute: (SQL) public static final int ERROR_INVALID_FOR_EXECUTE = 0x230c; //not a valid sql for execute: (SQL)
public static final int ERROR_PARAMETER_INDEX_OUT_RANGE = 0x230d; // parameter index out of range public static final int ERROR_PARAMETER_INDEX_OUT_RANGE = 0x230d; // parameter index out of range
public static final int ERROR_SQLCLIENT_EXCEPTION_ON_CONNECTION_CLOSED = 0x230e; // connection already closed public static final int ERROR_SQLCLIENT_EXCEPTION_ON_CONNECTION_CLOSED = 0x230e; // connection already closed
public static final int ERROR_UNKNOWN_SQL_TYPE_IN_TDENGINE = 0x230f; //unknown sql type in tdengine public static final int ERROR_UNKNOWN_SQL_TYPE_IN_TDENGINE = 0x230f; //unknown sql type in tdengine
public static final int ERROR_CANNOT_REGISTER_JNI_DRIVER = 0x2310; // can't register JDBC-JNI driver
public static final int ERROR_CANNOT_REGISTER_RESTFUL_DRIVER = 0x2311; // can't register JDBC-RESTful driver
public static final int ERROR_URL_NOT_SET = 0x2312; // url is not set
public static final int ERROR_INVALID_SQL = 0x2313; // invalid sql
public static final int ERROR_NUMERIC_VALUE_OUT_OF_RANGE = 0x2314; // numeric value out of range
public static final int ERROR_UNKNOWN_TAOS_TYPE_IN_TDENGINE = 0x2315; //unknown taos type in tdengine
public static final int ERROR_UNKNOWN = 0x2350; //unknown error public static final int ERROR_UNKNOWN = 0x2350; //unknown error
public static final int ERROR_SUBSCRIBE_FAILED = 0x2351; // failed to create subscription public static final int ERROR_SUBSCRIBE_FAILED = 0x2351; // failed to create subscription
public static final int ERROR_UNSUPPORTED_ENCODING = 0x2352; // Unsupported encoding public static final int ERROR_UNSUPPORTED_ENCODING = 0x2352; // Unsupported encoding
public static final int ERROR_JNI_TDENGINE_ERROR = 0x2353; // internal error of database public static final int ERROR_JNI_TDENGINE_ERROR = 0x2353; // internal error of database
public static final int ERROR_JNI_CONNECTION_NULL = 0x2354; // JNI connection is NULL public static final int ERROR_JNI_CONNECTION_NULL = 0x2354; // JNI connection is NULL
public static final int ERROR_JNI_RESULT_SET_NULL = 0x2355; // invalid JNI result set public static final int ERROR_JNI_RESULT_SET_NULL = 0x2355; // invalid JNI result set
...@@ -51,11 +56,16 @@ public class TSDBErrorNumbers { ...@@ -51,11 +56,16 @@ public class TSDBErrorNumbers {
errorNumbers.add(ERROR_PARAMETER_INDEX_OUT_RANGE); errorNumbers.add(ERROR_PARAMETER_INDEX_OUT_RANGE);
errorNumbers.add(ERROR_SQLCLIENT_EXCEPTION_ON_CONNECTION_CLOSED); errorNumbers.add(ERROR_SQLCLIENT_EXCEPTION_ON_CONNECTION_CLOSED);
errorNumbers.add(ERROR_UNKNOWN_SQL_TYPE_IN_TDENGINE); errorNumbers.add(ERROR_UNKNOWN_SQL_TYPE_IN_TDENGINE);
errorNumbers.add(ERROR_CANNOT_REGISTER_JNI_DRIVER);
errorNumbers.add(ERROR_CANNOT_REGISTER_RESTFUL_DRIVER);
errorNumbers.add(ERROR_URL_NOT_SET);
errorNumbers.add(ERROR_INVALID_SQL);
errorNumbers.add(ERROR_NUMERIC_VALUE_OUT_OF_RANGE);
errorNumbers.add(ERROR_UNKNOWN_TAOS_TYPE_IN_TDENGINE);
/*****************************************************/ /*****************************************************/
errorNumbers.add(ERROR_SUBSCRIBE_FAILED); errorNumbers.add(ERROR_SUBSCRIBE_FAILED);
errorNumbers.add(ERROR_UNSUPPORTED_ENCODING); errorNumbers.add(ERROR_UNSUPPORTED_ENCODING);
errorNumbers.add(ERROR_JNI_TDENGINE_ERROR); errorNumbers.add(ERROR_JNI_TDENGINE_ERROR);
errorNumbers.add(ERROR_JNI_CONNECTION_NULL); errorNumbers.add(ERROR_JNI_CONNECTION_NULL);
errorNumbers.add(ERROR_JNI_RESULT_SET_NULL); errorNumbers.add(ERROR_JNI_RESULT_SET_NULL);
...@@ -63,7 +73,6 @@ public class TSDBErrorNumbers { ...@@ -63,7 +73,6 @@ public class TSDBErrorNumbers {
errorNumbers.add(ERROR_JNI_SQL_NULL); errorNumbers.add(ERROR_JNI_SQL_NULL);
errorNumbers.add(ERROR_JNI_FETCH_END); errorNumbers.add(ERROR_JNI_FETCH_END);
errorNumbers.add(ERROR_JNI_OUT_OF_MEMORY); errorNumbers.add(ERROR_JNI_OUT_OF_MEMORY);
} }
private TSDBErrorNumbers() { private TSDBErrorNumbers() {
......
/** /**
* ************************************************************************* * *************************************************************************
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com> * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
* * <p>
* This program is free software: you can use, redistribute, and/or modify * 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 * it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation. * or later ("AGPL"), as published by the Free Software Foundation.
* * <p>
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. * FITNESS FOR A PARTICULAR PURPOSE.
* * <p>
* You should have received a copy of the GNU Affero General Public License * 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/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
**************************************************************************** */ * ***************************************************************************
*/
package com.taosdata.jdbc; package com.taosdata.jdbc;
import com.taosdata.jdbc.utils.TaosInfo; import com.taosdata.jdbc.utils.TaosInfo;
...@@ -23,7 +24,7 @@ import java.util.List; ...@@ -23,7 +24,7 @@ import java.util.List;
/** /**
* JNI connector * JNI connector
* */ */
public class TSDBJNIConnector { public class TSDBJNIConnector {
private static volatile Boolean isInitialized = false; private static volatile Boolean isInitialized = false;
...@@ -72,13 +73,13 @@ public class TSDBJNIConnector { ...@@ -72,13 +73,13 @@ public class TSDBJNIConnector {
if (!isInitialized) { if (!isInitialized) {
initImp(configDir); initImp(configDir);
if (setOptions(0, locale) < 0) { if (setOptions(0, locale) < 0) {
throw new SQLWarning(TSDBConstants.WrapErrMsg("Failed to set locale: " + locale + ". System default will be used.")); throw TSDBError.createSQLWarning("Failed to set locale: " + locale + ". System default will be used.");
} }
if (setOptions(1, charset) < 0) { if (setOptions(1, charset) < 0) {
throw new SQLWarning(TSDBConstants.WrapErrMsg("Failed to set charset: " + charset + ". System default will be used.")); throw TSDBError.createSQLWarning("Failed to set charset: " + charset + ". System default will be used.");
} }
if (setOptions(2, timezone) < 0) { if (setOptions(2, timezone) < 0) {
throw new SQLWarning(TSDBConstants.WrapErrMsg("Failed to set timezone: " + timezone + ". System default will be used.")); throw TSDBError.createSQLWarning("Failed to set timezone: " + timezone + ". System default will be used.");
} }
isInitialized = true; isInitialized = true;
TaosGlobalConfig.setCharset(getTsCharset()); TaosGlobalConfig.setCharset(getTsCharset());
......
...@@ -27,8 +27,8 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { ...@@ -27,8 +27,8 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
private final TSDBResultSetRowData rowData; private final TSDBResultSetRowData rowData;
private final TSDBResultSetBlockData blockData; private final TSDBResultSetBlockData blockData;
private boolean batchFetch = false; private boolean batchFetch;
private boolean lastWasNull = false; private boolean lastWasNull;
private boolean isClosed; private boolean isClosed;
public void setBatchFetch(boolean batchFetch) { public void setBatchFetch(boolean batchFetch) {
...@@ -86,7 +86,6 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { ...@@ -86,7 +86,6 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
if (rowData != null) { if (rowData != null) {
this.rowData.clear(); this.rowData.clear();
} }
int code = this.jniConnector.fetchRow(this.resultSetPointer, this.rowData); int code = this.jniConnector.fetchRow(this.resultSetPointer, this.rowData);
if (code == TSDBConstants.JNI_CONNECTION_NULL) { if (code == TSDBConstants.JNI_CONNECTION_NULL) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL);
...@@ -124,30 +123,27 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { ...@@ -124,30 +123,27 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
String res = null; String res = null;
int colIndex = getTrueColumnIndex(columnIndex); int colIndex = getTrueColumnIndex(columnIndex);
if (!this.getBatchFetch()) { if (this.getBatchFetch())
this.lastWasNull = this.rowData.wasNull(colIndex);
if (!lastWasNull) {
res = this.rowData.getString(colIndex, this.columnMetaDataList.get(colIndex).getColType());
}
return res;
} else {
return this.blockData.getString(colIndex); return this.blockData.getString(colIndex);
this.lastWasNull = this.rowData.wasNull(colIndex);
if (!lastWasNull) {
res = this.rowData.getString(colIndex, this.columnMetaDataList.get(colIndex).getColType());
} }
return res;
} }
public boolean getBoolean(int columnIndex) throws SQLException { public boolean getBoolean(int columnIndex) throws SQLException {
boolean res = false; boolean res = false;
int colIndex = getTrueColumnIndex(columnIndex); int colIndex = getTrueColumnIndex(columnIndex);
if (!this.getBatchFetch()) { if (this.getBatchFetch())
this.lastWasNull = this.rowData.wasNull(colIndex);
if (!lastWasNull) {
res = this.rowData.getBoolean(colIndex, this.columnMetaDataList.get(colIndex).getColType());
}
} else {
return this.blockData.getBoolean(colIndex); return this.blockData.getBoolean(colIndex);
}
this.lastWasNull = this.rowData.wasNull(colIndex);
if (!lastWasNull) {
res = this.rowData.getBoolean(colIndex, this.columnMetaDataList.get(colIndex).getColType());
}
return res; return res;
} }
...@@ -155,91 +151,84 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { ...@@ -155,91 +151,84 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
byte res = 0; byte res = 0;
int colIndex = getTrueColumnIndex(columnIndex); int colIndex = getTrueColumnIndex(columnIndex);
if (!this.getBatchFetch()) { if (this.getBatchFetch())
this.lastWasNull = this.rowData.wasNull(colIndex);
if (!lastWasNull) {
res = (byte) this.rowData.getInt(colIndex, this.columnMetaDataList.get(colIndex).getColType());
}
return res;
} else {
return (byte) this.blockData.getInt(colIndex); return (byte) this.blockData.getInt(colIndex);
this.lastWasNull = this.rowData.wasNull(colIndex);
if (!lastWasNull) {
res = (byte) this.rowData.getInt(colIndex, this.columnMetaDataList.get(colIndex).getColType());
} }
return res;
} }
public short getShort(int columnIndex) throws SQLException { public short getShort(int columnIndex) throws SQLException {
short res = 0; short res = 0;
int colIndex = getTrueColumnIndex(columnIndex); int colIndex = getTrueColumnIndex(columnIndex);
if (!this.getBatchFetch()) { if (this.getBatchFetch())
this.lastWasNull = this.rowData.wasNull(colIndex);
if (!lastWasNull) {
res = (short) this.rowData.getInt(colIndex, this.columnMetaDataList.get(colIndex).getColType());
}
return res;
} else {
return (short) this.blockData.getInt(colIndex); return (short) this.blockData.getInt(colIndex);
this.lastWasNull = this.rowData.wasNull(colIndex);
if (!lastWasNull) {
res = (short) this.rowData.getInt(colIndex, this.columnMetaDataList.get(colIndex).getColType());
} }
return res;
} }
public int getInt(int columnIndex) throws SQLException { public int getInt(int columnIndex) throws SQLException {
int res = 0; int res = 0;
int colIndex = getTrueColumnIndex(columnIndex); int colIndex = getTrueColumnIndex(columnIndex);
if (!this.getBatchFetch()) { if (this.getBatchFetch())
this.lastWasNull = this.rowData.wasNull(colIndex);
if (!lastWasNull) {
res = this.rowData.getInt(colIndex, this.columnMetaDataList.get(colIndex).getColType());
}
return res;
} else {
return this.blockData.getInt(colIndex); return this.blockData.getInt(colIndex);
}
this.lastWasNull = this.rowData.wasNull(colIndex);
if (!lastWasNull) {
res = this.rowData.getInt(colIndex, this.columnMetaDataList.get(colIndex).getColType());
}
return res;
} }
public long getLong(int columnIndex) throws SQLException { public long getLong(int columnIndex) throws SQLException {
long res = 0L; long res = 0L;
int colIndex = getTrueColumnIndex(columnIndex); int colIndex = getTrueColumnIndex(columnIndex);
if (!this.getBatchFetch()) { if (this.getBatchFetch())
this.lastWasNull = this.rowData.wasNull(colIndex);
if (!lastWasNull) {
res = this.rowData.getLong(colIndex, this.columnMetaDataList.get(colIndex).getColType());
}
return res;
} else {
return this.blockData.getLong(colIndex); return this.blockData.getLong(colIndex);
this.lastWasNull = this.rowData.wasNull(colIndex);
if (!lastWasNull) {
res = this.rowData.getLong(colIndex, this.columnMetaDataList.get(colIndex).getColType());
} }
return res;
} }
public float getFloat(int columnIndex) throws SQLException { public float getFloat(int columnIndex) throws SQLException {
float res = 0; float res = 0;
int colIndex = getTrueColumnIndex(columnIndex); int colIndex = getTrueColumnIndex(columnIndex);
if (!this.getBatchFetch()) { if (this.getBatchFetch())
this.lastWasNull = this.rowData.wasNull(colIndex);
if (!lastWasNull) {
res = this.rowData.getFloat(colIndex, this.columnMetaDataList.get(colIndex).getColType());
}
return res;
} else {
return (float) this.blockData.getDouble(colIndex); return (float) this.blockData.getDouble(colIndex);
}
this.lastWasNull = this.rowData.wasNull(colIndex);
if (!lastWasNull)
res = this.rowData.getFloat(colIndex, this.columnMetaDataList.get(colIndex).getColType());
return res;
} }
public double getDouble(int columnIndex) throws SQLException { public double getDouble(int columnIndex) throws SQLException {
double res = 0; double res = 0;
int colIndex = getTrueColumnIndex(columnIndex); int colIndex = getTrueColumnIndex(columnIndex);
if (!this.getBatchFetch()) { if (this.getBatchFetch())
this.lastWasNull = this.rowData.wasNull(colIndex);
if (!lastWasNull) {
res = this.rowData.getDouble(colIndex, this.columnMetaDataList.get(colIndex).getColType());
}
return res;
} else {
return this.blockData.getDouble(colIndex); return this.blockData.getDouble(colIndex);
this.lastWasNull = this.rowData.wasNull(colIndex);
if (!lastWasNull) {
res = this.rowData.getDouble(colIndex, this.columnMetaDataList.get(colIndex).getColType());
} }
return res;
} }
@Deprecated @Deprecated
...@@ -255,15 +244,14 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { ...@@ -255,15 +244,14 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
Timestamp res = null; Timestamp res = null;
int colIndex = getTrueColumnIndex(columnIndex); int colIndex = getTrueColumnIndex(columnIndex);
if (!this.getBatchFetch()) { if (this.getBatchFetch())
this.lastWasNull = this.rowData.wasNull(colIndex);
if (!lastWasNull) {
res = this.rowData.getTimestamp(colIndex);
}
return res;
} else {
return this.blockData.getTimestamp(columnIndex); return this.blockData.getTimestamp(columnIndex);
this.lastWasNull = this.rowData.wasNull(colIndex);
if (!lastWasNull) {
res = this.rowData.getTimestamp(colIndex);
} }
return res;
} }
public ResultSetMetaData getMetaData() throws SQLException { public ResultSetMetaData getMetaData() throws SQLException {
...@@ -274,12 +262,11 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { ...@@ -274,12 +262,11 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
public Object getObject(int columnIndex) throws SQLException { public Object getObject(int columnIndex) throws SQLException {
int colIndex = getTrueColumnIndex(columnIndex); int colIndex = getTrueColumnIndex(columnIndex);
if (!this.getBatchFetch()) { if (this.getBatchFetch())
this.lastWasNull = this.rowData.wasNull(colIndex);
return this.rowData.get(colIndex);
} else {
return this.blockData.get(colIndex); return this.blockData.get(colIndex);
}
this.lastWasNull = this.rowData.wasNull(colIndex);
return this.rowData.get(colIndex);
} }
@Override @Override
......
...@@ -126,34 +126,12 @@ public class TSDBResultSetMetaData extends WrapperImpl implements ResultSetMetaD ...@@ -126,34 +126,12 @@ public class TSDBResultSetMetaData extends WrapperImpl implements ResultSetMetaD
public int getColumnType(int column) throws SQLException { public int getColumnType(int column) throws SQLException {
ColumnMetaData meta = this.colMetaDataList.get(column - 1); ColumnMetaData meta = this.colMetaDataList.get(column - 1);
switch (meta.getColType()) { return TSDBConstants.taosType2JdbcType(meta.getColType());
case TSDBConstants.TSDB_DATA_TYPE_BOOL:
return Types.BOOLEAN;
case TSDBConstants.TSDB_DATA_TYPE_TINYINT:
return java.sql.Types.TINYINT;
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT:
return java.sql.Types.SMALLINT;
case TSDBConstants.TSDB_DATA_TYPE_INT:
return java.sql.Types.INTEGER;
case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
return java.sql.Types.BIGINT;
case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
return java.sql.Types.FLOAT;
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE:
return java.sql.Types.DOUBLE;
case TSDBConstants.TSDB_DATA_TYPE_BINARY:
return Types.BINARY;
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
return java.sql.Types.TIMESTAMP;
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
return Types.NCHAR;
}
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_VARIABLE);
} }
public String getColumnTypeName(int column) throws SQLException { public String getColumnTypeName(int column) throws SQLException {
ColumnMetaData meta = this.colMetaDataList.get(column - 1); ColumnMetaData meta = this.colMetaDataList.get(column - 1);
return TSDBConstants.DATATYPE_MAP.get(meta.getColType()); return TSDBConstants.taosType2JdbcTypeName(meta.getColType());
} }
public boolean isReadOnly(int column) throws SQLException { public boolean isReadOnly(int column) throws SQLException {
......
...@@ -14,208 +14,322 @@ ...@@ -14,208 +14,322 @@
*****************************************************************************/ *****************************************************************************/
package com.taosdata.jdbc; package com.taosdata.jdbc;
import java.math.BigDecimal;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.util.ArrayList; 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 = null;
private int colSize = 0; private int colSize = 0;
public TSDBResultSetRowData(int colSize) { public TSDBResultSetRowData(int colSize) {
this.setColSize(colSize); this.setColSize(colSize);
} }
public TSDBResultSetRowData() { public TSDBResultSetRowData() {
this.data = new ArrayList<>(); this.data = new ArrayList<>();
this.setColSize(0); this.setColSize(0);
} }
public void clear() { public void clear() {
if(this.data != null) { if (this.data != null) {
this.data.clear(); this.data.clear();
} }
if (this.colSize == 0) { if (this.colSize == 0) {
return; return;
} }
this.data = new ArrayList<>(colSize); this.data = new ArrayList<>(colSize);
this.data.addAll(Collections.nCopies(this.colSize, null)); this.data.addAll(Collections.nCopies(this.colSize, null));
} }
public boolean wasNull(int col) { public boolean wasNull(int col) {
return data.get(col) == null; return data.get(col) == null;
} }
public void setBoolean(int col, boolean value) { public void setBoolean(int col, boolean value) {
data.set(col, value); data.set(col, value);
} }
public boolean getBoolean(int col, int srcType) throws SQLException { public boolean getBoolean(int col, int srcType) throws SQLException {
Object obj = data.get(col); Object obj = data.get(col);
switch(srcType) { switch (srcType) {
case TSDBConstants.TSDB_DATA_TYPE_BOOL: return (Boolean) obj; case TSDBConstants.TSDB_DATA_TYPE_BOOL:
case TSDBConstants.TSDB_DATA_TYPE_FLOAT: return ((Float) obj) == 1.0? Boolean.TRUE:Boolean.FALSE; return (Boolean) obj;
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: return ((Double) obj) == 1.0? Boolean.TRUE:Boolean.FALSE; case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
case TSDBConstants.TSDB_DATA_TYPE_TINYINT: return ((Byte) obj) == 1? Boolean.TRUE:Boolean.FALSE; return ((Float) obj) == 1.0 ? Boolean.TRUE : Boolean.FALSE;
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT:return ((Short)obj) == 1? Boolean.TRUE:Boolean.FALSE; case TSDBConstants.TSDB_DATA_TYPE_DOUBLE:
case TSDBConstants.TSDB_DATA_TYPE_INT: return ((Integer)obj) == 1? Boolean.TRUE:Boolean.FALSE; return ((Double) obj) == 1.0 ? Boolean.TRUE : Boolean.FALSE;
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: case TSDBConstants.TSDB_DATA_TYPE_TINYINT:
case TSDBConstants.TSDB_DATA_TYPE_BIGINT: return ((Long) obj) == 1L? Boolean.TRUE:Boolean.FALSE; return ((Byte) obj) == 1 ? Boolean.TRUE : Boolean.FALSE;
} case TSDBConstants.TSDB_DATA_TYPE_SMALLINT:
return ((Short) obj) == 1 ? Boolean.TRUE : Boolean.FALSE;
return Boolean.TRUE; case TSDBConstants.TSDB_DATA_TYPE_INT:
} return ((Integer) obj) == 1 ? Boolean.TRUE : Boolean.FALSE;
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
public void setByte(int col, byte value) { case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
data.set(col, value); return ((Long) obj) == 1L ? Boolean.TRUE : Boolean.FALSE;
} }
public void setShort(int col, short value) { return Boolean.TRUE;
data.set(col, value); }
}
public void setByte(int col, byte value) {
public void setInt(int col, int value) { data.set(col, value);
data.set(col, value); }
}
public void setShort(int col, short value) {
public int getInt(int col, int srcType) throws SQLException { data.set(col, value);
Object obj = data.get(col); }
switch(srcType) { public void setInt(int col, int value) {
case TSDBConstants.TSDB_DATA_TYPE_BOOL: return Boolean.TRUE.equals(obj)? 1:0; data.set(col, value);
case TSDBConstants.TSDB_DATA_TYPE_FLOAT: return ((Float) obj).intValue(); }
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: return ((Double)obj).intValue();
case TSDBConstants.TSDB_DATA_TYPE_TINYINT: return (Byte) obj; public int getInt(int col, int srcType) throws SQLException {
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT:return (Short) obj; Object obj = data.get(col);
case TSDBConstants.TSDB_DATA_TYPE_INT: return (Integer) obj;
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: switch (srcType) {
case TSDBConstants.TSDB_DATA_TYPE_BIGINT: return ((Long) obj).intValue(); case TSDBConstants.TSDB_DATA_TYPE_BOOL:
case TSDBConstants.TSDB_DATA_TYPE_NCHAR: return Boolean.TRUE.equals(obj) ? 1 : 0;
case TSDBConstants.TSDB_DATA_TYPE_BINARY: return Integer.parseInt((String) obj); case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
} return ((Float) obj).intValue();
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE:
return 0; return ((Double) obj).intValue();
} case TSDBConstants.TSDB_DATA_TYPE_TINYINT:
return (Byte) obj;
public void setLong(int col, long value) { case TSDBConstants.TSDB_DATA_TYPE_SMALLINT:
data.set(col, value); return (Short) obj;
} case TSDBConstants.TSDB_DATA_TYPE_INT:
return (Integer) obj;
public long getLong(int col, int srcType) throws SQLException { case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
Object obj = data.get(col); case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
return ((Long) obj).intValue();
switch(srcType) { case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
case TSDBConstants.TSDB_DATA_TYPE_BOOL: return Boolean.TRUE.equals(obj)? 1:0; case TSDBConstants.TSDB_DATA_TYPE_BINARY:
case TSDBConstants.TSDB_DATA_TYPE_FLOAT: return ((Float) obj).longValue(); return Integer.parseInt((String) obj);
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: return ((Double) obj).longValue(); case TSDBConstants.TSDB_DATA_TYPE_UTINYINT: {
case TSDBConstants.TSDB_DATA_TYPE_TINYINT: return (Byte) obj; Byte value = (byte) obj;
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT:return (Short) obj; if (value < 0)
case TSDBConstants.TSDB_DATA_TYPE_INT: return (Integer) obj; throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE);
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: return value;
case TSDBConstants.TSDB_DATA_TYPE_BIGINT: return (Long) obj; }
case TSDBConstants.TSDB_DATA_TYPE_NCHAR: case TSDBConstants.TSDB_DATA_TYPE_USMALLINT: {
case TSDBConstants.TSDB_DATA_TYPE_BINARY: return Long.parseLong((String) obj); short value = (short) obj;
} if (value < 0)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE);
return 0; return value;
} }
case TSDBConstants.TSDB_DATA_TYPE_UINT: {
public void setFloat(int col, float value) { int value = (int) obj;
data.set(col, value); if (value < 0)
} throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE);
return value;
public float getFloat(int col, int srcType) throws SQLException { }
Object obj = data.get(col); case TSDBConstants.TSDB_DATA_TYPE_UBIGINT: {
long value = (long) obj;
switch(srcType) { if (value < 0)
case TSDBConstants.TSDB_DATA_TYPE_BOOL: return Boolean.TRUE.equals(obj)? 1:0; throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE);
case TSDBConstants.TSDB_DATA_TYPE_FLOAT: return (Float) obj; return new Long(value).intValue();
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: return ((Double) obj).floatValue(); }
case TSDBConstants.TSDB_DATA_TYPE_TINYINT: return (Byte) obj; }
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: return (Short) obj;
case TSDBConstants.TSDB_DATA_TYPE_INT: return (Integer) obj; return 0;
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: }
case TSDBConstants.TSDB_DATA_TYPE_BIGINT: return (Long) obj;
} public void setLong(int col, long value) {
data.set(col, value);
return 0; }
}
public long getLong(int col, int srcType) throws SQLException {
public void setDouble(int col, double value) { Object obj = data.get(col);
data.set(col, value);
} switch (srcType) {
case TSDBConstants.TSDB_DATA_TYPE_BOOL:
public double getDouble(int col, int srcType) throws SQLException { return Boolean.TRUE.equals(obj) ? 1 : 0;
Object obj = data.get(col); case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
return ((Float) obj).longValue();
switch(srcType) { case TSDBConstants.TSDB_DATA_TYPE_DOUBLE:
case TSDBConstants.TSDB_DATA_TYPE_BOOL: return Boolean.TRUE.equals(obj)? 1:0; return ((Double) obj).longValue();
case TSDBConstants.TSDB_DATA_TYPE_FLOAT: return (Float) obj; case TSDBConstants.TSDB_DATA_TYPE_TINYINT:
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: return (Double) obj; return (Byte) obj;
case TSDBConstants.TSDB_DATA_TYPE_TINYINT: return (Byte) obj; case TSDBConstants.TSDB_DATA_TYPE_SMALLINT:
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT:return (Short) obj; return (Short) obj;
case TSDBConstants.TSDB_DATA_TYPE_INT: return (Integer) obj; case TSDBConstants.TSDB_DATA_TYPE_INT:
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: return (Integer) obj;
case TSDBConstants.TSDB_DATA_TYPE_BIGINT: return (Long) obj; case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
} case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
return (Long) obj;
return 0; case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
} case TSDBConstants.TSDB_DATA_TYPE_BINARY:
return Long.parseLong((String) obj);
public void setString(int col, String value) { case TSDBConstants.TSDB_DATA_TYPE_UTINYINT: {
data.set(col, value); Byte value = (byte) obj;
} if (value < 0)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE);
public void setByteArray(int col, byte[] value) { return value;
}
case TSDBConstants.TSDB_DATA_TYPE_USMALLINT: {
short value = (short) obj;
if (value < 0)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE);
return value;
}
case TSDBConstants.TSDB_DATA_TYPE_UINT: {
int value = (int) obj;
if (value < 0)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE);
return value;
}
case TSDBConstants.TSDB_DATA_TYPE_UBIGINT: {
long value = (long) obj;
if (value < 0)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE);
return value;
}
}
return 0;
}
public void setFloat(int col, float value) {
data.set(col, value);
}
public float getFloat(int col, int srcType) throws SQLException {
Object obj = data.get(col);
switch (srcType) {
case TSDBConstants.TSDB_DATA_TYPE_BOOL:
return Boolean.TRUE.equals(obj) ? 1 : 0;
case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
return (Float) obj;
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE:
return ((Double) obj).floatValue();
case TSDBConstants.TSDB_DATA_TYPE_TINYINT:
return (Byte) obj;
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT:
return (Short) obj;
case TSDBConstants.TSDB_DATA_TYPE_INT:
return (Integer) obj;
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
return (Long) obj;
}
return 0;
}
public void setDouble(int col, double value) {
data.set(col, value);
}
public double getDouble(int col, int srcType) throws SQLException {
Object obj = data.get(col);
switch (srcType) {
case TSDBConstants.TSDB_DATA_TYPE_BOOL:
return Boolean.TRUE.equals(obj) ? 1 : 0;
case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
return (Float) obj;
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE:
return (Double) obj;
case TSDBConstants.TSDB_DATA_TYPE_TINYINT:
return (Byte) obj;
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT:
return (Short) obj;
case TSDBConstants.TSDB_DATA_TYPE_INT:
return (Integer) obj;
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
return (Long) obj;
}
return 0;
}
public void setString(int col, String value) {
data.set(col, value);
}
public void setByteArray(int col, byte[] value) {
try { try {
data.set(col, new String(value, TaosGlobalConfig.getCharset())); data.set(col, new String(value, TaosGlobalConfig.getCharset()));
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
/** /**
* The original type may not be a string type, but will be converted to by calling this method * The original type may not be a string type, but will be converted to by calling this method
* @param col column index *
* @return * @param col column index
* @throws SQLException * @return
*/ * @throws SQLException
public String getString(int col, int srcType) throws SQLException { */
if (srcType == TSDBConstants.TSDB_DATA_TYPE_BINARY || srcType == TSDBConstants.TSDB_DATA_TYPE_NCHAR) { public String getString(int col, int srcType) throws SQLException {
return (String) data.get(col); switch (srcType) {
} else { case TSDBConstants.TSDB_DATA_TYPE_BINARY:
return String.valueOf(data.get(col)); case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
} return (String) data.get(col);
} case TSDBConstants.TSDB_DATA_TYPE_UTINYINT: {
Byte value = new Byte(String.valueOf(data.get(col)));
public void setTimestamp(int col, long ts) { if (value >= 0)
data.set(col, ts); return value.toString();
} return Integer.toString(value & 0xff);
}
public Timestamp getTimestamp(int col) { case TSDBConstants.TSDB_DATA_TYPE_USMALLINT: {
return new Timestamp((Long) data.get(col)); Short value = new Short(String.valueOf(data.get(col)));
} if (value >= 0)
return value.toString();
public Object get(int col) { return Integer.toString(value & 0xffff);
return data.get(col); }
} case TSDBConstants.TSDB_DATA_TYPE_UINT: {
Integer value = new Integer(String.valueOf(data.get(col)));
public int getColSize() { if (value >= 0)
return colSize; return value.toString();
} return Long.toString(value & 0xffffffffl);
}
public void setColSize(int colSize) { case TSDBConstants.TSDB_DATA_TYPE_UBIGINT: {
this.colSize = colSize; Long value = new Long(String.valueOf(data.get(col)));
this.clear(); if (value >= 0)
} return value.toString();
long lowValue = value & 0x7fffffffffffffffL;
public ArrayList<Object> getData() { return BigDecimal.valueOf(lowValue).add(BigDecimal.valueOf(Long.MAX_VALUE)).add(BigDecimal.valueOf(1)).toString();
return data; }
} default:
return String.valueOf(data.get(col));
public void setData(ArrayList<Object> data) { }
this.data = (ArrayList<Object>) data.clone(); }
}
public void setTimestamp(int col, long ts) {
data.set(col, ts);
}
public Timestamp getTimestamp(int col) {
return new Timestamp((Long) data.get(col));
}
public Object get(int col) {
return data.get(col);
}
public int getColSize() {
return colSize;
}
public void setColSize(int colSize) {
this.colSize = colSize;
this.clear();
}
public ArrayList<Object> getData() {
return data;
}
public void setData(ArrayList<Object> data) {
this.data = (ArrayList<Object>) data.clone();
}
} }
...@@ -51,7 +51,6 @@ public class TSDBStatement extends AbstractStatement { ...@@ -51,7 +51,6 @@ public class TSDBStatement extends AbstractStatement {
this.connector.freeResultSet(pSql); this.connector.freeResultSet(pSql);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_WITH_EXECUTEQUERY); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_WITH_EXECUTEQUERY);
} }
TSDBResultSet res = new TSDBResultSet(this, this.connector, pSql); TSDBResultSet res = new TSDBResultSet(this, this.connector, pSql);
res.setBatchFetch(this.connection.getBatchFetch()); res.setBatchFetch(this.connection.getBatchFetch());
return res; return res;
......
...@@ -21,27 +21,23 @@ public class TSDBSubscribe { ...@@ -21,27 +21,23 @@ public class TSDBSubscribe {
private final long id; private final long id;
TSDBSubscribe(TSDBJNIConnector connecter, long id) throws SQLException { TSDBSubscribe(TSDBJNIConnector connecter, long id) throws SQLException {
if (null != connecter) { if (connecter == null)
this.connecter = connecter; throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL);
this.id = id;
} else { this.connecter = connecter;
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL)); this.id = id;
}
} }
/** /**
* consume * consume
*
*/ */
public TSDBResultSet consume() throws SQLException { public TSDBResultSet consume() throws SQLException {
if (this.connecter.isClosed()) { if (this.connecter.isClosed())
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL)); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL);
}
long resultSetPointer = this.connecter.consume(this.id); long resultSetPointer = this.connecter.consume(this.id);
if (resultSetPointer == TSDBConstants.JNI_CONNECTION_NULL) { if (resultSetPointer == TSDBConstants.JNI_CONNECTION_NULL) {
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL)); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL);
} else if (resultSetPointer == TSDBConstants.JNI_NULL_POINTER) { } else if (resultSetPointer == TSDBConstants.JNI_NULL_POINTER) {
return null; return null;
} else { } else {
...@@ -56,9 +52,9 @@ public class TSDBSubscribe { ...@@ -56,9 +52,9 @@ public class TSDBSubscribe {
* @throws SQLException * @throws SQLException
*/ */
public void close(boolean keepProgress) throws SQLException { public void close(boolean keepProgress) throws SQLException {
if (this.connecter.isClosed()) { if (this.connecter.isClosed())
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL)); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL);
}
this.connecter.unsubscribe(this.id, keepProgress); this.connecter.unsubscribe(this.id, keepProgress);
} }
} }
......
...@@ -27,7 +27,6 @@ public class RestfulConnection extends AbstractConnection { ...@@ -27,7 +27,6 @@ public class RestfulConnection extends AbstractConnection {
public Statement createStatement() throws SQLException { public Statement createStatement() throws SQLException {
if (isClosed()) if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
;
return new RestfulStatement(this, database); return new RestfulStatement(this, database);
} }
......
...@@ -2,9 +2,7 @@ package com.taosdata.jdbc.rs; ...@@ -2,9 +2,7 @@ package com.taosdata.jdbc.rs;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.taosdata.jdbc.AbstractDriver; import com.taosdata.jdbc.*;
import com.taosdata.jdbc.TSDBConstants;
import com.taosdata.jdbc.TSDBDriver;
import com.taosdata.jdbc.utils.HttpClientPoolUtil; import com.taosdata.jdbc.utils.HttpClientPoolUtil;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
...@@ -21,15 +19,16 @@ public class RestfulDriver extends AbstractDriver { ...@@ -21,15 +19,16 @@ public class RestfulDriver extends AbstractDriver {
try { try {
DriverManager.registerDriver(new RestfulDriver()); DriverManager.registerDriver(new RestfulDriver());
} catch (SQLException e) { } catch (SQLException e) {
throw new RuntimeException(TSDBConstants.WrapErrMsg("can not register Restful JDBC driver"), e); throw TSDBError.createRuntimeException(TSDBErrorNumbers.ERROR_URL_NOT_SET, e);
} }
} }
@Override @Override
public Connection connect(String url, Properties info) throws SQLException { public Connection connect(String url, Properties info) throws SQLException {
// throw SQLException if url is null // throw SQLException if url is null
if (url == null) if (url == null || url.trim().isEmpty() || url.trim().replaceAll("\\s", "").isEmpty())
throw new SQLException(TSDBConstants.WrapErrMsg("url is not set!")); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_URL_NOT_SET);
// return null if url is not be accepted // return null if url is not be accepted
if (!acceptsURL(url)) if (!acceptsURL(url))
return null; return null;
...@@ -61,14 +60,20 @@ public class RestfulDriver extends AbstractDriver { ...@@ -61,14 +60,20 @@ public class RestfulDriver extends AbstractDriver {
throw new SQLException(jsonResult.getString("desc")); throw new SQLException(jsonResult.getString("desc"));
} }
return new RestfulConnection(host, port, props, database, url); RestfulConnection conn = new RestfulConnection(host, port, props, database, url);
if (database != null && !database.trim().replaceAll("\\s", "").isEmpty()) {
Statement stmt = conn.createStatement();
stmt.execute("use " + database);
stmt.close();
}
return conn;
} }
@Override @Override
public boolean acceptsURL(String url) throws SQLException { public boolean acceptsURL(String url) throws SQLException {
if (url == null) if (url == null)
throw new SQLException(TSDBConstants.WrapErrMsg("url is null")); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_URL_NOT_SET);
return (url != null && url.length() > 0 && url.trim().length() > 0) && url.startsWith(URL_PREFIX); return url.length() > 0 && url.trim().length() > 0 && url.startsWith(URL_PREFIX);
} }
@Override @Override
......
...@@ -9,7 +9,6 @@ import com.taosdata.jdbc.TSDBErrorNumbers; ...@@ -9,7 +9,6 @@ import com.taosdata.jdbc.TSDBErrorNumbers;
import java.sql.*; import java.sql.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
public class RestfulResultSet extends AbstractResultSet implements ResultSet { public class RestfulResultSet extends AbstractResultSet implements ResultSet {
private volatile boolean isClosed; private volatile boolean isClosed;
...@@ -17,8 +16,9 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { ...@@ -17,8 +16,9 @@ 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 ArrayList<ArrayList<Object>> resultSet; private final ArrayList<ArrayList<Object>> resultSet;
// meta // meta
private ArrayList<String> columnNames; private ArrayList<String> columnNames;
private ArrayList<Field> columns; private ArrayList<Field> columns;
...@@ -32,6 +32,8 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { ...@@ -32,6 +32,8 @@ 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");
columnNames = new ArrayList<>(); columnNames = new ArrayList<>();
...@@ -39,10 +41,11 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { ...@@ -39,10 +41,11 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
for (int colIndex = 0; colIndex < columnMeta.size(); colIndex++) { for (int colIndex = 0; colIndex < columnMeta.size(); colIndex++) {
JSONArray col = columnMeta.getJSONArray(colIndex); JSONArray col = columnMeta.getJSONArray(colIndex);
String col_name = col.getString(0); String col_name = col.getString(0);
int col_type = TSDBConstants.taosType2JdbcType(col.getInteger(1)); int taos_type = col.getInteger(1);
int col_type = TSDBConstants.taosType2JdbcType(taos_type);
int col_length = col.getInteger(2); int col_length = col.getInteger(2);
columnNames.add(col_name); columnNames.add(col_name);
columns.add(new Field(col_name, col_type, col_length, "")); columns.add(new Field(col_name, col_type, col_length, "", taos_type));
} }
this.metaData = new RestfulResultSetMetaData(this.database, columns, this); this.metaData = new RestfulResultSetMetaData(this.database, columns, this);
...@@ -53,105 +56,50 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { ...@@ -53,105 +56,50 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
ArrayList row = new ArrayList(); ArrayList row = new ArrayList();
JSONArray jsonRow = data.getJSONArray(rowIndex); JSONArray jsonRow = data.getJSONArray(rowIndex);
for (int colIndex = 0; colIndex < jsonRow.size(); colIndex++) { for (int colIndex = 0; colIndex < jsonRow.size(); colIndex++) {
row.add(parseColumnData(jsonRow, colIndex, columns.get(colIndex).type)); row.add(parseColumnData(jsonRow, colIndex, columns.get(colIndex).taos_type));
} }
resultSet.add(row); resultSet.add(row);
} }
/*
int columnIndex = 0;
for (; columnIndex < data.size(); columnIndex++) {
ArrayList oneRow = new ArrayList<>();
JSONArray one = data.getJSONArray(columnIndex);
for (int j = 0; j < one.size(); j++) {
oneRow.add(one.getString(j));
}
resultSet.add(oneRow);
}
// column only names
JSONArray head = resultJson.getJSONArray("head");
for (int i = 0; i < head.size(); i++) {
String name = head.getString(i);
columnNames.add(name);
columns.add(new Field(name, "", 0, ""));
}
this.metaData = new RestfulResultSetMetaData(this.database, columns, this);
*/
} }
private Object parseColumnData(JSONArray row, int colIndex, int sqlType) { private Object parseColumnData(JSONArray row, int colIndex, int taosType) {
switch (sqlType) { switch (taosType) {
case Types.NULL: case TSDBConstants.TSDB_DATA_TYPE_BOOL:
return null;
case Types.BOOLEAN:
return row.getBoolean(colIndex); return row.getBoolean(colIndex);
case Types.TINYINT: case TSDBConstants.TSDB_DATA_TYPE_TINYINT:
case Types.SMALLINT: return row.getByte(colIndex);
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT:
return row.getShort(colIndex); return row.getShort(colIndex);
case Types.INTEGER: case TSDBConstants.TSDB_DATA_TYPE_INT:
return row.getInteger(colIndex); return row.getInteger(colIndex);
case Types.BIGINT: case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
return row.getBigInteger(colIndex); return row.getBigInteger(colIndex);
case Types.FLOAT: case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
return row.getFloat(colIndex); return row.getFloat(colIndex);
case Types.DOUBLE: case TSDBConstants.TSDB_DATA_TYPE_DOUBLE:
return row.getDouble(colIndex); return row.getDouble(colIndex);
case Types.TIMESTAMP: case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
return new Timestamp(row.getDate(colIndex).getTime()); return new Timestamp(row.getDate(colIndex).getTime());
case Types.BINARY: case TSDBConstants.TSDB_DATA_TYPE_BINARY:
case Types.NCHAR: case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
default: default:
return row.getString(colIndex); return row.getString(colIndex);
} }
} }
// /**
// * 由多个resultSet的JSON构造结果集
// *
// * @param resultJson: 包含data信息的结果集,有sql返回的结果集
// * @param fieldJson: 包含多个(最多2个)meta信息的结果集,有describe xxx
// **/
// public RestfulResultSet(String database, Statement statement, JSONObject resultJson, List<JSONObject> fieldJson) throws SQLException {
// this(database, statement, resultJson);
// ArrayList<Field> newColumns = new ArrayList<>();
//
// for (Field column : columns) {
// Field field = findField(column.name, fieldJson);
// if (field != null) {
// newColumns.add(field);
// } else {
// newColumns.add(column);
// }
// }
// this.columns = newColumns;
// this.metaData = new RestfulResultSetMetaData(this.database, this.columns, this);
// }
// public Field findField(String columnName, List<JSONObject> fieldJsonList) {
// for (JSONObject fieldJSON : fieldJsonList) {
// JSONArray fieldDataJson = fieldJSON.getJSONArray("data");
// for (int i = 0; i < fieldDataJson.size(); i++) {
// JSONArray field = fieldDataJson.getJSONArray(i);
// if (columnName.equalsIgnoreCase(field.getString(0))) {
// return new Field(field.getString(0), field.getString(1), field.getInteger(2), field.getString(3));
// }
// }
// }
// return null;
// }
public class Field { public class Field {
String name; String name;
int type; int type;
int length; int length;
String note; String note;
int taos_type;
public Field(String name, int type, int length, String note) { public Field(String name, int type, int length, String note, int taos_type) {
this.name = name; this.name = name;
this.type = type; this.type = type;
this.length = length; this.length = length;
this.note = note; this.note = note;
this.taos_type = taos_type;
} }
} }
...@@ -184,53 +132,119 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { ...@@ -184,53 +132,119 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
public String getString(int columnIndex) throws SQLException { public String getString(int columnIndex) throws SQLException {
if (isClosed()) if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
if (columnIndex > resultSet.get(pos).size())
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());
throw new SQLException(TSDBConstants.WrapErrMsg("Column Index out of range, " + columnIndex + " > " + resultSet.get(pos).size()));
}
columnIndex = getTrueColumnIndex(columnIndex); columnIndex = getTrueColumnIndex(columnIndex);
return resultSet.get(pos).get(columnIndex).toString(); Object value = resultSet.get(pos).get(columnIndex);
return value == null ? null : value.toString();
} }
@Override @Override
public boolean getBoolean(int columnIndex) throws SQLException { public boolean getBoolean(int columnIndex) throws SQLException {
if (isClosed()) if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED); 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); columnIndex = getTrueColumnIndex(columnIndex);
int result = getInt(columnIndex); int result = getInt(columnIndex);
return result == 0 ? false : true; return result == 0 ? false : true;
} }
@Override
public byte getByte(int columnIndex) throws SQLException {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
if (columnIndex > resultSet.get(pos).size())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE, "Column Index out of range, " + columnIndex + " > " + resultSet.get(pos).size());
columnIndex = getTrueColumnIndex(columnIndex);
Object value = resultSet.get(pos).get(columnIndex);
if (value == null)
return 0;
long valueAsLong = Long.parseLong(value.toString());
if (valueAsLong == Byte.MIN_VALUE)
return 0;
if (valueAsLong < Byte.MIN_VALUE || valueAsLong > Byte.MAX_VALUE)
throwRangeException(value.toString(), columnIndex, Types.TINYINT);
return (byte) valueAsLong;
}
private void throwRangeException(String valueAsString, int columnIndex, int jdbcType) throws SQLException {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE,
"'" + valueAsString + "' in column '" + columnIndex + "' is outside valid range for the jdbcType " + TSDBConstants.jdbcType2TaosTypeName(jdbcType));
}
@Override @Override
public short getShort(int columnIndex) throws SQLException { public short getShort(int columnIndex) throws SQLException {
if (isClosed()) if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED); 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); columnIndex = getTrueColumnIndex(columnIndex);
return Short.parseShort(resultSet.get(pos).get(columnIndex).toString()); Object value = resultSet.get(pos).get(columnIndex);
if (value == null)
return 0;
long valueAsLong = Long.parseLong(value.toString());
if (valueAsLong == Short.MIN_VALUE)
return 0;
if (valueAsLong < Short.MIN_VALUE || valueAsLong > Short.MAX_VALUE)
throwRangeException(value.toString(), columnIndex, Types.SMALLINT);
return (short) valueAsLong;
} }
@Override @Override
public int getInt(int columnIndex) throws SQLException { public int getInt(int columnIndex) throws SQLException {
if (isClosed()) if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED); 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); columnIndex = getTrueColumnIndex(columnIndex);
return Integer.parseInt(resultSet.get(pos).get(columnIndex).toString()); Object value = resultSet.get(pos).get(columnIndex);
if (value == null)
return 0;
long valueAsLong = Long.parseLong(value.toString());
if (valueAsLong == Integer.MIN_VALUE)
return 0;
if (valueAsLong < Integer.MIN_VALUE || valueAsLong > Integer.MAX_VALUE)
throwRangeException(value.toString(), columnIndex, Types.INTEGER);
return (int) valueAsLong;
} }
@Override @Override
public long getLong(int columnIndex) throws SQLException { public long getLong(int columnIndex) throws SQLException {
if (isClosed()) if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED); 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); columnIndex = getTrueColumnIndex(columnIndex);
return Long.parseLong(resultSet.get(pos).get(columnIndex).toString()); Object value = resultSet.get(pos).get(columnIndex);
if (value == null)
return 0;
long valueAsLong = 0;
try {
valueAsLong = Long.parseLong(value.toString());
if (valueAsLong == Long.MIN_VALUE)
return 0;
} catch (NumberFormatException e) {
throwRangeException(value.toString(), columnIndex, Types.BIGINT);
}
return valueAsLong;
} }
@Override @Override
public float getFloat(int columnIndex) throws SQLException { public float getFloat(int columnIndex) throws SQLException {
if (isClosed()) if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED); 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); columnIndex = getTrueColumnIndex(columnIndex);
return Float.parseFloat(resultSet.get(pos).get(columnIndex).toString()); return Float.parseFloat(resultSet.get(pos).get(columnIndex).toString());
} }
...@@ -239,6 +253,8 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { ...@@ -239,6 +253,8 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
public double getDouble(int columnIndex) throws SQLException { public double getDouble(int columnIndex) throws SQLException {
if (isClosed()) if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED); 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); columnIndex = getTrueColumnIndex(columnIndex);
return Double.parseDouble(resultSet.get(pos).get(columnIndex).toString()); return Double.parseDouble(resultSet.get(pos).get(columnIndex).toString());
...@@ -246,12 +262,14 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { ...@@ -246,12 +262,14 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
private int getTrueColumnIndex(int columnIndex) throws SQLException { private int getTrueColumnIndex(int columnIndex) throws SQLException {
if (columnIndex < 1) { if (columnIndex < 1) {
throw new SQLException("Column Index out of range, " + columnIndex + " < 1"); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE
, "Column Index out of range, " + columnIndex + " < 1");
} }
int numOfCols = resultSet.get(pos).size(); int numOfCols = resultSet.get(pos).size();
if (columnIndex > numOfCols) { if (columnIndex > numOfCols) {
throw new SQLException("Column Index out of range, " + columnIndex + " > " + numOfCols); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE
, "Column Index out of range, " + columnIndex + " > " + numOfCols);
} }
return columnIndex - 1; return columnIndex - 1;
......
package com.taosdata.jdbc.rs; package com.taosdata.jdbc.rs;
import com.taosdata.jdbc.TSDBConstants; import com.taosdata.jdbc.TSDBConstants;
import com.taosdata.jdbc.WrapperImpl;
import java.sql.ResultSetMetaData; import java.sql.ResultSetMetaData;
import java.sql.SQLException; import java.sql.SQLException;
...@@ -8,7 +9,7 @@ import java.sql.Timestamp; ...@@ -8,7 +9,7 @@ import java.sql.Timestamp;
import java.sql.Types; import java.sql.Types;
import java.util.ArrayList; import java.util.ArrayList;
public class RestfulResultSetMetaData implements ResultSetMetaData { public class RestfulResultSetMetaData extends WrapperImpl implements ResultSetMetaData {
private final String database; private final String database;
private ArrayList<RestfulResultSet.Field> fields; private ArrayList<RestfulResultSet.Field> fields;
...@@ -20,6 +21,10 @@ public class RestfulResultSetMetaData implements ResultSetMetaData { ...@@ -20,6 +21,10 @@ public class RestfulResultSetMetaData implements ResultSetMetaData {
this.resultSet = resultSet; this.resultSet = resultSet;
} }
public ArrayList<RestfulResultSet.Field> getFields() {
return fields;
}
@Override @Override
public int getColumnCount() throws SQLException { public int getColumnCount() throws SQLException {
return fields.size(); return fields.size();
...@@ -134,8 +139,8 @@ public class RestfulResultSetMetaData implements ResultSetMetaData { ...@@ -134,8 +139,8 @@ public class RestfulResultSetMetaData implements ResultSetMetaData {
@Override @Override
public String getColumnTypeName(int column) throws SQLException { public String getColumnTypeName(int column) throws SQLException {
int type = fields.get(column - 1).type; int taos_type = fields.get(column - 1).taos_type;
return TSDBConstants.jdbcType2TaosTypeName(type); return TSDBConstants.taosType2JdbcTypeName(taos_type);
} }
@Override @Override
...@@ -180,18 +185,4 @@ public class RestfulResultSetMetaData implements ResultSetMetaData { ...@@ -180,18 +185,4 @@ public class RestfulResultSetMetaData implements ResultSetMetaData {
return columnClassName; return columnClassName;
} }
@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
try {
return iface.cast(this);
} catch (ClassCastException cce) {
throw new SQLException("Unable to unwrap to " + iface.toString());
}
}
@Override
public boolean isWrapperFor(Class<?> iface) throws SQLException {
return iface.isInstance(this);
}
} }
...@@ -15,12 +15,12 @@ public class TSDBJNIConnectorTest { ...@@ -15,12 +15,12 @@ public class TSDBJNIConnectorTest {
public void test() { public void test() {
try { try {
// init // init
TSDBJNIConnector.init(null, null, null, null); TSDBJNIConnector.init("/etc/taos/taos.cfg", null, null, null);
// connect // connect
TSDBJNIConnector connector = new TSDBJNIConnector(); TSDBJNIConnector connector = new TSDBJNIConnector();
connector.connect("127.0.0.1", 6030, null, "root", "taosdata"); connector.connect("127.0.0.1", 6030, "unsign_jni", "root", "taosdata");
// executeQuery // executeQuery
long pSql = connector.executeQuery("show variables"); long pSql = connector.executeQuery("select * from unsign_jni.us_table");
if (connector.isUpdateQuery(pSql)) { if (connector.isUpdateQuery(pSql)) {
connector.freeResultSet(pSql); connector.freeResultSet(pSql);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_WITH_EXECUTEQUERY); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_WITH_EXECUTEQUERY);
...@@ -29,13 +29,13 @@ public class TSDBJNIConnectorTest { ...@@ -29,13 +29,13 @@ public class TSDBJNIConnectorTest {
List<ColumnMetaData> columnMetaDataList = new ArrayList<>(); List<ColumnMetaData> columnMetaDataList = new ArrayList<>();
int code = connector.getSchemaMetaData(pSql, columnMetaDataList); int code = connector.getSchemaMetaData(pSql, columnMetaDataList);
if (code == TSDBConstants.JNI_CONNECTION_NULL) { if (code == TSDBConstants.JNI_CONNECTION_NULL) {
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL)); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL);
} }
if (code == TSDBConstants.JNI_RESULT_SET_NULL) { if (code == TSDBConstants.JNI_RESULT_SET_NULL) {
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_RESULT_SET_NULL)); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_RESULT_SET_NULL);
} }
if (code == TSDBConstants.JNI_NUM_OF_FIELDS_0) { if (code == TSDBConstants.JNI_NUM_OF_FIELDS_0) {
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_NUM_OF_FIELDS_0)); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_NUM_OF_FIELDS_0);
} }
int columnSize = columnMetaDataList.size(); int columnSize = columnMetaDataList.size();
// print metadata // print metadata
......
...@@ -40,9 +40,12 @@ public class RestfulResultSetTest { ...@@ -40,9 +40,12 @@ public class RestfulResultSetTest {
Assert.assertEquals(true, f9); Assert.assertEquals(true, f9);
} }
@Test(expected = SQLFeatureNotSupportedException.class) @Test
public void getByte() throws SQLException { public void getByte() throws SQLException {
rs.getByte(1); byte f8 = rs.getByte("f8");
Assert.assertEquals(10, f8);
f8 = rs.getByte(8);
Assert.assertEquals(10, f8);
} }
@Test @Test
......
!c/
node_modules/
package-lock.json
此差异已折叠。
此差异已折叠。
此差异已折叠。
PROJECT(TDengine)
ADD_SUBDIRECTORY(c)
PROJECT(TDengine)
ADD_EXECUTABLE(tcodbc main.c ../../src/todbc_log.c)
IF (TD_LINUX OR TD_DARWIN)
TARGET_LINK_LIBRARIES(tcodbc taos odbc)
ENDIF ()
IF (TD_DARWIN)
target_include_directories(tcodbc PRIVATE /usr/local/include)
target_link_directories(tcodbc PUBLIC /usr/local/lib)
ENDIF ()
IF (TD_WINDOWS_64)
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /GL")
SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /GL")
TARGET_LINK_LIBRARIES(tcodbc taos_static odbc32 odbccp32 user32 legacy_stdio_definitions os)
ADD_EXECUTABLE(tms main.cpp)
TARGET_LINK_LIBRARIES(tms odbc32)
ENDIF ()
此差异已折叠。
此差异已折叠。
此差异已折叠。
{
"dependencies": {
"odbc": "^2.3.6"
}
}
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册