Merge branch 'develop' into xiaoping/add_test_case
This commit is contained in:
commit
245813e842
33
.travis.yml
33
.travis.yml
|
@ -270,19 +270,20 @@ matrix:
|
||||||
fi
|
fi
|
||||||
- make > /dev/null
|
- make > /dev/null
|
||||||
|
|
||||||
# - os: osx
|
- os: osx
|
||||||
# language: c
|
osx_image: xcode11.4
|
||||||
# compiler: clang
|
language: c
|
||||||
# env: DESC="mac/clang build"
|
compiler: clang
|
||||||
# git:
|
env: DESC="mac/clang build"
|
||||||
# - depth: 1
|
git:
|
||||||
# addons:
|
- depth: 1
|
||||||
# homebrew:
|
addons:
|
||||||
# - cmake
|
homebrew:
|
||||||
#
|
- cmake
|
||||||
# script:
|
|
||||||
# - cd ${TRAVIS_BUILD_DIR}
|
script:
|
||||||
# - mkdir debug
|
- cd ${TRAVIS_BUILD_DIR}
|
||||||
# - cd debug
|
- mkdir debug
|
||||||
# - cmake .. > /dev/null
|
- cd debug
|
||||||
# - make > /dev/null
|
- cmake .. > /dev/null
|
||||||
|
- make > /dev/null
|
||||||
|
|
|
@ -30,7 +30,7 @@ MESSAGE(STATUS "Community directory: " ${TD_COMMUNITY_DIR})
|
||||||
INCLUDE(cmake/input.inc)
|
INCLUDE(cmake/input.inc)
|
||||||
INCLUDE(cmake/platform.inc)
|
INCLUDE(cmake/platform.inc)
|
||||||
|
|
||||||
IF (TD_WINDOWS)
|
IF (TD_WINDOWS OR TD_DARWIN)
|
||||||
SET(TD_SOMODE_STATIC TRUE)
|
SET(TD_SOMODE_STATIC TRUE)
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
|
|
|
@ -176,5 +176,84 @@ pipeline {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
post {
|
||||||
|
|
||||||
|
success {
|
||||||
|
emailext (
|
||||||
|
subject: "PR-result: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]'",
|
||||||
|
body: '''<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
</head>
|
||||||
|
<body leftmargin="8" marginwidth="0" topmargin="8" marginheight="4" offset="0">
|
||||||
|
<table width="95%" cellpadding="0" cellspacing="0" style="font-size: 16pt; font-family: Tahoma, Arial, Helvetica, sans-serif">
|
||||||
|
<tr>
|
||||||
|
<td><br />
|
||||||
|
<b><font color="#0B610B"><font size="6">构建信息</font></font></b>
|
||||||
|
<hr size="2" width="100%" align="center" /></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<ul>
|
||||||
|
<div style="font-size:18px">
|
||||||
|
<li>构建名称>>分支:${PROJECT_NAME}</li>
|
||||||
|
<li>构建结果:<span style="color:green"> Successful </span></li>
|
||||||
|
<li>构建编号:${BUILD_NUMBER}</li>
|
||||||
|
<li>触发用户:${CAUSE}</li>
|
||||||
|
<li>提交信息:${CHANGE_TITLE}</li>
|
||||||
|
<li>构建地址:<a href=${BUILD_URL}>${BUILD_URL}</a></li>
|
||||||
|
<li>构建日志:<a href=${BUILD_URL}console>${BUILD_URL}console</a></li>
|
||||||
|
<li>变更集:${JELLY_SCRIPT}</li>
|
||||||
|
</div>
|
||||||
|
</ul>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table></font>
|
||||||
|
</body>
|
||||||
|
</html>''',
|
||||||
|
to: "${env.CHANGE_AUTHOR_EMAIL}",
|
||||||
|
from: "support@taosdata.com"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
failure {
|
||||||
|
emailext (
|
||||||
|
subject: "PR-result: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]'",
|
||||||
|
body: '''<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
</head>
|
||||||
|
<body leftmargin="8" marginwidth="0" topmargin="8" marginheight="4" offset="0">
|
||||||
|
<table width="95%" cellpadding="0" cellspacing="0" style="font-size: 16pt; font-family: Tahoma, Arial, Helvetica, sans-serif">
|
||||||
|
<tr>
|
||||||
|
<td><br />
|
||||||
|
<b><font color="#0B610B"><font size="6">构建信息</font></font></b>
|
||||||
|
<hr size="2" width="100%" align="center" /></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<ul>
|
||||||
|
<div style="font-size:18px">
|
||||||
|
<li>构建名称>>分支:${PROJECT_NAME}</li>
|
||||||
|
<li>构建结果:<span style="color:green"> Successful </span></li>
|
||||||
|
<li>构建编号:${BUILD_NUMBER}</li>
|
||||||
|
<li>触发用户:${CAUSE}</li>
|
||||||
|
<li>提交信息:${CHANGE_TITLE}</li>
|
||||||
|
<li>构建地址:<a href=${BUILD_URL}>${BUILD_URL}</a></li>
|
||||||
|
<li>构建日志:<a href=${BUILD_URL}console>${BUILD_URL}console</a></li>
|
||||||
|
<li>变更集:${JELLY_SCRIPT}</li>
|
||||||
|
</div>
|
||||||
|
</ul>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table></font>
|
||||||
|
</body>
|
||||||
|
</html>''',
|
||||||
|
to: "${env.CHANGE_AUTHOR_EMAIL}",
|
||||||
|
from: "support@taosdata.com"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
23
README.md
23
README.md
|
@ -126,7 +126,7 @@ cmake .. -DCPUTYPE=aarch32 && cmake --build .
|
||||||
|
|
||||||
If you use the Visual Studio 2013, please open a command window by executing "cmd.exe".
|
If you use the Visual Studio 2013, please open a command window by executing "cmd.exe".
|
||||||
Please specify "x86_amd64" for 64 bits Windows or specify "x86" is for 32 bits Windows when you execute vcvarsall.bat.
|
Please specify "x86_amd64" for 64 bits Windows or specify "x86" is for 32 bits Windows when you execute vcvarsall.bat.
|
||||||
```
|
```cmd
|
||||||
mkdir debug && cd debug
|
mkdir debug && cd debug
|
||||||
"C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" < x86_amd64 | x86 >
|
"C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" < x86_amd64 | x86 >
|
||||||
cmake .. -G "NMake Makefiles"
|
cmake .. -G "NMake Makefiles"
|
||||||
|
@ -137,7 +137,8 @@ If you use the Visual Studio 2019 or 2017:
|
||||||
|
|
||||||
please open a command window by executing "cmd.exe".
|
please open a command window by executing "cmd.exe".
|
||||||
Please specify "x64" for 64 bits Windows or specify "x86" is for 32 bits Windows when you execute vcvarsall.bat.
|
Please specify "x64" for 64 bits Windows or specify "x86" is for 32 bits Windows when you execute vcvarsall.bat.
|
||||||
```
|
|
||||||
|
```cmd
|
||||||
mkdir debug && cd debug
|
mkdir debug && cd debug
|
||||||
"c:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat" < x64 | x86 >
|
"c:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat" < x64 | x86 >
|
||||||
cmake .. -G "NMake Makefiles"
|
cmake .. -G "NMake Makefiles"
|
||||||
|
@ -145,27 +146,37 @@ nmake
|
||||||
```
|
```
|
||||||
|
|
||||||
Or, you can simply open a command window by clicking Windows Start -> "Visual Studio < 2019 | 2017 >" folder -> "x64 Native Tools Command Prompt for VS < 2019 | 2017 >" or "x86 Native Tools Command Prompt for VS < 2019 | 2017 >" depends what architecture your Windows is, then execute commands as follows:
|
Or, you can simply open a command window by clicking Windows Start -> "Visual Studio < 2019 | 2017 >" folder -> "x64 Native Tools Command Prompt for VS < 2019 | 2017 >" or "x86 Native Tools Command Prompt for VS < 2019 | 2017 >" depends what architecture your Windows is, then execute commands as follows:
|
||||||
```
|
```cmd
|
||||||
mkdir debug && cd debug
|
mkdir debug && cd debug
|
||||||
cmake .. -G "NMake Makefiles"
|
cmake .. -G "NMake Makefiles"
|
||||||
nmake
|
nmake
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### On Mac OS X platform
|
||||||
|
|
||||||
|
Please install XCode command line tools and cmake. Verified with XCode 11.4+ on Catalina and Big Sur.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
mkdir debug && cd debug
|
||||||
|
cmake .. && cmake --build .
|
||||||
|
```
|
||||||
|
|
||||||
# Quick Run
|
# Quick Run
|
||||||
|
|
||||||
# Quick Run
|
# Quick Run
|
||||||
To quickly start a TDengine server after building, run the command below in terminal:
|
To quickly start a TDengine server after building, run the command below in terminal:
|
||||||
```cmd
|
```bash
|
||||||
./build/bin/taosd -c test/cfg
|
./build/bin/taosd -c test/cfg
|
||||||
```
|
```
|
||||||
In another terminal, use the TDengine shell to connect the server:
|
In another terminal, use the TDengine shell to connect the server:
|
||||||
```
|
```bash
|
||||||
./build/bin/taos -c test/cfg
|
./build/bin/taos -c test/cfg
|
||||||
```
|
```
|
||||||
option "-c test/cfg" specifies the system configuration file directory.
|
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:
|
||||||
```cmd
|
```bash
|
||||||
make install
|
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. It should be noted that installing from source code does not configure service management for TDengine.
|
||||||
|
|
|
@ -128,6 +128,8 @@ IF (TD_DARWIN_64)
|
||||||
SET(COMMON_FLAGS "-std=gnu99 -Wall -Werror -Wno-missing-braces -fPIC -msse4.2 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE")
|
SET(COMMON_FLAGS "-std=gnu99 -Wall -Werror -Wno-missing-braces -fPIC -msse4.2 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE")
|
||||||
SET(DEBUG_FLAGS "-O0 -g3 -DDEBUG")
|
SET(DEBUG_FLAGS "-O0 -g3 -DDEBUG")
|
||||||
SET(RELEASE_FLAGS "-Og")
|
SET(RELEASE_FLAGS "-Og")
|
||||||
|
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/cJson/inc)
|
||||||
|
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/lz4/inc)
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
IF (TD_WINDOWS)
|
IF (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.17-dist.jar DESTINATION connector/jdbc)
|
INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos-jdbcdriver-2.0.18-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")
|
||||||
|
|
|
@ -13,3 +13,7 @@ ADD_SUBDIRECTORY(MsvcLibX)
|
||||||
IF (TD_LINUX AND TD_MQTT)
|
IF (TD_LINUX AND TD_MQTT)
|
||||||
ADD_SUBDIRECTORY(MQTT-C)
|
ADD_SUBDIRECTORY(MQTT-C)
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
|
IF (TD_DARWIN AND TD_MQTT)
|
||||||
|
ADD_SUBDIRECTORY(MQTT-C)
|
||||||
|
ENDIF ()
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
TDengine 提供了遵循 JDBC 标准(3.0)API 规范的 `taos-jdbcdriver` 实现,可在 maven 的中央仓库 [Sonatype Repository][1] 搜索下载。
|
TDengine 提供了遵循 JDBC 标准(3.0)API 规范的 `taos-jdbcdriver` 实现,可在 maven 的中央仓库 [Sonatype Repository][1] 搜索下载。
|
||||||
|
|
||||||
`taos-jdbcdriver` 的实现包括 2 种形式: JDBC-JNI 和 JDBC-RESTful(taos-jdbcdriver-2.0.17 开始支持 JDBC-RESTful)。 JDBC-JNI 通过调用客户端 libtaos.so(或 taos.dll )的本地方法实现, JDBC-RESTful 则在内部封装了 RESTful 接口实现。
|
`taos-jdbcdriver` 的实现包括 2 种形式: JDBC-JNI 和 JDBC-RESTful(taos-jdbcdriver-2.0.18 开始支持 JDBC-RESTful)。 JDBC-JNI 通过调用客户端 libtaos.so(或 taos.dll )的本地方法实现, JDBC-RESTful 则在内部封装了 RESTful 接口实现。
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ maven 项目中使用如下 pom.xml 配置即可:
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.taosdata.jdbc</groupId>
|
<groupId>com.taosdata.jdbc</groupId>
|
||||||
<artifactId>taos-jdbcdriver</artifactId>
|
<artifactId>taos-jdbcdriver</artifactId>
|
||||||
<version>2.0.17</version>
|
<version>2.0.18</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -334,16 +334,17 @@ conn.close();
|
||||||
```java
|
```java
|
||||||
public static void main(String[] args) throws SQLException {
|
public static void main(String[] args) throws SQLException {
|
||||||
HikariConfig config = new HikariConfig();
|
HikariConfig config = new HikariConfig();
|
||||||
|
// jdbc properties
|
||||||
config.setJdbcUrl("jdbc:TAOS://127.0.0.1:6030/log");
|
config.setJdbcUrl("jdbc:TAOS://127.0.0.1:6030/log");
|
||||||
config.setUsername("root");
|
config.setUsername("root");
|
||||||
config.setPassword("taosdata");
|
config.setPassword("taosdata");
|
||||||
|
// connection pool configurations
|
||||||
config.setMinimumIdle(3); //minimum number of idle connection
|
config.setMinimumIdle(10); //minimum number of idle connection
|
||||||
config.setMaximumPoolSize(10); //maximum number of connection in the pool
|
config.setMaximumPoolSize(10); //maximum number of connection in the pool
|
||||||
config.setConnectionTimeout(10000); //maximum wait milliseconds for get connection from pool
|
config.setConnectionTimeout(30000); //maximum wait milliseconds for get connection from pool
|
||||||
config.setIdleTimeout(60000); // max idle time for recycle idle connection
|
config.setMaxLifetime(0); // maximum life time for each connection
|
||||||
config.setConnectionTestQuery("describe log.dn"); //validation query
|
config.setIdleTimeout(0); // max idle time for recycle idle connection
|
||||||
config.setValidationTimeout(3000); //validation query timeout
|
config.setConnectionTestQuery("select server_status()"); //validation query
|
||||||
|
|
||||||
HikariDataSource ds = new HikariDataSource(config); //create datasource
|
HikariDataSource ds = new HikariDataSource(config); //create datasource
|
||||||
|
|
||||||
|
@ -375,32 +376,22 @@ conn.close();
|
||||||
* 使用示例如下:
|
* 使用示例如下:
|
||||||
```java
|
```java
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
Properties properties = new Properties();
|
|
||||||
properties.put("driverClassName","com.taosdata.jdbc.TSDBDriver");
|
|
||||||
properties.put("url","jdbc:TAOS://127.0.0.1:6030/log");
|
|
||||||
properties.put("username","root");
|
|
||||||
properties.put("password","taosdata");
|
|
||||||
|
|
||||||
properties.put("maxActive","10"); //maximum number of connection in the pool
|
DruidDataSource dataSource = new DruidDataSource();
|
||||||
properties.put("initialSize","3");//initial number of connection
|
// jdbc properties
|
||||||
properties.put("maxWait","10000");//maximum wait milliseconds for get connection from pool
|
dataSource.setDriverClassName("com.taosdata.jdbc.TSDBDriver");
|
||||||
properties.put("minIdle","3");//minimum number of connection in the pool
|
dataSource.setUrl(url);
|
||||||
|
dataSource.setUsername("root");
|
||||||
|
dataSource.setPassword("taosdata");
|
||||||
|
// pool configurations
|
||||||
|
dataSource.setInitialSize(10);
|
||||||
|
dataSource.setMinIdle(10);
|
||||||
|
dataSource.setMaxActive(10);
|
||||||
|
dataSource.setMaxWait(30000);
|
||||||
|
dataSource.setValidationQuery("select server_status()");
|
||||||
|
|
||||||
properties.put("timeBetweenEvictionRunsMillis","3000");// the interval milliseconds to test connection
|
Connection connection = dataSource.getConnection(); // get connection
|
||||||
|
|
||||||
properties.put("minEvictableIdleTimeMillis","60000");//the minimum milliseconds to keep idle
|
|
||||||
properties.put("maxEvictableIdleTimeMillis","90000");//the maximum milliseconds to keep idle
|
|
||||||
|
|
||||||
properties.put("validationQuery","describe log.dn"); //validation query
|
|
||||||
properties.put("testWhileIdle","true"); // test connection while idle
|
|
||||||
properties.put("testOnBorrow","false"); // don't need while testWhileIdle is true
|
|
||||||
properties.put("testOnReturn","false"); // don't need while testWhileIdle is true
|
|
||||||
|
|
||||||
//create druid datasource
|
|
||||||
DataSource ds = DruidDataSourceFactory.createDataSource(properties);
|
|
||||||
Connection connection = ds.getConnection(); // get connection
|
|
||||||
Statement statement = connection.createStatement(); // get statement
|
Statement statement = connection.createStatement(); // get statement
|
||||||
|
|
||||||
//query or insert
|
//query or insert
|
||||||
// ...
|
// ...
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,7 @@ mkdir -p ${pkg_dir}${install_home_path}/include
|
||||||
mkdir -p ${pkg_dir}${install_home_path}/init.d
|
mkdir -p ${pkg_dir}${install_home_path}/init.d
|
||||||
mkdir -p ${pkg_dir}${install_home_path}/script
|
mkdir -p ${pkg_dir}${install_home_path}/script
|
||||||
|
|
||||||
|
echo "" > ${pkg_dir}${install_home_path}/email
|
||||||
cp ${compile_dir}/../packaging/cfg/taos.cfg ${pkg_dir}${install_home_path}/cfg
|
cp ${compile_dir}/../packaging/cfg/taos.cfg ${pkg_dir}${install_home_path}/cfg
|
||||||
cp ${compile_dir}/../packaging/deb/taosd ${pkg_dir}${install_home_path}/init.d
|
cp ${compile_dir}/../packaging/deb/taosd ${pkg_dir}${install_home_path}/init.d
|
||||||
cp ${compile_dir}/../packaging/tools/post.sh ${pkg_dir}${install_home_path}/script
|
cp ${compile_dir}/../packaging/tools/post.sh ${pkg_dir}${install_home_path}/script
|
||||||
|
|
|
@ -51,6 +51,7 @@ mkdir -p %{buildroot}%{homepath}/include
|
||||||
mkdir -p %{buildroot}%{homepath}/init.d
|
mkdir -p %{buildroot}%{homepath}/init.d
|
||||||
mkdir -p %{buildroot}%{homepath}/script
|
mkdir -p %{buildroot}%{homepath}/script
|
||||||
|
|
||||||
|
echo "" > %{buildroot}%{homepath}/email
|
||||||
cp %{_compiledir}/../packaging/cfg/taos.cfg %{buildroot}%{homepath}/cfg
|
cp %{_compiledir}/../packaging/cfg/taos.cfg %{buildroot}%{homepath}/cfg
|
||||||
cp %{_compiledir}/../packaging/rpm/taosd %{buildroot}%{homepath}/init.d
|
cp %{_compiledir}/../packaging/rpm/taosd %{buildroot}%{homepath}/init.d
|
||||||
cp %{_compiledir}/../packaging/tools/post.sh %{buildroot}%{homepath}/script
|
cp %{_compiledir}/../packaging/tools/post.sh %{buildroot}%{homepath}/script
|
||||||
|
|
|
@ -21,7 +21,7 @@ else
|
||||||
cd ${script_dir}
|
cd ${script_dir}
|
||||||
script_dir="$(pwd)"
|
script_dir="$(pwd)"
|
||||||
data_dir="/var/lib/taos"
|
data_dir="/var/lib/taos"
|
||||||
log_dir="~/TDengineLog"
|
log_dir=~/TDengine/log
|
||||||
fi
|
fi
|
||||||
|
|
||||||
log_link_dir="/usr/local/taos/log"
|
log_link_dir="/usr/local/taos/log"
|
||||||
|
|
|
@ -24,7 +24,7 @@ data_dir="/var/lib/taos"
|
||||||
if [ "$osType" != "Darwin" ]; then
|
if [ "$osType" != "Darwin" ]; then
|
||||||
log_dir="/var/log/taos"
|
log_dir="/var/log/taos"
|
||||||
else
|
else
|
||||||
log_dir="~/TDengineLog"
|
log_dir=~/TDengine/log
|
||||||
fi
|
fi
|
||||||
|
|
||||||
data_link_dir="/usr/local/taos/data"
|
data_link_dir="/usr/local/taos/data"
|
||||||
|
@ -178,7 +178,9 @@ function install_bin() {
|
||||||
function install_lib() {
|
function install_lib() {
|
||||||
# Remove links
|
# Remove links
|
||||||
${csudo} rm -f ${lib_link_dir}/libtaos.* || :
|
${csudo} rm -f ${lib_link_dir}/libtaos.* || :
|
||||||
|
if [ "$osType" != "Darwin" ]; then
|
||||||
${csudo} rm -f ${lib64_link_dir}/libtaos.* || :
|
${csudo} rm -f ${lib64_link_dir}/libtaos.* || :
|
||||||
|
fi
|
||||||
|
|
||||||
if [ "$osType" != "Darwin" ]; then
|
if [ "$osType" != "Darwin" ]; then
|
||||||
${csudo} cp ${binary_dir}/build/lib/libtaos.so.${verNumber} ${install_main_dir}/driver && ${csudo} chmod 777 ${install_main_dir}/driver/*
|
${csudo} cp ${binary_dir}/build/lib/libtaos.so.${verNumber} ${install_main_dir}/driver && ${csudo} chmod 777 ${install_main_dir}/driver/*
|
||||||
|
@ -190,12 +192,14 @@ function install_lib() {
|
||||||
${csudo} ln -sf ${lib64_link_dir}/libtaos.so.1 ${lib64_link_dir}/libtaos.so
|
${csudo} ln -sf ${lib64_link_dir}/libtaos.so.1 ${lib64_link_dir}/libtaos.so
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
${csudo} cp ${binary_dir}/build/lib/libtaos.* ${install_main_dir}/driver && ${csudo} chmod 777 ${install_main_dir}/driver/*
|
${csudo} cp -Rf ${binary_dir}/build/lib/libtaos.* ${install_main_dir}/driver && ${csudo} chmod 777 ${install_main_dir}/driver/*
|
||||||
${csudo} ln -sf ${install_main_dir}/driver/libtaos.* ${lib_link_dir}/libtaos.1.dylib
|
${csudo} ln -sf ${install_main_dir}/driver/libtaos.1.dylib ${lib_link_dir}/libtaos.1.dylib
|
||||||
${csudo} ln -sf ${lib_link_dir}/libtaos.1.dylib ${lib_link_dir}/libtaos.dylib
|
${csudo} ln -sf ${lib_link_dir}/libtaos.1.dylib ${lib_link_dir}/libtaos.dylib
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "$osType" != "Darwin" ]; then
|
||||||
${csudo} ldconfig
|
${csudo} ldconfig
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
function install_header() {
|
function install_header() {
|
||||||
|
|
|
@ -8,6 +8,4 @@ INCLUDE_DIRECTORIES(${TD_ENTERPRISE_DIR}/src/inc)
|
||||||
INCLUDE_DIRECTORIES(inc)
|
INCLUDE_DIRECTORIES(inc)
|
||||||
AUX_SOURCE_DIRECTORY(src SRC)
|
AUX_SOURCE_DIRECTORY(src SRC)
|
||||||
|
|
||||||
IF (TD_LINUX OR TD_WINDOWS)
|
|
||||||
ADD_LIBRARY(balance ${SRC})
|
ADD_LIBRARY(balance ${SRC})
|
||||||
ENDIF ()
|
|
||||||
|
|
|
@ -28,6 +28,28 @@ IF (TD_LINUX)
|
||||||
|
|
||||||
ADD_SUBDIRECTORY(tests)
|
ADD_SUBDIRECTORY(tests)
|
||||||
|
|
||||||
|
ELSEIF (TD_DARWIN)
|
||||||
|
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/jni/linux)
|
||||||
|
|
||||||
|
# set the static lib name
|
||||||
|
ADD_LIBRARY(taos_static STATIC ${SRC})
|
||||||
|
TARGET_LINK_LIBRARIES(taos_static common query trpc tutil pthread m)
|
||||||
|
SET_TARGET_PROPERTIES(taos_static PROPERTIES OUTPUT_NAME "taos_static")
|
||||||
|
SET_TARGET_PROPERTIES(taos_static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
|
||||||
|
|
||||||
|
# generate dynamic library (*.dylib)
|
||||||
|
ADD_LIBRARY(taos SHARED ${SRC})
|
||||||
|
TARGET_LINK_LIBRARIES(taos common query trpc tutil pthread m)
|
||||||
|
SET_TARGET_PROPERTIES(taos PROPERTIES CLEAN_DIRECT_OUTPUT 1)
|
||||||
|
|
||||||
|
#set version of .dylib
|
||||||
|
#VERSION dylib version
|
||||||
|
#SOVERSION dylib version
|
||||||
|
#MESSAGE(STATUS "build version ${TD_VER_NUMBER}")
|
||||||
|
SET_TARGET_PROPERTIES(taos PROPERTIES VERSION ${TD_VER_NUMBER} SOVERSION 1)
|
||||||
|
|
||||||
|
ADD_SUBDIRECTORY(tests)
|
||||||
|
|
||||||
ELSEIF (TD_WINDOWS)
|
ELSEIF (TD_WINDOWS)
|
||||||
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/jni/windows)
|
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/jni/windows)
|
||||||
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/jni/windows/win32)
|
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/jni/windows/win32)
|
||||||
|
@ -49,12 +71,12 @@ ELSEIF (TD_DARWIN)
|
||||||
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/jni/linux)
|
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/jni/linux)
|
||||||
|
|
||||||
ADD_LIBRARY(taos_static STATIC ${SRC})
|
ADD_LIBRARY(taos_static STATIC ${SRC})
|
||||||
TARGET_LINK_LIBRARIES(taos_static trpc tutil pthread m)
|
TARGET_LINK_LIBRARIES(taos_static query trpc tutil pthread m)
|
||||||
SET_TARGET_PROPERTIES(taos_static PROPERTIES OUTPUT_NAME "taos_static")
|
SET_TARGET_PROPERTIES(taos_static PROPERTIES OUTPUT_NAME "taos_static")
|
||||||
|
|
||||||
# generate dynamic library (*.dylib)
|
# generate dynamic library (*.dylib)
|
||||||
ADD_LIBRARY(taos SHARED ${SRC})
|
ADD_LIBRARY(taos SHARED ${SRC})
|
||||||
TARGET_LINK_LIBRARIES(taos trpc tutil pthread m)
|
TARGET_LINK_LIBRARIES(taos query trpc tutil pthread m)
|
||||||
|
|
||||||
SET_TARGET_PROPERTIES(taos PROPERTIES CLEAN_DIRECT_OUTPUT 1)
|
SET_TARGET_PROPERTIES(taos PROPERTIES CLEAN_DIRECT_OUTPUT 1)
|
||||||
|
|
||||||
|
|
|
@ -749,7 +749,10 @@ static int32_t tscProcessCurrentUser(SSqlObj *pSql) {
|
||||||
|
|
||||||
static int32_t tscProcessCurrentDB(SSqlObj *pSql) {
|
static int32_t tscProcessCurrentDB(SSqlObj *pSql) {
|
||||||
char db[TSDB_DB_NAME_LEN] = {0};
|
char db[TSDB_DB_NAME_LEN] = {0};
|
||||||
|
|
||||||
|
pthread_mutex_lock(&pSql->pTscObj->mutex);
|
||||||
extractDBName(pSql->pTscObj->db, db);
|
extractDBName(pSql->pTscObj->db, db);
|
||||||
|
pthread_mutex_unlock(&pSql->pTscObj->mutex);
|
||||||
|
|
||||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, pSql->cmd.clauseIndex);
|
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, pSql->cmd.clauseIndex);
|
||||||
|
|
||||||
|
|
|
@ -905,6 +905,13 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql) {
|
||||||
return tscInvalidSQLErrMsg(pCmd->payload, "keyword TAGS expected", sToken.z);
|
return tscInvalidSQLErrMsg(pCmd->payload, "keyword TAGS expected", sToken.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
index = 0;
|
||||||
|
sToken = tStrGetToken(sql, &index, false, 0, NULL);
|
||||||
|
sql += index;
|
||||||
|
if (sToken.type != TK_LP) {
|
||||||
|
return tscInvalidSQLErrMsg(pCmd->payload, NULL, sToken.z);
|
||||||
|
}
|
||||||
|
|
||||||
SKVRowBuilder kvRowBuilder = {0};
|
SKVRowBuilder kvRowBuilder = {0};
|
||||||
if (tdInitKVRowBuilder(&kvRowBuilder) < 0) {
|
if (tdInitKVRowBuilder(&kvRowBuilder) < 0) {
|
||||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
|
@ -1554,6 +1561,7 @@ void tscImportDataFromFile(SSqlObj *pSql) {
|
||||||
tscError("%p failed to open file %s to load data from file, code:%s", pSql, pCmd->payload, tstrerror(pSql->res.code));
|
tscError("%p failed to open file %s to load data from file, code:%s", pSql, pCmd->payload, tstrerror(pSql->res.code));
|
||||||
|
|
||||||
tfree(pSupporter);
|
tfree(pSupporter);
|
||||||
|
taos_free_result(pNew);
|
||||||
tscAsyncResultOnError(pSql);
|
tscAsyncResultOnError(pSql);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,10 +13,12 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef __APPLE__
|
||||||
#define _BSD_SOURCE
|
#define _BSD_SOURCE
|
||||||
#define _XOPEN_SOURCE 500
|
#define _XOPEN_SOURCE 500
|
||||||
#define _DEFAULT_SOURCE
|
#define _DEFAULT_SOURCE
|
||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
|
#endif // __APPLE__
|
||||||
|
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "ttype.h"
|
#include "ttype.h"
|
||||||
|
@ -60,7 +62,7 @@ static int32_t setShowInfo(SSqlObj* pSql, SSqlInfo* pInfo);
|
||||||
static char* getAccountId(SSqlObj* pSql);
|
static char* getAccountId(SSqlObj* pSql);
|
||||||
|
|
||||||
static bool has(SArray* pFieldList, int32_t startIdx, const char* name);
|
static bool has(SArray* pFieldList, int32_t startIdx, const char* name);
|
||||||
static char* getCurrentDBName(SSqlObj* pSql);
|
static char* cloneCurrentDBName(SSqlObj* pSql);
|
||||||
static bool hasSpecifyDB(SStrToken* pTableName);
|
static bool hasSpecifyDB(SStrToken* pTableName);
|
||||||
static bool validateTableColumnInfo(SArray* pFieldList, SSqlCmd* pCmd);
|
static bool validateTableColumnInfo(SArray* pFieldList, SSqlCmd* pCmd);
|
||||||
static bool validateTagParams(SArray* pTagsList, SArray* pFieldList, SSqlCmd* pCmd);
|
static bool validateTagParams(SArray* pTagsList, SArray* pFieldList, SSqlCmd* pCmd);
|
||||||
|
@ -921,16 +923,19 @@ int32_t tscSetTableFullName(STableMetaInfo* pTableMetaInfo, SStrToken* pTableNam
|
||||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
||||||
}
|
}
|
||||||
} else { // get current DB name first, and then set it into path
|
} else { // get current DB name first, and then set it into path
|
||||||
char* t = getCurrentDBName(pSql);
|
char* t = cloneCurrentDBName(pSql);
|
||||||
if (strlen(t) == 0) {
|
if (strlen(t) == 0) {
|
||||||
return TSDB_CODE_TSC_DB_NOT_SELECTED;
|
return TSDB_CODE_TSC_DB_NOT_SELECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
code = tNameFromString(&pTableMetaInfo->name, t, T_NAME_ACCT | T_NAME_DB);
|
code = tNameFromString(&pTableMetaInfo->name, t, T_NAME_ACCT | T_NAME_DB);
|
||||||
if (code != 0) {
|
if (code != 0) {
|
||||||
|
free(t);
|
||||||
return TSDB_CODE_TSC_DB_NOT_SELECTED;
|
return TSDB_CODE_TSC_DB_NOT_SELECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(t);
|
||||||
|
|
||||||
if (pTableName->n >= TSDB_TABLE_NAME_LEN) {
|
if (pTableName->n >= TSDB_TABLE_NAME_LEN) {
|
||||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
||||||
}
|
}
|
||||||
|
@ -1244,8 +1249,12 @@ static bool has(SArray* pFieldList, int32_t startIdx, const char* name) {
|
||||||
|
|
||||||
static char* getAccountId(SSqlObj* pSql) { return pSql->pTscObj->acctId; }
|
static char* getAccountId(SSqlObj* pSql) { return pSql->pTscObj->acctId; }
|
||||||
|
|
||||||
static char* getCurrentDBName(SSqlObj* pSql) {
|
static char* cloneCurrentDBName(SSqlObj* pSql) {
|
||||||
return pSql->pTscObj->db;
|
pthread_mutex_lock(&pSql->pTscObj->mutex);
|
||||||
|
char *p = strdup(pSql->pTscObj->db);
|
||||||
|
pthread_mutex_unlock(&pSql->pTscObj->mutex);
|
||||||
|
|
||||||
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* length limitation, strstr cannot be applied */
|
/* length limitation, strstr cannot be applied */
|
||||||
|
@ -4300,6 +4309,77 @@ static void doAddJoinTagsColumnsIntoTagList(SSqlCmd* pCmd, SQueryInfo* pQueryInf
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t validateTagCondExpr(SSqlCmd* pCmd, tExprNode *p) {
|
||||||
|
const char *msg1 = "invalid tag operator";
|
||||||
|
const char* msg2 = "not supported filter condition";
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (p->nodeType != TSQL_NODE_EXPR) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!p->_node.pLeft || !p->_node.pRight) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IS_ARITHMETIC_OPTR(p->_node.optr)) {
|
||||||
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IS_RELATION_OPTR(p->_node.optr)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
tVariant * vVariant = NULL;
|
||||||
|
int32_t schemaType = -1;
|
||||||
|
|
||||||
|
if (p->_node.pLeft->nodeType == TSQL_NODE_VALUE && p->_node.pRight->nodeType == TSQL_NODE_COL) {
|
||||||
|
if (!p->_node.pRight->pSchema) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
vVariant = p->_node.pLeft->pVal;
|
||||||
|
schemaType = p->_node.pRight->pSchema->type;
|
||||||
|
} else if (p->_node.pLeft->nodeType == TSQL_NODE_COL && p->_node.pRight->nodeType == TSQL_NODE_VALUE) {
|
||||||
|
if (!p->_node.pLeft->pSchema) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
vVariant = p->_node.pRight->pVal;
|
||||||
|
schemaType = p->_node.pLeft->pSchema->type;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (schemaType >= TSDB_DATA_TYPE_TINYINT && schemaType <= TSDB_DATA_TYPE_BIGINT) {
|
||||||
|
schemaType = TSDB_DATA_TYPE_BIGINT;
|
||||||
|
} else if (schemaType == TSDB_DATA_TYPE_FLOAT || schemaType == TSDB_DATA_TYPE_DOUBLE) {
|
||||||
|
schemaType = TSDB_DATA_TYPE_DOUBLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t retVal = TSDB_CODE_SUCCESS;
|
||||||
|
if (schemaType == TSDB_DATA_TYPE_BINARY) {
|
||||||
|
char *tmp = calloc(1, vVariant->nLen + TSDB_NCHAR_SIZE);
|
||||||
|
retVal = tVariantDump(vVariant, tmp, schemaType, false);
|
||||||
|
free(tmp);
|
||||||
|
} else if (schemaType == TSDB_DATA_TYPE_NCHAR) {
|
||||||
|
// pRight->val.nLen + 1 is larger than the actual nchar string length
|
||||||
|
char *tmp = calloc(1, (vVariant->nLen + 1) * TSDB_NCHAR_SIZE);
|
||||||
|
retVal = tVariantDump(vVariant, tmp, schemaType, false);
|
||||||
|
free(tmp);
|
||||||
|
} else {
|
||||||
|
double tmp;
|
||||||
|
retVal = tVariantDump(vVariant, (char*)&tmp, schemaType, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (retVal != TSDB_CODE_SUCCESS) {
|
||||||
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
|
||||||
|
}
|
||||||
|
}while (0);
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t getTagQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondExpr* pCondExpr, tSQLExpr** pExpr) {
|
static int32_t getTagQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondExpr* pCondExpr, tSQLExpr** pExpr) {
|
||||||
int32_t ret = TSDB_CODE_SUCCESS;
|
int32_t ret = TSDB_CODE_SUCCESS;
|
||||||
|
|
||||||
|
@ -4342,6 +4422,10 @@ static int32_t getTagQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondE
|
||||||
tsSetSTableQueryCond(&pQueryInfo->tagCond, uid, &bw);
|
tsSetSTableQueryCond(&pQueryInfo->tagCond, uid, &bw);
|
||||||
doCompactQueryExpr(pExpr);
|
doCompactQueryExpr(pExpr);
|
||||||
|
|
||||||
|
if (ret == TSDB_CODE_SUCCESS) {
|
||||||
|
ret = validateTagCondExpr(pCmd, p);
|
||||||
|
}
|
||||||
|
|
||||||
tSqlExprDestroy(p1);
|
tSqlExprDestroy(p1);
|
||||||
tExprTreeDestroy(p, NULL);
|
tExprTreeDestroy(p, NULL);
|
||||||
|
|
||||||
|
@ -4349,6 +4433,10 @@ static int32_t getTagQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondE
|
||||||
if (pQueryInfo->tagCond.pCond != NULL && taosArrayGetSize(pQueryInfo->tagCond.pCond) > 0 && !UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
|
if (pQueryInfo->tagCond.pCond != NULL && taosArrayGetSize(pQueryInfo->tagCond.pCond) > 0 && !UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
|
||||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "filter on tag not supported for normal table");
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "filter on tag not supported for normal table");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ret) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pCondExpr->pTagCond = NULL;
|
pCondExpr->pTagCond = NULL;
|
||||||
|
|
|
@ -1251,7 +1251,9 @@ int32_t tscBuildShowMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
|
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
|
||||||
|
|
||||||
if (tNameIsEmpty(&pTableMetaInfo->name)) {
|
if (tNameIsEmpty(&pTableMetaInfo->name)) {
|
||||||
|
pthread_mutex_lock(&pObj->mutex);
|
||||||
tstrncpy(pShowMsg->db, pObj->db, sizeof(pShowMsg->db));
|
tstrncpy(pShowMsg->db, pObj->db, sizeof(pShowMsg->db));
|
||||||
|
pthread_mutex_unlock(&pObj->mutex);
|
||||||
} else {
|
} else {
|
||||||
tNameGetFullDbName(&pTableMetaInfo->name, pShowMsg->db);
|
tNameGetFullDbName(&pTableMetaInfo->name, pShowMsg->db);
|
||||||
}
|
}
|
||||||
|
@ -1611,9 +1613,14 @@ int tscBuildConnectMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
|
|
||||||
// TODO refactor full_name
|
// TODO refactor full_name
|
||||||
char *db; // ugly code to move the space
|
char *db; // ugly code to move the space
|
||||||
|
|
||||||
|
pthread_mutex_lock(&pObj->mutex);
|
||||||
db = strstr(pObj->db, TS_PATH_DELIMITER);
|
db = strstr(pObj->db, TS_PATH_DELIMITER);
|
||||||
|
|
||||||
db = (db == NULL) ? pObj->db : db + 1;
|
db = (db == NULL) ? pObj->db : db + 1;
|
||||||
tstrncpy(pConnect->db, db, sizeof(pConnect->db));
|
tstrncpy(pConnect->db, db, sizeof(pConnect->db));
|
||||||
|
pthread_mutex_unlock(&pObj->mutex);
|
||||||
|
|
||||||
tstrncpy(pConnect->clientVersion, version, sizeof(pConnect->clientVersion));
|
tstrncpy(pConnect->clientVersion, version, sizeof(pConnect->clientVersion));
|
||||||
tstrncpy(pConnect->msgVersion, "", sizeof(pConnect->msgVersion));
|
tstrncpy(pConnect->msgVersion, "", sizeof(pConnect->msgVersion));
|
||||||
|
|
||||||
|
@ -2131,10 +2138,13 @@ int tscProcessConnectRsp(SSqlObj *pSql) {
|
||||||
|
|
||||||
SConnectRsp *pConnect = (SConnectRsp *)pRes->pRsp;
|
SConnectRsp *pConnect = (SConnectRsp *)pRes->pRsp;
|
||||||
tstrncpy(pObj->acctId, pConnect->acctId, sizeof(pObj->acctId)); // copy acctId from response
|
tstrncpy(pObj->acctId, pConnect->acctId, sizeof(pObj->acctId)); // copy acctId from response
|
||||||
|
|
||||||
|
pthread_mutex_lock(&pObj->mutex);
|
||||||
int32_t len = sprintf(temp, "%s%s%s", pObj->acctId, TS_PATH_DELIMITER, pObj->db);
|
int32_t len = sprintf(temp, "%s%s%s", pObj->acctId, TS_PATH_DELIMITER, pObj->db);
|
||||||
|
|
||||||
assert(len <= sizeof(pObj->db));
|
assert(len <= sizeof(pObj->db));
|
||||||
tstrncpy(pObj->db, temp, sizeof(pObj->db));
|
tstrncpy(pObj->db, temp, sizeof(pObj->db));
|
||||||
|
pthread_mutex_unlock(&pObj->mutex);
|
||||||
|
|
||||||
if (pConnect->epSet.numOfEps > 0) {
|
if (pConnect->epSet.numOfEps > 0) {
|
||||||
tscEpSetHtons(&pConnect->epSet);
|
tscEpSetHtons(&pConnect->epSet);
|
||||||
|
@ -2161,11 +2171,18 @@ int tscProcessConnectRsp(SSqlObj *pSql) {
|
||||||
int tscProcessUseDbRsp(SSqlObj *pSql) {
|
int tscProcessUseDbRsp(SSqlObj *pSql) {
|
||||||
STscObj * pObj = pSql->pTscObj;
|
STscObj * pObj = pSql->pTscObj;
|
||||||
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0, 0);
|
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0, 0);
|
||||||
return tNameExtractFullName(&pTableMetaInfo->name, pObj->db);
|
|
||||||
|
pthread_mutex_lock(&pObj->mutex);
|
||||||
|
int ret = tNameExtractFullName(&pTableMetaInfo->name, pObj->db);
|
||||||
|
pthread_mutex_unlock(&pObj->mutex);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tscProcessDropDbRsp(SSqlObj *pSql) {
|
int tscProcessDropDbRsp(SSqlObj *pSql) {
|
||||||
pSql->pTscObj->db[0] = 0;
|
//TODO LOCK DB WHEN MODIFY IT
|
||||||
|
//pSql->pTscObj->db[0] = 0;
|
||||||
|
|
||||||
taosHashEmpty(tscTableMetaInfo);
|
taosHashEmpty(tscTableMetaInfo);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -295,6 +295,10 @@ void taos_close(TAOS *taos) {
|
||||||
|
|
||||||
tscDebug("%p HB is freed", pHb);
|
tscDebug("%p HB is freed", pHb);
|
||||||
taosReleaseRef(tscObjRef, pHb->self);
|
taosReleaseRef(tscObjRef, pHb->self);
|
||||||
|
#ifdef __APPLE__
|
||||||
|
// to satisfy later tsem_destroy in taos_free_result
|
||||||
|
tsem_init(&pHb->rspSem, 0, 0);
|
||||||
|
#endif // __APPLE__
|
||||||
taos_free_result(pHb);
|
taos_free_result(pHb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1942,6 +1942,10 @@ SSqlObj* createSimpleSubObj(SSqlObj* pSql, __async_cb_func_t fp, void* param, in
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tscAddSubqueryInfo(pCmd) != TSDB_CODE_SUCCESS) {
|
if (tscAddSubqueryInfo(pCmd) != TSDB_CODE_SUCCESS) {
|
||||||
|
#ifdef __APPLE__
|
||||||
|
// to satisfy later tsem_destroy in taos_free_result
|
||||||
|
tsem_init(&pNew->rspSem, 0, 0);
|
||||||
|
#endif // __APPLE__
|
||||||
tscFreeSqlObj(pNew);
|
tscFreeSqlObj(pNew);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -2508,7 +2512,11 @@ bool tscSetSqlOwner(SSqlObj* pSql) {
|
||||||
SSqlRes* pRes = &pSql->res;
|
SSqlRes* pRes = &pSql->res;
|
||||||
|
|
||||||
// set the sql object owner
|
// set the sql object owner
|
||||||
|
#ifdef __APPLE__
|
||||||
|
pthread_t threadId = (pthread_t)taosGetSelfPthreadId();
|
||||||
|
#else // __APPLE__
|
||||||
uint64_t threadId = taosGetSelfPthreadId();
|
uint64_t threadId = taosGetSelfPthreadId();
|
||||||
|
#endif // __APPLE__
|
||||||
if (atomic_val_compare_exchange_64(&pSql->owner, 0, threadId) != 0) {
|
if (atomic_val_compare_exchange_64(&pSql->owner, 0, threadId) != 0) {
|
||||||
pRes->code = TSDB_CODE_QRY_IN_EXEC;
|
pRes->code = TSDB_CODE_QRY_IN_EXEC;
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -137,7 +137,7 @@ int32_t tsTableIncStepPerVnode = TSDB_TABLES_STEP;
|
||||||
int8_t tsEnableBalance = 1;
|
int8_t tsEnableBalance = 1;
|
||||||
int8_t tsAlternativeRole = 0;
|
int8_t tsAlternativeRole = 0;
|
||||||
int32_t tsBalanceInterval = 300; // seconds
|
int32_t tsBalanceInterval = 300; // seconds
|
||||||
int32_t tsOfflineThreshold = 86400 * 100; // seconds 10days
|
int32_t tsOfflineThreshold = 86400 * 100; // seconds 100 days
|
||||||
int32_t tsMnodeEqualVnodeNum = 4;
|
int32_t tsMnodeEqualVnodeNum = 4;
|
||||||
int8_t tsEnableFlowCtrl = 1;
|
int8_t tsEnableFlowCtrl = 1;
|
||||||
int8_t tsEnableSlaveQuery = 1;
|
int8_t tsEnableSlaveQuery = 1;
|
||||||
|
@ -550,7 +550,7 @@ static void doInitGlobalConfig(void) {
|
||||||
cfg.valType = TAOS_CFG_VTYPE_INT32;
|
cfg.valType = TAOS_CFG_VTYPE_INT32;
|
||||||
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW;
|
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW;
|
||||||
cfg.minValue = 3;
|
cfg.minValue = 3;
|
||||||
cfg.maxValue = 7200000;
|
cfg.maxValue = 86400 * 365;
|
||||||
cfg.ptrLength = 0;
|
cfg.ptrLength = 0;
|
||||||
cfg.unitType = TAOS_CFG_UTYPE_SECOND;
|
cfg.unitType = TAOS_CFG_UTYPE_SECOND;
|
||||||
taosInitConfigOption(cfg);
|
taosInitConfigOption(cfg);
|
||||||
|
|
|
@ -430,7 +430,7 @@ static FORCE_INLINE int32_t convertToInteger(tVariant *pVariant, int64_t *result
|
||||||
}
|
}
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
if (IS_SIGNED_NUMERIC_TYPE(pVariant->nType)) {
|
if (IS_SIGNED_NUMERIC_TYPE(pVariant->nType) || (pVariant->nType == TSDB_DATA_TYPE_BOOL)) {
|
||||||
*result = pVariant->i64;
|
*result = pVariant->i64;
|
||||||
} else if (IS_UNSIGNED_NUMERIC_TYPE(pVariant->nType)) {
|
} else if (IS_UNSIGNED_NUMERIC_TYPE(pVariant->nType)) {
|
||||||
*result = pVariant->u64;
|
*result = pVariant->u64;
|
||||||
|
@ -775,7 +775,7 @@ int32_t tVariantDump(tVariant *pVariant, char *payload, int16_t type, bool inclu
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
wcsncpy((wchar_t *)p, pVariant->wpz, pVariant->nLen);
|
memcpy(p, pVariant->wpz, pVariant->nLen);
|
||||||
newlen = pVariant->nLen;
|
newlen = pVariant->nLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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.17-dist.jar ${LIBRARY_OUTPUT_PATH}
|
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/target/taos-jdbcdriver-2.0.18-dist.jar ${LIBRARY_OUTPUT_PATH}
|
||||||
COMMAND mvn -Dmaven.test.skip=true clean -f ${CMAKE_CURRENT_SOURCE_DIR}/pom.xml
|
COMMAND mvn -Dmaven.test.skip=true clean -f ${CMAKE_CURRENT_SOURCE_DIR}/pom.xml
|
||||||
COMMENT "build jdbc driver")
|
COMMENT "build jdbc driver")
|
||||||
ADD_CUSTOM_TARGET(${JDBC_TARGET_NAME} ALL WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH} DEPENDS ${JDBC_CMD_NAME})
|
ADD_CUSTOM_TARGET(${JDBC_TARGET_NAME} ALL WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH} DEPENDS ${JDBC_CMD_NAME})
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
<groupId>com.taosdata.jdbc</groupId>
|
<groupId>com.taosdata.jdbc</groupId>
|
||||||
<artifactId>taos-jdbcdriver</artifactId>
|
<artifactId>taos-jdbcdriver</artifactId>
|
||||||
<version>2.0.17</version>
|
<version>2.0.18</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>JDBCDriver</name>
|
<name>JDBCDriver</name>
|
||||||
|
|
|
@ -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.17</version>
|
<version>2.0.18</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>
|
||||||
|
@ -126,7 +126,7 @@
|
||||||
<include>**/*Test.java</include>
|
<include>**/*Test.java</include>
|
||||||
</includes>
|
</includes>
|
||||||
<excludes>
|
<excludes>
|
||||||
<exclude>**/BatchInsertTest.java</exclude>
|
<exclude>**/AppMemoryLeakTest.java</exclude>
|
||||||
<exclude>**/FailOverTest.java</exclude>
|
<exclude>**/FailOverTest.java</exclude>
|
||||||
</excludes>
|
</excludes>
|
||||||
<testFailureIgnore>true</testFailureIgnore>
|
<testFailureIgnore>true</testFailureIgnore>
|
||||||
|
|
|
@ -19,9 +19,12 @@ import java.util.Map;
|
||||||
|
|
||||||
public abstract class TSDBConstants {
|
public abstract class TSDBConstants {
|
||||||
|
|
||||||
|
public static final String STATEMENT_CLOSED = "Statement already closed.";
|
||||||
public static final String DEFAULT_PORT = "6200";
|
public static final String DEFAULT_PORT = "6200";
|
||||||
public static final String UNSUPPORT_METHOD_EXCEPTIONZ_MSG = "this operation is NOT supported currently!";
|
public static final String UNSUPPORT_METHOD_EXCEPTIONZ_MSG = "this operation is NOT supported currently!";
|
||||||
public static final String INVALID_VARIABLES = "invalid variables";
|
public static final String INVALID_VARIABLES = "invalid variables";
|
||||||
|
public static final String RESULT_SET_IS_CLOSED = "resultSet is closed.";
|
||||||
|
|
||||||
public static Map<Integer, String> DATATYPE_MAP = null;
|
public static Map<Integer, String> DATATYPE_MAP = null;
|
||||||
|
|
||||||
public static final long JNI_NULL_POINTER = 0L;
|
public static final long JNI_NULL_POINTER = 0L;
|
||||||
|
@ -74,7 +77,7 @@ public abstract class TSDBConstants {
|
||||||
}
|
}
|
||||||
|
|
||||||
static {
|
static {
|
||||||
DATATYPE_MAP = new HashMap<Integer, String>();
|
DATATYPE_MAP = new HashMap<>();
|
||||||
DATATYPE_MAP.put(1, "BOOL");
|
DATATYPE_MAP.put(1, "BOOL");
|
||||||
DATATYPE_MAP.put(2, "TINYINT");
|
DATATYPE_MAP.put(2, "TINYINT");
|
||||||
DATATYPE_MAP.put(3, "SMALLINT");
|
DATATYPE_MAP.put(3, "SMALLINT");
|
||||||
|
|
|
@ -100,7 +100,6 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
|
||||||
* order to process those supported SQLs.
|
* order to process those supported SQLs.
|
||||||
*/
|
*/
|
||||||
private void preprocessSql() {
|
private void preprocessSql() {
|
||||||
|
|
||||||
/***** For processing some of Spark SQLs*****/
|
/***** For processing some of Spark SQLs*****/
|
||||||
// should replace it first
|
// should replace it first
|
||||||
this.rawSql = this.rawSql.replaceAll("or (.*) is null", "");
|
this.rawSql = this.rawSql.replaceAll("or (.*) is null", "");
|
||||||
|
@ -149,7 +148,6 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
|
||||||
rawSql = rawSql.replace(matcher.group(1), tableFullName);
|
rawSql = rawSql.replace(matcher.group(1), tableFullName);
|
||||||
}
|
}
|
||||||
/***** for inner queries *****/
|
/***** for inner queries *****/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -196,7 +194,7 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setNull(int parameterIndex, int sqlType) throws SQLException {
|
public void setNull(int parameterIndex, int sqlType) throws SQLException {
|
||||||
setObject(parameterIndex, new String("NULL"));
|
setObject(parameterIndex, "NULL");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -123,11 +123,21 @@ public class TSDBResultSet implements ResultSet {
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> T unwrap(Class<T> iface) throws SQLException {
|
public <T> T unwrap(Class<T> iface) throws SQLException {
|
||||||
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
if (isClosed())
|
||||||
|
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.RESULT_SET_IS_CLOSED));
|
||||||
|
|
||||||
|
try {
|
||||||
|
return iface.cast(this);
|
||||||
|
} catch (ClassCastException cce) {
|
||||||
|
throw new SQLException("Unable to unwrap to " + iface.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isWrapperFor(Class<?> iface) throws SQLException {
|
public boolean isWrapperFor(Class<?> iface) throws SQLException {
|
||||||
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
if (isClosed())
|
||||||
|
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.RESULT_SET_IS_CLOSED));
|
||||||
|
|
||||||
|
return iface.isInstance(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean next() throws SQLException {
|
public boolean next() throws SQLException {
|
||||||
|
|
|
@ -52,12 +52,18 @@ public class TSDBStatement implements Statement {
|
||||||
this.isClosed = false;
|
this.isClosed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public <T> T unwrap(Class<T> iface) throws SQLException {
|
public <T> T unwrap(Class<T> iface) throws SQLException {
|
||||||
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
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 {
|
public boolean isWrapperFor(Class<?> iface) throws SQLException {
|
||||||
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
return iface.isInstance(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResultSet executeQuery(String sql) throws SQLException {
|
public ResultSet executeQuery(String sql) throws SQLException {
|
||||||
|
@ -130,10 +136,15 @@ public class TSDBStatement implements Statement {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMaxFieldSize(int max) throws SQLException {
|
public void setMaxFieldSize(int max) throws SQLException {
|
||||||
|
if (isClosed())
|
||||||
|
throw new SQLException(TSDBConstants.STATEMENT_CLOSED);
|
||||||
|
|
||||||
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMaxRows() throws SQLException {
|
public int getMaxRows() throws SQLException {
|
||||||
|
if (isClosed())
|
||||||
|
throw new SQLException(TSDBConstants.STATEMENT_CLOSED);
|
||||||
// always set maxRows to zero, meaning unlimitted rows in a resultSet
|
// always set maxRows to zero, meaning unlimitted rows in a resultSet
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,28 +15,28 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class RestfulResultSet implements ResultSet {
|
public class RestfulResultSet implements ResultSet {
|
||||||
private static final String RESULT_SET_IS_CLOSED = "resultSet is closed.";
|
|
||||||
private volatile boolean isClosed;
|
private volatile boolean isClosed;
|
||||||
private int pos = -1;
|
private int pos = -1;
|
||||||
|
|
||||||
private final String database;
|
private final String database;
|
||||||
private final Statement statement;
|
private final Statement statement;
|
||||||
// data
|
// data
|
||||||
private ArrayList<ArrayList<Object>> resultSet;
|
private ArrayList<ArrayList<Object>> resultSet = new ArrayList<>();
|
||||||
// meta
|
// meta
|
||||||
private ArrayList<String> columnNames;
|
private ArrayList<String> columnNames = new ArrayList<>();
|
||||||
private ArrayList<Field> columns;
|
private ArrayList<Field> columns = new ArrayList<>();
|
||||||
private RestfulResultSetMetaData metaData;
|
private RestfulResultSetMetaData metaData;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 由一个result的Json构造结果集,对应执行show databases, show tables等这些语句,返回结果集,但无法获取结果集对应的meta,统一当成String处理
|
* 由一个result的Json构造结果集,对应执行show databases, show tables等这些语句,返回结果集,但无法获取结果集对应的meta,统一当成String处理
|
||||||
|
*
|
||||||
|
* @param resultJson: 包含data信息的结果集,有sql返回的结果集
|
||||||
***/
|
***/
|
||||||
public RestfulResultSet(String database, Statement statement, JSONObject resultJson) {
|
public RestfulResultSet(String database, Statement statement, JSONObject resultJson) {
|
||||||
this.database = database;
|
this.database = database;
|
||||||
this.statement = statement;
|
this.statement = statement;
|
||||||
// row data
|
// row data
|
||||||
JSONArray data = resultJson.getJSONArray("data");
|
JSONArray data = resultJson.getJSONArray("data");
|
||||||
resultSet = new ArrayList<>();
|
|
||||||
int columnIndex = 0;
|
int columnIndex = 0;
|
||||||
for (; columnIndex < data.size(); columnIndex++) {
|
for (; columnIndex < data.size(); columnIndex++) {
|
||||||
ArrayList oneRow = new ArrayList<>();
|
ArrayList oneRow = new ArrayList<>();
|
||||||
|
@ -48,15 +48,13 @@ public class RestfulResultSet implements ResultSet {
|
||||||
}
|
}
|
||||||
|
|
||||||
// column only names
|
// column only names
|
||||||
columnNames = new ArrayList<>();
|
|
||||||
columns = new ArrayList<>();
|
|
||||||
JSONArray head = resultJson.getJSONArray("head");
|
JSONArray head = resultJson.getJSONArray("head");
|
||||||
for (int i = 0; i < head.size(); i++) {
|
for (int i = 0; i < head.size(); i++) {
|
||||||
String name = head.getString(i);
|
String name = head.getString(i);
|
||||||
columnNames.add(name);
|
columnNames.add(name);
|
||||||
columns.add(new Field(name, "", 0, ""));
|
columns.add(new Field(name, "", 0, ""));
|
||||||
}
|
}
|
||||||
this.metaData = new RestfulResultSetMetaData(this.database, columns);
|
this.metaData = new RestfulResultSetMetaData(this.database, columns, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -78,7 +76,7 @@ public class RestfulResultSet implements ResultSet {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.columns = newColumns;
|
this.columns = newColumns;
|
||||||
this.metaData = new RestfulResultSetMetaData(this.database, this.columns);
|
this.metaData = new RestfulResultSetMetaData(this.database, this.columns, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Field findField(String columnName, List<JSONObject> fieldJsonList) {
|
public Field findField(String columnName, List<JSONObject> fieldJsonList) {
|
||||||
|
@ -91,7 +89,6 @@ public class RestfulResultSet implements ResultSet {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,10 +109,9 @@ public class RestfulResultSet implements ResultSet {
|
||||||
@Override
|
@Override
|
||||||
public boolean next() throws SQLException {
|
public boolean next() throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(RESULT_SET_IS_CLOSED));
|
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.RESULT_SET_IS_CLOSED));
|
||||||
|
|
||||||
if (pos < resultSet.size() - 1) {
|
|
||||||
pos++;
|
pos++;
|
||||||
|
if (pos <= resultSet.size() - 1) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -131,37 +127,38 @@ public class RestfulResultSet implements ResultSet {
|
||||||
@Override
|
@Override
|
||||||
public boolean wasNull() throws SQLException {
|
public boolean wasNull() throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(RESULT_SET_IS_CLOSED));
|
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.RESULT_SET_IS_CLOSED));
|
||||||
return resultSet.isEmpty();
|
return resultSet.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getString(int columnIndex) throws SQLException {
|
public String getString(int columnIndex) throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(RESULT_SET_IS_CLOSED));
|
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.RESULT_SET_IS_CLOSED));
|
||||||
|
|
||||||
if (columnIndex > resultSet.get(pos).size()) {
|
if (columnIndex > resultSet.get(pos).size()) {
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg("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()));
|
||||||
}
|
}
|
||||||
return resultSet.get(pos).get(columnIndex - 1).toString();
|
|
||||||
|
columnIndex = getTrueColumnIndex(columnIndex);
|
||||||
|
return resultSet.get(pos).get(columnIndex).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean getBoolean(int columnIndex) throws SQLException {
|
public boolean getBoolean(int columnIndex) throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(RESULT_SET_IS_CLOSED));
|
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.RESULT_SET_IS_CLOSED));
|
||||||
|
|
||||||
String result = getString(columnIndex);
|
columnIndex = getTrueColumnIndex(columnIndex);
|
||||||
if (!(result.equals("true") || result.equals("false"))) {
|
int result = getInt(columnIndex);
|
||||||
throw new SQLException("not boolean value");
|
return result == 0 ? false : true;
|
||||||
}
|
|
||||||
return result.equals("true");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte getByte(int columnIndex) throws SQLException {
|
public byte getByte(int columnIndex) throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(RESULT_SET_IS_CLOSED));
|
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.RESULT_SET_IS_CLOSED));
|
||||||
|
|
||||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
}
|
}
|
||||||
|
@ -169,40 +166,55 @@ public class RestfulResultSet implements ResultSet {
|
||||||
@Override
|
@Override
|
||||||
public short getShort(int columnIndex) throws SQLException {
|
public short getShort(int columnIndex) throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(RESULT_SET_IS_CLOSED));
|
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.RESULT_SET_IS_CLOSED));
|
||||||
|
columnIndex = getTrueColumnIndex(columnIndex);
|
||||||
return Short.parseShort(getString(columnIndex));
|
return Short.parseShort(resultSet.get(pos).get(columnIndex).toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getInt(int columnIndex) throws SQLException {
|
public int getInt(int columnIndex) throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(RESULT_SET_IS_CLOSED));
|
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.RESULT_SET_IS_CLOSED));
|
||||||
return Integer.parseInt(getString(columnIndex));
|
columnIndex = getTrueColumnIndex(columnIndex);
|
||||||
|
return Integer.parseInt(resultSet.get(pos).get(columnIndex).toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getLong(int columnIndex) throws SQLException {
|
public long getLong(int columnIndex) throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(RESULT_SET_IS_CLOSED));
|
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.RESULT_SET_IS_CLOSED));
|
||||||
|
columnIndex = getTrueColumnIndex(columnIndex);
|
||||||
return Long.parseLong(getString(columnIndex));
|
return Long.parseLong(resultSet.get(pos).get(columnIndex).toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float getFloat(int columnIndex) throws SQLException {
|
public float getFloat(int columnIndex) throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(RESULT_SET_IS_CLOSED));
|
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.RESULT_SET_IS_CLOSED));
|
||||||
|
columnIndex = getTrueColumnIndex(columnIndex);
|
||||||
return Float.parseFloat(getString(columnIndex));
|
return Float.parseFloat(resultSet.get(pos).get(columnIndex).toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double getDouble(int columnIndex) throws SQLException {
|
public double getDouble(int columnIndex) throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(RESULT_SET_IS_CLOSED));
|
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.RESULT_SET_IS_CLOSED));
|
||||||
|
|
||||||
return Double.parseDouble(getString(columnIndex));
|
columnIndex = getTrueColumnIndex(columnIndex);
|
||||||
|
return Double.parseDouble(resultSet.get(pos).get(columnIndex).toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getTrueColumnIndex(int columnIndex) throws SQLException {
|
||||||
|
if (columnIndex < 1) {
|
||||||
|
throw new SQLException("Column Index out of range, " + columnIndex + " < 1");
|
||||||
|
}
|
||||||
|
|
||||||
|
int numOfCols = resultSet.get(pos).size();
|
||||||
|
if (columnIndex > numOfCols) {
|
||||||
|
throw new SQLException("Column Index out of range, " + columnIndex + " > " + numOfCols);
|
||||||
|
}
|
||||||
|
|
||||||
|
return columnIndex - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************************************************/
|
/*******************************************************************************************************************/
|
||||||
|
@ -210,7 +222,7 @@ public class RestfulResultSet implements ResultSet {
|
||||||
@Override
|
@Override
|
||||||
public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException {
|
public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(RESULT_SET_IS_CLOSED));
|
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.RESULT_SET_IS_CLOSED));
|
||||||
|
|
||||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
}
|
}
|
||||||
|
@ -218,7 +230,7 @@ public class RestfulResultSet implements ResultSet {
|
||||||
@Override
|
@Override
|
||||||
public byte[] getBytes(int columnIndex) throws SQLException {
|
public byte[] getBytes(int columnIndex) throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(RESULT_SET_IS_CLOSED));
|
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.RESULT_SET_IS_CLOSED));
|
||||||
|
|
||||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
}
|
}
|
||||||
|
@ -226,7 +238,7 @@ public class RestfulResultSet implements ResultSet {
|
||||||
@Override
|
@Override
|
||||||
public Date getDate(int columnIndex) throws SQLException {
|
public Date getDate(int columnIndex) throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(RESULT_SET_IS_CLOSED));
|
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.RESULT_SET_IS_CLOSED));
|
||||||
|
|
||||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
}
|
}
|
||||||
|
@ -234,7 +246,7 @@ public class RestfulResultSet implements ResultSet {
|
||||||
@Override
|
@Override
|
||||||
public Time getTime(int columnIndex) throws SQLException {
|
public Time getTime(int columnIndex) throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(RESULT_SET_IS_CLOSED));
|
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.RESULT_SET_IS_CLOSED));
|
||||||
|
|
||||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
}
|
}
|
||||||
|
@ -242,17 +254,18 @@ public class RestfulResultSet implements ResultSet {
|
||||||
@Override
|
@Override
|
||||||
public Timestamp getTimestamp(int columnIndex) throws SQLException {
|
public Timestamp getTimestamp(int columnIndex) throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(RESULT_SET_IS_CLOSED));
|
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.RESULT_SET_IS_CLOSED));
|
||||||
|
|
||||||
String strDate = getString(columnIndex);
|
columnIndex = getTrueColumnIndex(columnIndex);
|
||||||
strDate = strDate.substring(1, strDate.length() - 1);
|
String strDate = resultSet.get(pos).get(columnIndex).toString();
|
||||||
|
// strDate = strDate.substring(1, strDate.length() - 1);
|
||||||
return Timestamp.valueOf(strDate);
|
return Timestamp.valueOf(strDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InputStream getAsciiStream(int columnIndex) throws SQLException {
|
public InputStream getAsciiStream(int columnIndex) throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(RESULT_SET_IS_CLOSED));
|
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.RESULT_SET_IS_CLOSED));
|
||||||
|
|
||||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
}
|
}
|
||||||
|
@ -260,7 +273,7 @@ public class RestfulResultSet implements ResultSet {
|
||||||
@Override
|
@Override
|
||||||
public InputStream getUnicodeStream(int columnIndex) throws SQLException {
|
public InputStream getUnicodeStream(int columnIndex) throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(RESULT_SET_IS_CLOSED));
|
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.RESULT_SET_IS_CLOSED));
|
||||||
|
|
||||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
}
|
}
|
||||||
|
@ -268,17 +281,16 @@ public class RestfulResultSet implements ResultSet {
|
||||||
@Override
|
@Override
|
||||||
public InputStream getBinaryStream(int columnIndex) throws SQLException {
|
public InputStream getBinaryStream(int columnIndex) throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(RESULT_SET_IS_CLOSED));
|
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.RESULT_SET_IS_CLOSED));
|
||||||
|
|
||||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*************************************************************************************************************/
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getString(String columnLabel) throws SQLException {
|
public String getString(String columnLabel) throws SQLException {
|
||||||
if (isClosed())
|
return getString(findColumn(columnLabel));
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(RESULT_SET_IS_CLOSED));
|
|
||||||
|
|
||||||
return getString(findColumn(columnLabel) + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -338,53 +350,44 @@ public class RestfulResultSet implements ResultSet {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Timestamp getTimestamp(String columnLabel) throws SQLException {
|
public Timestamp getTimestamp(String columnLabel) throws SQLException {
|
||||||
if (isClosed())
|
return getTimestamp(findColumn(columnLabel));
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(RESULT_SET_IS_CLOSED));
|
|
||||||
return Timestamp.valueOf(getString(findColumn(columnLabel)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InputStream getAsciiStream(String columnLabel) throws SQLException {
|
public InputStream getAsciiStream(String columnLabel) throws SQLException {
|
||||||
if (isClosed())
|
return getAsciiStream(findColumn(columnLabel));
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(RESULT_SET_IS_CLOSED));
|
|
||||||
|
|
||||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InputStream getUnicodeStream(String columnLabel) throws SQLException {
|
public InputStream getUnicodeStream(String columnLabel) throws SQLException {
|
||||||
if (isClosed())
|
return getUnicodeStream(findColumn(columnLabel));
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(RESULT_SET_IS_CLOSED));
|
|
||||||
|
|
||||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InputStream getBinaryStream(String columnLabel) throws SQLException {
|
public InputStream getBinaryStream(String columnLabel) throws SQLException {
|
||||||
if (isClosed())
|
return getBinaryStream(findColumn(columnLabel));
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(RESULT_SET_IS_CLOSED));
|
|
||||||
|
|
||||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*************************************************************************************************************/
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SQLWarning getWarnings() throws SQLException {
|
public SQLWarning getWarnings() throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(RESULT_SET_IS_CLOSED));
|
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.RESULT_SET_IS_CLOSED));
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void clearWarnings() throws SQLException {
|
public void clearWarnings() throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(RESULT_SET_IS_CLOSED));
|
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.RESULT_SET_IS_CLOSED));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getCursorName() throws SQLException {
|
public String getCursorName() throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(RESULT_SET_IS_CLOSED));
|
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.RESULT_SET_IS_CLOSED));
|
||||||
|
|
||||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
}
|
}
|
||||||
|
@ -392,7 +395,7 @@ public class RestfulResultSet implements ResultSet {
|
||||||
@Override
|
@Override
|
||||||
public ResultSetMetaData getMetaData() throws SQLException {
|
public ResultSetMetaData getMetaData() throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(RESULT_SET_IS_CLOSED));
|
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.RESULT_SET_IS_CLOSED));
|
||||||
|
|
||||||
return this.metaData;
|
return this.metaData;
|
||||||
}
|
}
|
||||||
|
@ -400,7 +403,7 @@ public class RestfulResultSet implements ResultSet {
|
||||||
@Override
|
@Override
|
||||||
public Object getObject(int columnIndex) throws SQLException {
|
public Object getObject(int columnIndex) throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(RESULT_SET_IS_CLOSED));
|
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.RESULT_SET_IS_CLOSED));
|
||||||
|
|
||||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
}
|
}
|
||||||
|
@ -413,15 +416,18 @@ public class RestfulResultSet implements ResultSet {
|
||||||
@Override
|
@Override
|
||||||
public int findColumn(String columnLabel) throws SQLException {
|
public int findColumn(String columnLabel) throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(RESULT_SET_IS_CLOSED));
|
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.RESULT_SET_IS_CLOSED));
|
||||||
|
|
||||||
return columnNames.indexOf(columnLabel);
|
int columnIndex = columnNames.indexOf(columnLabel);
|
||||||
|
if (columnIndex == -1)
|
||||||
|
throw new SQLException("cannot find Column in resultSet");
|
||||||
|
return columnIndex + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Reader getCharacterStream(int columnIndex) throws SQLException {
|
public Reader getCharacterStream(int columnIndex) throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(RESULT_SET_IS_CLOSED));
|
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.RESULT_SET_IS_CLOSED));
|
||||||
|
|
||||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
}
|
}
|
||||||
|
@ -429,7 +435,7 @@ public class RestfulResultSet implements ResultSet {
|
||||||
@Override
|
@Override
|
||||||
public Reader getCharacterStream(String columnLabel) throws SQLException {
|
public Reader getCharacterStream(String columnLabel) throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(RESULT_SET_IS_CLOSED));
|
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.RESULT_SET_IS_CLOSED));
|
||||||
|
|
||||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
}
|
}
|
||||||
|
@ -437,7 +443,7 @@ public class RestfulResultSet implements ResultSet {
|
||||||
@Override
|
@Override
|
||||||
public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
|
public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(RESULT_SET_IS_CLOSED));
|
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.RESULT_SET_IS_CLOSED));
|
||||||
|
|
||||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
}
|
}
|
||||||
|
@ -445,7 +451,7 @@ public class RestfulResultSet implements ResultSet {
|
||||||
@Override
|
@Override
|
||||||
public BigDecimal getBigDecimal(String columnLabel) throws SQLException {
|
public BigDecimal getBigDecimal(String columnLabel) throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(RESULT_SET_IS_CLOSED));
|
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.RESULT_SET_IS_CLOSED));
|
||||||
|
|
||||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
}
|
}
|
||||||
|
@ -453,78 +459,132 @@ public class RestfulResultSet implements ResultSet {
|
||||||
@Override
|
@Override
|
||||||
public boolean isBeforeFirst() throws SQLException {
|
public boolean isBeforeFirst() throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(RESULT_SET_IS_CLOSED));
|
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.RESULT_SET_IS_CLOSED));
|
||||||
|
return this.pos == -1 && this.resultSet.size() != 0;
|
||||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAfterLast() throws SQLException {
|
public boolean isAfterLast() throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(RESULT_SET_IS_CLOSED));
|
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.RESULT_SET_IS_CLOSED));
|
||||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
|
||||||
|
return this.pos >= resultSet.size() && this.resultSet.size() != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isFirst() throws SQLException {
|
public boolean isFirst() throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(RESULT_SET_IS_CLOSED));
|
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.RESULT_SET_IS_CLOSED));
|
||||||
|
|
||||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
return this.pos == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isLast() throws SQLException {
|
public boolean isLast() throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(RESULT_SET_IS_CLOSED));
|
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.RESULT_SET_IS_CLOSED));
|
||||||
|
if (this.resultSet.size() == 0)
|
||||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
return false;
|
||||||
|
return this.pos == (this.resultSet.size() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void beforeFirst() throws SQLException {
|
public void beforeFirst() throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(RESULT_SET_IS_CLOSED));
|
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.RESULT_SET_IS_CLOSED));
|
||||||
|
|
||||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
synchronized (this) {
|
||||||
|
if (this.resultSet.size() > 0) {
|
||||||
|
this.pos = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterLast() throws SQLException {
|
public void afterLast() throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(RESULT_SET_IS_CLOSED));
|
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.RESULT_SET_IS_CLOSED));
|
||||||
|
synchronized (this) {
|
||||||
|
if (this.resultSet.size() > 0) {
|
||||||
|
this.pos = this.resultSet.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean first() throws SQLException {
|
public boolean first() throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(RESULT_SET_IS_CLOSED));
|
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.RESULT_SET_IS_CLOSED));
|
||||||
|
|
||||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
if (this.resultSet.size() == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
synchronized (this) {
|
||||||
|
this.pos = 0;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean last() throws SQLException {
|
public boolean last() throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(RESULT_SET_IS_CLOSED));
|
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.RESULT_SET_IS_CLOSED));
|
||||||
|
if (this.resultSet.size() == 0)
|
||||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
return false;
|
||||||
|
synchronized (this) {
|
||||||
|
this.pos = this.resultSet.size() - 1;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getRow() throws SQLException {
|
public int getRow() throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(RESULT_SET_IS_CLOSED));
|
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.RESULT_SET_IS_CLOSED));
|
||||||
|
int row;
|
||||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
synchronized (this) {
|
||||||
|
if (this.pos < 0 || this.pos >= this.resultSet.size())
|
||||||
|
return 0;
|
||||||
|
row = this.pos + 1;
|
||||||
|
}
|
||||||
|
return row;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean absolute(int row) throws SQLException {
|
public boolean absolute(int row) throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(RESULT_SET_IS_CLOSED));
|
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.RESULT_SET_IS_CLOSED));
|
||||||
|
|
||||||
|
// if (this.resultSet.size() == 0)
|
||||||
|
// return false;
|
||||||
|
//
|
||||||
|
// if (row == 0) {
|
||||||
|
// beforeFirst();
|
||||||
|
// return false;
|
||||||
|
// } else if (row == 1) {
|
||||||
|
// return first();
|
||||||
|
// } else if (row == -1) {
|
||||||
|
// return last();
|
||||||
|
// } else if (row > this.resultSet.size()) {
|
||||||
|
// afterLast();
|
||||||
|
// return false;
|
||||||
|
// } else {
|
||||||
|
// if (row < 0) {
|
||||||
|
// // adjust to reflect after end of result set
|
||||||
|
// int newRowPosition = this.resultSet.size() + row + 1;
|
||||||
|
// if (newRowPosition <= 0) {
|
||||||
|
// beforeFirst();
|
||||||
|
// return false;
|
||||||
|
// } else {
|
||||||
|
// return absolute(newRowPosition);
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// row--; // adjust for index difference
|
||||||
|
// this.pos = row;
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
}
|
}
|
||||||
|
@ -532,7 +592,7 @@ public class RestfulResultSet implements ResultSet {
|
||||||
@Override
|
@Override
|
||||||
public boolean relative(int rows) throws SQLException {
|
public boolean relative(int rows) throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(RESULT_SET_IS_CLOSED));
|
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.RESULT_SET_IS_CLOSED));
|
||||||
|
|
||||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
}
|
}
|
||||||
|
@ -540,7 +600,7 @@ public class RestfulResultSet implements ResultSet {
|
||||||
@Override
|
@Override
|
||||||
public boolean previous() throws SQLException {
|
public boolean previous() throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(RESULT_SET_IS_CLOSED));
|
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.RESULT_SET_IS_CLOSED));
|
||||||
|
|
||||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
}
|
}
|
||||||
|
@ -548,17 +608,18 @@ public class RestfulResultSet implements ResultSet {
|
||||||
@Override
|
@Override
|
||||||
public void setFetchDirection(int direction) throws SQLException {
|
public void setFetchDirection(int direction) throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(RESULT_SET_IS_CLOSED));
|
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.RESULT_SET_IS_CLOSED));
|
||||||
if (direction != ResultSet.FETCH_REVERSE || direction != ResultSet.FETCH_REVERSE || direction != ResultSet.FETCH_UNKNOWN)
|
if ((direction != ResultSet.FETCH_FORWARD) && (direction != ResultSet.FETCH_REVERSE) && (direction != ResultSet.FETCH_UNKNOWN))
|
||||||
throw new SQLException(TSDBConstants.INVALID_VARIABLES);
|
throw new SQLException(TSDBConstants.INVALID_VARIABLES);
|
||||||
|
|
||||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
if (!(getType() == ResultSet.TYPE_FORWARD_ONLY && direction == ResultSet.FETCH_FORWARD))
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getFetchDirection() throws SQLException {
|
public int getFetchDirection() throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(RESULT_SET_IS_CLOSED));
|
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.RESULT_SET_IS_CLOSED));
|
||||||
|
|
||||||
return ResultSet.FETCH_FORWARD;
|
return ResultSet.FETCH_FORWARD;
|
||||||
}
|
}
|
||||||
|
@ -566,17 +627,17 @@ public class RestfulResultSet implements ResultSet {
|
||||||
@Override
|
@Override
|
||||||
public void setFetchSize(int rows) throws SQLException {
|
public void setFetchSize(int rows) throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(RESULT_SET_IS_CLOSED));
|
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.RESULT_SET_IS_CLOSED));
|
||||||
if (rows < 0)
|
if (rows < 0)
|
||||||
throw new SQLException(TSDBConstants.INVALID_VARIABLES);
|
throw new SQLException(TSDBConstants.INVALID_VARIABLES);
|
||||||
|
|
||||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getFetchSize() throws SQLException {
|
public int getFetchSize() throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(RESULT_SET_IS_CLOSED));
|
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.RESULT_SET_IS_CLOSED));
|
||||||
|
|
||||||
return this.resultSet.size();
|
return this.resultSet.size();
|
||||||
}
|
}
|
||||||
|
@ -834,7 +895,7 @@ public class RestfulResultSet implements ResultSet {
|
||||||
@Override
|
@Override
|
||||||
public Statement getStatement() throws SQLException {
|
public Statement getStatement() throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg(RESULT_SET_IS_CLOSED));
|
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.RESULT_SET_IS_CLOSED));
|
||||||
|
|
||||||
return this.statement;
|
return this.statement;
|
||||||
}
|
}
|
||||||
|
@ -992,14 +1053,15 @@ public class RestfulResultSet implements ResultSet {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getHoldability() throws SQLException {
|
public int getHoldability() throws SQLException {
|
||||||
|
if (isClosed())
|
||||||
|
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.RESULT_SET_IS_CLOSED));
|
||||||
|
|
||||||
return ResultSet.HOLD_CURSORS_OVER_COMMIT;
|
return ResultSet.HOLD_CURSORS_OVER_COMMIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isClosed() throws SQLException {
|
public boolean isClosed() throws SQLException {
|
||||||
return false;
|
return isClosed;
|
||||||
//TODO: SQLFeature Not Supported
|
|
||||||
// throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1224,11 +1286,21 @@ public class RestfulResultSet implements ResultSet {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T unwrap(Class<T> iface) throws SQLException {
|
public <T> T unwrap(Class<T> iface) throws SQLException {
|
||||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
if (isClosed())
|
||||||
|
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.RESULT_SET_IS_CLOSED));
|
||||||
|
|
||||||
|
try {
|
||||||
|
return iface.cast(this);
|
||||||
|
} catch (ClassCastException cce) {
|
||||||
|
throw new SQLException("Unable to unwrap to " + iface.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isWrapperFor(Class<?> iface) throws SQLException {
|
public boolean isWrapperFor(Class<?> iface) throws SQLException {
|
||||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
if (isClosed())
|
||||||
|
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.RESULT_SET_IS_CLOSED));
|
||||||
|
|
||||||
|
return iface.isInstance(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,22 @@
|
||||||
package com.taosdata.jdbc.rs;
|
package com.taosdata.jdbc.rs;
|
||||||
|
|
||||||
|
import com.taosdata.jdbc.TSDBConstants;
|
||||||
|
|
||||||
import java.sql.ResultSetMetaData;
|
import java.sql.ResultSetMetaData;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Timestamp;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
public class RestfulResultSetMetaData implements ResultSetMetaData {
|
public class RestfulResultSetMetaData implements ResultSetMetaData {
|
||||||
|
|
||||||
private final String database;
|
private final String database;
|
||||||
private ArrayList<RestfulResultSet.Field> fields;
|
private ArrayList<RestfulResultSet.Field> fields;
|
||||||
|
private final RestfulResultSet resultSet;
|
||||||
|
|
||||||
public RestfulResultSetMetaData(String database, ArrayList<RestfulResultSet.Field> fields) {
|
public RestfulResultSetMetaData(String database, ArrayList<RestfulResultSet.Field> fields, RestfulResultSet resultSet) {
|
||||||
this.database = database;
|
this.database = database;
|
||||||
this.fields = fields;
|
this.fields = fields;
|
||||||
|
this.resultSet = resultSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -26,13 +31,12 @@ public class RestfulResultSetMetaData implements ResultSetMetaData {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isCaseSensitive(int column) throws SQLException {
|
public boolean isCaseSensitive(int column) throws SQLException {
|
||||||
//TODO
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSearchable(int column) throws SQLException {
|
public boolean isSearchable(int column) throws SQLException {
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -42,17 +46,30 @@ public class RestfulResultSetMetaData implements ResultSetMetaData {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int isNullable(int column) throws SQLException {
|
public int isNullable(int column) throws SQLException {
|
||||||
|
if (column == 1)
|
||||||
|
return ResultSetMetaData.columnNoNulls;
|
||||||
return ResultSetMetaData.columnNullable;
|
return ResultSetMetaData.columnNullable;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSigned(int column) throws SQLException {
|
public boolean isSigned(int column) throws SQLException {
|
||||||
|
String type = this.fields.get(column - 1).type.toUpperCase();
|
||||||
|
switch (type) {
|
||||||
|
case "TINYINT":
|
||||||
|
case "SMALLINT":
|
||||||
|
case "INT":
|
||||||
|
case "BIGINT":
|
||||||
|
case "FLOAT":
|
||||||
|
case "DOUBLE":
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getColumnDisplaySize(int column) throws SQLException {
|
public int getColumnDisplaySize(int column) throws SQLException {
|
||||||
return 0;
|
return this.fields.get(column - 1).length;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -62,27 +79,46 @@ public class RestfulResultSetMetaData implements ResultSetMetaData {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getColumnName(int column) throws SQLException {
|
public String getColumnName(int column) throws SQLException {
|
||||||
return null;
|
return fields.get(column - 1).name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getSchemaName(int column) throws SQLException {
|
public String getSchemaName(int column) throws SQLException {
|
||||||
return this.database;
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getPrecision(int column) throws SQLException {
|
public int getPrecision(int column) throws SQLException {
|
||||||
|
String type = this.fields.get(column - 1).type.toUpperCase();
|
||||||
|
switch (type) {
|
||||||
|
case "FLOAT":
|
||||||
|
return 5;
|
||||||
|
case "DOUBLE":
|
||||||
|
return 9;
|
||||||
|
case "BINARY":
|
||||||
|
case "NCHAR":
|
||||||
|
return this.fields.get(column - 1).length;
|
||||||
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getScale(int column) throws SQLException {
|
public int getScale(int column) throws SQLException {
|
||||||
|
String type = this.fields.get(column - 1).type.toUpperCase();
|
||||||
|
switch (type) {
|
||||||
|
case "FLOAT":
|
||||||
|
return 5;
|
||||||
|
case "DOUBLE":
|
||||||
|
return 9;
|
||||||
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getTableName(int column) throws SQLException {
|
public String getTableName(int column) throws SQLException {
|
||||||
return null;
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -92,17 +128,41 @@ public class RestfulResultSetMetaData implements ResultSetMetaData {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getColumnType(int column) throws SQLException {
|
public int getColumnType(int column) throws SQLException {
|
||||||
return 0;
|
String type = this.fields.get(column - 1).type.toUpperCase();
|
||||||
|
switch (type) {
|
||||||
|
case "BOOL":
|
||||||
|
return java.sql.Types.BOOLEAN;
|
||||||
|
case "TINYINT":
|
||||||
|
return java.sql.Types.TINYINT;
|
||||||
|
case "SMALLINT":
|
||||||
|
return java.sql.Types.SMALLINT;
|
||||||
|
case "INT":
|
||||||
|
return java.sql.Types.INTEGER;
|
||||||
|
case "BIGINT":
|
||||||
|
return java.sql.Types.BIGINT;
|
||||||
|
case "FLOAT":
|
||||||
|
return java.sql.Types.FLOAT;
|
||||||
|
case "DOUBLE":
|
||||||
|
return java.sql.Types.DOUBLE;
|
||||||
|
case "BINARY":
|
||||||
|
return java.sql.Types.BINARY;
|
||||||
|
case "TIMESTAMP":
|
||||||
|
return java.sql.Types.TIMESTAMP;
|
||||||
|
case "NCHAR":
|
||||||
|
return java.sql.Types.NCHAR;
|
||||||
|
}
|
||||||
|
throw new SQLException(TSDBConstants.INVALID_VARIABLES);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getColumnTypeName(int column) throws SQLException {
|
public String getColumnTypeName(int column) throws SQLException {
|
||||||
return null;
|
String type = fields.get(column - 1).type;
|
||||||
|
return type.toUpperCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isReadOnly(int column) throws SQLException {
|
public boolean isReadOnly(int column) throws SQLException {
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -117,16 +177,43 @@ public class RestfulResultSetMetaData implements ResultSetMetaData {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getColumnClassName(int column) throws SQLException {
|
public String getColumnClassName(int column) throws SQLException {
|
||||||
return null;
|
String type = this.fields.get(column - 1).type;
|
||||||
|
String columnClassName = "";
|
||||||
|
switch (type) {
|
||||||
|
case "BOOL":
|
||||||
|
return Boolean.class.getName();
|
||||||
|
case "TINYINT":
|
||||||
|
case "SMALLINT":
|
||||||
|
return Short.class.getName();
|
||||||
|
case "INT":
|
||||||
|
return Integer.class.getName();
|
||||||
|
case "BIGINT":
|
||||||
|
return Long.class.getName();
|
||||||
|
case "FLOAT":
|
||||||
|
return Float.class.getName();
|
||||||
|
case "DOUBLE":
|
||||||
|
return Double.class.getName();
|
||||||
|
case "TIMESTAMP":
|
||||||
|
return Timestamp.class.getName();
|
||||||
|
case "BINARY":
|
||||||
|
case "NCHAR":
|
||||||
|
return String.class.getName();
|
||||||
|
}
|
||||||
|
return columnClassName;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T unwrap(Class<T> iface) throws SQLException {
|
public <T> T unwrap(Class<T> iface) throws SQLException {
|
||||||
return null;
|
try {
|
||||||
|
return iface.cast(this);
|
||||||
|
} catch (ClassCastException cce) {
|
||||||
|
throw new SQLException("Unable to unwrap to " + iface.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isWrapperFor(Class<?> iface) throws SQLException {
|
public boolean isWrapperFor(Class<?> iface) throws SQLException {
|
||||||
return false;
|
return iface.isInstance(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,6 @@ import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class RestfulStatement implements Statement {
|
public class RestfulStatement implements Statement {
|
||||||
|
|
||||||
private static final String STATEMENT_CLOSED = "Statement already closed.";
|
|
||||||
private boolean closed;
|
private boolean closed;
|
||||||
private String database;
|
private String database;
|
||||||
private final RestfulConnection conn;
|
private final RestfulConnection conn;
|
||||||
|
@ -65,17 +64,163 @@ public class RestfulStatement implements Statement {
|
||||||
public ResultSet executeQuery(String sql) throws SQLException {
|
public ResultSet executeQuery(String sql) throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException("statement already closed");
|
throw new SQLException("statement already closed");
|
||||||
if (!SqlSyntaxValidator.isSelectSql(sql))
|
if (!SqlSyntaxValidator.isValidForExecuteQuery(sql))
|
||||||
throw new SQLException("not a select sql for executeQuery: " + sql);
|
throw new SQLException("not a valid sql for executeQuery: " + sql);
|
||||||
|
|
||||||
final String url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sql";
|
final String url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sql";
|
||||||
|
if (SqlSyntaxValidator.isDatabaseUnspecifiedQuery(sql)) {
|
||||||
|
return executeOneQuery(url, sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.database == null || this.database.isEmpty())
|
||||||
|
throw new SQLException("Database not specified or available");
|
||||||
|
HttpClientPoolUtil.execute(url, "use " + this.database);
|
||||||
|
return executeOneQuery(url, sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int executeUpdate(String sql) throws SQLException {
|
||||||
|
if (isClosed())
|
||||||
|
throw new SQLException("statement already closed");
|
||||||
|
if (!SqlSyntaxValidator.isValidForExecuteUpdate(sql))
|
||||||
|
throw new SQLException("not a valid sql for executeUpdate: " + sql);
|
||||||
|
|
||||||
|
final String url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sql";
|
||||||
|
if (SqlSyntaxValidator.isDatabaseUnspecifiedUpdate(sql)) {
|
||||||
|
return executeOneUpdate(url, sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.database == null || this.database.isEmpty())
|
||||||
|
throw new SQLException("Database not specified or available");
|
||||||
|
HttpClientPoolUtil.execute(url, "use " + this.database);
|
||||||
|
return executeOneUpdate(url, sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws SQLException {
|
||||||
|
synchronized (RestfulStatement.class) {
|
||||||
|
if (!isClosed())
|
||||||
|
this.closed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxFieldSize() throws SQLException {
|
||||||
|
if (isClosed())
|
||||||
|
throw new SQLException(TSDBConstants.STATEMENT_CLOSED);
|
||||||
|
return TSDBConstants.maxFieldSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMaxFieldSize(int max) throws SQLException {
|
||||||
|
if (isClosed())
|
||||||
|
throw new SQLException(TSDBConstants.STATEMENT_CLOSED);
|
||||||
|
if (max < 0)
|
||||||
|
throw new SQLException(TSDBConstants.INVALID_VARIABLES);
|
||||||
|
// nothing to do
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxRows() throws SQLException {
|
||||||
|
if (isClosed())
|
||||||
|
throw new SQLException(TSDBConstants.STATEMENT_CLOSED);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMaxRows(int max) throws SQLException {
|
||||||
|
if (isClosed())
|
||||||
|
throw new SQLException(TSDBConstants.STATEMENT_CLOSED);
|
||||||
|
if (max < 0)
|
||||||
|
throw new SQLException(TSDBConstants.INVALID_VARIABLES);
|
||||||
|
// nothing to do
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setEscapeProcessing(boolean enable) throws SQLException {
|
||||||
|
if (isClosed())
|
||||||
|
throw new SQLException(TSDBConstants.STATEMENT_CLOSED);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getQueryTimeout() throws SQLException {
|
||||||
|
if (isClosed())
|
||||||
|
throw new SQLException(TSDBConstants.STATEMENT_CLOSED);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setQueryTimeout(int seconds) throws SQLException {
|
||||||
|
if (isClosed())
|
||||||
|
throw new SQLException(TSDBConstants.STATEMENT_CLOSED);
|
||||||
|
if (seconds < 0)
|
||||||
|
throw new SQLException(TSDBConstants.INVALID_VARIABLES);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancel() throws SQLException {
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SQLWarning getWarnings() throws SQLException {
|
||||||
|
if (isClosed())
|
||||||
|
throw new SQLException(TSDBConstants.STATEMENT_CLOSED);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearWarnings() throws SQLException {
|
||||||
|
// nothing to do
|
||||||
|
if (isClosed())
|
||||||
|
throw new SQLException(TSDBConstants.STATEMENT_CLOSED);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCursorName(String name) throws SQLException {
|
||||||
|
if (isClosed())
|
||||||
|
throw new SQLException(TSDBConstants.STATEMENT_CLOSED);
|
||||||
|
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute(String sql) throws SQLException {
|
||||||
|
if (isClosed())
|
||||||
|
throw new SQLException("Invalid method call on a closed statement.");
|
||||||
|
if (!SqlSyntaxValidator.isValidForExecute(sql))
|
||||||
|
throw new SQLException("not a valid sql for execute: " + sql);
|
||||||
|
|
||||||
|
//如果执行了use操作应该将当前Statement的catalog设置为新的database
|
||||||
|
final String url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sql";
|
||||||
|
if (SqlSyntaxValidator.isUseSql(sql)) {
|
||||||
|
HttpClientPoolUtil.execute(url, sql);
|
||||||
|
this.database = sql.trim().replace("use", "").trim();
|
||||||
|
this.conn.setCatalog(this.database);
|
||||||
|
} else if (SqlSyntaxValidator.isDatabaseUnspecifiedQuery(sql)) {
|
||||||
|
executeOneQuery(url, sql);
|
||||||
|
} else if (SqlSyntaxValidator.isDatabaseUnspecifiedUpdate(sql)) {
|
||||||
|
executeOneUpdate(url, sql);
|
||||||
|
} else {
|
||||||
|
if (SqlSyntaxValidator.isValidForExecuteQuery(sql)) {
|
||||||
|
executeQuery(sql);
|
||||||
|
} else {
|
||||||
|
executeUpdate(sql);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ResultSet executeOneQuery(String url, String sql) throws SQLException {
|
||||||
|
if (!SqlSyntaxValidator.isValidForExecuteQuery(sql))
|
||||||
|
throw new SQLException("not a select sql for executeQuery: " + sql);
|
||||||
|
|
||||||
// row data
|
// row data
|
||||||
String result = HttpClientPoolUtil.execute(url, sql);
|
String result = HttpClientPoolUtil.execute(url, sql);
|
||||||
JSONObject resultJson = JSON.parseObject(result);
|
JSONObject resultJson = JSON.parseObject(result);
|
||||||
if (resultJson.getString("status").equals("error")) {
|
if (resultJson.getString("status").equals("error")) {
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg("SQL execution error: " + resultJson.getString("desc") + "\n" + "error code: " + resultJson.getString("code")));
|
throw new SQLException(TSDBConstants.WrapErrMsg("SQL execution error: " + resultJson.getString("desc") + "\n" + "error code: " + resultJson.getString("code")));
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse table name from sql
|
// parse table name from sql
|
||||||
String[] tableIdentifiers = parseTableIdentifier(sql);
|
String[] tableIdentifiers = parseTableIdentifier(sql);
|
||||||
if (tableIdentifiers != null) {
|
if (tableIdentifiers != null) {
|
||||||
|
@ -93,23 +238,14 @@ public class RestfulStatement implements Statement {
|
||||||
} else {
|
} else {
|
||||||
this.resultSet = new RestfulResultSet(database, this, resultJson);
|
this.resultSet = new RestfulResultSet(database, this, resultJson);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.affectedRows = 0;
|
this.affectedRows = 0;
|
||||||
return resultSet;
|
return resultSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private int executeOneUpdate(String url, String sql) throws SQLException {
|
||||||
public int executeUpdate(String sql) throws SQLException {
|
|
||||||
if (isClosed())
|
|
||||||
throw new SQLException("statement already closed");
|
|
||||||
if (!SqlSyntaxValidator.isValidForExecuteUpdate(sql))
|
if (!SqlSyntaxValidator.isValidForExecuteUpdate(sql))
|
||||||
throw new SQLException("not a valid sql for executeUpdate: " + sql);
|
throw new SQLException("not a valid sql for executeUpdate: " + sql);
|
||||||
|
|
||||||
if (this.database == null)
|
|
||||||
throw new SQLException("Database not specified or available");
|
|
||||||
|
|
||||||
final String url = "http://" + conn.getHost().trim() + ":" + conn.getPort() + "/rest/sql";
|
|
||||||
// HttpClientPoolUtil.execute(url, "use " + conn.getDatabase());
|
|
||||||
String result = HttpClientPoolUtil.execute(url, sql);
|
String result = HttpClientPoolUtil.execute(url, sql);
|
||||||
JSONObject jsonObject = JSON.parseObject(result);
|
JSONObject jsonObject = JSON.parseObject(result);
|
||||||
if (jsonObject.getString("status").equals("error")) {
|
if (jsonObject.getString("status").equals("error")) {
|
||||||
|
@ -120,130 +256,10 @@ public class RestfulStatement implements Statement {
|
||||||
return this.affectedRows;
|
return this.affectedRows;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() throws SQLException {
|
|
||||||
synchronized (RestfulStatement.class) {
|
|
||||||
if (!isClosed())
|
|
||||||
this.closed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getMaxFieldSize() throws SQLException {
|
|
||||||
if (isClosed())
|
|
||||||
throw new SQLException(STATEMENT_CLOSED);
|
|
||||||
return TSDBConstants.maxFieldSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setMaxFieldSize(int max) throws SQLException {
|
|
||||||
if (isClosed())
|
|
||||||
throw new SQLException(STATEMENT_CLOSED);
|
|
||||||
if (max < 0)
|
|
||||||
throw new SQLException(TSDBConstants.INVALID_VARIABLES);
|
|
||||||
// nothing to do
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getMaxRows() throws SQLException {
|
|
||||||
if (isClosed())
|
|
||||||
throw new SQLException(STATEMENT_CLOSED);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setMaxRows(int max) throws SQLException {
|
|
||||||
if (isClosed())
|
|
||||||
throw new SQLException(STATEMENT_CLOSED);
|
|
||||||
if (max < 0)
|
|
||||||
throw new SQLException(TSDBConstants.INVALID_VARIABLES);
|
|
||||||
// nothing to do
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setEscapeProcessing(boolean enable) throws SQLException {
|
|
||||||
if (isClosed())
|
|
||||||
throw new SQLException(RestfulStatement.STATEMENT_CLOSED);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getQueryTimeout() throws SQLException {
|
|
||||||
if (isClosed())
|
|
||||||
throw new SQLException(STATEMENT_CLOSED);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setQueryTimeout(int seconds) throws SQLException {
|
|
||||||
if (isClosed())
|
|
||||||
throw new SQLException(STATEMENT_CLOSED);
|
|
||||||
if (seconds < 0)
|
|
||||||
throw new SQLException(TSDBConstants.INVALID_VARIABLES);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void cancel() throws SQLException {
|
|
||||||
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SQLWarning getWarnings() throws SQLException {
|
|
||||||
if (isClosed())
|
|
||||||
throw new SQLException(STATEMENT_CLOSED);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void clearWarnings() throws SQLException {
|
|
||||||
// nothing to do
|
|
||||||
if (isClosed())
|
|
||||||
throw new SQLException(STATEMENT_CLOSED);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setCursorName(String name) throws SQLException {
|
|
||||||
if (isClosed())
|
|
||||||
throw new SQLException(RestfulStatement.STATEMENT_CLOSED);
|
|
||||||
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean execute(String sql) throws SQLException {
|
|
||||||
if (isClosed()) {
|
|
||||||
throw new SQLException("Invalid method call on a closed statement.");
|
|
||||||
}
|
|
||||||
//如果执行了use操作应该将当前Statement的catalog设置为新的database
|
|
||||||
if (SqlSyntaxValidator.isUseSql(sql)) {
|
|
||||||
this.database = sql.trim().replace("use", "").trim();
|
|
||||||
this.conn.setCatalog(this.database);
|
|
||||||
}
|
|
||||||
if (this.database == null)
|
|
||||||
throw new SQLException("Database not specified or available");
|
|
||||||
|
|
||||||
if (SqlSyntaxValidator.isSelectSql(sql)) {
|
|
||||||
executeQuery(sql);
|
|
||||||
} else if (SqlSyntaxValidator.isShowSql(sql) || SqlSyntaxValidator.isDescribeSql(sql)) {
|
|
||||||
final String url = "http://" + conn.getHost().trim() + ":" + conn.getPort() + "/rest/sql";
|
|
||||||
if (!SqlSyntaxValidator.isShowDatabaseSql(sql)) {
|
|
||||||
HttpClientPoolUtil.execute(url, "use " + conn.getDatabase());
|
|
||||||
}
|
|
||||||
String result = HttpClientPoolUtil.execute(url, sql);
|
|
||||||
JSONObject resultJson = JSON.parseObject(result);
|
|
||||||
if (resultJson.getString("status").equals("error")) {
|
|
||||||
throw new SQLException(TSDBConstants.WrapErrMsg("SQL execution error: " + resultJson.getString("desc") + "\n" + "error code: " + resultJson.getString("code")));
|
|
||||||
}
|
|
||||||
this.resultSet = new RestfulResultSet(database, this, resultJson);
|
|
||||||
} else {
|
|
||||||
executeUpdate(sql);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResultSet getResultSet() throws SQLException {
|
public ResultSet getResultSet() throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(STATEMENT_CLOSED);
|
throw new SQLException(TSDBConstants.STATEMENT_CLOSED);
|
||||||
return resultSet;
|
return resultSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,7 +291,7 @@ public class RestfulStatement implements Statement {
|
||||||
@Override
|
@Override
|
||||||
public void setFetchSize(int rows) throws SQLException {
|
public void setFetchSize(int rows) throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(STATEMENT_CLOSED);
|
throw new SQLException(TSDBConstants.STATEMENT_CLOSED);
|
||||||
if (rows < 0)
|
if (rows < 0)
|
||||||
throw new SQLException(TSDBConstants.INVALID_VARIABLES);
|
throw new SQLException(TSDBConstants.INVALID_VARIABLES);
|
||||||
//nothing to do
|
//nothing to do
|
||||||
|
@ -284,28 +300,28 @@ public class RestfulStatement implements Statement {
|
||||||
@Override
|
@Override
|
||||||
public int getFetchSize() throws SQLException {
|
public int getFetchSize() throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(STATEMENT_CLOSED);
|
throw new SQLException(TSDBConstants.STATEMENT_CLOSED);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getResultSetConcurrency() throws SQLException {
|
public int getResultSetConcurrency() throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(STATEMENT_CLOSED);
|
throw new SQLException(TSDBConstants.STATEMENT_CLOSED);
|
||||||
return this.resultSet.getConcurrency();
|
return this.resultSet.getConcurrency();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getResultSetType() throws SQLException {
|
public int getResultSetType() throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(STATEMENT_CLOSED);
|
throw new SQLException(TSDBConstants.STATEMENT_CLOSED);
|
||||||
return this.resultSet.getType();
|
return this.resultSet.getType();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addBatch(String sql) throws SQLException {
|
public void addBatch(String sql) throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(STATEMENT_CLOSED);
|
throw new SQLException(TSDBConstants.STATEMENT_CLOSED);
|
||||||
//TODO:
|
//TODO:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -323,14 +339,14 @@ public class RestfulStatement implements Statement {
|
||||||
@Override
|
@Override
|
||||||
public Connection getConnection() throws SQLException {
|
public Connection getConnection() throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(STATEMENT_CLOSED);
|
throw new SQLException(TSDBConstants.STATEMENT_CLOSED);
|
||||||
return this.conn;
|
return this.conn;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean getMoreResults(int current) throws SQLException {
|
public boolean getMoreResults(int current) throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(STATEMENT_CLOSED);
|
throw new SQLException(TSDBConstants.STATEMENT_CLOSED);
|
||||||
if (resultSet == null)
|
if (resultSet == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -388,7 +404,7 @@ public class RestfulStatement implements Statement {
|
||||||
@Override
|
@Override
|
||||||
public int getResultSetHoldability() throws SQLException {
|
public int getResultSetHoldability() throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(STATEMENT_CLOSED);
|
throw new SQLException(TSDBConstants.STATEMENT_CLOSED);
|
||||||
return this.resultSet.getHoldability();
|
return this.resultSet.getHoldability();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -400,28 +416,28 @@ public class RestfulStatement implements Statement {
|
||||||
@Override
|
@Override
|
||||||
public void setPoolable(boolean poolable) throws SQLException {
|
public void setPoolable(boolean poolable) throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(STATEMENT_CLOSED);
|
throw new SQLException(TSDBConstants.STATEMENT_CLOSED);
|
||||||
//nothing to do
|
//nothing to do
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPoolable() throws SQLException {
|
public boolean isPoolable() throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(STATEMENT_CLOSED);
|
throw new SQLException(TSDBConstants.STATEMENT_CLOSED);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void closeOnCompletion() throws SQLException {
|
public void closeOnCompletion() throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(STATEMENT_CLOSED);
|
throw new SQLException(TSDBConstants.STATEMENT_CLOSED);
|
||||||
this.closeOnCompletion = true;
|
this.closeOnCompletion = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isCloseOnCompletion() throws SQLException {
|
public boolean isCloseOnCompletion() throws SQLException {
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SQLException(STATEMENT_CLOSED);
|
throw new SQLException(TSDBConstants.STATEMENT_CLOSED);
|
||||||
return this.closeOnCompletion;
|
return this.closeOnCompletion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,11 @@ import java.sql.Connection;
|
||||||
|
|
||||||
public class SqlSyntaxValidator {
|
public class SqlSyntaxValidator {
|
||||||
|
|
||||||
private static final String[] updateSQL = {"insert", "update", "delete", "create", "alter", "drop", "show", "describe", "use", "import"};
|
private static final String[] SQL = {"select", "insert", "import", "create", "use", "alter", "drop", "set", "show", "describe"};
|
||||||
private static final String[] querySQL = {"select"};
|
private static final String[] updateSQL = {"insert", "import", "create", "use", "alter", "drop", "set"};
|
||||||
|
private static final String[] querySQL = {"select", "show", "describe"};
|
||||||
|
|
||||||
|
private static final String[] databaseUnspecifiedShow = {"databases", "dnodes", "mnodes", "variables"};
|
||||||
|
|
||||||
private TSDBConnection tsdbConnection;
|
private TSDBConnection tsdbConnection;
|
||||||
|
|
||||||
|
@ -37,8 +40,38 @@ public class SqlSyntaxValidator {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isValidForExecuteQuery(String sql) {
|
||||||
|
for (String prefix : querySQL) {
|
||||||
|
if (sql.trim().toLowerCase().startsWith(prefix))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isValidForExecute(String sql) {
|
||||||
|
for (String prefix : SQL) {
|
||||||
|
if (sql.trim().toLowerCase().startsWith(prefix))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isDatabaseUnspecifiedQuery(String sql) {
|
||||||
|
for (String databaseObj : databaseUnspecifiedShow) {
|
||||||
|
if (sql.trim().toLowerCase().matches("show\\s+" + databaseObj + ".*"))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isDatabaseUnspecifiedUpdate(String sql) {
|
||||||
|
sql = sql.trim().toLowerCase();
|
||||||
|
return sql.matches("create\\s+database.*") || sql.startsWith("set") || sql.matches("drop\\s+database.*");
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean isUseSql(String sql) {
|
public static boolean isUseSql(String sql) {
|
||||||
return sql.trim().toLowerCase().startsWith("use") || sql.trim().toLowerCase().matches("create\\s*database.*") || sql.toLowerCase().toLowerCase().matches("drop\\s*database.*");
|
return sql.trim().toLowerCase().startsWith("use");
|
||||||
|
// || sql.trim().toLowerCase().matches("create\\s*database.*") || sql.toLowerCase().toLowerCase().matches("drop\\s*database.*");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isShowSql(String sql) {
|
public static boolean isShowSql(String sql) {
|
||||||
|
@ -58,8 +91,9 @@ public class SqlSyntaxValidator {
|
||||||
return sql.trim().toLowerCase().startsWith("select");
|
return sql.trim().toLowerCase().startsWith("select");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static boolean isShowDatabaseSql(String sql) {
|
public static boolean isShowDatabaseSql(String sql) {
|
||||||
return sql.trim().toLowerCase().matches("show\\s*databases");
|
return sql.trim().toLowerCase().matches("show\\s*databases");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
package com.taosdata.jdbc;
|
|
||||||
|
|
||||||
import com.taosdata.jdbc.utils.TDNodes;
|
|
||||||
|
|
||||||
import org.junit.AfterClass;
|
|
||||||
import org.junit.BeforeClass;
|
|
||||||
|
|
||||||
public abstract class BaseTest {
|
|
||||||
|
|
||||||
private static boolean testCluster = false;
|
|
||||||
private static TDNodes nodes = new TDNodes();
|
|
||||||
|
|
||||||
@BeforeClass
|
|
||||||
public static void setupEnv() {
|
|
||||||
try {
|
|
||||||
if (nodes.getTDNode(1).getTaosdPid() != null) {
|
|
||||||
System.out.println("Kill taosd before running JDBC test");
|
|
||||||
nodes.getTDNode(1).setRunning(1);
|
|
||||||
nodes.stop(1);
|
|
||||||
}
|
|
||||||
nodes.setTestCluster(testCluster);
|
|
||||||
nodes.deploy(1);
|
|
||||||
nodes.start(1);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@AfterClass
|
|
||||||
public static void cleanUpEnv() {
|
|
||||||
nodes.stop(1);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,115 +0,0 @@
|
||||||
package com.taosdata.jdbc;
|
|
||||||
|
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import java.sql.*;
|
|
||||||
import java.util.Properties;
|
|
||||||
import java.util.Random;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
|
|
||||||
public class BatchInsertTest {
|
|
||||||
|
|
||||||
private Connection connection;
|
|
||||||
|
|
||||||
private static String dbName = "test";
|
|
||||||
private static String stbName = "meters";
|
|
||||||
private static String host = "127.0.0.1";
|
|
||||||
private static int numOfTables = 30;
|
|
||||||
private static int numOfRecordsPerTable = 1000;
|
|
||||||
private static long ts = 1496732686000l;
|
|
||||||
private static String tablePrefix = "t";
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void createDatabase() throws SQLException {
|
|
||||||
try {
|
|
||||||
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
|
||||||
} catch (ClassNotFoundException e) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Properties properties = new Properties();
|
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
|
||||||
connection = DriverManager.getConnection("jdbc:TAOS://" + host + ":0/", properties);
|
|
||||||
|
|
||||||
Statement stmt = connection.createStatement();
|
|
||||||
stmt.execute("drop database if exists " + dbName);
|
|
||||||
stmt.execute("create database if not exists " + dbName);
|
|
||||||
stmt.execute("use " + dbName);
|
|
||||||
|
|
||||||
String createTableSql = "create table " + stbName + "(ts timestamp, f1 int, f2 int, f3 int) tags(areaid int, loc binary(20))";
|
|
||||||
stmt.execute(createTableSql);
|
|
||||||
|
|
||||||
for (int i = 0; i < numOfTables; i++) {
|
|
||||||
String loc = i % 2 == 0 ? "beijing" : "shanghai";
|
|
||||||
String createSubTalbesSql = "create table " + tablePrefix + i + " using " + stbName + " tags(" + i + ", '" + loc + "')";
|
|
||||||
stmt.execute(createSubTalbesSql);
|
|
||||||
}
|
|
||||||
stmt.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testBatchInsert() throws SQLException {
|
|
||||||
ExecutorService executorService = Executors.newFixedThreadPool(numOfTables);
|
|
||||||
for (int i = 0; i < numOfTables; i++) {
|
|
||||||
final int index = i;
|
|
||||||
executorService.execute(() -> {
|
|
||||||
try {
|
|
||||||
long startTime = System.currentTimeMillis();
|
|
||||||
Statement statement = connection.createStatement(); // get statement
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
sb.append("INSERT INTO " + tablePrefix + index + " VALUES");
|
|
||||||
Random rand = new Random();
|
|
||||||
for (int j = 1; j <= numOfRecordsPerTable; j++) {
|
|
||||||
sb.append("(" + (ts + j) + ", ");
|
|
||||||
sb.append(rand.nextInt(100) + ", ");
|
|
||||||
sb.append(rand.nextInt(100) + ", ");
|
|
||||||
sb.append(rand.nextInt(100) + ")");
|
|
||||||
}
|
|
||||||
statement.addBatch(sb.toString());
|
|
||||||
statement.executeBatch();
|
|
||||||
long endTime = System.currentTimeMillis();
|
|
||||||
System.out.println("Thread " + index + " takes " + (endTime - startTime) + " microseconds");
|
|
||||||
connection.commit();
|
|
||||||
statement.close();
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
executorService.shutdown();
|
|
||||||
|
|
||||||
try {
|
|
||||||
executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
Statement statement = connection.createStatement();
|
|
||||||
ResultSet rs = statement.executeQuery("select * from meters");
|
|
||||||
int num = 0;
|
|
||||||
while (rs.next()) {
|
|
||||||
num++;
|
|
||||||
}
|
|
||||||
assertEquals(num, numOfTables * numOfRecordsPerTable);
|
|
||||||
rs.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@After
|
|
||||||
public void close() {
|
|
||||||
try {
|
|
||||||
if (connection != null)
|
|
||||||
connection.close();
|
|
||||||
} catch (SQLException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,9 +1,7 @@
|
||||||
package com.taosdata.jdbc;
|
package com.taosdata.jdbc;
|
||||||
|
|
||||||
import org.junit.AfterClass;
|
import org.junit.*;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.runners.MethodSorters;
|
||||||
import org.junit.FixMethodOrder;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import java.sql.*;
|
import java.sql.*;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
@ -11,14 +9,13 @@ import java.util.Properties;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
@FixMethodOrder()
|
@FixMethodOrder(value = MethodSorters.NAME_ASCENDING)
|
||||||
public class PreparedStatementTest extends BaseTest {
|
public class PreparedStatementTest {
|
||||||
static Connection connection = null;
|
static Connection connection;
|
||||||
static PreparedStatement statement = null;
|
static TSDBPreparedStatement statement;
|
||||||
static String dbName = "test";
|
static String dbName = "test";
|
||||||
static String tName = "t0";
|
static String tName = "t0";
|
||||||
static String host = "localhost";
|
static String host = "localhost";
|
||||||
static ResultSet resSet = null;
|
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void createConnection() throws SQLException {
|
public static void createConnection() throws SQLException {
|
||||||
|
@ -28,19 +25,16 @@ public class PreparedStatementTest extends BaseTest {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Properties properties = new Properties();
|
Properties properties = new Properties();
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_HOST, host);
|
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
||||||
connection = DriverManager.getConnection("jdbc:TAOS://" + host + ":0/", properties);
|
connection = DriverManager.getConnection("jdbc:TAOS://" + host + ":0/", properties);
|
||||||
|
|
||||||
String sql = "drop database if exists " + dbName;
|
String sql = "drop database if exists " + dbName;
|
||||||
statement = (TSDBPreparedStatement) connection.prepareStatement(sql);
|
statement = (TSDBPreparedStatement) connection.prepareStatement(sql);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void createTableAndQuery() throws SQLException {
|
public void case001_createTableAndQuery() throws SQLException {
|
||||||
long ts = System.currentTimeMillis();
|
long ts = System.currentTimeMillis();
|
||||||
|
|
||||||
statement.executeUpdate("create database if not exists " + dbName);
|
statement.executeUpdate("create database if not exists " + dbName);
|
||||||
|
@ -48,141 +42,132 @@ public class PreparedStatementTest extends BaseTest {
|
||||||
statement.executeUpdate("insert into " + dbName + "." + tName + " values (" + ts + ", 1)");
|
statement.executeUpdate("insert into " + dbName + "." + tName + " values (" + ts + ", 1)");
|
||||||
|
|
||||||
PreparedStatement selectStatement = connection.prepareStatement("select * from " + dbName + "." + tName);
|
PreparedStatement selectStatement = connection.prepareStatement("select * from " + dbName + "." + tName);
|
||||||
|
|
||||||
ResultSet resultSet = selectStatement.executeQuery();
|
ResultSet resultSet = selectStatement.executeQuery();
|
||||||
assertTrue(null != resultSet);
|
assertTrue(null != resultSet);
|
||||||
|
|
||||||
boolean isClosed = statement.isClosed();
|
boolean isClosed = statement.isClosed();
|
||||||
assertEquals(false, isClosed);
|
assertEquals(false, isClosed);
|
||||||
|
selectStatement.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPreparedStatement() throws SQLException {
|
public void case002_testPreparedStatement() throws SQLException {
|
||||||
long ts = System.currentTimeMillis() + 20000;
|
long ts = System.currentTimeMillis() + 20000;
|
||||||
PreparedStatement saveStatement = connection
|
|
||||||
.prepareStatement("insert into " + dbName + "." + tName + " values (" + ts + ", 1)");
|
|
||||||
|
|
||||||
|
PreparedStatement saveStatement = connection.prepareStatement("insert into " + dbName + "." + tName + " values (" + ts + ", 1)");
|
||||||
int affectedRows = saveStatement.executeUpdate();
|
int affectedRows = saveStatement.executeUpdate();
|
||||||
assertTrue(1 == affectedRows);
|
assertTrue(1 == affectedRows);
|
||||||
|
saveStatement.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSavedPreparedStatement() throws SQLException {
|
public void case003_testSavedPreparedStatement() throws SQLException {
|
||||||
long ts = System.currentTimeMillis();
|
long ts = System.currentTimeMillis();
|
||||||
|
TSDBPreparedStatement saveStatement = (TSDBPreparedStatement) connection.prepareStatement("insert into " + dbName + "." + tName + " values (?, ?)");
|
||||||
TSDBPreparedStatement saveStatement = (TSDBPreparedStatement) connection
|
|
||||||
.prepareStatement("insert into " + dbName + "." + tName + " values (?, ?)");
|
|
||||||
|
|
||||||
saveStatement.setObject(1, ts + 10000);
|
saveStatement.setObject(1, ts + 10000);
|
||||||
saveStatement.setObject(2, 3);
|
saveStatement.setObject(2, 3);
|
||||||
int rows = saveStatement.executeUpdate();
|
int rows = saveStatement.executeUpdate();
|
||||||
assertEquals(1, rows);
|
assertEquals(1, rows);
|
||||||
|
saveStatement.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUnsupport() {
|
public void case004_testUnsupport() throws SQLException {
|
||||||
// if(null == resSet) {
|
|
||||||
// return;
|
Assert.assertNotNull(statement.unwrap(TSDBPreparedStatement.class));
|
||||||
// }
|
Assert.assertTrue(statement.isWrapperFor(TSDBPreparedStatement.class));
|
||||||
TSDBPreparedStatement tsdbStatement = (TSDBPreparedStatement) statement;
|
|
||||||
try {
|
try {
|
||||||
tsdbStatement.unwrap(null);
|
statement.getMaxFieldSize();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
tsdbStatement.isWrapperFor(null);
|
statement.setMaxFieldSize(0);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
tsdbStatement.getMaxFieldSize();
|
statement.setEscapeProcessing(true);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
tsdbStatement.setMaxFieldSize(0);
|
statement.cancel();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
tsdbStatement.setEscapeProcessing(true);
|
statement.getWarnings();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
tsdbStatement.cancel();
|
statement.clearWarnings();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
tsdbStatement.getWarnings();
|
statement.setCursorName(null);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
tsdbStatement.clearWarnings();
|
statement.getMoreResults();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
tsdbStatement.setCursorName(null);
|
statement.setFetchDirection(0);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
tsdbStatement.getMoreResults();
|
statement.getFetchDirection();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
tsdbStatement.setFetchDirection(0);
|
statement.getResultSetConcurrency();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
tsdbStatement.getFetchDirection();
|
statement.getResultSetType();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
tsdbStatement.getResultSetConcurrency();
|
statement.getConnection();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
tsdbStatement.getResultSetType();
|
statement.getMoreResults();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
tsdbStatement.getConnection();
|
statement.getGeneratedKeys();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
tsdbStatement.getMoreResults();
|
statement.executeUpdate(null, 0);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
tsdbStatement.getGeneratedKeys();
|
statement.executeUpdate(null, new int[]{0});
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
tsdbStatement.executeUpdate(null, 0);
|
statement.executeUpdate(null, new String[]{"str1", "str2"});
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
tsdbStatement.executeUpdate(null, new int[]{0});
|
statement.getResultSetHoldability();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
tsdbStatement.executeUpdate(null, new String[]{"str1", "str2"});
|
statement.setPoolable(true);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
tsdbStatement.getResultSetHoldability();
|
statement.isPoolable();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
tsdbStatement.setPoolable(true);
|
statement.closeOnCompletion();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
tsdbStatement.isPoolable();
|
statement.isCloseOnCompletion();
|
||||||
} catch (SQLException e) {
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
tsdbStatement.closeOnCompletion();
|
|
||||||
} catch (SQLException e) {
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
tsdbStatement.isCloseOnCompletion();
|
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,37 +6,22 @@ import org.junit.Test;
|
||||||
|
|
||||||
import java.sql.*;
|
import java.sql.*;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import java.util.Properties;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.*;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertTrue;
|
public class QueryDataTest {
|
||||||
|
|
||||||
public class QueryDataTest extends BaseTest {
|
static Connection connection;
|
||||||
|
static Statement statement;
|
||||||
static Connection connection = null;
|
|
||||||
static Statement statement = null;
|
|
||||||
static String dbName = "test";
|
static String dbName = "test";
|
||||||
static String stbName = "meters";
|
static String stbName = "meters";
|
||||||
static String host = "localhost";
|
static String host = "127.0.0.1";
|
||||||
static int numOfTables = 30;
|
|
||||||
final static int numOfRecordsPerTable = 1000;
|
|
||||||
static long ts = 1496732686000l;
|
|
||||||
final static String tablePrefix = "t";
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void createDatabase() throws SQLException {
|
public void createDatabase() {
|
||||||
try {
|
try {
|
||||||
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
||||||
} catch (ClassNotFoundException e) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Properties properties = new Properties();
|
Properties properties = new Properties();
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_HOST, host);
|
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
||||||
|
@ -47,35 +32,41 @@ public class QueryDataTest extends BaseTest {
|
||||||
statement.executeUpdate("create database if not exists " + dbName);
|
statement.executeUpdate("create database if not exists " + dbName);
|
||||||
statement.executeUpdate("use " + dbName);
|
statement.executeUpdate("use " + dbName);
|
||||||
|
|
||||||
String createTableSql = "create table " + stbName + "(ts timestamp, name binary(6))";
|
String createTableSql = "create table " + stbName + "(ts timestamp, name binary(64))";
|
||||||
statement.executeUpdate(createTableSql);
|
statement.executeUpdate(createTableSql);
|
||||||
|
|
||||||
|
} catch (ClassNotFoundException | SQLException e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testQueryBinaryData() throws SQLException {
|
public void testQueryBinaryData() throws SQLException {
|
||||||
|
String insertSql = "insert into " + stbName + " values(now, 'taosdata')";
|
||||||
String insertSql = "insert into " + stbName + " values(now, 'taosda')";
|
|
||||||
System.out.println(insertSql);
|
System.out.println(insertSql);
|
||||||
|
|
||||||
statement.executeUpdate(insertSql);
|
statement.executeUpdate(insertSql);
|
||||||
|
|
||||||
String querySql = "select * from " + stbName;
|
String querySql = "select * from " + stbName;
|
||||||
ResultSet rs = statement.executeQuery(querySql);
|
ResultSet rs = statement.executeQuery(querySql);
|
||||||
|
|
||||||
while (rs.next()) {
|
while (rs.next()) {
|
||||||
String name = rs.getString(2) + "001";
|
String name = rs.getString(2);
|
||||||
System.out.println("name = " + name);
|
System.out.println("name = " + name);
|
||||||
assertEquals(name, "taosda001");
|
assertEquals("taosdata", name);
|
||||||
}
|
}
|
||||||
rs.close();
|
rs.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@After
|
@After
|
||||||
public void close() throws Exception {
|
public void close() {
|
||||||
|
try {
|
||||||
|
if (statement != null)
|
||||||
statement.close();
|
statement.close();
|
||||||
|
if (connection != null)
|
||||||
connection.close();
|
connection.close();
|
||||||
Thread.sleep(10);
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
package com.taosdata.jdbc;
|
package com.taosdata.jdbc;
|
||||||
|
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.Assert;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
@ -13,42 +14,37 @@ import java.util.Properties;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
public class ResultSetTest extends BaseTest {
|
public class ResultSetTest {
|
||||||
static Connection connection = null;
|
static Connection connection;
|
||||||
static Statement statement = null;
|
static Statement statement;
|
||||||
static String dbName = "test";
|
static String dbName = "test";
|
||||||
static String tName = "t0";
|
static String tName = "t0";
|
||||||
static String host = "localhost";
|
static String host = "localhost";
|
||||||
static ResultSet resSet = null;
|
static ResultSet resSet;
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void createDatabaseAndTable() throws SQLException {
|
public static void createDatabaseAndTable() {
|
||||||
try {
|
try {
|
||||||
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
||||||
} catch (ClassNotFoundException e) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Properties properties = new Properties();
|
Properties properties = new Properties();
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_HOST, host);
|
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
|
||||||
|
|
||||||
connection = DriverManager.getConnection("jdbc:TAOS://" + host + ":0/", properties);
|
connection = DriverManager.getConnection("jdbc:TAOS://" + host + ":0/", properties);
|
||||||
|
|
||||||
statement = connection.createStatement();
|
statement = connection.createStatement();
|
||||||
statement.executeUpdate("drop database if exists " + dbName);
|
statement.executeUpdate("drop database if exists " + dbName);
|
||||||
statement.executeUpdate("create database if not exists " + dbName);
|
statement.executeUpdate("create database if not exists " + dbName);
|
||||||
statement.executeUpdate("create table if not exists " + dbName + "." + tName +
|
statement.execute("use " + dbName);
|
||||||
" (ts timestamp, k1 int, k2 bigint, k3 float, k4 double, k5 binary(30), k6 smallint, k7 bool, k8 nchar(20))");
|
statement.executeUpdate("create table if not exists " + dbName + "." + tName + " (ts timestamp, k1 int, k2 bigint, k3 float, k4 double, k5 binary(30), k6 smallint, k7 bool, k8 nchar(20))");
|
||||||
|
} catch (ClassNotFoundException | SQLException e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
statement.executeQuery("use " + dbName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testResultSet() {
|
public void testResultSet() {
|
||||||
String sql = null;
|
String sql;
|
||||||
long ts = 1496732686000l;
|
long ts = 1496732686000l;
|
||||||
int v1 = 2147483600;
|
int v1 = 2147483600;
|
||||||
long v2 = ts + 1000;
|
long v2 = ts + 1000;
|
||||||
|
@ -119,16 +115,8 @@ public class ResultSetTest extends BaseTest {
|
||||||
public void testUnsupport() throws SQLException {
|
public void testUnsupport() throws SQLException {
|
||||||
statement.executeQuery("show databases");
|
statement.executeQuery("show databases");
|
||||||
resSet = statement.getResultSet();
|
resSet = statement.getResultSet();
|
||||||
try {
|
Assert.assertNotNull(resSet.unwrap(TSDBResultSet.class));
|
||||||
resSet.unwrap(null);
|
Assert.assertTrue(resSet.isWrapperFor(TSDBResultSet.class));
|
||||||
} catch (SQLException e) {
|
|
||||||
assertTrue(e.getMessage().contains("this operation is NOT supported currently!"));
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
resSet.isWrapperFor(null);
|
|
||||||
} catch (SQLException e) {
|
|
||||||
assertTrue(e.getMessage().contains("this operation is NOT supported currently!"));
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
resSet.getAsciiStream(0);
|
resSet.getAsciiStream(0);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
|
@ -815,13 +803,18 @@ public class ResultSetTest extends BaseTest {
|
||||||
assertEquals(res.length, 2);
|
assertEquals(res.length, 2);
|
||||||
statement.clearBatch();
|
statement.clearBatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterClass
|
@AfterClass
|
||||||
public static void close() throws Exception {
|
public static void close() {
|
||||||
|
try {
|
||||||
statement.executeUpdate("drop database " + dbName);
|
statement.executeUpdate("drop database " + dbName);
|
||||||
|
if (statement != null)
|
||||||
statement.close();
|
statement.close();
|
||||||
|
if (connection != null)
|
||||||
connection.close();
|
connection.close();
|
||||||
Thread.sleep(10);
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ public class StableTest {
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
||||||
connection = DriverManager.getConnection("jdbc:TAOS://" + host + ":0/", properties);
|
connection = DriverManager.getConnection("jdbc:TAOS://" + host + ":0/", properties);
|
||||||
Statement statement = connection.createStatement();
|
Statement statement = connection.createStatement();
|
||||||
|
statement.execute("drop database if exists " + dbName);
|
||||||
statement.execute("create database if not exists " + dbName);
|
statement.execute("create database if not exists " + dbName);
|
||||||
statement.execute("use " + dbName);
|
statement.execute("use " + dbName);
|
||||||
statement.close();
|
statement.close();
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package com.taosdata.jdbc;
|
package com.taosdata.jdbc;
|
||||||
|
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.Assert;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
@ -16,23 +17,22 @@ public class StatementTest {
|
||||||
static String dbName = "test";
|
static String dbName = "test";
|
||||||
static String tName = "t0";
|
static String tName = "t0";
|
||||||
static String host = "localhost";
|
static String host = "localhost";
|
||||||
static ResultSet resSet = null;
|
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void createConnection() throws SQLException {
|
public static void createConnection() throws SQLException {
|
||||||
try {
|
try {
|
||||||
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
||||||
} catch (ClassNotFoundException e) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Properties properties = new Properties();
|
Properties properties = new Properties();
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
||||||
connection = DriverManager.getConnection("jdbc:TAOS://" + host + ":0/?user=root&password=taosdata", properties);
|
connection = DriverManager.getConnection("jdbc:TAOS://" + host + ":0/?user=root&password=taosdata", properties);
|
||||||
|
|
||||||
statement = connection.createStatement();
|
statement = connection.createStatement();
|
||||||
statement.executeUpdate("drop database if exists " + dbName);
|
statement.executeUpdate("drop database if exists " + dbName);
|
||||||
|
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -49,7 +49,6 @@ public class StatementTest {
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -67,118 +66,46 @@ public class StatementTest {
|
||||||
assertEquals(false, isClosed);
|
assertEquals(false, isClosed);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test(expected = SQLException.class)
|
||||||
public void testUnsupport() {
|
public void testUnsupport() throws SQLException {
|
||||||
TSDBStatement tsdbStatement = (TSDBStatement) statement;
|
Assert.assertNotNull(statement.unwrap(TSDBStatement.class));
|
||||||
try {
|
Assert.assertTrue(statement.isWrapperFor(TSDBStatement.class));
|
||||||
tsdbStatement.unwrap(null);
|
|
||||||
} catch (SQLException e) {
|
statement.getMaxFieldSize();
|
||||||
}
|
statement.setMaxFieldSize(0);
|
||||||
try {
|
statement.setEscapeProcessing(true);
|
||||||
tsdbStatement.isWrapperFor(null);
|
statement.cancel();
|
||||||
} catch (SQLException e) {
|
statement.getWarnings();
|
||||||
}
|
statement.clearWarnings();
|
||||||
try {
|
statement.setCursorName(null);
|
||||||
tsdbStatement.getMaxFieldSize();
|
statement.getMoreResults();
|
||||||
} catch (SQLException e) {
|
statement.setFetchDirection(0);
|
||||||
}
|
statement.getFetchDirection();
|
||||||
try {
|
statement.getResultSetConcurrency();
|
||||||
tsdbStatement.setMaxFieldSize(0);
|
statement.getResultSetType();
|
||||||
} catch (SQLException e) {
|
statement.getConnection();
|
||||||
}
|
statement.getMoreResults();
|
||||||
try {
|
statement.getGeneratedKeys();
|
||||||
tsdbStatement.setEscapeProcessing(true);
|
statement.executeUpdate(null, 0);
|
||||||
} catch (SQLException e) {
|
statement.executeUpdate(null, new int[]{0});
|
||||||
}
|
statement.executeUpdate(null, new String[]{"str1", "str2"});
|
||||||
try {
|
statement.getResultSetHoldability();
|
||||||
tsdbStatement.cancel();
|
statement.setPoolable(true);
|
||||||
} catch (SQLException e) {
|
statement.isPoolable();
|
||||||
}
|
statement.closeOnCompletion();
|
||||||
try {
|
statement.isCloseOnCompletion();
|
||||||
tsdbStatement.getWarnings();
|
|
||||||
} catch (SQLException e) {
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
tsdbStatement.clearWarnings();
|
|
||||||
} catch (SQLException e) {
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
tsdbStatement.setCursorName(null);
|
|
||||||
} catch (SQLException e) {
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
tsdbStatement.getMoreResults();
|
|
||||||
} catch (SQLException e) {
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
tsdbStatement.setFetchDirection(0);
|
|
||||||
} catch (SQLException e) {
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
tsdbStatement.getFetchDirection();
|
|
||||||
} catch (SQLException e) {
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
tsdbStatement.getResultSetConcurrency();
|
|
||||||
} catch (SQLException e) {
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
tsdbStatement.getResultSetType();
|
|
||||||
} catch (SQLException e) {
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
tsdbStatement.getConnection();
|
|
||||||
} catch (SQLException e) {
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
tsdbStatement.getMoreResults();
|
|
||||||
} catch (SQLException e) {
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
tsdbStatement.getGeneratedKeys();
|
|
||||||
} catch (SQLException e) {
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
tsdbStatement.executeUpdate(null, 0);
|
|
||||||
} catch (SQLException e) {
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
tsdbStatement.executeUpdate(null, new int[]{0});
|
|
||||||
} catch (SQLException e) {
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
tsdbStatement.executeUpdate(null, new String[]{"str1", "str2"});
|
|
||||||
} catch (SQLException e) {
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
tsdbStatement.getResultSetHoldability();
|
|
||||||
} catch (SQLException e) {
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
tsdbStatement.setPoolable(true);
|
|
||||||
} catch (SQLException e) {
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
tsdbStatement.isPoolable();
|
|
||||||
} catch (SQLException e) {
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
tsdbStatement.closeOnCompletion();
|
|
||||||
} catch (SQLException e) {
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
tsdbStatement.isCloseOnCompletion();
|
|
||||||
} catch (SQLException e) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterClass
|
@AfterClass
|
||||||
public static void close() throws Exception {
|
public static void close() {
|
||||||
if (!statement.isClosed()) {
|
try {
|
||||||
statement.executeUpdate("drop database if exists " + dbName);
|
statement.execute("drop database if exists " + dbName);
|
||||||
|
if (statement != null)
|
||||||
statement.close();
|
statement.close();
|
||||||
|
if (connection != null)
|
||||||
connection.close();
|
connection.close();
|
||||||
Thread.sleep(10);
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,21 +10,18 @@ import java.sql.SQLException;
|
||||||
import java.sql.Statement;
|
import java.sql.Statement;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
public class SubscribeTest extends BaseTest {
|
public class SubscribeTest {
|
||||||
Connection connection = null;
|
Connection connection;
|
||||||
Statement statement = null;
|
Statement statement;
|
||||||
String dbName = "test";
|
String dbName = "test";
|
||||||
String tName = "t0";
|
String tName = "t0";
|
||||||
String host = "localhost";
|
String host = "localhost";
|
||||||
String topic = "test";
|
String topic = "test";
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void createDatabase() throws SQLException {
|
public void createDatabase() {
|
||||||
try {
|
try {
|
||||||
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
||||||
} catch (ClassNotFoundException e) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Properties properties = new Properties();
|
Properties properties = new Properties();
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_HOST, host);
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_HOST, host);
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
||||||
|
@ -41,6 +38,10 @@ public class SubscribeTest extends BaseTest {
|
||||||
String sql = "insert into " + dbName + "." + tName + " values (" + ts + ", " + (100 + i) + ", " + i + ")";
|
String sql = "insert into " + dbName + "." + tName + " values (" + ts + ", " + (100 + i) + ", " + i + ")";
|
||||||
statement.executeUpdate(sql);
|
statement.executeUpdate(sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} catch (ClassNotFoundException | SQLException e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -79,10 +80,16 @@ public class SubscribeTest extends BaseTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
public void close() throws Exception {
|
public void close() {
|
||||||
|
try {
|
||||||
statement.executeQuery("drop database " + dbName);
|
statement.executeQuery("drop database " + dbName);
|
||||||
|
if (statement != null)
|
||||||
statement.close();
|
statement.close();
|
||||||
|
if (connection != null)
|
||||||
connection.close();
|
connection.close();
|
||||||
Thread.sleep(10);
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -6,37 +6,9 @@ import java.sql.*;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
public class TSDBDatabaseMetaDataTest {
|
public class TSDBDatabaseMetaDataTest {
|
||||||
private TSDBDatabaseMetaData metaData;
|
|
||||||
private static final String host = "127.0.0.1";
|
private static final String host = "127.0.0.1";
|
||||||
private Connection connection;
|
private static Connection connection;
|
||||||
|
private static TSDBDatabaseMetaData metaData;
|
||||||
@BeforeClass
|
|
||||||
public void before() {
|
|
||||||
try {
|
|
||||||
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
|
||||||
Properties properties = new Properties();
|
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_HOST, host);
|
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
|
||||||
connection = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata", properties);
|
|
||||||
metaData = connection.getMetaData().unwrap(TSDBDatabaseMetaData.class);
|
|
||||||
} catch (ClassNotFoundException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (SQLException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@AfterClass
|
|
||||||
public void after() {
|
|
||||||
try {
|
|
||||||
if (connection != null)
|
|
||||||
connection.close();
|
|
||||||
} catch (SQLException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void unwrap() throws SQLException {
|
public void unwrap() throws SQLException {
|
||||||
|
@ -61,7 +33,7 @@ public class TSDBDatabaseMetaDataTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getURL() throws SQLException {
|
public void getURL() throws SQLException {
|
||||||
Assert.assertEquals("jdbc:TAOS://localhost:6030/?user=root&password=taosdata", metaData.getURL());
|
Assert.assertEquals("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata", metaData.getURL());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -975,4 +947,32 @@ public class TSDBDatabaseMetaDataTest {
|
||||||
public void generatedKeyAlwaysReturned() throws SQLException {
|
public void generatedKeyAlwaysReturned() throws SQLException {
|
||||||
Assert.assertFalse(metaData.generatedKeyAlwaysReturned());
|
Assert.assertFalse(metaData.generatedKeyAlwaysReturned());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void beforeClass() {
|
||||||
|
try {
|
||||||
|
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
||||||
|
Properties properties = new Properties();
|
||||||
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
||||||
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
||||||
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
||||||
|
connection = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata", properties);
|
||||||
|
metaData = connection.getMetaData().unwrap(TSDBDatabaseMetaData.class);
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void afterClass() {
|
||||||
|
try {
|
||||||
|
if (connection != null)
|
||||||
|
connection.close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -3,9 +3,6 @@ package com.taosdata.jdbc;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.sql.*;
|
import java.sql.*;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
|
@ -27,54 +24,15 @@ public class TSDBDriverTest {
|
||||||
"jdbc:TAOS://:/test",
|
"jdbc:TAOS://:/test",
|
||||||
"jdbc:TAOS://localhost:0/?user=root&password=taosdata"
|
"jdbc:TAOS://localhost:0/?user=root&password=taosdata"
|
||||||
};
|
};
|
||||||
private static boolean islibLoaded = false;
|
|
||||||
private static boolean isTaosdActived;
|
|
||||||
|
|
||||||
private Connection conn;
|
private Connection conn;
|
||||||
|
|
||||||
@BeforeClass
|
|
||||||
public static void before() {
|
|
||||||
String osName = System.getProperty("os.name").toLowerCase();
|
|
||||||
if (!osName.equals("linux"))
|
|
||||||
return;
|
|
||||||
// try to load taos lib
|
|
||||||
try {
|
|
||||||
System.loadLibrary("taos");
|
|
||||||
islibLoaded = true;
|
|
||||||
} catch (UnsatisfiedLinkError error) {
|
|
||||||
System.out.println("load tdengine lib failed.");
|
|
||||||
error.printStackTrace();
|
|
||||||
}
|
|
||||||
// check taosd is activated
|
|
||||||
try {
|
|
||||||
String[] cmd = {"/bin/bash", "-c", "ps -ef | grep taosd | grep -v \"grep\""};
|
|
||||||
Process exec = Runtime.getRuntime().exec(cmd);
|
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(exec.getInputStream()));
|
|
||||||
int lineCnt = 0;
|
|
||||||
while (reader.readLine() != null) {
|
|
||||||
lineCnt++;
|
|
||||||
}
|
|
||||||
if (lineCnt > 0)
|
|
||||||
isTaosdActived = true;
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
|
||||||
} catch (ClassNotFoundException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testConnectWithJdbcURL() {
|
public void testConnectWithJdbcURL() {
|
||||||
final String url = "jdbc:TAOS://localhost:6030/log?user=root&password=taosdata";
|
final String url = "jdbc:TAOS://localhost:6030/log?user=root&password=taosdata";
|
||||||
try {
|
try {
|
||||||
if (islibLoaded && isTaosdActived) {
|
|
||||||
conn = DriverManager.getConnection(url);
|
conn = DriverManager.getConnection(url);
|
||||||
assertNotNull("failure - connection should not be null", conn);
|
assertNotNull("failure - connection should not be null", conn);
|
||||||
}
|
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
fail("failure - should not throw Exception");
|
fail("failure - should not throw Exception");
|
||||||
|
@ -89,10 +47,8 @@ public class TSDBDriverTest {
|
||||||
connProps.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
connProps.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
||||||
connProps.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
connProps.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
||||||
try {
|
try {
|
||||||
if (islibLoaded && isTaosdActived) {
|
|
||||||
conn = DriverManager.getConnection(jdbcUrl, connProps);
|
conn = DriverManager.getConnection(jdbcUrl, connProps);
|
||||||
assertNotNull("failure - connection should not be null", conn);
|
assertNotNull("failure - connection should not be null", conn);
|
||||||
}
|
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
fail("failure - should not throw Exception");
|
fail("failure - should not throw Exception");
|
||||||
|
@ -107,10 +63,8 @@ public class TSDBDriverTest {
|
||||||
connProps.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
connProps.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
||||||
connProps.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
connProps.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
||||||
try {
|
try {
|
||||||
if (islibLoaded && isTaosdActived) {
|
|
||||||
conn = DriverManager.getConnection(jdbcUrl, connProps);
|
conn = DriverManager.getConnection(jdbcUrl, connProps);
|
||||||
assertNotNull("failure - connection should not be null", conn);
|
assertNotNull("failure - connection should not be null", conn);
|
||||||
}
|
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
fail("failure - should not throw Exception");
|
fail("failure - should not throw Exception");
|
||||||
|
@ -207,4 +161,14 @@ public class TSDBDriverTest {
|
||||||
assertNull("failure - getParentLogger should be be null", new TSDBDriver().getParentLogger());
|
assertNull("failure - getParentLogger should be be null", new TSDBDriver().getParentLogger());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void before() {
|
||||||
|
try {
|
||||||
|
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,186 @@
|
||||||
|
package com.taosdata.jdbc;
|
||||||
|
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DriverManager;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
public class TSDBPreparedStatementTest {
|
||||||
|
private static final String host = "127.0.0.1";
|
||||||
|
private static Connection conn;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void executeQuery() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void executeUpdate() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setNull() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setBoolean() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setByte() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setShort() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setInt() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setLong() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setFloat() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setDouble() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setBigDecimal() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setString() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setBytes() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setDate() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setTime() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setTimestamp() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setAsciiStream() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setUnicodeStream() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setBinaryStream() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void clearParameters() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setObject() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void execute() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void addBatch() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setCharacterStream() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setRef() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setBlob() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setClob() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setArray() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getMetaData() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setURL() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getParameterMetaData() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setRowId() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setNString() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setNCharacterStream() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setNClob() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setSQLXML() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void beforeClass() {
|
||||||
|
try {
|
||||||
|
Class.forName("com.taosdata.jdbc.rs.RestfulDriver");
|
||||||
|
conn = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata");
|
||||||
|
} catch (ClassNotFoundException | SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void afterClass() {
|
||||||
|
try {
|
||||||
|
if (conn != null)
|
||||||
|
conn.close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,14 +1,12 @@
|
||||||
package com.taosdata.jdbc.cases;
|
package com.taosdata.jdbc.cases;
|
||||||
|
|
||||||
import com.taosdata.jdbc.lib.TSDBCommon;
|
import com.taosdata.jdbc.TSDBDriver;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.sql.Connection;
|
import java.sql.*;
|
||||||
import java.sql.ResultSet;
|
import java.util.Properties;
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.sql.Statement;
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
|
@ -18,23 +16,40 @@ import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
public class BatchInsertTest {
|
public class BatchInsertTest {
|
||||||
|
|
||||||
static String host = "localhost";
|
static String host = "127.0.0.1";
|
||||||
static String dbName = "test";
|
static String dbName = "test";
|
||||||
static String stbName = "meters";
|
static String stbName = "meters";
|
||||||
static int numOfTables = 30;
|
static int numOfTables = 30;
|
||||||
final static int numOfRecordsPerTable = 1000;
|
final static int numOfRecordsPerTable = 1000;
|
||||||
static long ts = 1496732686000l;
|
static long ts = 1496732686000l;
|
||||||
final static String tablePrefix = "t";
|
final static String tablePrefix = "t";
|
||||||
|
|
||||||
private Connection connection;
|
private Connection connection;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void before() {
|
public void before() {
|
||||||
try {
|
try {
|
||||||
connection = TSDBCommon.getConn(host);
|
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
||||||
TSDBCommon.createDatabase(connection, dbName);
|
Properties properties = new Properties();
|
||||||
TSDBCommon.createStable(connection, stbName);
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_HOST, host);
|
||||||
TSDBCommon.createTables(connection, numOfTables, stbName, tablePrefix);
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
||||||
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
||||||
|
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
||||||
|
connection = DriverManager.getConnection("jdbc:TAOS://" + host + ":0/", properties);
|
||||||
|
|
||||||
|
Statement statement = connection.createStatement();
|
||||||
|
statement.executeUpdate("drop database if exists " + dbName);
|
||||||
|
statement.executeUpdate("create database if not exists " + dbName);
|
||||||
|
statement.executeUpdate("use " + dbName);
|
||||||
|
// create stable
|
||||||
|
String createTableSql = "create table " + stbName + "(ts timestamp, f1 int, f2 int, f3 int) tags(areaid int, loc binary(20))";
|
||||||
|
statement.executeUpdate(createTableSql);
|
||||||
|
// create tables
|
||||||
|
for(int i = 0; i < numOfTables; i++) {
|
||||||
|
String loc = i % 2 == 0 ? "beijing" : "shanghai";
|
||||||
|
String createSubTalbesSql = "create table " + tablePrefix + i + " using " + stbName + " tags(" + i + ", '" + loc + "')";
|
||||||
|
statement.executeUpdate(createSubTalbesSql);
|
||||||
|
}
|
||||||
|
statement.close();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
@ -45,9 +60,7 @@ public class BatchInsertTest {
|
||||||
ExecutorService executorService = Executors.newFixedThreadPool(numOfTables);
|
ExecutorService executorService = Executors.newFixedThreadPool(numOfTables);
|
||||||
for (int i = 0; i < numOfTables; i++) {
|
for (int i = 0; i < numOfTables; i++) {
|
||||||
final int index = i;
|
final int index = i;
|
||||||
executorService.execute(new Runnable() {
|
executorService.execute(() -> {
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
try {
|
try {
|
||||||
long startTime = System.currentTimeMillis();
|
long startTime = System.currentTimeMillis();
|
||||||
Statement statement = connection.createStatement(); // get statement
|
Statement statement = connection.createStatement(); // get statement
|
||||||
|
@ -69,7 +82,6 @@ public class BatchInsertTest {
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,7 +114,6 @@ public class BatchInsertTest {
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,47 +0,0 @@
|
||||||
package com.taosdata.jdbc.lib;
|
|
||||||
|
|
||||||
import com.taosdata.jdbc.TSDBDriver;
|
|
||||||
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.DriverManager;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.sql.Statement;
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
public class TSDBCommon {
|
|
||||||
|
|
||||||
public static Connection getConn(String host) throws SQLException, ClassNotFoundException {
|
|
||||||
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
|
||||||
Properties properties = new Properties();
|
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_HOST, host);
|
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
|
||||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
|
||||||
return DriverManager.getConnection("jdbc:TAOS://" + host + ":0/", properties);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void createDatabase(Connection connection, String dbName) throws SQLException {
|
|
||||||
Statement statement = connection.createStatement();
|
|
||||||
statement.executeUpdate("drop database if exists " + dbName);
|
|
||||||
statement.executeUpdate("create database if not exists " + dbName);
|
|
||||||
statement.executeUpdate("use " + dbName);
|
|
||||||
statement.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void createStable(Connection connection, String stbName) throws SQLException {
|
|
||||||
Statement statement = connection.createStatement();
|
|
||||||
String createTableSql = "create table " + stbName + "(ts timestamp, f1 int, f2 int, f3 int) tags(areaid int, loc binary(20))";
|
|
||||||
statement.executeUpdate(createTableSql);
|
|
||||||
statement.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void createTables(Connection connection, int numOfTables, String stbName,String tablePrefix) throws SQLException {
|
|
||||||
Statement statement = connection.createStatement();
|
|
||||||
for(int i = 0; i < numOfTables; i++) {
|
|
||||||
String loc = i % 2 == 0 ? "beijing" : "shanghai";
|
|
||||||
String createSubTalbesSql = "create table " + tablePrefix + i + " using " + stbName + " tags(" + i + ", '" + loc + "')";
|
|
||||||
statement.executeUpdate(createSubTalbesSql);
|
|
||||||
}
|
|
||||||
statement.close();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -8,6 +8,7 @@ import java.sql.*;
|
||||||
public class AuthenticationTest {
|
public class AuthenticationTest {
|
||||||
|
|
||||||
private static final String host = "127.0.0.1";
|
private static final String host = "127.0.0.1";
|
||||||
|
// private static final String host = "master";
|
||||||
private static final String user = "root";
|
private static final String user = "root";
|
||||||
private static final String password = "123456";
|
private static final String password = "123456";
|
||||||
private Connection conn;
|
private Connection conn;
|
||||||
|
|
|
@ -10,23 +10,12 @@ import java.util.Random;
|
||||||
public class RestfulJDBCTest {
|
public class RestfulJDBCTest {
|
||||||
|
|
||||||
private static final String host = "127.0.0.1";
|
private static final String host = "127.0.0.1";
|
||||||
private Connection connection;
|
// private static final String host = "master";
|
||||||
|
private static Connection connection;
|
||||||
@Before
|
private Random random = new Random(System.currentTimeMillis());
|
||||||
public void before() throws ClassNotFoundException, SQLException {
|
|
||||||
Class.forName("com.taosdata.jdbc.rs.RestfulDriver");
|
|
||||||
connection = DriverManager.getConnection("jdbc:TAOS-RS://" + host + ":6041/restful_test?user=root&password=taosdata");
|
|
||||||
}
|
|
||||||
|
|
||||||
@After
|
|
||||||
public void after() throws SQLException {
|
|
||||||
if (connection != null)
|
|
||||||
connection.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询所有log.log
|
* select * from log.log
|
||||||
**/
|
**/
|
||||||
@Test
|
@Test
|
||||||
public void testCase001() {
|
public void testCase001() {
|
||||||
|
@ -85,7 +74,6 @@ public class RestfulJDBCTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Random random = new Random(System.currentTimeMillis());
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase005() {
|
public void testCase005() {
|
||||||
|
@ -105,5 +93,50 @@ public class RestfulJDBCTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase006() {
|
||||||
|
try (Statement stmt = connection.createStatement()) {
|
||||||
|
ResultSet rs = stmt.executeQuery("select * from weather");
|
||||||
|
while (rs.next()) {
|
||||||
|
System.out.print("ts: " + rs.getTimestamp("ts"));
|
||||||
|
System.out.print(", temperature: " + rs.getString("temperature"));
|
||||||
|
System.out.print(", humidity: " + rs.getString("humidity"));
|
||||||
|
System.out.println(", location: " + rs.getString("location"));
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCase007() {
|
||||||
|
try (Statement stmt = connection.createStatement()) {
|
||||||
|
ResultSet rs = stmt.executeQuery("select * from weather");
|
||||||
|
ResultSetMetaData meta = rs.getMetaData();
|
||||||
|
while (rs.next()) {
|
||||||
|
int columnCount = meta.getColumnCount();
|
||||||
|
for (int i = 1; i <= columnCount; i++) {
|
||||||
|
String columnLabel = meta.getColumnLabel(i);
|
||||||
|
String value = rs.getString(i);
|
||||||
|
System.out.print(columnLabel + ": " + value + "\t");
|
||||||
|
}
|
||||||
|
System.out.println();
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void before() throws ClassNotFoundException, SQLException {
|
||||||
|
Class.forName("com.taosdata.jdbc.rs.RestfulDriver");
|
||||||
|
connection = DriverManager.getConnection("jdbc:TAOS-RS://" + host + ":6041/restful_test?user=root&password=taosdata");
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void after() throws SQLException {
|
||||||
|
if (connection != null)
|
||||||
|
connection.close();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,221 @@
|
||||||
|
package com.taosdata.jdbc.rs;
|
||||||
|
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.sql.*;
|
||||||
|
|
||||||
|
public class RestfulResultSetMetaDataTest {
|
||||||
|
|
||||||
|
private static final String host = "127.0.0.1";
|
||||||
|
// private static final String host = "master";
|
||||||
|
|
||||||
|
private static Connection conn;
|
||||||
|
private static Statement stmt;
|
||||||
|
private static ResultSet rs;
|
||||||
|
private static ResultSetMetaData meta;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getColumnCount() throws SQLException {
|
||||||
|
Assert.assertEquals(10, meta.getColumnCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void isAutoIncrement() throws SQLException {
|
||||||
|
Assert.assertFalse(meta.isAutoIncrement(1));
|
||||||
|
Assert.assertFalse(meta.isAutoIncrement(2));
|
||||||
|
Assert.assertFalse(meta.isAutoIncrement(3));
|
||||||
|
Assert.assertFalse(meta.isAutoIncrement(4));
|
||||||
|
Assert.assertFalse(meta.isAutoIncrement(5));
|
||||||
|
Assert.assertFalse(meta.isAutoIncrement(6));
|
||||||
|
Assert.assertFalse(meta.isAutoIncrement(7));
|
||||||
|
Assert.assertFalse(meta.isAutoIncrement(8));
|
||||||
|
Assert.assertFalse(meta.isAutoIncrement(9));
|
||||||
|
Assert.assertFalse(meta.isAutoIncrement(10));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void isCaseSensitive() throws SQLException {
|
||||||
|
Assert.assertFalse(meta.isCaseSensitive(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void isSearchable() throws SQLException {
|
||||||
|
Assert.assertTrue(meta.isSearchable(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void isCurrency() throws SQLException {
|
||||||
|
Assert.assertFalse(meta.isCurrency(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void isNullable() throws SQLException {
|
||||||
|
Assert.assertEquals(ResultSetMetaData.columnNoNulls, meta.isNullable(1));
|
||||||
|
Assert.assertEquals(ResultSetMetaData.columnNullable, meta.isNullable(2));
|
||||||
|
Assert.assertEquals(ResultSetMetaData.columnNullable, meta.isNullable(3));
|
||||||
|
Assert.assertEquals(ResultSetMetaData.columnNullable, meta.isNullable(4));
|
||||||
|
Assert.assertEquals(ResultSetMetaData.columnNullable, meta.isNullable(5));
|
||||||
|
Assert.assertEquals(ResultSetMetaData.columnNullable, meta.isNullable(6));
|
||||||
|
Assert.assertEquals(ResultSetMetaData.columnNullable, meta.isNullable(7));
|
||||||
|
Assert.assertEquals(ResultSetMetaData.columnNullable, meta.isNullable(8));
|
||||||
|
Assert.assertEquals(ResultSetMetaData.columnNullable, meta.isNullable(9));
|
||||||
|
Assert.assertEquals(ResultSetMetaData.columnNullable, meta.isNullable(10));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void isSigned() throws SQLException {
|
||||||
|
Assert.assertFalse(meta.isSigned(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getColumnDisplaySize() throws SQLException {
|
||||||
|
Assert.assertEquals(64, meta.getColumnDisplaySize(10));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getColumnLabel() throws SQLException {
|
||||||
|
Assert.assertEquals("f1", meta.getColumnLabel(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getColumnName() throws SQLException {
|
||||||
|
Assert.assertEquals("f1", meta.getColumnName(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getSchemaName() throws SQLException {
|
||||||
|
Assert.assertEquals("", meta.getSchemaName(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getPrecision() throws SQLException {
|
||||||
|
Assert.assertEquals(0, meta.getPrecision(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getScale() throws SQLException {
|
||||||
|
Assert.assertEquals(0, meta.getScale(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getTableName() throws SQLException {
|
||||||
|
Assert.assertEquals("", meta.getTableName(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getCatalogName() throws SQLException {
|
||||||
|
Assert.assertEquals("restful_test", meta.getCatalogName(1));
|
||||||
|
Assert.assertEquals("restful_test", meta.getCatalogName(2));
|
||||||
|
Assert.assertEquals("restful_test", meta.getCatalogName(3));
|
||||||
|
Assert.assertEquals("restful_test", meta.getCatalogName(4));
|
||||||
|
Assert.assertEquals("restful_test", meta.getCatalogName(5));
|
||||||
|
Assert.assertEquals("restful_test", meta.getCatalogName(6));
|
||||||
|
Assert.assertEquals("restful_test", meta.getCatalogName(7));
|
||||||
|
Assert.assertEquals("restful_test", meta.getCatalogName(8));
|
||||||
|
Assert.assertEquals("restful_test", meta.getCatalogName(9));
|
||||||
|
Assert.assertEquals("restful_test", meta.getCatalogName(10));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getColumnType() throws SQLException {
|
||||||
|
Assert.assertEquals(Types.TIMESTAMP, meta.getColumnType(1));
|
||||||
|
Assert.assertEquals(Types.INTEGER, meta.getColumnType(2));
|
||||||
|
Assert.assertEquals(Types.BIGINT, meta.getColumnType(3));
|
||||||
|
Assert.assertEquals(Types.FLOAT, meta.getColumnType(4));
|
||||||
|
Assert.assertEquals(Types.DOUBLE, meta.getColumnType(5));
|
||||||
|
Assert.assertEquals(Types.BINARY, meta.getColumnType(6));
|
||||||
|
Assert.assertEquals(Types.SMALLINT, meta.getColumnType(7));
|
||||||
|
Assert.assertEquals(Types.TINYINT, meta.getColumnType(8));
|
||||||
|
Assert.assertEquals(Types.BOOLEAN, meta.getColumnType(9));
|
||||||
|
Assert.assertEquals(Types.NCHAR, meta.getColumnType(10));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getColumnTypeName() throws SQLException {
|
||||||
|
Assert.assertEquals("TIMESTAMP", meta.getColumnTypeName(1));
|
||||||
|
Assert.assertEquals("INT", meta.getColumnTypeName(2));
|
||||||
|
Assert.assertEquals("BIGINT", meta.getColumnTypeName(3));
|
||||||
|
Assert.assertEquals("FLOAT", meta.getColumnTypeName(4));
|
||||||
|
Assert.assertEquals("DOUBLE", meta.getColumnTypeName(5));
|
||||||
|
Assert.assertEquals("BINARY", meta.getColumnTypeName(6));
|
||||||
|
Assert.assertEquals("SMALLINT", meta.getColumnTypeName(7));
|
||||||
|
Assert.assertEquals("TINYINT", meta.getColumnTypeName(8));
|
||||||
|
Assert.assertEquals("BOOL", meta.getColumnTypeName(9));
|
||||||
|
Assert.assertEquals("NCHAR", meta.getColumnTypeName(10));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void isReadOnly() throws SQLException {
|
||||||
|
Assert.assertTrue(meta.isReadOnly(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void isWritable() throws SQLException {
|
||||||
|
Assert.assertFalse(meta.isWritable(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void isDefinitelyWritable() throws SQLException {
|
||||||
|
Assert.assertFalse(meta.isDefinitelyWritable(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getColumnClassName() throws SQLException {
|
||||||
|
Assert.assertEquals(Timestamp.class.getName(), meta.getColumnClassName(1));
|
||||||
|
Assert.assertEquals(Integer.class.getName(), meta.getColumnClassName(2));
|
||||||
|
Assert.assertEquals(Long.class.getName(), meta.getColumnClassName(3));
|
||||||
|
Assert.assertEquals(Float.class.getName(), meta.getColumnClassName(4));
|
||||||
|
Assert.assertEquals(Double.class.getName(), meta.getColumnClassName(5));
|
||||||
|
Assert.assertEquals(String.class.getName(), meta.getColumnClassName(6));
|
||||||
|
Assert.assertEquals(Short.class.getName(), meta.getColumnClassName(7));
|
||||||
|
Assert.assertEquals(Short.class.getName(), meta.getColumnClassName(8));
|
||||||
|
Assert.assertEquals(Boolean.class.getName(), meta.getColumnClassName(9));
|
||||||
|
Assert.assertEquals(String.class.getName(), meta.getColumnClassName(10));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void unwrap() throws SQLException {
|
||||||
|
Assert.assertNotNull(meta.unwrap(RestfulResultSetMetaData.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void isWrapperFor() throws SQLException {
|
||||||
|
Assert.assertTrue(meta.isWrapperFor(RestfulResultSetMetaData.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void beforeClass() {
|
||||||
|
try {
|
||||||
|
Class.forName("com.taosdata.jdbc.rs.RestfulDriver");
|
||||||
|
conn = DriverManager.getConnection("jdbc:TAOS-RS://" + host + ":6041/restful_test?user=root&password=taosdata");
|
||||||
|
stmt = conn.createStatement();
|
||||||
|
stmt.execute("create database if not exists restful_test");
|
||||||
|
stmt.execute("use restful_test");
|
||||||
|
stmt.execute("drop table if exists weather");
|
||||||
|
stmt.execute("create table if not exists weather(f1 timestamp, f2 int, f3 bigint, f4 float, f5 double, f6 binary(64), f7 smallint, f8 tinyint, f9 bool, f10 nchar(64))");
|
||||||
|
stmt.execute("insert into restful_test.weather values('2021-01-01 00:00:00.000', 1, 100, 3.1415, 3.1415926, 'abc', 10, 10, true, '涛思数据')");
|
||||||
|
rs = stmt.executeQuery("select * from restful_test.weather");
|
||||||
|
rs.next();
|
||||||
|
meta = rs.getMetaData();
|
||||||
|
} catch (ClassNotFoundException | SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void afterClass() {
|
||||||
|
try {
|
||||||
|
if (rs != null)
|
||||||
|
rs.close();
|
||||||
|
if (stmt != null)
|
||||||
|
stmt.close();
|
||||||
|
if (conn != null)
|
||||||
|
conn.close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,588 @@
|
||||||
|
package com.taosdata.jdbc.rs;
|
||||||
|
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.sql.*;
|
||||||
|
|
||||||
|
public class RestfulResultSetTest {
|
||||||
|
|
||||||
|
private static final String host = "127.0.0.1";
|
||||||
|
// private static final String host = "master";
|
||||||
|
|
||||||
|
private static Connection conn;
|
||||||
|
private static Statement stmt;
|
||||||
|
private static ResultSet rs;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void wasNull() throws SQLException {
|
||||||
|
Assert.assertFalse(rs.wasNull());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getString() throws SQLException {
|
||||||
|
String f10 = rs.getString("f10");
|
||||||
|
Assert.assertEquals("涛思数据", f10);
|
||||||
|
f10 = rs.getString(10);
|
||||||
|
Assert.assertEquals("涛思数据", f10);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getBoolean() throws SQLException {
|
||||||
|
Boolean f9 = rs.getBoolean("f9");
|
||||||
|
Assert.assertEquals(true, f9);
|
||||||
|
f9 = rs.getBoolean(9);
|
||||||
|
Assert.assertEquals(true, f9);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void getByte() throws SQLException {
|
||||||
|
rs.getByte(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getShort() throws SQLException {
|
||||||
|
short f7 = rs.getShort("f7");
|
||||||
|
Assert.assertEquals(10, f7);
|
||||||
|
f7 = rs.getShort(7);
|
||||||
|
Assert.assertEquals(10, f7);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getInt() throws SQLException {
|
||||||
|
int f2 = rs.getInt("f2");
|
||||||
|
Assert.assertEquals(1, f2);
|
||||||
|
f2 = rs.getInt(2);
|
||||||
|
Assert.assertEquals(1, f2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getLong() throws SQLException {
|
||||||
|
long f3 = rs.getLong("f3");
|
||||||
|
Assert.assertEquals(100, f3);
|
||||||
|
f3 = rs.getLong(3);
|
||||||
|
Assert.assertEquals(100, f3);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getFloat() throws SQLException {
|
||||||
|
float f4 = rs.getFloat("f4");
|
||||||
|
Assert.assertEquals(3.1415f, f4, 0f);
|
||||||
|
f4 = rs.getFloat(4);
|
||||||
|
Assert.assertEquals(3.1415f, f4, 0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getDouble() throws SQLException {
|
||||||
|
double f5 = rs.getDouble("f5");
|
||||||
|
Assert.assertEquals(3.1415926, f5, 0.0);
|
||||||
|
f5 = rs.getDouble(5);
|
||||||
|
Assert.assertEquals(3.1415926, f5, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void getBigDecimal() throws SQLException {
|
||||||
|
rs.getBigDecimal("f1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void getBytes() throws SQLException {
|
||||||
|
rs.getBytes("f1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void getDate() throws SQLException {
|
||||||
|
rs.getDate("f1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void getTime() throws SQLException {
|
||||||
|
rs.getTime("f1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getTimestamp() throws SQLException {
|
||||||
|
Timestamp f1 = rs.getTimestamp("f1");
|
||||||
|
Assert.assertEquals("2021-01-01 00:00:00.0", f1.toString());
|
||||||
|
f1 = rs.getTimestamp(1);
|
||||||
|
Assert.assertEquals("2021-01-01 00:00:00.0", f1.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void getAsciiStream() throws SQLException {
|
||||||
|
rs.getAsciiStream("f1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void getUnicodeStream() throws SQLException {
|
||||||
|
rs.getUnicodeStream("f1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void getBinaryStream() throws SQLException {
|
||||||
|
rs.getBinaryStream("f1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getWarnings() throws SQLException {
|
||||||
|
Assert.assertNull(rs.getWarnings());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void clearWarnings() throws SQLException {
|
||||||
|
rs.clearWarnings();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void getCursorName() throws SQLException {
|
||||||
|
rs.getCursorName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getMetaData() throws SQLException {
|
||||||
|
ResultSetMetaData meta = rs.getMetaData();
|
||||||
|
Assert.assertNotNull(meta);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void getObject() throws SQLException {
|
||||||
|
rs.getObject("f1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLException.class)
|
||||||
|
public void findColumn() throws SQLException {
|
||||||
|
int columnIndex = rs.findColumn("f1");
|
||||||
|
Assert.assertEquals(1, columnIndex);
|
||||||
|
columnIndex = rs.findColumn("f2");
|
||||||
|
Assert.assertEquals(2, columnIndex);
|
||||||
|
columnIndex = rs.findColumn("f3");
|
||||||
|
Assert.assertEquals(3, columnIndex);
|
||||||
|
columnIndex = rs.findColumn("f4");
|
||||||
|
Assert.assertEquals(4, columnIndex);
|
||||||
|
columnIndex = rs.findColumn("f5");
|
||||||
|
Assert.assertEquals(5, columnIndex);
|
||||||
|
columnIndex = rs.findColumn("f6");
|
||||||
|
Assert.assertEquals(6, columnIndex);
|
||||||
|
columnIndex = rs.findColumn("f7");
|
||||||
|
Assert.assertEquals(7, columnIndex);
|
||||||
|
columnIndex = rs.findColumn("f8");
|
||||||
|
Assert.assertEquals(8, columnIndex);
|
||||||
|
columnIndex = rs.findColumn("f9");
|
||||||
|
Assert.assertEquals(9, columnIndex);
|
||||||
|
columnIndex = rs.findColumn("f10");
|
||||||
|
Assert.assertEquals(10, columnIndex);
|
||||||
|
|
||||||
|
rs.findColumn("f11");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void getCharacterStream() throws SQLException {
|
||||||
|
rs.getCharacterStream(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void isBeforeFirst() throws SQLException {
|
||||||
|
Assert.assertFalse(rs.isBeforeFirst());
|
||||||
|
rs.beforeFirst();
|
||||||
|
Assert.assertTrue(rs.isBeforeFirst());
|
||||||
|
rs.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void isAfterLast() throws SQLException {
|
||||||
|
Assert.assertFalse(rs.isAfterLast());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void isFirst() throws SQLException {
|
||||||
|
Assert.assertTrue(rs.isFirst());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void isLast() throws SQLException {
|
||||||
|
Assert.assertTrue(rs.isLast());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void beforeFirst() throws SQLException {
|
||||||
|
rs.beforeFirst();
|
||||||
|
Assert.assertTrue(rs.isBeforeFirst());
|
||||||
|
rs.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void afterLast() throws SQLException {
|
||||||
|
rs.afterLast();
|
||||||
|
Assert.assertTrue(rs.isAfterLast());
|
||||||
|
rs.first();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void first() throws SQLException {
|
||||||
|
rs.first();
|
||||||
|
Assert.assertEquals("2021-01-01 00:00:00.0", rs.getTimestamp("f1").toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void last() throws SQLException {
|
||||||
|
rs.last();
|
||||||
|
Assert.assertEquals("2021-01-01 00:00:00.0", rs.getTimestamp("f1").toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getRow() throws SQLException {
|
||||||
|
int row = rs.getRow();
|
||||||
|
Assert.assertEquals(1, row);
|
||||||
|
rs.beforeFirst();
|
||||||
|
row = rs.getRow();
|
||||||
|
Assert.assertEquals(0, row);
|
||||||
|
rs.first();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void absolute() throws SQLException {
|
||||||
|
rs.absolute(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void relative() throws SQLException {
|
||||||
|
rs.relative(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void previous() throws SQLException {
|
||||||
|
rs.previous();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLException.class)
|
||||||
|
public void setFetchDirection() throws SQLException {
|
||||||
|
rs.setFetchDirection(ResultSet.FETCH_FORWARD);
|
||||||
|
rs.setFetchDirection(ResultSet.FETCH_UNKNOWN);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getFetchDirection() throws SQLException {
|
||||||
|
Assert.assertEquals(ResultSet.FETCH_FORWARD, rs.getFetchDirection());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLException.class)
|
||||||
|
public void setFetchSize() throws SQLException {
|
||||||
|
rs.setFetchSize(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getFetchSize() throws SQLException {
|
||||||
|
Assert.assertEquals(1, rs.getFetchSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getType() throws SQLException {
|
||||||
|
Assert.assertEquals(ResultSet.TYPE_FORWARD_ONLY, rs.getType());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getConcurrency() throws SQLException {
|
||||||
|
Assert.assertEquals(ResultSet.CONCUR_READ_ONLY, rs.getConcurrency());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void rowUpdated() throws SQLException {
|
||||||
|
rs.rowUpdated();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void rowInserted() throws SQLException {
|
||||||
|
rs.rowInserted();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void rowDeleted() throws SQLException {
|
||||||
|
rs.rowDeleted();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void updateNull() throws SQLException {
|
||||||
|
rs.updateNull("f1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void updateBoolean() throws SQLException {
|
||||||
|
rs.updateBoolean(1, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void updateByte() throws SQLException {
|
||||||
|
rs.updateByte(1, new Byte("0"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void updateShort() throws SQLException {
|
||||||
|
rs.updateShort(1, new Short("0"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void updateInt() throws SQLException {
|
||||||
|
rs.updateInt(1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void updateLong() throws SQLException {
|
||||||
|
rs.updateLong(1, 1l);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void updateFloat() throws SQLException {
|
||||||
|
rs.updateFloat(1, 1f);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void updateDouble() throws SQLException {
|
||||||
|
rs.updateDouble(1, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void updateBigDecimal() throws SQLException {
|
||||||
|
rs.updateBigDecimal(1, new BigDecimal(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void updateString() throws SQLException {
|
||||||
|
rs.updateString(1, "abc");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void updateBytes() throws SQLException {
|
||||||
|
rs.updateBytes(1, new byte[]{});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void updateDate() throws SQLException {
|
||||||
|
rs.updateDate(1, new Date(System.currentTimeMillis()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void updateTime() throws SQLException {
|
||||||
|
rs.updateTime(1, new Time(System.currentTimeMillis()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void updateTimestamp() throws SQLException {
|
||||||
|
rs.updateTimestamp(1, new Timestamp(System.currentTimeMillis()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void updateAsciiStream() throws SQLException {
|
||||||
|
rs.updateAsciiStream(1, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void updateBinaryStream() throws SQLException {
|
||||||
|
rs.updateBinaryStream(1, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void updateCharacterStream() throws SQLException {
|
||||||
|
rs.updateCharacterStream(1, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void updateObject() throws SQLException {
|
||||||
|
rs.updateObject(1, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void insertRow() throws SQLException {
|
||||||
|
rs.insertRow();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void updateRow() throws SQLException {
|
||||||
|
rs.updateRow();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void deleteRow() throws SQLException {
|
||||||
|
rs.deleteRow();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void refreshRow() throws SQLException {
|
||||||
|
rs.refreshRow();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void cancelRowUpdates() throws SQLException {
|
||||||
|
rs.cancelRowUpdates();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void moveToInsertRow() throws SQLException {
|
||||||
|
rs.moveToInsertRow();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getStatement() throws SQLException {
|
||||||
|
Statement stmt = rs.getStatement();
|
||||||
|
Assert.assertNotNull(stmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void moveToCurrentRow() throws SQLException {
|
||||||
|
rs.moveToCurrentRow();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void getRef() throws SQLException {
|
||||||
|
rs.getRef(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void getBlob() throws SQLException {
|
||||||
|
rs.getBlob("f1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void getClob() throws SQLException {
|
||||||
|
rs.getClob("f1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void getArray() throws SQLException {
|
||||||
|
rs.getArray("f1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void getURL() throws SQLException {
|
||||||
|
rs.getURL("f1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void updateRef() throws SQLException {
|
||||||
|
rs.updateRef("f1", null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void updateBlob() throws SQLException {
|
||||||
|
rs.updateBlob(1, (InputStream) null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void updateClob() throws SQLException {
|
||||||
|
rs.updateClob(1, (Reader) null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void updateArray() throws SQLException {
|
||||||
|
rs.updateArray(1, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void getRowId() throws SQLException {
|
||||||
|
rs.getRowId("f1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void updateRowId() throws SQLException {
|
||||||
|
rs.updateRowId(1, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getHoldability() throws SQLException {
|
||||||
|
Assert.assertEquals(ResultSet.HOLD_CURSORS_OVER_COMMIT, rs.getHoldability());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void isClosed() throws SQLException {
|
||||||
|
Assert.assertFalse(rs.isClosed());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void updateNString() throws SQLException {
|
||||||
|
rs.updateNString(1, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void updateNClob() throws SQLException {
|
||||||
|
rs.updateNClob(1, (Reader) null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void getNClob() throws SQLException {
|
||||||
|
rs.getNClob("f1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void getSQLXML() throws SQLException {
|
||||||
|
rs.getSQLXML("f1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void updateSQLXML() throws SQLException {
|
||||||
|
rs.updateSQLXML(1, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void getNString() throws SQLException {
|
||||||
|
rs.getNString("f1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void getNCharacterStream() throws SQLException {
|
||||||
|
rs.getNCharacterStream("f1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||||
|
public void updateNCharacterStream() throws SQLException {
|
||||||
|
rs.updateNCharacterStream(1, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void unwrap() throws SQLException {
|
||||||
|
RestfulResultSet unwrap = rs.unwrap(RestfulResultSet.class);
|
||||||
|
Assert.assertNotNull(unwrap);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void isWrapperFor() throws SQLException {
|
||||||
|
Assert.assertTrue(rs.isWrapperFor(RestfulResultSet.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void beforeClass() {
|
||||||
|
try {
|
||||||
|
Class.forName("com.taosdata.jdbc.rs.RestfulDriver");
|
||||||
|
conn = DriverManager.getConnection("jdbc:TAOS-RS://" + host + ":6041/restful_test?user=root&password=taosdata");
|
||||||
|
stmt = conn.createStatement();
|
||||||
|
stmt.execute("create database if not exists restful_test");
|
||||||
|
stmt.execute("use restful_test");
|
||||||
|
stmt.execute("drop table if exists weather");
|
||||||
|
stmt.execute("create table if not exists weather(f1 timestamp, f2 int, f3 bigint, f4 float, f5 double, f6 binary(64), f7 smallint, f8 tinyint, f9 bool, f10 nchar(64))");
|
||||||
|
stmt.execute("insert into restful_test.weather values('2021-01-01 00:00:00.000', 1, 100, 3.1415, 3.1415926, 'abc', 10, 10, true, '涛思数据')");
|
||||||
|
rs = stmt.executeQuery("select * from restful_test.weather");
|
||||||
|
rs.next();
|
||||||
|
} catch (ClassNotFoundException | SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void afterClass() {
|
||||||
|
try {
|
||||||
|
if (rs != null)
|
||||||
|
rs.close();
|
||||||
|
if (stmt != null)
|
||||||
|
stmt.close();
|
||||||
|
if (conn != null)
|
||||||
|
conn.close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
package com.taosdata.jdbc.rs;
|
package com.taosdata.jdbc.rs;
|
||||||
|
|
||||||
|
import com.taosdata.jdbc.utils.SQLExecutor;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.FixMethodOrder;
|
import org.junit.FixMethodOrder;
|
||||||
|
@ -11,378 +12,315 @@ import java.sql.*;
|
||||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||||
public class SQLTest {
|
public class SQLTest {
|
||||||
private static final String host = "127.0.0.1";
|
private static final String host = "127.0.0.1";
|
||||||
|
// private static final String host = "master";
|
||||||
private static Connection connection;
|
private static Connection connection;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase001() {
|
public void testCase001() {
|
||||||
String sql = "create database if not exists restful_test";
|
String sql = "create database if not exists restful_test";
|
||||||
execute(sql);
|
SQLExecutor.execute(connection, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase002() {
|
public void testCase002() {
|
||||||
String sql = "use restful_test";
|
String sql = "use restful_test";
|
||||||
execute(sql);
|
SQLExecutor.execute(connection, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase003() {
|
public void testCase003() {
|
||||||
String sql = "show databases";
|
String sql = "show databases";
|
||||||
executeWithResult(sql);
|
SQLExecutor.executeWithResult(connection, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase004() {
|
public void testCase004() {
|
||||||
String sql = "show tables";
|
String sql = "show tables";
|
||||||
executeWithResult(sql);
|
SQLExecutor.executeWithResult(connection, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase005() {
|
public void testCase005() {
|
||||||
String sql = "show stables";
|
String sql = "show stables";
|
||||||
executeWithResult(sql);
|
SQLExecutor.executeWithResult(connection, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase006() {
|
public void testCase006() {
|
||||||
String sql = "show dnodes";
|
String sql = "show dnodes";
|
||||||
executeWithResult(sql);
|
SQLExecutor.executeWithResult(connection, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase007() {
|
public void testCase007() {
|
||||||
String sql = "show vgroups";
|
String sql = "show vgroups";
|
||||||
executeWithResult(sql);
|
SQLExecutor.executeWithResult(connection, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase008() {
|
public void testCase008() {
|
||||||
String sql = "drop table if exists restful_test.weather";
|
String sql = "drop table if exists restful_test.weather";
|
||||||
execute(sql);
|
SQLExecutor.execute(connection, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase009() {
|
public void testCase009() {
|
||||||
String sql = "create table if not exists restful_test.weather(ts timestamp, temperature float) tags(location nchar(64))";
|
String sql = "create table if not exists restful_test.weather(ts timestamp, temperature float) tags(location nchar(64))";
|
||||||
execute(sql);
|
SQLExecutor.execute(connection, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase010() {
|
public void testCase010() {
|
||||||
String sql = "create table t1 using restful_test.weather tags('北京')";
|
String sql = "create table t1 using restful_test.weather tags('北京')";
|
||||||
execute(sql);
|
SQLExecutor.execute(connection, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase011() {
|
public void testCase011() {
|
||||||
String sql = "insert into restful_test.t1 values(now, 22.22)";
|
String sql = "insert into restful_test.t1 values(now, 22.22)";
|
||||||
executeUpdate(sql);
|
SQLExecutor.executeUpdate(connection, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase012() {
|
public void testCase012() {
|
||||||
String sql = "insert into restful_test.t1 values('2020-01-01 00:00:00.000', 22.22)";
|
String sql = "insert into restful_test.t1 values('2020-01-01 00:00:00.000', 22.22)";
|
||||||
executeUpdate(sql);
|
SQLExecutor.executeUpdate(connection, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase013() {
|
public void testCase013() {
|
||||||
String sql = "insert into restful_test.t1 values('2020-01-01 00:01:00.000', 22.22),('2020-01-01 00:02:00.000', 22.22)";
|
String sql = "insert into restful_test.t1 values('2020-01-01 00:01:00.000', 22.22),('2020-01-01 00:02:00.000', 22.22)";
|
||||||
executeUpdate(sql);
|
SQLExecutor.executeUpdate(connection, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase014() {
|
public void testCase014() {
|
||||||
String sql = "insert into restful_test.t2 using weather tags('上海') values('2020-01-01 00:03:00.000', 22.22)";
|
String sql = "insert into restful_test.t2 using weather tags('上海') values('2020-01-01 00:03:00.000', 22.22)";
|
||||||
executeUpdate(sql);
|
SQLExecutor.executeUpdate(connection, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase015() {
|
public void testCase015() {
|
||||||
String sql = "insert into restful_test.t2 using weather tags('上海') values('2020-01-01 00:01:00.000', 22.22),('2020-01-01 00:02:00.000', 22.22)";
|
String sql = "insert into restful_test.t2 using weather tags('上海') values('2020-01-01 00:01:00.000', 22.22),('2020-01-01 00:02:00.000', 22.22)";
|
||||||
executeUpdate(sql);
|
SQLExecutor.executeUpdate(connection, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase016() {
|
public void testCase016() {
|
||||||
String sql = "insert into t1 values('2020-01-01 01:0:00.000', 22.22),('2020-01-01 02:00:00.000', 22.22) t2 values('2020-01-01 01:0:00.000', 33.33),('2020-01-01 02:00:00.000', 33.33)";
|
String sql = "insert into t1 values('2020-01-01 01:0:00.000', 22.22),('2020-01-01 02:00:00.000', 22.22) t2 values('2020-01-01 01:0:00.000', 33.33),('2020-01-01 02:00:00.000', 33.33)";
|
||||||
executeUpdate(sql);
|
SQLExecutor.executeUpdate(connection, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase017() {
|
public void testCase017() {
|
||||||
String sql = "Insert into t3 using weather tags('广东') values('2020-01-01 01:0:00.000', 22.22),('2020-01-01 02:00:00.000', 22.22) t4 using weather tags('天津') values('2020-01-01 01:0:00.000', 33.33),('2020-01-01 02:00:00.000', 33.33)";
|
String sql = "Insert into t3 using weather tags('广东') values('2020-01-01 01:0:00.000', 22.22),('2020-01-01 02:00:00.000', 22.22) t4 using weather tags('天津') values('2020-01-01 01:0:00.000', 33.33),('2020-01-01 02:00:00.000', 33.33)";
|
||||||
executeUpdate(sql);
|
SQLExecutor.executeUpdate(connection, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase018() {
|
public void testCase018() {
|
||||||
String sql = "select * from restful_test.t1";
|
String sql = "select * from restful_test.t1";
|
||||||
executeQuery(sql);
|
SQLExecutor.executeQuery(connection, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase019() {
|
public void testCase019() {
|
||||||
String sql = "select * from restful_test.weather";
|
String sql = "select * from restful_test.weather";
|
||||||
executeQuery(sql);
|
SQLExecutor.executeQuery(connection, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase020() {
|
public void testCase020() {
|
||||||
String sql = "select ts, temperature from restful_test.t1";
|
String sql = "select ts, temperature from restful_test.t1";
|
||||||
executeQuery(sql);
|
SQLExecutor.executeQuery(connection, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase021() {
|
public void testCase021() {
|
||||||
String sql = "select ts, temperature from restful_test.weather";
|
String sql = "select ts, temperature from restful_test.weather";
|
||||||
executeQuery(sql);
|
SQLExecutor.executeQuery(connection, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase022() {
|
public void testCase022() {
|
||||||
String sql = "select temperature, ts from restful_test.t1";
|
String sql = "select temperature, ts from restful_test.t1";
|
||||||
executeQuery(sql);
|
SQLExecutor.executeQuery(connection, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase023() {
|
public void testCase023() {
|
||||||
String sql = "select temperature, ts from restful_test.weather";
|
String sql = "select temperature, ts from restful_test.weather";
|
||||||
executeQuery(sql);
|
SQLExecutor.executeQuery(connection, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase024() {
|
public void testCase024() {
|
||||||
String sql = "import into restful_test.t5 using weather tags('石家庄') values('2020-01-01 00:01:00.000', 22.22)";
|
String sql = "import into restful_test.t5 using weather tags('石家庄') values('2020-01-01 00:01:00.000', 22.22)";
|
||||||
executeUpdate(sql);
|
SQLExecutor.executeUpdate(connection, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase025() {
|
public void testCase025() {
|
||||||
String sql = "import into restful_test.t6 using weather tags('沈阳') values('2020-01-01 00:01:00.000', 22.22),('2020-01-01 00:02:00.000', 22.22)";
|
String sql = "import into restful_test.t6 using weather tags('沈阳') values('2020-01-01 00:01:00.000', 22.22),('2020-01-01 00:02:00.000', 22.22)";
|
||||||
executeUpdate(sql);
|
SQLExecutor.executeUpdate(connection, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase026() {
|
public void testCase026() {
|
||||||
String sql = "import into restful_test.t7 using weather tags('长沙') values('2020-01-01 00:01:00.000', 22.22) restful_test.t8 using weather tags('吉林') values('2020-01-01 00:01:00.000', 22.22)";
|
String sql = "import into restful_test.t7 using weather tags('长沙') values('2020-01-01 00:01:00.000', 22.22) restful_test.t8 using weather tags('吉林') values('2020-01-01 00:01:00.000', 22.22)";
|
||||||
executeUpdate(sql);
|
SQLExecutor.executeUpdate(connection, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase027() {
|
public void testCase027() {
|
||||||
String sql = "import into restful_test.t9 using weather tags('武汉') values('2020-01-01 00:01:00.000', 22.22) ,('2020-01-02 00:01:00.000', 22.22) restful_test.t10 using weather tags('哈尔滨') values('2020-01-01 00:01:00.000', 22.22),('2020-01-02 00:01:00.000', 22.22)";
|
String sql = "import into restful_test.t9 using weather tags('武汉') values('2020-01-01 00:01:00.000', 22.22) ,('2020-01-02 00:01:00.000', 22.22) restful_test.t10 using weather tags('哈尔滨') values('2020-01-01 00:01:00.000', 22.22),('2020-01-02 00:01:00.000', 22.22)";
|
||||||
executeUpdate(sql);
|
SQLExecutor.executeUpdate(connection, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase028() {
|
public void testCase028() {
|
||||||
String sql = "select location, temperature, ts from restful_test.weather where temperature > 1";
|
String sql = "select location, temperature, ts from restful_test.weather where temperature > 1";
|
||||||
executeQuery(sql);
|
SQLExecutor.executeQuery(connection, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase029() {
|
public void testCase029() {
|
||||||
String sql = "select location, temperature, ts from restful_test.weather where temperature < 1";
|
String sql = "select location, temperature, ts from restful_test.weather where temperature < 1";
|
||||||
executeQuery(sql);
|
SQLExecutor.executeQuery(connection, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase030() {
|
public void testCase030() {
|
||||||
String sql = "select location, temperature, ts from restful_test.weather where ts > now";
|
String sql = "select location, temperature, ts from restful_test.weather where ts > now";
|
||||||
executeQuery(sql);
|
SQLExecutor.executeQuery(connection, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase031() {
|
public void testCase031() {
|
||||||
String sql = "select location, temperature, ts from restful_test.weather where ts < now";
|
String sql = "select location, temperature, ts from restful_test.weather where ts < now";
|
||||||
executeQuery(sql);
|
SQLExecutor.executeQuery(connection, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase032() {
|
public void testCase032() {
|
||||||
String sql = "select count(*) from restful_test.weather";
|
String sql = "select count(*) from restful_test.weather";
|
||||||
executeQuery(sql);
|
SQLExecutor.executeQuery(connection, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase033() {
|
public void testCase033() {
|
||||||
String sql = "select first(*) from restful_test.weather";
|
String sql = "select first(*) from restful_test.weather";
|
||||||
executeQuery(sql);
|
SQLExecutor.executeQuery(connection, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase034() {
|
public void testCase034() {
|
||||||
String sql = "select last(*) from restful_test.weather";
|
String sql = "select last(*) from restful_test.weather";
|
||||||
executeQuery(sql);
|
SQLExecutor.executeQuery(connection, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase035() {
|
public void testCase035() {
|
||||||
String sql = "select last_row(*) from restful_test.weather";
|
String sql = "select last_row(*) from restful_test.weather";
|
||||||
executeQuery(sql);
|
SQLExecutor.executeQuery(connection, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase036() {
|
public void testCase036() {
|
||||||
String sql = "select ts, ts as primary_key from restful_test.weather";
|
String sql = "select ts, ts as primary_key from restful_test.weather";
|
||||||
executeQuery(sql);
|
SQLExecutor.executeQuery(connection, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase037() {
|
public void testCase037() {
|
||||||
String sql = "select database()";
|
String sql = "select database()";
|
||||||
execute("use restful_test");
|
SQLExecutor.execute(connection, "use restful_test");
|
||||||
executeQuery(sql);
|
SQLExecutor.executeQuery(connection, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase038() {
|
public void testCase038() {
|
||||||
String sql = "select client_version()";
|
String sql = "select client_version()";
|
||||||
executeQuery(sql);
|
SQLExecutor.executeQuery(connection, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase039() {
|
public void testCase039() {
|
||||||
String sql = "select server_status()";
|
String sql = "select server_status()";
|
||||||
executeQuery(sql);
|
SQLExecutor.executeQuery(connection, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase040() {
|
public void testCase040() {
|
||||||
String sql = "select server_status() as status";
|
String sql = "select server_status() as status";
|
||||||
executeQuery(sql);
|
SQLExecutor.executeQuery(connection, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase041() {
|
public void testCase041() {
|
||||||
String sql = "select tbname, location from restful_test.weather";
|
String sql = "select tbname, location from restful_test.weather";
|
||||||
executeQuery(sql);
|
SQLExecutor.executeQuery(connection, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase042() {
|
public void testCase042() {
|
||||||
String sql = "select count(tbname) from restful_test.weather";
|
String sql = "select count(tbname) from restful_test.weather";
|
||||||
executeQuery(sql);
|
SQLExecutor.executeQuery(connection, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase043() {
|
public void testCase043() {
|
||||||
String sql = "select * from restful_test.weather where ts < now - 1h";
|
String sql = "select * from restful_test.weather where ts < now - 1h";
|
||||||
executeQuery(sql);
|
SQLExecutor.executeQuery(connection, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase044() {
|
public void testCase044() {
|
||||||
String sql = "select * from restful_test.weather where ts < now - 1h and location like '%'";
|
String sql = "select * from restful_test.weather where ts < now - 1h and location like '%'";
|
||||||
executeQuery(sql);
|
SQLExecutor.executeQuery(connection, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase045() {
|
public void testCase045() {
|
||||||
String sql = "select * from restful_test.weather where ts < now - 1h order by ts";
|
String sql = "select * from restful_test.weather where ts < now - 1h order by ts";
|
||||||
executeQuery(sql);
|
SQLExecutor.executeQuery(connection, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase046() {
|
public void testCase046() {
|
||||||
String sql = "select last(*) from restful_test.weather where ts < now - 1h group by tbname order by tbname";
|
String sql = "select last(*) from restful_test.weather where ts < now - 1h group by tbname order by tbname";
|
||||||
executeQuery(sql);
|
SQLExecutor.executeQuery(connection, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase047() {
|
public void testCase047() {
|
||||||
String sql = "select * from restful_test.weather limit 2";
|
String sql = "select * from restful_test.weather limit 2";
|
||||||
executeQuery(sql);
|
SQLExecutor.executeQuery(connection, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase048() {
|
public void testCase048() {
|
||||||
String sql = "select * from restful_test.weather limit 2 offset 5";
|
String sql = "select * from restful_test.weather limit 2 offset 5";
|
||||||
executeQuery(sql);
|
SQLExecutor.executeQuery(connection, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase049() {
|
public void testCase049() {
|
||||||
String sql = "select * from restful_test.t1, restful_test.t3 where t1.ts = t3.ts ";
|
String sql = "select * from restful_test.t1, restful_test.t3 where t1.ts = t3.ts ";
|
||||||
executeQuery(sql);
|
SQLExecutor.executeQuery(connection, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase050() {
|
public void testCase050() {
|
||||||
String sql = "select * from restful_test.t1, restful_test.t3 where t1.ts = t3.ts and t1.location = t3.location";
|
String sql = "select * from restful_test.t1, restful_test.t3 where t1.ts = t3.ts and t1.location = t3.location";
|
||||||
executeQuery(sql);
|
SQLExecutor.executeQuery(connection, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase051() {
|
public void testCase051() {
|
||||||
String sql = "select * from restful_test.t1 tt, restful_test.t3 yy where tt.ts = yy.ts";
|
String sql = "select * from restful_test.t1 tt, restful_test.t3 yy where tt.ts = yy.ts";
|
||||||
executeQuery(sql);
|
SQLExecutor.executeQuery(connection, sql);
|
||||||
}
|
|
||||||
|
|
||||||
private void executeUpdate(String sql) {
|
|
||||||
try (Statement statement = connection.createStatement()) {
|
|
||||||
long start = System.currentTimeMillis();
|
|
||||||
int affectedRows = statement.executeUpdate(sql);
|
|
||||||
long end = System.currentTimeMillis();
|
|
||||||
System.out.println("[ affected rows : " + affectedRows + " ] time cost: " + (end - start) + " ms, execute statement ====> " + sql);
|
|
||||||
} catch (SQLException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void executeWithResult(String sql) {
|
|
||||||
try (Statement statement = connection.createStatement()) {
|
|
||||||
statement.execute(sql);
|
|
||||||
ResultSet resultSet = statement.getResultSet();
|
|
||||||
printResult(resultSet);
|
|
||||||
} catch (SQLException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void execute(String sql) {
|
|
||||||
try (Statement statement = connection.createStatement()) {
|
|
||||||
long start = System.currentTimeMillis();
|
|
||||||
boolean execute = statement.execute(sql);
|
|
||||||
long end = System.currentTimeMillis();
|
|
||||||
printSql(sql, execute, (end - start));
|
|
||||||
} catch (SQLException e) {
|
|
||||||
System.out.println("ERROR execute SQL ===> " + sql);
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void printSql(String sql, boolean succeed, long cost) {
|
|
||||||
System.out.println("[ " + (succeed ? "OK" : "ERROR!") + " ] time cost: " + cost + " ms, execute statement ====> " + sql);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void executeQuery(String sql) {
|
|
||||||
try (Statement statement = connection.createStatement()) {
|
|
||||||
long start = System.currentTimeMillis();
|
|
||||||
ResultSet resultSet = statement.executeQuery(sql);
|
|
||||||
long end = System.currentTimeMillis();
|
|
||||||
printSql(sql, true, (end - start));
|
|
||||||
printResult(resultSet);
|
|
||||||
} catch (SQLException e) {
|
|
||||||
System.out.println("ERROR execute SQL ===> " + sql);
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void printResult(ResultSet resultSet) throws SQLException {
|
|
||||||
ResultSetMetaData metaData = resultSet.getMetaData();
|
|
||||||
while (resultSet.next()) {
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
for (int i = 1; i <= metaData.getColumnCount(); i++) {
|
|
||||||
String columnLabel = metaData.getColumnLabel(i);
|
|
||||||
String value = resultSet.getString(i);
|
|
||||||
sb.append(columnLabel + ": " + value + "\t");
|
|
||||||
}
|
|
||||||
System.out.println(sb.toString());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
package com.taosdata.jdbc.utils;
|
||||||
|
|
||||||
|
import java.sql.*;
|
||||||
|
|
||||||
|
public class SQLExecutor {
|
||||||
|
|
||||||
|
// insert, import
|
||||||
|
public static void executeUpdate(Connection connection, String sql) {
|
||||||
|
try (Statement statement = connection.createStatement()) {
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
int affectedRows = statement.executeUpdate(sql);
|
||||||
|
long end = System.currentTimeMillis();
|
||||||
|
System.out.println("[ affected rows : " + affectedRows + " ] time cost: " + (end - start) + " ms, execute statement ====> " + sql);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// show databases, show tables, show stables
|
||||||
|
public static void executeWithResult(Connection connection, String sql) {
|
||||||
|
try (Statement statement = connection.createStatement()) {
|
||||||
|
statement.execute(sql);
|
||||||
|
ResultSet resultSet = statement.getResultSet();
|
||||||
|
printResult(resultSet);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// use database, create database, create table, drop table...
|
||||||
|
public static void execute(Connection connection, String sql) {
|
||||||
|
try (Statement statement = connection.createStatement()) {
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
boolean execute = statement.execute(sql);
|
||||||
|
long end = System.currentTimeMillis();
|
||||||
|
printSql(sql, execute, (end - start));
|
||||||
|
} catch (SQLException e) {
|
||||||
|
System.out.println("ERROR execute SQL ===> " + sql);
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// select
|
||||||
|
public static void executeQuery(Connection connection, String sql) {
|
||||||
|
try (Statement statement = connection.createStatement()) {
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
ResultSet resultSet = statement.executeQuery(sql);
|
||||||
|
long end = System.currentTimeMillis();
|
||||||
|
printSql(sql, true, (end - start));
|
||||||
|
printResult(resultSet);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
System.out.println("ERROR execute SQL ===> " + sql);
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void printSql(String sql, boolean succeed, long cost) {
|
||||||
|
System.out.println("[ " + (succeed ? "OK" : "ERROR!") + " ] time cost: " + cost + " ms, execute statement ====> " + sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void printResult(ResultSet resultSet) throws SQLException {
|
||||||
|
ResultSetMetaData metaData = resultSet.getMetaData();
|
||||||
|
while (resultSet.next()) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (int i = 1; i <= metaData.getColumnCount(); i++) {
|
||||||
|
String columnLabel = metaData.getColumnLabel(i);
|
||||||
|
String value = resultSet.getString(i);
|
||||||
|
sb.append(columnLabel + ": " + value + "\t");
|
||||||
|
}
|
||||||
|
System.out.println(sb.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -16,10 +16,6 @@ public class SqlSyntaxValidatorTest {
|
||||||
@Test
|
@Test
|
||||||
public void isUseSQL() {
|
public void isUseSQL() {
|
||||||
Assert.assertTrue(SqlSyntaxValidator.isUseSql("use database test"));
|
Assert.assertTrue(SqlSyntaxValidator.isUseSql("use database test"));
|
||||||
Assert.assertTrue(SqlSyntaxValidator.isUseSql("create database test"));
|
|
||||||
Assert.assertTrue(SqlSyntaxValidator.isUseSql("create database if not exist test"));
|
|
||||||
Assert.assertTrue(SqlSyntaxValidator.isUseSql("drop database test"));
|
|
||||||
Assert.assertTrue(SqlSyntaxValidator.isUseSql("drop database if exist test"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -6,7 +6,6 @@ INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/client/inc)
|
||||||
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/query/inc)
|
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/query/inc)
|
||||||
AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/src SRC)
|
AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/src SRC)
|
||||||
|
|
||||||
IF (TD_LINUX OR TD_WINDOWS)
|
|
||||||
ADD_LIBRARY(tcq ${SRC})
|
ADD_LIBRARY(tcq ${SRC})
|
||||||
IF (TD_SOMODE_STATIC)
|
IF (TD_SOMODE_STATIC)
|
||||||
TARGET_LINK_LIBRARIES(tcq tutil common taos_static)
|
TARGET_LINK_LIBRARIES(tcq tutil common taos_static)
|
||||||
|
@ -14,4 +13,3 @@ IF (TD_LINUX OR TD_WINDOWS)
|
||||||
TARGET_LINK_LIBRARIES(tcq tutil common taos)
|
TARGET_LINK_LIBRARIES(tcq tutil common taos)
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
ADD_SUBDIRECTORY(test)
|
ADD_SUBDIRECTORY(test)
|
||||||
ENDIF ()
|
|
||||||
|
|
|
@ -10,7 +10,6 @@ INCLUDE_DIRECTORIES(${TD_ENTERPRISE_DIR}/src/inc)
|
||||||
INCLUDE_DIRECTORIES(inc)
|
INCLUDE_DIRECTORIES(inc)
|
||||||
AUX_SOURCE_DIRECTORY(src SRC)
|
AUX_SOURCE_DIRECTORY(src SRC)
|
||||||
|
|
||||||
IF (TD_LINUX OR TD_WINDOWS)
|
|
||||||
ADD_EXECUTABLE(taosd ${SRC})
|
ADD_EXECUTABLE(taosd ${SRC})
|
||||||
TARGET_LINK_LIBRARIES(taosd mnode monitor http tsdb twal vnode cJson lz4 balance sync)
|
TARGET_LINK_LIBRARIES(taosd mnode monitor http tsdb twal vnode cJson lz4 balance sync)
|
||||||
|
|
||||||
|
@ -28,7 +27,7 @@ IF (TD_LINUX OR TD_WINDOWS)
|
||||||
TARGET_LINK_LIBRARIES(taosd grant)
|
TARGET_LINK_LIBRARIES(taosd grant)
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
IF (TD_LINUX AND TD_MQTT)
|
IF ((TD_LINUX OR TD_WINDOWS) AND TD_MQTT)
|
||||||
TARGET_LINK_LIBRARIES(taosd mqtt)
|
TARGET_LINK_LIBRARIES(taosd mqtt)
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
|
@ -46,4 +45,3 @@ IF (TD_LINUX OR TD_WINDOWS)
|
||||||
COMMAND ${CMAKE_COMMAND} -E echo charset UTF-8 >> ${TD_TESTS_OUTPUT_DIR}/cfg/taos.cfg
|
COMMAND ${CMAKE_COMMAND} -E echo charset UTF-8 >> ${TD_TESTS_OUTPUT_DIR}/cfg/taos.cfg
|
||||||
COMMENT "prepare taosd environment")
|
COMMENT "prepare taosd environment")
|
||||||
ADD_CUSTOM_TARGET(${PREPARE_ENV_TARGET} ALL WORKING_DIRECTORY ${TD_EXECUTABLE_OUTPUT_PATH} DEPENDS ${PREPARE_ENV_CMD})
|
ADD_CUSTOM_TARGET(${PREPARE_ENV_TARGET} ALL WORKING_DIRECTORY ${TD_EXECUTABLE_OUTPUT_PATH} DEPENDS ${PREPARE_ENV_CMD})
|
||||||
ENDIF ()
|
|
||||||
|
|
|
@ -236,6 +236,13 @@ static void sendTelemetryReport() {
|
||||||
taosCloseSocket(fd);
|
taosCloseSocket(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
static int sem_timedwait(tsem_t *sem, struct timespec *to) {
|
||||||
|
fprintf(stderr, "%s[%d]%s(): not implemented yet!\n", basename(__FILE__), __LINE__, __func__);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
#endif // __APPLE__
|
||||||
|
|
||||||
static void* telemetryThread(void* param) {
|
static void* telemetryThread(void* param) {
|
||||||
struct timespec end = {0};
|
struct timespec end = {0};
|
||||||
clock_gettime(CLOCK_REALTIME, &end);
|
clock_gettime(CLOCK_REALTIME, &end);
|
||||||
|
|
|
@ -163,6 +163,11 @@ do { \
|
||||||
#define TSDB_BINARY_OP_MULTIPLY 32
|
#define TSDB_BINARY_OP_MULTIPLY 32
|
||||||
#define TSDB_BINARY_OP_DIVIDE 33
|
#define TSDB_BINARY_OP_DIVIDE 33
|
||||||
#define TSDB_BINARY_OP_REMAINDER 34
|
#define TSDB_BINARY_OP_REMAINDER 34
|
||||||
|
|
||||||
|
|
||||||
|
#define IS_RELATION_OPTR(op) (((op) >= TSDB_RELATION_LESS) && ((op) <= TSDB_RELATION_IN))
|
||||||
|
#define IS_ARITHMETIC_OPTR(op) (((op) >= TSDB_BINARY_OP_ADD) && ((op) <= TSDB_BINARY_OP_REMAINDER))
|
||||||
|
|
||||||
#define TS_PATH_DELIMITER_LEN 1
|
#define TS_PATH_DELIMITER_LEN 1
|
||||||
|
|
||||||
#define TSDB_UNI_LEN 24
|
#define TSDB_UNI_LEN 24
|
||||||
|
|
|
@ -256,6 +256,8 @@ TAOS_DEFINE_ERROR(TSDB_CODE_QRY_HAS_RSP, 0, 0x0708, "Query shou
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_IN_EXEC, 0, 0x0709, "Multiple retrieval of this query")
|
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_IN_EXEC, 0, 0x0709, "Multiple retrieval of this query")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_TOO_MANY_TIMEWINDOW, 0, 0x070A, "Too many time window in query")
|
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_TOO_MANY_TIMEWINDOW, 0, 0x070A, "Too many time window in query")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_NOT_ENOUGH_BUFFER, 0, 0x070B, "Query buffer limit has reached")
|
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_NOT_ENOUGH_BUFFER, 0, 0x070B, "Query buffer limit has reached")
|
||||||
|
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_INCONSISTAN, 0, 0x070C, "File inconsistance in replica")
|
||||||
|
|
||||||
|
|
||||||
// grant
|
// grant
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_EXPIRED, 0, 0x0800, "License expired")
|
TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_EXPIRED, 0, 0x0800, "License expired")
|
||||||
|
|
|
@ -37,7 +37,10 @@ ELSEIF (TD_DARWIN)
|
||||||
LIST(APPEND SRC ./src/shellCommand.c)
|
LIST(APPEND SRC ./src/shellCommand.c)
|
||||||
LIST(APPEND SRC ./src/shellImport.c)
|
LIST(APPEND SRC ./src/shellImport.c)
|
||||||
ADD_EXECUTABLE(shell ${SRC})
|
ADD_EXECUTABLE(shell ${SRC})
|
||||||
TARGET_LINK_LIBRARIES(shell taos_static)
|
# linking with dylib
|
||||||
|
TARGET_LINK_LIBRARIES(shell taos)
|
||||||
|
# linking taos statically
|
||||||
|
# TARGET_LINK_LIBRARIES(shell taos_static)
|
||||||
SET_TARGET_PROPERTIES(shell PROPERTIES OUTPUT_NAME taos)
|
SET_TARGET_PROPERTIES(shell PROPERTIES OUTPUT_NAME taos)
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
#include "shellCommand.h"
|
#include "shellCommand.h"
|
||||||
#include "tkey.h"
|
#include "tkey.h"
|
||||||
|
|
||||||
|
#include "tscLog.h"
|
||||||
|
|
||||||
#define OPT_ABORT 1 /* <20>Cabort */
|
#define OPT_ABORT 1 /* <20>Cabort */
|
||||||
|
|
||||||
int indicator = 1;
|
int indicator = 1;
|
||||||
|
@ -348,6 +350,9 @@ void *shellLoopQuery(void *arg) {
|
||||||
reset_terminal_mode();
|
reset_terminal_mode();
|
||||||
} while (shellRunCommand(con, command) == 0);
|
} while (shellRunCommand(con, command) == 0);
|
||||||
|
|
||||||
|
tfree(command);
|
||||||
|
exitShell();
|
||||||
|
|
||||||
pthread_cleanup_pop(1);
|
pthread_cleanup_pop(1);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -19,6 +19,10 @@
|
||||||
|
|
||||||
extern char configDir[];
|
extern char configDir[];
|
||||||
|
|
||||||
|
void printVersion() {
|
||||||
|
printf("version: %s\n", version);
|
||||||
|
}
|
||||||
|
|
||||||
void printHelp() {
|
void printHelp() {
|
||||||
char indent[10] = " ";
|
char indent[10] = " ";
|
||||||
printf("taos shell is used to test the TDengine database\n");
|
printf("taos shell is used to test the TDengine database\n");
|
||||||
|
@ -51,6 +55,8 @@ void printHelp() {
|
||||||
printf("%s%s%s\n", indent, indent, "Net role when network connectivity test, default is startup, options: client|server|rpc|startup.");
|
printf("%s%s%s\n", indent, indent, "Net role when network connectivity test, default is startup, options: client|server|rpc|startup.");
|
||||||
printf("%s%s\n", indent, "-l");
|
printf("%s%s\n", indent, "-l");
|
||||||
printf("%s%s%s\n", indent, indent, "Packet length used for net test, default is 1000 bytes.");
|
printf("%s%s%s\n", indent, indent, "Packet length used for net test, default is 1000 bytes.");
|
||||||
|
printf("%s%s\n", indent, "-V");
|
||||||
|
printf("%s%s%s\n", indent, indent, "Print program version.");
|
||||||
|
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
@ -69,6 +75,9 @@ void shellParseArgument(int argc, char *argv[], SShellArguments *arguments) {
|
||||||
// for password
|
// for password
|
||||||
else if (strcmp(argv[i], "-p") == 0) {
|
else if (strcmp(argv[i], "-p") == 0) {
|
||||||
arguments->is_use_passwd = true;
|
arguments->is_use_passwd = true;
|
||||||
|
if (i < argc - 1 && argv[i + 1][0] != '-') {
|
||||||
|
arguments->password = argv[++i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// for management port
|
// for management port
|
||||||
else if (strcmp(argv[i], "-P") == 0) {
|
else if (strcmp(argv[i], "-P") == 0) {
|
||||||
|
@ -145,7 +154,6 @@ void shellParseArgument(int argc, char *argv[], SShellArguments *arguments) {
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// For time zone
|
|
||||||
else if (strcmp(argv[i], "-n") == 0) {
|
else if (strcmp(argv[i], "-n") == 0) {
|
||||||
if (i < argc - 1) {
|
if (i < argc - 1) {
|
||||||
arguments->netTestRole = argv[++i];
|
arguments->netTestRole = argv[++i];
|
||||||
|
@ -154,7 +162,6 @@ void shellParseArgument(int argc, char *argv[], SShellArguments *arguments) {
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// For time zone
|
|
||||||
else if (strcmp(argv[i], "-l") == 0) {
|
else if (strcmp(argv[i], "-l") == 0) {
|
||||||
if (i < argc - 1) {
|
if (i < argc - 1) {
|
||||||
arguments->pktLen = atoi(argv[++i]);
|
arguments->pktLen = atoi(argv[++i]);
|
||||||
|
@ -163,10 +170,14 @@ void shellParseArgument(int argc, char *argv[], SShellArguments *arguments) {
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (strcmp(argv[i], "-V") == 0) {
|
||||||
|
printVersion();
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
// For temperory command TODO
|
// For temperory command TODO
|
||||||
else if (strcmp(argv[i], "--help") == 0) {
|
else if (strcmp(argv[i], "--help") == 0) {
|
||||||
printHelp();
|
printHelp();
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_SUCCESS);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "wrong options\n");
|
fprintf(stderr, "wrong options\n");
|
||||||
printHelp();
|
printHelp();
|
||||||
|
|
|
@ -17,4 +17,13 @@ ELSEIF (TD_WINDOWS)
|
||||||
AUX_SOURCE_DIRECTORY(. SRC)
|
AUX_SOURCE_DIRECTORY(. SRC)
|
||||||
ADD_EXECUTABLE(taosdemo ${SRC})
|
ADD_EXECUTABLE(taosdemo ${SRC})
|
||||||
TARGET_LINK_LIBRARIES(taosdemo taos_static)
|
TARGET_LINK_LIBRARIES(taosdemo taos_static)
|
||||||
|
ELSEIF (TD_DARWIN)
|
||||||
|
AUX_SOURCE_DIRECTORY(. SRC)
|
||||||
|
ADD_EXECUTABLE(taosdemo ${SRC})
|
||||||
|
|
||||||
|
IF (TD_SOMODE_STATIC)
|
||||||
|
TARGET_LINK_LIBRARIES(taosdemo taos_static)
|
||||||
|
ELSE ()
|
||||||
|
TARGET_LINK_LIBRARIES(taosdemo taos)
|
||||||
|
ENDIF ()
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
|
@ -23,3 +23,25 @@ IF (TD_LINUX)
|
||||||
TARGET_LINK_LIBRARIES(taosdemox taos cJson)
|
TARGET_LINK_LIBRARIES(taosdemox taos cJson)
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
|
IF (TD_DARWIN)
|
||||||
|
# missing a few dependencies, such as <argp.h>
|
||||||
|
# AUX_SOURCE_DIRECTORY(. SRC)
|
||||||
|
# ADD_EXECUTABLE(taosdemox ${SRC})
|
||||||
|
#
|
||||||
|
# #find_program(HAVE_CURL NAMES curl)
|
||||||
|
# IF ((NOT TD_ARM_64) AND (NOT TD_ARM_32))
|
||||||
|
# ADD_DEFINITIONS(-DTD_LOWA_CURL)
|
||||||
|
# LINK_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/libcurl/lib)
|
||||||
|
# ADD_LIBRARY(curl STATIC IMPORTED)
|
||||||
|
# SET_PROPERTY(TARGET curl PROPERTY IMPORTED_LOCATION ${TD_COMMUNITY_DIR}/deps/libcurl/lib/libcurl.a)
|
||||||
|
# TARGET_LINK_LIBRARIES(taosdemox curl)
|
||||||
|
# ENDIF ()
|
||||||
|
#
|
||||||
|
# IF (TD_SOMODE_STATIC)
|
||||||
|
# TARGET_LINK_LIBRARIES(taosdemox taos_static cJson)
|
||||||
|
# ELSE ()
|
||||||
|
# TARGET_LINK_LIBRARIES(taosdemox taos cJson)
|
||||||
|
# ENDIF ()
|
||||||
|
ENDIF ()
|
||||||
|
|
||||||
|
|
|
@ -14,3 +14,13 @@ IF (TD_LINUX)
|
||||||
TARGET_LINK_LIBRARIES(taosdump taos)
|
TARGET_LINK_LIBRARIES(taosdump taos)
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
|
IF (TD_DARWIN)
|
||||||
|
# missing <argp.h> for macosx
|
||||||
|
# ADD_EXECUTABLE(taosdump ${SRC})
|
||||||
|
# IF (TD_SOMODE_STATIC)
|
||||||
|
# TARGET_LINK_LIBRARIES(taosdump taos_static)
|
||||||
|
# ELSE ()
|
||||||
|
# TARGET_LINK_LIBRARIES(taosdump taos)
|
||||||
|
# ENDIF ()
|
||||||
|
ENDIF ()
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
|
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
|
||||||
PROJECT(TDengine)
|
PROJECT(TDengine)
|
||||||
|
|
||||||
IF (TD_LINUX OR TD_WINDOWS)
|
|
||||||
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/query/inc)
|
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/query/inc)
|
||||||
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/dnode/inc)
|
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/dnode/inc)
|
||||||
|
|
||||||
|
@ -9,4 +8,3 @@ IF (TD_LINUX OR TD_WINDOWS)
|
||||||
AUX_SOURCE_DIRECTORY(src SRC)
|
AUX_SOURCE_DIRECTORY(src SRC)
|
||||||
|
|
||||||
ADD_LIBRARY(mnode ${SRC})
|
ADD_LIBRARY(mnode ${SRC})
|
||||||
ENDIF ()
|
|
|
@ -0,0 +1,93 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can use, redistribute, and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, version 3
|
||||||
|
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _eok_h_fd274616_996c_400e_9023_ae70be881fa3_
|
||||||
|
#define _eok_h_fd274616_996c_400e_9023_ae70be881fa3_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
|
||||||
|
enum EPOLL_EVENTS
|
||||||
|
{
|
||||||
|
EPOLLIN = 0x001,
|
||||||
|
#define EPOLLIN EPOLLIN
|
||||||
|
EPOLLPRI = 0x002,
|
||||||
|
#define EPOLLPRI EPOLLPRI
|
||||||
|
EPOLLOUT = 0x004,
|
||||||
|
#define EPOLLOUT EPOLLOUT
|
||||||
|
EPOLLRDNORM = 0x040,
|
||||||
|
#define EPOLLRDNORM EPOLLRDNORM
|
||||||
|
EPOLLRDBAND = 0x080,
|
||||||
|
#define EPOLLRDBAND EPOLLRDBAND
|
||||||
|
EPOLLWRNORM = 0x100,
|
||||||
|
#define EPOLLWRNORM EPOLLWRNORM
|
||||||
|
EPOLLWRBAND = 0x200,
|
||||||
|
#define EPOLLWRBAND EPOLLWRBAND
|
||||||
|
EPOLLMSG = 0x400,
|
||||||
|
#define EPOLLMSG EPOLLMSG
|
||||||
|
EPOLLERR = 0x008,
|
||||||
|
#define EPOLLERR EPOLLERR
|
||||||
|
EPOLLHUP = 0x010,
|
||||||
|
#define EPOLLHUP EPOLLHUP
|
||||||
|
EPOLLRDHUP = 0x2000,
|
||||||
|
#define EPOLLRDHUP EPOLLRDHUP
|
||||||
|
EPOLLEXCLUSIVE = 1u << 28,
|
||||||
|
#define EPOLLEXCLUSIVE EPOLLEXCLUSIVE
|
||||||
|
EPOLLWAKEUP = 1u << 29,
|
||||||
|
#define EPOLLWAKEUP EPOLLWAKEUP
|
||||||
|
EPOLLONESHOT = 1u << 30,
|
||||||
|
#define EPOLLONESHOT EPOLLONESHOT
|
||||||
|
EPOLLET = 1u << 31
|
||||||
|
#define EPOLLET EPOLLET
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Valid opcodes ( "op" parameter ) to issue to epoll_ctl(). */
|
||||||
|
#define EPOLL_CTL_ADD 1 /* Add a file descriptor to the interface. */
|
||||||
|
#define EPOLL_CTL_DEL 2 /* Remove a file descriptor from the interface. */
|
||||||
|
#define EPOLL_CTL_MOD 3 /* Change file descriptor epoll_event structure. */
|
||||||
|
|
||||||
|
|
||||||
|
typedef union epoll_data
|
||||||
|
{
|
||||||
|
void *ptr;
|
||||||
|
int fd;
|
||||||
|
uint32_t u32;
|
||||||
|
uint64_t u64;
|
||||||
|
} epoll_data_t;
|
||||||
|
|
||||||
|
struct epoll_event
|
||||||
|
{
|
||||||
|
uint32_t events; /* Epoll events */
|
||||||
|
epoll_data_t data; /* User data variable */
|
||||||
|
};
|
||||||
|
|
||||||
|
int epoll_create(int size);
|
||||||
|
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
|
||||||
|
int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);
|
||||||
|
int epoll_close(int epfd);
|
||||||
|
|
||||||
|
#endif // __APPLE__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // _eok_h_fd274616_996c_400e_9023_ae70be881fa3_
|
||||||
|
|
|
@ -75,11 +75,11 @@ extern "C" {
|
||||||
#define TAOS_OS_FUNC_FILE_SENDIFLE
|
#define TAOS_OS_FUNC_FILE_SENDIFLE
|
||||||
|
|
||||||
#define TAOS_OS_FUNC_SEMPHONE
|
#define TAOS_OS_FUNC_SEMPHONE
|
||||||
#define tsem_t dispatch_semaphore_t
|
typedef struct tsem_s *tsem_t;
|
||||||
int tsem_init(dispatch_semaphore_t *sem, int pshared, unsigned int value);
|
int tsem_init(tsem_t *sem, int pshared, unsigned int value);
|
||||||
int tsem_wait(dispatch_semaphore_t *sem);
|
int tsem_wait(tsem_t *sem);
|
||||||
int tsem_post(dispatch_semaphore_t *sem);
|
int tsem_post(tsem_t *sem);
|
||||||
int tsem_destroy(dispatch_semaphore_t *sem);
|
int tsem_destroy(tsem_t *sem);
|
||||||
|
|
||||||
#define TAOS_OS_FUNC_SOCKET_SETSOCKETOPT
|
#define TAOS_OS_FUNC_SOCKET_SETSOCKETOPT
|
||||||
#define TAOS_OS_FUNC_STRING_STR2INT64
|
#define TAOS_OS_FUNC_STRING_STR2INT64
|
||||||
|
@ -91,7 +91,12 @@ extern "C" {
|
||||||
typedef int(*__compar_fn_t)(const void *, const void *);
|
typedef int(*__compar_fn_t)(const void *, const void *);
|
||||||
|
|
||||||
// for send function in tsocket.c
|
// for send function in tsocket.c
|
||||||
|
#if defined(MSG_NOSIGNAL)
|
||||||
|
#undef MSG_NOSIGNAL
|
||||||
|
#endif
|
||||||
|
|
||||||
#define MSG_NOSIGNAL 0
|
#define MSG_NOSIGNAL 0
|
||||||
|
|
||||||
#define SO_NO_CHECK 0x1234
|
#define SO_NO_CHECK 0x1234
|
||||||
#define SOL_TCP 0x1234
|
#define SOL_TCP 0x1234
|
||||||
#define TCP_KEEPIDLE 0x1234
|
#define TCP_KEEPIDLE 0x1234
|
||||||
|
@ -100,6 +105,18 @@ typedef int(*__compar_fn_t)(const void *, const void *);
|
||||||
#define PTHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE
|
#define PTHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
int64_t tsosStr2int64(char *str);
|
||||||
|
|
||||||
|
#include "eok.h"
|
||||||
|
|
||||||
|
void taos_block_sigalrm(void);
|
||||||
|
|
||||||
|
#define TAOS_OS_DEF_EPOLL
|
||||||
|
#define TAOS_EPOLL_WAIT_TIME 500
|
||||||
|
typedef int32_t SOCKET;
|
||||||
|
typedef SOCKET EpollFd;
|
||||||
|
#define EpollClose(pollFd) epoll_close(pollFd)
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -96,7 +96,7 @@ extern "C" {
|
||||||
#ifdef _ISOC11_SOURCE
|
#ifdef _ISOC11_SOURCE
|
||||||
#define threadlocal _Thread_local
|
#define threadlocal _Thread_local
|
||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
#define threadlocal
|
#define threadlocal __thread
|
||||||
#elif defined(__GNUC__) && !defined(threadlocal)
|
#elif defined(__GNUC__) && !defined(threadlocal)
|
||||||
#define threadlocal __thread
|
#define threadlocal __thread
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -30,3 +30,4 @@ void osInit() {
|
||||||
strcpy(tsScriptDir, "~/TDengine/cfg");
|
strcpy(tsScriptDir, "~/TDengine/cfg");
|
||||||
strcpy(tsOsName, "Darwin");
|
strcpy(tsOsName, "Darwin");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,28 +13,269 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// fail-fast or let-it-crash philosophy
|
||||||
|
// https://en.wikipedia.org/wiki/Fail-fast
|
||||||
|
// https://stackoverflow.com/questions/4393197/erlangs-let-it-crash-philosophy-applicable-elsewhere
|
||||||
|
// experimentally, we follow log-and-crash here
|
||||||
|
|
||||||
#define _DEFAULT_SOURCE
|
#define _DEFAULT_SOURCE
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
|
|
||||||
int tsem_init(dispatch_semaphore_t *sem, int pshared, unsigned int value) {
|
// #define SEM_USE_PTHREAD
|
||||||
*sem = dispatch_semaphore_create(value);
|
// #define SEM_USE_POSIX
|
||||||
if (*sem == NULL) {
|
#define SEM_USE_SEM
|
||||||
|
|
||||||
|
#ifdef SEM_USE_SEM
|
||||||
|
#include <mach/mach_init.h>
|
||||||
|
#include <mach/mach_error.h>
|
||||||
|
#include <mach/semaphore.h>
|
||||||
|
#include <mach/task.h>
|
||||||
|
|
||||||
|
static pthread_t sem_thread;
|
||||||
|
static pthread_once_t sem_once;
|
||||||
|
static task_t sem_port;
|
||||||
|
static volatile int sem_inited = 0;
|
||||||
|
static semaphore_t sem_exit;
|
||||||
|
|
||||||
|
static void* sem_thread_routine(void *arg) {
|
||||||
|
(void)arg;
|
||||||
|
sem_port = mach_task_self();
|
||||||
|
kern_return_t ret = semaphore_create(sem_port, &sem_exit, SYNC_POLICY_FIFO, 0);
|
||||||
|
if (ret != KERN_SUCCESS) {
|
||||||
|
fprintf(stderr, "==%s[%d]%s()==failed to create sem_exit\n", basename(__FILE__), __LINE__, __func__);
|
||||||
|
sem_inited = -1;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
sem_inited = 1;
|
||||||
|
semaphore_wait(sem_exit);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void once_init(void) {
|
||||||
|
int r = 0;
|
||||||
|
r = pthread_create(&sem_thread, NULL, sem_thread_routine, NULL);
|
||||||
|
if (r) {
|
||||||
|
fprintf(stderr, "==%s[%d]%s()==failed to create thread\n", basename(__FILE__), __LINE__, __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
while (sem_inited==0) {
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct tsem_s {
|
||||||
|
#ifdef SEM_USE_PTHREAD
|
||||||
|
pthread_mutex_t lock;
|
||||||
|
pthread_cond_t cond;
|
||||||
|
volatile int64_t val;
|
||||||
|
#elif defined(SEM_USE_POSIX)
|
||||||
|
size_t id;
|
||||||
|
sem_t *sem;
|
||||||
|
#elif defined(SEM_USE_SEM)
|
||||||
|
semaphore_t sem;
|
||||||
|
#else // SEM_USE_PTHREAD
|
||||||
|
dispatch_semaphore_t sem;
|
||||||
|
#endif // SEM_USE_PTHREAD
|
||||||
|
|
||||||
|
volatile unsigned int valid:1;
|
||||||
|
};
|
||||||
|
|
||||||
|
int tsem_init(tsem_t *sem, int pshared, unsigned int value) {
|
||||||
|
// fprintf(stderr, "==%s[%d]%s():[%p]==creating\n", basename(__FILE__), __LINE__, __func__, sem);
|
||||||
|
if (*sem) {
|
||||||
|
fprintf(stderr, "==%s[%d]%s():[%p]==already initialized\n", basename(__FILE__), __LINE__, __func__, sem);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
struct tsem_s *p = (struct tsem_s*)calloc(1, sizeof(*p));
|
||||||
|
if (!p) {
|
||||||
|
fprintf(stderr, "==%s[%d]%s():[%p]==out of memory\n", basename(__FILE__), __LINE__, __func__, sem);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef SEM_USE_PTHREAD
|
||||||
|
int r = pthread_mutex_init(&p->lock, NULL);
|
||||||
|
do {
|
||||||
|
if (r) break;
|
||||||
|
r = pthread_cond_init(&p->cond, NULL);
|
||||||
|
if (r) {
|
||||||
|
pthread_mutex_destroy(&p->lock);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
p->val = value;
|
||||||
|
} while (0);
|
||||||
|
if (r) {
|
||||||
|
fprintf(stderr, "==%s[%d]%s():[%p]==not created\n", basename(__FILE__), __LINE__, __func__, sem);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
#elif defined(SEM_USE_POSIX)
|
||||||
|
static size_t tick = 0;
|
||||||
|
do {
|
||||||
|
size_t id = atomic_add_fetch_64(&tick, 1);
|
||||||
|
if (id==SEM_VALUE_MAX) {
|
||||||
|
atomic_store_64(&tick, 0);
|
||||||
|
id = 0;
|
||||||
|
}
|
||||||
|
char name[NAME_MAX-4];
|
||||||
|
snprintf(name, sizeof(name), "/t%ld", id);
|
||||||
|
p->sem = sem_open(name, O_CREAT|O_EXCL, pshared, value);
|
||||||
|
p->id = id;
|
||||||
|
if (p->sem!=SEM_FAILED) break;
|
||||||
|
int e = errno;
|
||||||
|
if (e==EEXIST) continue;
|
||||||
|
if (e==EINTR) continue;
|
||||||
|
fprintf(stderr, "==%s[%d]%s():[%p]==not created[%d]%s\n", basename(__FILE__), __LINE__, __func__, sem, e, strerror(e));
|
||||||
|
abort();
|
||||||
|
} while (p->sem==SEM_FAILED);
|
||||||
|
#elif defined(SEM_USE_SEM)
|
||||||
|
pthread_once(&sem_once, once_init);
|
||||||
|
if (sem_inited!=1) {
|
||||||
|
fprintf(stderr, "==%s[%d]%s():[%p]==internal resource init failed\n", basename(__FILE__), __LINE__, __func__, sem);
|
||||||
|
errno = ENOMEM;
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
kern_return_t ret = semaphore_create(sem_port, &p->sem, SYNC_POLICY_FIFO, value);
|
||||||
|
if (ret != KERN_SUCCESS) {
|
||||||
|
fprintf(stderr, "==%s[%d]%s():[%p]==semophore_create failed\n", basename(__FILE__), __LINE__, __func__, sem);
|
||||||
|
// we fail-fast here, because we have less-doc about semaphore_create for the moment
|
||||||
|
abort();
|
||||||
}
|
}
|
||||||
|
#else // SEM_USE_PTHREAD
|
||||||
|
p->sem = dispatch_semaphore_create(value);
|
||||||
|
if (p->sem == NULL) {
|
||||||
|
fprintf(stderr, "==%s[%d]%s():[%p]==not created\n", basename(__FILE__), __LINE__, __func__, sem);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
#endif // SEM_USE_PTHREAD
|
||||||
|
|
||||||
|
p->valid = 1;
|
||||||
|
|
||||||
|
*sem = p;
|
||||||
|
|
||||||
int tsem_wait(dispatch_semaphore_t *sem) {
|
|
||||||
dispatch_semaphore_wait(*sem, DISPATCH_TIME_FOREVER);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tsem_post(dispatch_semaphore_t *sem) {
|
int tsem_wait(tsem_t *sem) {
|
||||||
dispatch_semaphore_signal(*sem);
|
if (!*sem) {
|
||||||
|
fprintf(stderr, "==%s[%d]%s():[%p]==not initialized\n", basename(__FILE__), __LINE__, __func__, sem);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
struct tsem_s *p = *sem;
|
||||||
|
if (!p->valid) {
|
||||||
|
fprintf(stderr, "==%s[%d]%s():[%p]==already destroyed\n", basename(__FILE__), __LINE__, __func__, sem);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
#ifdef SEM_USE_PTHREAD
|
||||||
|
if (pthread_mutex_lock(&p->lock)) {
|
||||||
|
fprintf(stderr, "==%s[%d]%s():[%p]==internal logic error\n", basename(__FILE__), __LINE__, __func__, sem);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
p->val -= 1;
|
||||||
|
if (p->val < 0) {
|
||||||
|
if (pthread_cond_wait(&p->cond, &p->lock)) {
|
||||||
|
fprintf(stderr, "==%s[%d]%s():[%p]==internal logic error\n", basename(__FILE__), __LINE__, __func__, sem);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pthread_mutex_unlock(&p->lock)) {
|
||||||
|
fprintf(stderr, "==%s[%d]%s():[%p]==internal logic error\n", basename(__FILE__), __LINE__, __func__, sem);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
#elif defined(SEM_USE_POSIX)
|
||||||
|
return sem_wait(p->sem);
|
||||||
|
#elif defined(SEM_USE_SEM)
|
||||||
|
return semaphore_wait(p->sem);
|
||||||
|
#else // SEM_USE_PTHREAD
|
||||||
|
return dispatch_semaphore_wait(p->sem, DISPATCH_TIME_FOREVER);
|
||||||
|
#endif // SEM_USE_PTHREAD
|
||||||
|
}
|
||||||
|
|
||||||
|
int tsem_post(tsem_t *sem) {
|
||||||
|
if (!*sem) {
|
||||||
|
fprintf(stderr, "==%s[%d]%s():[%p]==not initialized\n", basename(__FILE__), __LINE__, __func__, sem);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
struct tsem_s *p = *sem;
|
||||||
|
if (!p->valid) {
|
||||||
|
fprintf(stderr, "==%s[%d]%s():[%p]==already destroyed\n", basename(__FILE__), __LINE__, __func__, sem);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
#ifdef SEM_USE_PTHREAD
|
||||||
|
if (pthread_mutex_lock(&p->lock)) {
|
||||||
|
fprintf(stderr, "==%s[%d]%s():[%p]==internal logic error\n", basename(__FILE__), __LINE__, __func__, sem);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
p->val += 1;
|
||||||
|
if (p->val <= 0) {
|
||||||
|
if (pthread_cond_signal(&p->cond)) {
|
||||||
|
fprintf(stderr, "==%s[%d]%s():[%p]==internal logic error\n", basename(__FILE__), __LINE__, __func__, sem);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pthread_mutex_unlock(&p->lock)) {
|
||||||
|
fprintf(stderr, "==%s[%d]%s():[%p]==internal logic error\n", basename(__FILE__), __LINE__, __func__, sem);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
#elif defined(SEM_USE_POSIX)
|
||||||
|
return sem_post(p->sem);
|
||||||
|
#elif defined(SEM_USE_SEM)
|
||||||
|
return semaphore_signal(p->sem);
|
||||||
|
#else // SEM_USE_PTHREAD
|
||||||
|
return dispatch_semaphore_signal(p->sem);
|
||||||
|
#endif // SEM_USE_PTHREAD
|
||||||
|
}
|
||||||
|
|
||||||
|
int tsem_destroy(tsem_t *sem) {
|
||||||
|
// fprintf(stderr, "==%s[%d]%s():[%p]==destroying\n", basename(__FILE__), __LINE__, __func__, sem);
|
||||||
|
if (!*sem) {
|
||||||
|
// fprintf(stderr, "==%s[%d]%s():[%p]==not initialized\n", basename(__FILE__), __LINE__, __func__, sem);
|
||||||
|
// abort();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
struct tsem_s *p = *sem;
|
||||||
|
if (!p->valid) {
|
||||||
|
// fprintf(stderr, "==%s[%d]%s():[%p]==already destroyed\n", basename(__FILE__), __LINE__, __func__, sem);
|
||||||
|
// abort();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#ifdef SEM_USE_PTHREAD
|
||||||
|
if (pthread_mutex_lock(&p->lock)) {
|
||||||
|
fprintf(stderr, "==%s[%d]%s():[%p]==internal logic error\n", basename(__FILE__), __LINE__, __func__, sem);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
p->valid = 0;
|
||||||
|
if (pthread_cond_destroy(&p->cond)) {
|
||||||
|
fprintf(stderr, "==%s[%d]%s():[%p]==internal logic error\n", basename(__FILE__), __LINE__, __func__, sem);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
if (pthread_mutex_unlock(&p->lock)) {
|
||||||
|
fprintf(stderr, "==%s[%d]%s():[%p]==internal logic error\n", basename(__FILE__), __LINE__, __func__, sem);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
if (pthread_mutex_destroy(&p->lock)) {
|
||||||
|
fprintf(stderr, "==%s[%d]%s():[%p]==internal logic error\n", basename(__FILE__), __LINE__, __func__, sem);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
#elif defined(SEM_USE_POSIX)
|
||||||
|
char name[NAME_MAX-4];
|
||||||
|
snprintf(name, sizeof(name), "/t%ld", p->id);
|
||||||
|
int r = sem_unlink(name);
|
||||||
|
if (r) {
|
||||||
|
int e = errno;
|
||||||
|
fprintf(stderr, "==%s[%d]%s():[%p]==unlink failed[%d]%s\n", basename(__FILE__), __LINE__, __func__, sem, e, strerror(e));
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
#elif defined(SEM_USE_SEM)
|
||||||
|
semaphore_destroy(sem_port, p->sem);
|
||||||
|
#else // SEM_USE_PTHREAD
|
||||||
|
#endif // SEM_USE_PTHREAD
|
||||||
|
|
||||||
|
p->valid = 0;
|
||||||
|
free(p);
|
||||||
|
|
||||||
|
*sem = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tsem_destroy(dispatch_semaphore_t *sem) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
|
@ -102,3 +102,15 @@ int taosSystem(const char *cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void taosSetCoreDump() {}
|
void taosSetCoreDump() {}
|
||||||
|
|
||||||
|
char *taosGetCmdlineByPID(int pid) {
|
||||||
|
return "[not supported yet]";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool taosGetSystemUid(char *uid) {
|
||||||
|
uuid_t uuid = {0};
|
||||||
|
uuid_generate(uuid);
|
||||||
|
// it's caller's responsibility to make enough space for `uid`, that's 36-char + 1-null
|
||||||
|
uuid_unparse(uuid, uid);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
@ -13,9 +13,82 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// fail-fast or let-it-crash philosophy
|
||||||
|
// https://en.wikipedia.org/wiki/Fail-fast
|
||||||
|
// https://stackoverflow.com/questions/4393197/erlangs-let-it-crash-philosophy-applicable-elsewhere
|
||||||
|
// experimentally, we follow log-and-crash here
|
||||||
|
|
||||||
#define _DEFAULT_SOURCE
|
#define _DEFAULT_SOURCE
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
#include <sys/event.h>
|
||||||
|
|
||||||
|
static void (*timer_callback)(int);
|
||||||
|
static int timer_ms = 0;
|
||||||
|
static pthread_t timer_thread;
|
||||||
|
static int timer_kq = -1;
|
||||||
|
static volatile int timer_stop = 0;
|
||||||
|
|
||||||
|
static void* timer_routine(void *arg) {
|
||||||
|
(void)arg;
|
||||||
|
|
||||||
|
int r = 0;
|
||||||
|
struct timespec to = {0};
|
||||||
|
to.tv_sec = timer_ms / 1000;
|
||||||
|
to.tv_nsec = (timer_ms % 1000) * 1000000;
|
||||||
|
while (!timer_stop) {
|
||||||
|
struct kevent64_s kev[10] = {0};
|
||||||
|
r = kevent64(timer_kq, NULL, 0, kev, sizeof(kev)/sizeof(kev[0]), 0, &to);
|
||||||
|
if (r!=0) {
|
||||||
|
fprintf(stderr, "==%s[%d]%s()==kevent64 failed\n", basename(__FILE__), __LINE__, __func__);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
timer_callback(SIGALRM); // just mock
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int taosInitTimer(void (*callback)(int), int ms) {
|
||||||
|
int r = 0;
|
||||||
|
timer_ms = ms;
|
||||||
|
timer_callback = callback;
|
||||||
|
|
||||||
|
timer_kq = kqueue();
|
||||||
|
if (timer_kq==-1) {
|
||||||
|
fprintf(stderr, "==%s[%d]%s()==failed to create timer kq\n", basename(__FILE__), __LINE__, __func__);
|
||||||
|
// since no caller of this func checks the return value for the moment
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
r = pthread_create(&timer_thread, NULL, timer_routine, NULL);
|
||||||
|
if (r) {
|
||||||
|
fprintf(stderr, "==%s[%d]%s()==failed to create timer thread\n", basename(__FILE__), __LINE__, __func__);
|
||||||
|
// since no caller of this func checks the return value for the moment
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void taosUninitTimer() {
|
||||||
|
int r = 0;
|
||||||
|
timer_stop = 1;
|
||||||
|
r = pthread_join(timer_thread, NULL);
|
||||||
|
if (r) {
|
||||||
|
fprintf(stderr, "==%s[%d]%s()==failed to join timer thread\n", basename(__FILE__), __LINE__, __func__);
|
||||||
|
// since no caller of this func checks the return value for the moment
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
close(timer_kq);
|
||||||
|
timer_kq = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void taos_block_sigalrm(void) {
|
||||||
|
// we don't know if there's any specific API for SIGALRM to deliver to specific thread
|
||||||
|
// this implementation relies on kqueue rather than SIGALRM
|
||||||
|
}
|
||||||
|
#else
|
||||||
int taosInitTimer(void (*callback)(int), int ms) {
|
int taosInitTimer(void (*callback)(int), int ms) {
|
||||||
signal(SIGALRM, callback);
|
signal(SIGALRM, callback);
|
||||||
|
|
||||||
|
@ -34,3 +107,17 @@ void taosUninitTimer() {
|
||||||
setitimer(ITIMER_REAL, &tv, NULL);
|
setitimer(ITIMER_REAL, &tv, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void taos_block_sigalrm(void) {
|
||||||
|
// since SIGALRM has been used
|
||||||
|
// consideration: any better solution?
|
||||||
|
static __thread int already_set = 0;
|
||||||
|
if (!already_set) {
|
||||||
|
sigset_t set;
|
||||||
|
sigemptyset(&set);
|
||||||
|
sigaddset(&set, SIGALRM);
|
||||||
|
pthread_sigmask(SIG_BLOCK, &set, NULL);
|
||||||
|
already_set = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,893 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can use, redistribute, and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, version 3
|
||||||
|
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// fail-fast or let-it-crash philosophy
|
||||||
|
// https://en.wikipedia.org/wiki/Fail-fast
|
||||||
|
// https://stackoverflow.com/questions/4393197/erlangs-let-it-crash-philosophy-applicable-elsewhere
|
||||||
|
// experimentally, we follow log-and-crash here
|
||||||
|
|
||||||
|
#include "eok.h"
|
||||||
|
|
||||||
|
#include "os.h"
|
||||||
|
|
||||||
|
#include <sys/event.h>
|
||||||
|
|
||||||
|
// #define BALANCE_CHECK_WHEN_CLOSE
|
||||||
|
|
||||||
|
#ifdef ENABLE_LOG
|
||||||
|
#define D(fmt, ...) fprintf(stderr, "%s[%d]%s(): " fmt "\n", basename(__FILE__), __LINE__, __func__, ##__VA_ARGS__)
|
||||||
|
#define E(fmt, ...) do { \
|
||||||
|
fprintf(stderr, "%s[%d]%s(): %d[%s]: " fmt "\n", \
|
||||||
|
basename(__FILE__), __LINE__, __func__, \
|
||||||
|
errno, strerror(errno), \
|
||||||
|
##__VA_ARGS__); \
|
||||||
|
} while (0)
|
||||||
|
#else // !ENABLE_LOG
|
||||||
|
#define D(fmt, ...) (void)fmt
|
||||||
|
#define E(fmt, ...) (void)fmt
|
||||||
|
#endif // ENABLE_LOG
|
||||||
|
|
||||||
|
#define A(statement, fmt, ...) do { \
|
||||||
|
if (statement) break; \
|
||||||
|
fprintf(stderr, "%s[%d]%s(): assert [%s] failed: %d[%s]: " fmt "\n", \
|
||||||
|
basename(__FILE__), __LINE__, __func__, \
|
||||||
|
#statement, errno, strerror(errno), \
|
||||||
|
##__VA_ARGS__); \
|
||||||
|
abort(); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
static int eok_dummy = 0;
|
||||||
|
|
||||||
|
typedef struct ep_over_kq_s ep_over_kq_t;
|
||||||
|
typedef struct eok_event_s eok_event_t;
|
||||||
|
|
||||||
|
struct ep_over_kq_s {
|
||||||
|
int kq;
|
||||||
|
|
||||||
|
// !!!
|
||||||
|
// idx in the eoks list
|
||||||
|
// used as pseudo-file-desciptor
|
||||||
|
// must be 'closed' with epoll_close
|
||||||
|
int idx;
|
||||||
|
|
||||||
|
ep_over_kq_t *next;
|
||||||
|
|
||||||
|
int sv[2]; // 0 for read, 1 for write
|
||||||
|
|
||||||
|
// all registered 'epoll events, key by fd'
|
||||||
|
int evs_count;
|
||||||
|
eok_event_t *evs_head;
|
||||||
|
eok_event_t *evs_tail;
|
||||||
|
eok_event_t *evs_free;
|
||||||
|
|
||||||
|
// all kev changes list pending to be processed by kevent64
|
||||||
|
// key by tuple (ident,filter), ident === fd in this case
|
||||||
|
struct kevent64_s *kchanges;
|
||||||
|
int nchanges;
|
||||||
|
int ichanges;
|
||||||
|
|
||||||
|
// kev eventslist for kevent64 to store active events
|
||||||
|
// they remain alive among kevent64 calls
|
||||||
|
struct kevent64_s *kevslist;
|
||||||
|
int nevslist;
|
||||||
|
|
||||||
|
pthread_mutex_t lock;
|
||||||
|
|
||||||
|
volatile unsigned int lock_valid:1;
|
||||||
|
volatile unsigned int waiting:1;
|
||||||
|
volatile unsigned int changed:1;
|
||||||
|
volatile unsigned int wakenup:1;
|
||||||
|
volatile unsigned int stopping:1;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct eok_event_s {
|
||||||
|
int fd;
|
||||||
|
struct epoll_event epev;
|
||||||
|
volatile unsigned int changed; // 0:registered;1:add;2:mod;3:del
|
||||||
|
|
||||||
|
eok_event_t *next;
|
||||||
|
eok_event_t *prev;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct eoks_s eoks_t;
|
||||||
|
struct eoks_s {
|
||||||
|
pthread_mutex_t lock;
|
||||||
|
ep_over_kq_t **eoks; // note: this memory leaks when process terminates
|
||||||
|
int neoks; // we can add an extra api to let user clean
|
||||||
|
ep_over_kq_t *eoks_free_list; // currently, we just keep it simple stupid
|
||||||
|
};
|
||||||
|
|
||||||
|
static eoks_t eoks = {
|
||||||
|
.lock = PTHREAD_MUTEX_INITIALIZER,
|
||||||
|
.eoks = NULL,
|
||||||
|
.neoks = 0,
|
||||||
|
.eoks_free_list = NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef ENABLE_LOG
|
||||||
|
static const char* op_str(int op) {
|
||||||
|
switch (op) {
|
||||||
|
case EPOLL_CTL_ADD: return "EPOLL_CTL_ADD";
|
||||||
|
case EPOLL_CTL_MOD: return "EPOLL_CTL_MOD";
|
||||||
|
case EPOLL_CTL_DEL: return "EPOLL_CTL_DEL";
|
||||||
|
default: return "UNKNOWN";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static __thread char buf_slots[10][1024] = {0};
|
||||||
|
static __thread int buf_slots_linelen = sizeof(buf_slots[0])/sizeof(buf_slots[0][0]);
|
||||||
|
static __thread int buf_slots_count = sizeof(buf_slots)/(sizeof(buf_slots[0])/sizeof(buf_slots[0][0]));
|
||||||
|
|
||||||
|
static const char* events_str(uint32_t events, int slots) {
|
||||||
|
A(slots>=0 && slots<buf_slots_count, "internal logic error");
|
||||||
|
char *buf = buf_slots[slots];
|
||||||
|
char *p = buf;
|
||||||
|
size_t len = buf_slots_linelen;
|
||||||
|
int n = 0;
|
||||||
|
buf[0] = '\0';
|
||||||
|
// copied from <sys/epoll.h> on linux
|
||||||
|
// EPOLLIN = 0x001,
|
||||||
|
// #define EPOLLIN EPOLLIN
|
||||||
|
// EPOLLPRI = 0x002,
|
||||||
|
// #define EPOLLPRI EPOLLPRI
|
||||||
|
// EPOLLOUT = 0x004,
|
||||||
|
// #define EPOLLOUT EPOLLOUT
|
||||||
|
// EPOLLRDNORM = 0x040,
|
||||||
|
// #define EPOLLRDNORM EPOLLRDNORM
|
||||||
|
// EPOLLRDBAND = 0x080,
|
||||||
|
// #define EPOLLRDBAND EPOLLRDBAND
|
||||||
|
// EPOLLWRNORM = 0x100,
|
||||||
|
// #define EPOLLWRNORM EPOLLWRNORM
|
||||||
|
// EPOLLWRBAND = 0x200,
|
||||||
|
// #define EPOLLWRBAND EPOLLWRBAND
|
||||||
|
// EPOLLMSG = 0x400,
|
||||||
|
// #define EPOLLMSG EPOLLMSG
|
||||||
|
// EPOLLERR = 0x008,
|
||||||
|
// #define EPOLLERR EPOLLERR
|
||||||
|
// EPOLLHUP = 0x010,
|
||||||
|
// #define EPOLLHUP EPOLLHUP
|
||||||
|
// EPOLLRDHUP = 0x2000,
|
||||||
|
// #define EPOLLRDHUP EPOLLRDHUP
|
||||||
|
// EPOLLEXCLUSIVE = 1u << 28,
|
||||||
|
// #define EPOLLEXCLUSIVE EPOLLEXCLUSIVE
|
||||||
|
// EPOLLWAKEUP = 1u << 29,
|
||||||
|
// #define EPOLLWAKEUP EPOLLWAKEUP
|
||||||
|
// EPOLLONESHOT = 1u << 30,
|
||||||
|
// #define EPOLLONESHOT EPOLLONESHOT
|
||||||
|
// EPOLLET = 1u << 31
|
||||||
|
// #define EPOLLET EPOLLET
|
||||||
|
#define CHK_EV(ev) \
|
||||||
|
if (len>0 && (events & (ev))==(ev)) { \
|
||||||
|
n = snprintf(p, len, "%s%s", p!=buf ? "|" : "", #ev); \
|
||||||
|
p += n; \
|
||||||
|
len -= n; \
|
||||||
|
}
|
||||||
|
CHK_EV(EPOLLIN);
|
||||||
|
CHK_EV(EPOLLPRI);
|
||||||
|
CHK_EV(EPOLLOUT);
|
||||||
|
CHK_EV(EPOLLRDNORM);
|
||||||
|
CHK_EV(EPOLLRDBAND);
|
||||||
|
CHK_EV(EPOLLWRNORM);
|
||||||
|
CHK_EV(EPOLLWRBAND);
|
||||||
|
CHK_EV(EPOLLMSG);
|
||||||
|
CHK_EV(EPOLLERR);
|
||||||
|
CHK_EV(EPOLLHUP);
|
||||||
|
CHK_EV(EPOLLRDHUP);
|
||||||
|
CHK_EV(EPOLLEXCLUSIVE);
|
||||||
|
CHK_EV(EPOLLWAKEUP);
|
||||||
|
CHK_EV(EPOLLONESHOT);
|
||||||
|
CHK_EV(EPOLLET);
|
||||||
|
#undef CHK_EV
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char* kev_flags_str(uint16_t flags, int slots) {
|
||||||
|
A(slots>=0 && slots<buf_slots_count, "internal logic error");
|
||||||
|
char *buf = buf_slots[slots];
|
||||||
|
char *p = buf;
|
||||||
|
size_t len = buf_slots_linelen;
|
||||||
|
int n = 0;
|
||||||
|
buf[0] = '\0';
|
||||||
|
// copied to <sys/event.h>
|
||||||
|
// #define EV_ADD 0x0001 /* add event to kq (implies enable) */
|
||||||
|
// #define EV_DELETE 0x0002 /* delete event from kq */
|
||||||
|
// #define EV_ENABLE 0x0004 /* enable event */
|
||||||
|
// #define EV_DISABLE 0x0008 /* disable event (not reported) */
|
||||||
|
// /* flags */
|
||||||
|
// #define EV_ONESHOT 0x0010 /* only report one occurrence */
|
||||||
|
// #define EV_CLEAR 0x0020 /* clear event state after reporting */
|
||||||
|
// #define EV_RECEIPT 0x0040 /* force immediate event output */
|
||||||
|
// /* ... with or without EV_ERROR */
|
||||||
|
// /* ... use KEVENT_FLAG_ERROR_EVENTS */
|
||||||
|
// /* on syscalls supporting flags */
|
||||||
|
// #define EV_DISPATCH 0x0080 /* disable event after reporting */
|
||||||
|
// #define EV_UDATA_SPECIFIC 0x0100 /* unique kevent per udata value */
|
||||||
|
// #define EV_DISPATCH2 (EV_DISPATCH | EV_UDATA_SPECIFIC)
|
||||||
|
// /* ... in combination with EV_DELETE */
|
||||||
|
// /* will defer delete until udata-specific */
|
||||||
|
// /* event enabled. EINPROGRESS will be */
|
||||||
|
// /* returned to indicate the deferral */
|
||||||
|
// #define EV_VANISHED 0x0200 /* report that source has vanished */
|
||||||
|
// /* ... only valid with EV_DISPATCH2 */
|
||||||
|
// #define EV_SYSFLAGS 0xF000 /* reserved by system */
|
||||||
|
// #define EV_FLAG0 0x1000 /* filter-specific flag */
|
||||||
|
// #define EV_FLAG1 0x2000 /* filter-specific flag */
|
||||||
|
// /* returned values */
|
||||||
|
// #define EV_EOF 0x8000 /* EOF detected */
|
||||||
|
// #define EV_ERROR 0x4000 /* error, data contains errno */
|
||||||
|
#define CHK_EV(ev) \
|
||||||
|
if (len>0 && (flags & (ev))==(ev)) { \
|
||||||
|
n = snprintf(p, len, "%s%s", p!=buf ? "|" : "", #ev); \
|
||||||
|
p += n; \
|
||||||
|
len -= n; \
|
||||||
|
}
|
||||||
|
CHK_EV(EV_ADD);
|
||||||
|
CHK_EV(EV_DELETE);
|
||||||
|
CHK_EV(EV_ENABLE);
|
||||||
|
CHK_EV(EV_DISABLE);
|
||||||
|
CHK_EV(EV_ONESHOT);
|
||||||
|
CHK_EV(EV_CLEAR);
|
||||||
|
CHK_EV(EV_RECEIPT);
|
||||||
|
CHK_EV(EV_DISPATCH);
|
||||||
|
CHK_EV(EV_UDATA_SPECIFIC);
|
||||||
|
CHK_EV(EV_DISPATCH2);
|
||||||
|
CHK_EV(EV_VANISHED);
|
||||||
|
CHK_EV(EV_SYSFLAGS);
|
||||||
|
CHK_EV(EV_FLAG0);
|
||||||
|
CHK_EV(EV_FLAG1);
|
||||||
|
CHK_EV(EV_EOF);
|
||||||
|
CHK_EV(EV_ERROR);
|
||||||
|
#undef CHK_EV
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
#endif // ENABLE_LOG
|
||||||
|
|
||||||
|
static ep_over_kq_t* eoks_alloc(void);
|
||||||
|
static void eoks_free(ep_over_kq_t *eok);
|
||||||
|
static ep_over_kq_t* eoks_find(int epfd);
|
||||||
|
|
||||||
|
static eok_event_t* eok_find_ev(ep_over_kq_t *eok, int fd);
|
||||||
|
static eok_event_t* eok_calloc_ev(ep_over_kq_t *eok);
|
||||||
|
static void eok_free_ev(ep_over_kq_t *eok, eok_event_t *ev);
|
||||||
|
static void eok_wakeup(ep_over_kq_t *eok);
|
||||||
|
|
||||||
|
static int eok_chgs_refresh(ep_over_kq_t *eok, eok_event_t *oev, eok_event_t *ev, struct kevent64_s *krev, struct kevent64_s *kwev);
|
||||||
|
|
||||||
|
static struct kevent64_s* eok_alloc_eventslist(ep_over_kq_t *eok, int maxevents);
|
||||||
|
|
||||||
|
int epoll_create(int size) {
|
||||||
|
(void)size;
|
||||||
|
int e = 0;
|
||||||
|
ep_over_kq_t *eok = eoks_alloc();
|
||||||
|
if (!eok) return -1;
|
||||||
|
|
||||||
|
A(eok->kq==-1, "internal logic error");
|
||||||
|
A(eok->lock_valid, "internal logic error");
|
||||||
|
A(eok->idx>=0 && eok->idx<eoks.neoks, "internal logic error");
|
||||||
|
A(eok->next==NULL, "internal logic error");
|
||||||
|
A(eok->sv[0]==-1, "internal logic error");
|
||||||
|
A(eok->sv[1]==-1, "internal logic error");
|
||||||
|
|
||||||
|
eok->kq = kqueue();
|
||||||
|
if (eok->kq==-1) {
|
||||||
|
e = errno;
|
||||||
|
eoks_free(eok);
|
||||||
|
errno = e;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (socketpair(AF_LOCAL, SOCK_STREAM, 0, eok->sv)) {
|
||||||
|
e = errno;
|
||||||
|
eoks_free(eok);
|
||||||
|
errno = e;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct epoll_event ev = {0};
|
||||||
|
ev.events = EPOLLIN;
|
||||||
|
ev.data.ptr = &eok_dummy;
|
||||||
|
D("epoll_create epfd:[%d] and sv0[%d]", eok->idx, eok->sv[0]);
|
||||||
|
if (epoll_ctl(eok->idx, EPOLL_CTL_ADD, eok->sv[0], &ev)) {
|
||||||
|
e = errno;
|
||||||
|
epoll_close(eok->idx);
|
||||||
|
errno = e;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return eok->idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event) {
|
||||||
|
D("epoll_ctling epfd:[%d], op:[%s], fd:[%d], events:[%04x:%s]",
|
||||||
|
epfd, op_str(op), fd,
|
||||||
|
event ? event->events : 0,
|
||||||
|
event ? events_str(event->events, 0) : "NULL");
|
||||||
|
int e = 0;
|
||||||
|
if (epfd<0 || epfd>=eoks.neoks) {
|
||||||
|
errno = EBADF;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (fd==-1) {
|
||||||
|
errno = EBADF;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (event && !(event->events & (EPOLLIN | EPOLLERR | EPOLLHUP | EPOLLRDHUP | EPOLLOUT))) {
|
||||||
|
e = ENOTSUP;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ep_over_kq_t *eok = eoks_find(epfd);
|
||||||
|
if (!eok) {
|
||||||
|
errno = EBADF;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
A(0==pthread_mutex_lock(&eok->lock), "");
|
||||||
|
do {
|
||||||
|
eok_event_t* oev = eok_find_ev(eok, fd);
|
||||||
|
if (op==EPOLL_CTL_ADD && oev) {
|
||||||
|
e = EEXIST;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (op!=EPOLL_CTL_ADD && !oev) {
|
||||||
|
e = ENOENT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (op!=EPOLL_CTL_DEL && !event) {
|
||||||
|
e = EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// prepare krev/kwev
|
||||||
|
struct kevent64_s krev = {0};
|
||||||
|
struct kevent64_s kwev = {0};
|
||||||
|
krev.ident = -1;
|
||||||
|
kwev.ident = -1;
|
||||||
|
uint16_t flags = 0;
|
||||||
|
// prepare internal eok event
|
||||||
|
eok_event_t ev = {0};
|
||||||
|
ev.fd = fd;
|
||||||
|
if (event) ev.epev = *event;
|
||||||
|
struct epoll_event *pev = event;
|
||||||
|
switch (op) {
|
||||||
|
case EPOLL_CTL_ADD: {
|
||||||
|
flags = EV_ADD;
|
||||||
|
ev.changed = 1;
|
||||||
|
} break;
|
||||||
|
case EPOLL_CTL_MOD: {
|
||||||
|
flags = EV_ADD;
|
||||||
|
ev.changed = 2;
|
||||||
|
} break;
|
||||||
|
case EPOLL_CTL_DEL: {
|
||||||
|
// event is ignored
|
||||||
|
// pev points to registered epoll_event
|
||||||
|
pev = &oev->epev;
|
||||||
|
flags = EV_DELETE;
|
||||||
|
ev.changed = 3;
|
||||||
|
} break;
|
||||||
|
default: {
|
||||||
|
e = ENOTSUP;
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e) break;
|
||||||
|
|
||||||
|
// udata will be delayed to be set
|
||||||
|
if (pev->events & (EPOLLIN | EPOLLERR | EPOLLHUP | EPOLLRDHUP)) {
|
||||||
|
flags |= EV_EOF;
|
||||||
|
EV_SET64(&krev, ev.fd, EVFILT_READ, flags, 0, 0, -1, 0, 0);
|
||||||
|
}
|
||||||
|
if (pev->events & EPOLLOUT) {
|
||||||
|
EV_SET64(&kwev, ev.fd, EVFILT_WRITE, flags, 0, 0, -1, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// refresh registered evlist and changelist in a transaction way
|
||||||
|
if (eok_chgs_refresh(eok, oev, &ev, &krev, &kwev)) {
|
||||||
|
e = errno;
|
||||||
|
A(e, "internal logic error");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
eok->changed = 1;
|
||||||
|
eok_wakeup(eok);
|
||||||
|
} while (0);
|
||||||
|
A(0==pthread_mutex_unlock(&eok->lock), "");
|
||||||
|
|
||||||
|
if (e) {
|
||||||
|
errno = e;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct timespec do_timespec_diff(struct timespec *from, struct timespec *to);
|
||||||
|
|
||||||
|
int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout) {
|
||||||
|
taos_block_sigalrm();
|
||||||
|
|
||||||
|
int e = 0;
|
||||||
|
if (!events) {
|
||||||
|
errno = EINVAL;
|
||||||
|
E("epoll_waiting epfd:[%d], maxevents:[%d], timeout:[%d] failed", epfd, maxevents, timeout);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (maxevents<=0) {
|
||||||
|
errno = EINVAL;
|
||||||
|
E("epoll_waiting epfd:[%d], maxevents:[%d], timeout:[%d] failed", epfd, maxevents, timeout);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct timespec abstime = {0};
|
||||||
|
A(TIME_UTC==timespec_get(&abstime, TIME_UTC), "internal logic error");
|
||||||
|
|
||||||
|
if (timeout!=-1) {
|
||||||
|
if (timeout<0) timeout = 0;
|
||||||
|
int64_t t = abstime.tv_nsec + timeout * 1000000;
|
||||||
|
abstime.tv_sec += t / 1000000000;
|
||||||
|
abstime.tv_nsec = t % 1000000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
int r = 0;
|
||||||
|
|
||||||
|
ep_over_kq_t *eok = eoks_find(epfd);
|
||||||
|
if (!eok) {
|
||||||
|
errno = EBADF;
|
||||||
|
E("epoll_waiting epfd:[%d], maxevents:[%d], timeout:[%d] failed", epfd, maxevents, timeout);
|
||||||
|
errno = EBADF;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cnts = 0;
|
||||||
|
A(0==pthread_mutex_lock(&eok->lock), "");
|
||||||
|
do {
|
||||||
|
cnts = 0;
|
||||||
|
A(eok->waiting==0, "internal logic error");
|
||||||
|
struct kevent64_s *eventslist = eok_alloc_eventslist(eok, maxevents);
|
||||||
|
if (!eventslist) {
|
||||||
|
e = ENOMEM;
|
||||||
|
E("epoll_waiting epfd:[%d], maxevents:[%d], timeout:[%d] failed", epfd, maxevents, timeout);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
memset(eventslist, 0, maxevents * sizeof(*eventslist));
|
||||||
|
|
||||||
|
struct timespec now = {0};
|
||||||
|
A(TIME_UTC==timespec_get(&now, TIME_UTC), "internal logic error");
|
||||||
|
struct timespec to = do_timespec_diff(&now, &abstime);
|
||||||
|
struct timespec *pto = &to;
|
||||||
|
if (timeout==-1) {
|
||||||
|
pto = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// taking the changelist
|
||||||
|
struct kevent64_s *kchanges = eok->kchanges;
|
||||||
|
int nchanges = eok->nchanges;
|
||||||
|
int ichanges = eok->ichanges;
|
||||||
|
// let outside world to add changes
|
||||||
|
eok->kchanges = NULL;
|
||||||
|
eok->nchanges = 0;
|
||||||
|
eok->ichanges = 0;
|
||||||
|
|
||||||
|
eok->changed = 0;
|
||||||
|
eok->wakenup = 0;
|
||||||
|
eok->waiting = 1;
|
||||||
|
|
||||||
|
A(0==pthread_mutex_unlock(&eok->lock), "");
|
||||||
|
if (ichanges>0) {
|
||||||
|
D("kevent64 epfd[%d] changing [%d] changes and waiting...", eok->idx, ichanges);
|
||||||
|
}
|
||||||
|
errno = 0;
|
||||||
|
r = kevent64(eok->kq, kchanges, ichanges, eventslist, maxevents, 0, pto);
|
||||||
|
e = errno;
|
||||||
|
if (e) {
|
||||||
|
E("kevent64 epfd[%d] waiting done, with r[%d]", eok->idx, r);
|
||||||
|
}
|
||||||
|
A(0==pthread_mutex_lock(&eok->lock), "");
|
||||||
|
|
||||||
|
eok->waiting = 0;
|
||||||
|
|
||||||
|
if (kchanges) {
|
||||||
|
if (eok->kchanges==NULL) {
|
||||||
|
// reuse
|
||||||
|
A(eok->nchanges==0 && eok->ichanges==0, "internal logic error");
|
||||||
|
eok->kchanges = kchanges;
|
||||||
|
eok->nchanges = nchanges;
|
||||||
|
} else {
|
||||||
|
free(kchanges);
|
||||||
|
kchanges = NULL;
|
||||||
|
}
|
||||||
|
nchanges = 0;
|
||||||
|
ichanges = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r==0) {
|
||||||
|
A(timeout!=-1, "internal logic error");
|
||||||
|
}
|
||||||
|
for (int i=0; i<r; ++i) {
|
||||||
|
struct kevent64_s *kev = eventslist + i;
|
||||||
|
A(kev->udata && eok->evs_head && eok->evs_tail, "internal logic error");
|
||||||
|
eok_event_t *ev = (eok_event_t*)kev->udata;
|
||||||
|
A(kev->ident == ev->fd, "internal logic error");
|
||||||
|
if (kev->flags & EV_ERROR) {
|
||||||
|
D("epfd[%d] error when processing change list for fd[%d], error[%s], kev_flags:[%04x:%s]",
|
||||||
|
epfd, ev->fd, strerror(kev->data), kev->flags, kev_flags_str(kev->flags, 0));
|
||||||
|
}
|
||||||
|
switch (kev->filter) {
|
||||||
|
case EVFILT_READ: {
|
||||||
|
A((ev->epev.events & EPOLLIN), "internal logic errro");
|
||||||
|
if (ev->epev.data.ptr==&eok_dummy) {
|
||||||
|
// it's coming from wakeup socket pair
|
||||||
|
char c = '\0';
|
||||||
|
A(1==recv(kev->ident, &c, 1, 0), "internal logic error");
|
||||||
|
A(0==memcmp(&c, "1", 1), "internal logic error");
|
||||||
|
D("epfd[%d] wokenup", epfd);
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
if (ev->changed==3) {
|
||||||
|
D("epfd[%d] already requested to delete for fd[%d]", epfd, ev->fd);
|
||||||
|
// TODO: write a unit test for this case
|
||||||
|
// EV_DELETE?
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// converting to epoll_event
|
||||||
|
// we shall collect all kevents for the uniq fd into one epoll_evnt
|
||||||
|
// but currently, taos never use EPOLLOUT
|
||||||
|
// just let it this way for the moment
|
||||||
|
struct epoll_event pev = {0};
|
||||||
|
pev.data.ptr = ev->epev.data.ptr;
|
||||||
|
pev.events = EPOLLIN;
|
||||||
|
if (kev->flags & EV_EOF) {
|
||||||
|
// take all these as EOF for the moment
|
||||||
|
pev.events |= (EPOLLHUP | EPOLLERR | EPOLLRDHUP);
|
||||||
|
}
|
||||||
|
// rounded to what user care
|
||||||
|
pev.events = pev.events & ev->epev.events;
|
||||||
|
D("epfd[%d] events found for fd[%d]: [%04x:%s], which was registered: [%04x:%s], kev_flags: [%04x:%s]",
|
||||||
|
epfd,
|
||||||
|
ev->fd, pev.events, events_str(pev.events, 0),
|
||||||
|
ev->epev.events, events_str(ev->epev.events, 1),
|
||||||
|
kev->flags, kev_flags_str(kev->flags, 2));
|
||||||
|
// now we get ev and store it
|
||||||
|
events[cnts++] = pev;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case EVFILT_WRITE: {
|
||||||
|
A(0, "not implemented yet");
|
||||||
|
} break;
|
||||||
|
default: {
|
||||||
|
A(0, "internal logic error");
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (r>=0) {
|
||||||
|
// we can safely rule out delete-requested-events from the regitered evlists
|
||||||
|
// if only changelist are correctly registered
|
||||||
|
eok_event_t *p = eok->evs_head;
|
||||||
|
while (p) {
|
||||||
|
eok_event_t *next = p->next;
|
||||||
|
if (p->changed==3) {
|
||||||
|
D("epfd[%d] removing registered event for fd[%d]: [%04x:%s]", epfd, p->fd, p->epev.events, events_str(p->epev.events, 0));
|
||||||
|
eok_free_ev(eok, p);
|
||||||
|
}
|
||||||
|
p = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cnts==0) {
|
||||||
|
// if no user-cared-events is up
|
||||||
|
// we check to see if time is up
|
||||||
|
if (timeout!=-1) {
|
||||||
|
A(TIME_UTC==timespec_get(&now, TIME_UTC), "internal logic error");
|
||||||
|
to = do_timespec_diff(&now, &abstime);
|
||||||
|
if (to.tv_sec==0 && to.tv_nsec==0) break;
|
||||||
|
}
|
||||||
|
// time is not up yet, continue loop
|
||||||
|
}
|
||||||
|
} while (cnts==0);
|
||||||
|
if (cnts>0) {
|
||||||
|
D("kevent64 epfd[%d] waiting done with [%d] events", epfd, cnts);
|
||||||
|
}
|
||||||
|
A(0==pthread_mutex_unlock(&eok->lock), "");
|
||||||
|
|
||||||
|
if (e) {
|
||||||
|
errno = e;
|
||||||
|
E("epfd[%d] epoll_wait failed", epfd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// tell user how many events are valid
|
||||||
|
return cnts;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct timespec do_timespec_diff(struct timespec *from, struct timespec *to) {
|
||||||
|
struct timespec delta;
|
||||||
|
delta.tv_sec = to->tv_sec - from->tv_sec;
|
||||||
|
delta.tv_nsec = to->tv_nsec - from->tv_nsec;
|
||||||
|
// norm and round up
|
||||||
|
while (delta.tv_nsec<0) {
|
||||||
|
delta.tv_sec -= 1;
|
||||||
|
delta.tv_nsec += 1000000000;
|
||||||
|
}
|
||||||
|
if (delta.tv_sec < 0) {
|
||||||
|
delta.tv_sec = 0;
|
||||||
|
delta.tv_nsec = 0;
|
||||||
|
}
|
||||||
|
return delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
int epoll_close(int epfd) {
|
||||||
|
D("epoll_closing epfd: [%d]", epfd);
|
||||||
|
ep_over_kq_t *eok = eoks_find(epfd);
|
||||||
|
if (!eok) {
|
||||||
|
errno = EBADF;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
A(0==pthread_mutex_lock(&eok->lock), "");
|
||||||
|
do {
|
||||||
|
// panic if it would be double-closed
|
||||||
|
A(eok->stopping==0, "internal logic error");
|
||||||
|
eok->stopping = 1;
|
||||||
|
// panic if epoll_wait is pending
|
||||||
|
A(eok->waiting==0, "internal logic error");
|
||||||
|
|
||||||
|
if (eok->kq!=-1) {
|
||||||
|
close(eok->kq);
|
||||||
|
eok->kq = -1;
|
||||||
|
}
|
||||||
|
} while (0);
|
||||||
|
A(0==pthread_mutex_unlock(&eok->lock), "");
|
||||||
|
eoks_free(eok);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct kevent64_s* eok_alloc_eventslist(ep_over_kq_t *eok, int maxevents) {
|
||||||
|
if (maxevents<=eok->nevslist) return eok->kevslist;
|
||||||
|
struct kevent64_s *p = (struct kevent64_s*)realloc(eok->kevslist, sizeof(*p)*maxevents);
|
||||||
|
if (!p) return NULL;
|
||||||
|
eok->kevslist = p;
|
||||||
|
eok->nevslist = maxevents;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
static eok_event_t* eok_find_ev(ep_over_kq_t *eok, int fd) {
|
||||||
|
eok_event_t *p = eok->evs_head;
|
||||||
|
while (p) {
|
||||||
|
if (p->fd == fd) return p;
|
||||||
|
p = p->next;
|
||||||
|
}
|
||||||
|
errno = ENOENT;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static eok_event_t* eok_calloc_ev(ep_over_kq_t *eok) {
|
||||||
|
eok_event_t *p = NULL;
|
||||||
|
if (eok->evs_free) {
|
||||||
|
p = eok->evs_free;
|
||||||
|
eok->evs_free = p->next;
|
||||||
|
p->next = NULL;
|
||||||
|
A(p->prev==NULL, "internal logic error");
|
||||||
|
} else {
|
||||||
|
p = (eok_event_t*)calloc(1, sizeof(*p));
|
||||||
|
if (!p) return NULL;
|
||||||
|
A(p->next==NULL, "internal logic error");
|
||||||
|
A(p->prev==NULL, "internal logic error");
|
||||||
|
}
|
||||||
|
// dirty link
|
||||||
|
p->prev = eok->evs_tail;
|
||||||
|
if (eok->evs_tail) eok->evs_tail->next = p;
|
||||||
|
else eok->evs_head = p;
|
||||||
|
eok->evs_tail = p;
|
||||||
|
|
||||||
|
eok->evs_count += 1;
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void eok_free_ev(ep_over_kq_t *eok, eok_event_t *ev) {
|
||||||
|
if (ev->prev) ev->prev->next = ev->next;
|
||||||
|
else eok->evs_head = ev->next;
|
||||||
|
if (ev->next) ev->next->prev = ev->prev;
|
||||||
|
else eok->evs_tail = ev->prev;
|
||||||
|
ev->prev = NULL;
|
||||||
|
ev->next = eok->evs_free;
|
||||||
|
eok->evs_free = ev;
|
||||||
|
|
||||||
|
eok->evs_count -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void eok_wakeup(ep_over_kq_t *eok) {
|
||||||
|
if (!eok->waiting) return;
|
||||||
|
if (eok->wakenup) return;
|
||||||
|
eok->wakenup = 1;
|
||||||
|
A(1==send(eok->sv[1], "1", 1, 0), "");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int eok_chgs_refresh(ep_over_kq_t *eok, eok_event_t *oev, eok_event_t *ev, struct kevent64_s *krev, struct kevent64_s *kwev) {
|
||||||
|
if (!oev) oev = eok_calloc_ev(eok);
|
||||||
|
if (!oev) return -1;
|
||||||
|
int n = 0;
|
||||||
|
if (krev->ident==ev->fd) ++n;
|
||||||
|
if (kwev->ident==ev->fd) ++n;
|
||||||
|
A(n, "internal logic error");
|
||||||
|
if (eok->ichanges+n>eok->nchanges) {
|
||||||
|
struct kevent64_s *p = (struct kevent64_s*)realloc(eok->kchanges, sizeof(*p) * (eok->nchanges + 10));
|
||||||
|
if (!p) {
|
||||||
|
if (ev->changed==1) {
|
||||||
|
// roll back
|
||||||
|
A(oev, "internal logic error");
|
||||||
|
eok_free_ev(eok, oev);
|
||||||
|
}
|
||||||
|
errno = ENOMEM;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
eok->kchanges = p;
|
||||||
|
eok->nchanges += 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy to registered event slot
|
||||||
|
oev->fd = ev->fd;
|
||||||
|
if (ev->changed!=3) {
|
||||||
|
// if add/mod, copy epoll_event
|
||||||
|
oev->epev = ev->epev;
|
||||||
|
}
|
||||||
|
oev->changed = ev->changed;
|
||||||
|
|
||||||
|
// copy to changes list
|
||||||
|
n = 0;
|
||||||
|
if (krev->ident==ev->fd) {
|
||||||
|
krev->udata = (uint64_t)oev;
|
||||||
|
eok->kchanges[eok->ichanges++] = *krev;
|
||||||
|
++n;
|
||||||
|
}
|
||||||
|
if (kwev->ident==ev->fd) {
|
||||||
|
kwev->udata = (uint64_t)oev;
|
||||||
|
eok->kchanges[eok->ichanges++] = *kwev;
|
||||||
|
++n;
|
||||||
|
}
|
||||||
|
D("epfd[%d]: add #changes[%d] for fd[%d], and now #changes/registers [%d/%d]", eok->idx, n, ev->fd, eok->ichanges, eok->evs_count);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ep_over_kq_t* eoks_alloc(void) {
|
||||||
|
ep_over_kq_t *eok = NULL;
|
||||||
|
|
||||||
|
A(0==pthread_mutex_lock(&eoks.lock), "");
|
||||||
|
do {
|
||||||
|
if (eoks.eoks_free_list) {
|
||||||
|
eok = eoks.eoks_free_list;
|
||||||
|
eoks.eoks_free_list = eok->next;
|
||||||
|
A(eoks.eoks, "internal logic error");
|
||||||
|
A(eok->idx>=0 && eok->idx<eoks.neoks, "internal logic error");
|
||||||
|
A(*(eoks.eoks + eok->idx)==NULL, "internal logic error");
|
||||||
|
*(eoks.eoks + eok->idx) = eok;
|
||||||
|
eok->next = NULL;
|
||||||
|
eok->stopping = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
eok = (ep_over_kq_t*)calloc(1, sizeof(*eok));
|
||||||
|
if (!eok) break;
|
||||||
|
eok->idx = -1;
|
||||||
|
ep_over_kq_t **ar = (ep_over_kq_t**)realloc(eoks.eoks, sizeof(**ar) * (eoks.neoks+1));
|
||||||
|
if (!ar) break;
|
||||||
|
eoks.eoks = ar;
|
||||||
|
*(eoks.eoks + eoks.neoks) = eok;
|
||||||
|
eok->idx = eoks.neoks;
|
||||||
|
eok->kq = -1;
|
||||||
|
eok->sv[0] = -1;
|
||||||
|
eok->sv[1] = -1;
|
||||||
|
eoks.neoks += 1;
|
||||||
|
} while (0);
|
||||||
|
A(0==pthread_mutex_unlock(&eoks.lock), "");
|
||||||
|
|
||||||
|
if (!eok) {
|
||||||
|
errno = ENOMEM;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (eok->idx==-1) {
|
||||||
|
free(eok);
|
||||||
|
errno = ENOMEM;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (eok->lock_valid) {
|
||||||
|
return eok;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0==pthread_mutex_init(&eok->lock, NULL)) {
|
||||||
|
eok->lock_valid = 1;
|
||||||
|
return eok;
|
||||||
|
}
|
||||||
|
|
||||||
|
eoks_free(eok);
|
||||||
|
errno = ENOMEM;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void eoks_free(ep_over_kq_t *eok) {
|
||||||
|
A(0==pthread_mutex_lock(&eoks.lock), "");
|
||||||
|
do {
|
||||||
|
A(eok->idx>=0 && eok->idx<eoks.neoks, "internal logic error");
|
||||||
|
A(eok->next==NULL, "internal logic error");
|
||||||
|
|
||||||
|
// leave eok->kchanges as is
|
||||||
|
A(eok->ichanges==0, "internal logic error");
|
||||||
|
|
||||||
|
A(eok->waiting==0, "internal logic error");
|
||||||
|
eok_event_t *ev = eok->evs_head;
|
||||||
|
int sv_closed = 0;
|
||||||
|
while (ev) {
|
||||||
|
eok_event_t *next = ev->next;
|
||||||
|
if (ev->fd==eok->sv[0]) {
|
||||||
|
// fd is critical system resource
|
||||||
|
A(sv_closed==0, "internal logic error");
|
||||||
|
close(eok->sv[0]);
|
||||||
|
eok->sv[0] = -1;
|
||||||
|
close(eok->sv[1]);
|
||||||
|
eok->sv[1] = -1;
|
||||||
|
eok_free_ev(eok, ev);
|
||||||
|
} else {
|
||||||
|
// user forget calling epoll_ctl(EPOLL_CTL_DEL) before calling epoll_close/close?
|
||||||
|
// calling close(ev->fd) here smells really bad
|
||||||
|
#ifndef BALANCE_CHECK_WHEN_CLOSE
|
||||||
|
// we just let it be and reclaim ev
|
||||||
|
eok_free_ev(eok, ev);
|
||||||
|
#else
|
||||||
|
// panic otherwise, if BALANCE_CHECK_WHEN_CLOSE is defined
|
||||||
|
A(eok->evs_head==NULL && eok->evs_tail==NULL && eok->evs_count==0,
|
||||||
|
"epfd[%d] fd[%d]: internal logic error: have you epoll_ctl(EPOLL_CTL_DEL) everything before calling epoll_close?",
|
||||||
|
eok->idx, ev->fd);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
ev = next;
|
||||||
|
}
|
||||||
|
// if (eok->evs_count==1) {
|
||||||
|
// A(eok->evs_head && eok->evs_tail && eok->evs_head==eok->evs_tail, "internal logic error");
|
||||||
|
// A(eok->evs_head->fd==eok->sv[0] && eok->sv[0]!=-1 && eok->sv[1]!=-1, "internal logic error");
|
||||||
|
// // fd is critical system resource
|
||||||
|
// close(eok->sv[0]);
|
||||||
|
// eok->sv[0] = -1;
|
||||||
|
// close(eok->sv[1]);
|
||||||
|
// eok->sv[1] = -1;
|
||||||
|
// eok_free_ev(eok, eok->evs_head);
|
||||||
|
// }
|
||||||
|
A(eok->evs_head==NULL && eok->evs_tail==NULL && eok->evs_count==0,
|
||||||
|
"internal logic error: have you epoll_ctl(EPOLL_CTL_DEL) everything before calling epoll_close?");
|
||||||
|
A(eok->sv[0]==-1 && eok->sv[1]==-1, "internal logic error");
|
||||||
|
if (eok->kq!=-1) {
|
||||||
|
close(eok->kq);
|
||||||
|
eok->kq = -1;
|
||||||
|
}
|
||||||
|
eok->next = eoks.eoks_free_list;
|
||||||
|
eoks.eoks_free_list = eok;
|
||||||
|
*(eoks.eoks + eok->idx) = NULL;
|
||||||
|
} while (0);
|
||||||
|
A(0==pthread_mutex_unlock(&eoks.lock), "");
|
||||||
|
}
|
||||||
|
|
||||||
|
static ep_over_kq_t* eoks_find(int epfd) {
|
||||||
|
ep_over_kq_t *eok = NULL;
|
||||||
|
A(0==pthread_mutex_lock(&eoks.lock), "");
|
||||||
|
do {
|
||||||
|
if (epfd<0 || epfd>=eoks.neoks) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
A(eoks.eoks, "internal logic error");
|
||||||
|
eok = *(eoks.eoks + epfd);
|
||||||
|
A(eok->next==NULL, "internal logic error");
|
||||||
|
A(eok->lock_valid, "internal logic error");
|
||||||
|
} while (0);
|
||||||
|
A(0==pthread_mutex_unlock(&eoks.lock), "");
|
||||||
|
return eok;
|
||||||
|
}
|
||||||
|
|
|
@ -13,3 +13,4 @@ TARGET_LINK_LIBRARIES(osdetail os)
|
||||||
IF (TD_ARM_32 OR TD_LINUX_32)
|
IF (TD_ARM_32 OR TD_LINUX_32)
|
||||||
TARGET_LINK_LIBRARIES(osdetail atomic)
|
TARGET_LINK_LIBRARIES(osdetail atomic)
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
|
|
|
@ -116,6 +116,9 @@ void taosUninitTimer() {
|
||||||
pthread_sigmask(SIG_BLOCK, &set, NULL);
|
pthread_sigmask(SIG_BLOCK, &set, NULL);
|
||||||
*/
|
*/
|
||||||
void taosMsleep(int mseconds) {
|
void taosMsleep(int mseconds) {
|
||||||
|
#ifdef __APPLE__
|
||||||
|
taos_block_sigalrm();
|
||||||
|
#endif // __APPLE__
|
||||||
#if 1
|
#if 1
|
||||||
usleep(mseconds * 1000);
|
usleep(mseconds * 1000);
|
||||||
#else
|
#else
|
||||||
|
@ -136,6 +139,7 @@ void taosMsleep(int mseconds) {
|
||||||
|
|
||||||
/* pthread_sigmask(SIG_UNBLOCK, &set, NULL); */
|
/* pthread_sigmask(SIG_UNBLOCK, &set, NULL); */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -9,7 +9,6 @@ INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/query/inc)
|
||||||
INCLUDE_DIRECTORIES(inc)
|
INCLUDE_DIRECTORIES(inc)
|
||||||
AUX_SOURCE_DIRECTORY(src SRC)
|
AUX_SOURCE_DIRECTORY(src SRC)
|
||||||
|
|
||||||
IF (TD_LINUX OR TD_WINDOWS)
|
|
||||||
ADD_LIBRARY(http ${SRC})
|
ADD_LIBRARY(http ${SRC})
|
||||||
TARGET_LINK_LIBRARIES(http z)
|
TARGET_LINK_LIBRARIES(http z)
|
||||||
|
|
||||||
|
@ -22,4 +21,3 @@ IF (TD_LINUX OR TD_WINDOWS)
|
||||||
IF (TD_ADMIN)
|
IF (TD_ADMIN)
|
||||||
TARGET_LINK_LIBRARIES(http admin)
|
TARGET_LINK_LIBRARIES(http admin)
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
ENDIF ()
|
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
#define TDENGINE_HTTP_UTIL_H
|
#define TDENGINE_HTTP_UTIL_H
|
||||||
|
|
||||||
bool httpCheckUsedbSql(char *sql);
|
bool httpCheckUsedbSql(char *sql);
|
||||||
void httpTimeToString(time_t t, char *buf, int32_t buflen);
|
void httpTimeToString(int32_t t, char *buf, int32_t buflen);
|
||||||
|
|
||||||
bool httpUrlMatch(HttpContext *pContext, int32_t pos, char *cmp);
|
bool httpUrlMatch(HttpContext *pContext, int32_t pos, char *cmp);
|
||||||
bool httpParseRequest(HttpContext *pContext);
|
bool httpParseRequest(HttpContext *pContext);
|
||||||
|
|
|
@ -535,7 +535,7 @@ char *httpDecodeUrl(const char *enc) {
|
||||||
dec = str.str;
|
dec = str.str;
|
||||||
str.str = NULL;
|
str.str = NULL;
|
||||||
}
|
}
|
||||||
httpCleanupString(&str);
|
//httpCleanupString(&str);
|
||||||
return dec;
|
return dec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -646,7 +646,7 @@ static int32_t httpParserOnTarget(HttpParser *parser, HTTP_PARSER_STATE state, c
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
parser->target = strdup(parser->str.str);
|
parser->target = httpDecodeUrl(parser->str.str);
|
||||||
if (!parser->target) {
|
if (!parser->target) {
|
||||||
httpError("context:%p, fd:%d, parser state:%d, char:[%c]%02x, oom", pContext, pContext->fd, state, c, c);
|
httpError("context:%p, fd:%d, parser state:%d, char:[%c]%02x, oom", pContext, pContext->fd, state, c, c);
|
||||||
ok = -1;
|
ok = -1;
|
||||||
|
@ -715,6 +715,10 @@ static int32_t httpParserOnVersion(HttpParser *parser, HTTP_PARSER_STATE state,
|
||||||
|
|
||||||
if (parser->method) {
|
if (parser->method) {
|
||||||
ok = httpOnRequestLine(parser, parser->method, parser->target, parser->version);
|
ok = httpOnRequestLine(parser, parser->method, parser->target, parser->version);
|
||||||
|
if (parser->target) {
|
||||||
|
free(parser->target);
|
||||||
|
parser->target = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
httpClearString(&parser->str);
|
httpClearString(&parser->str);
|
||||||
|
|
|
@ -27,11 +27,36 @@
|
||||||
|
|
||||||
static bool httpReadData(HttpContext *pContext);
|
static bool httpReadData(HttpContext *pContext);
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
static int sv_dummy = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
static void httpStopThread(HttpThread *pThread) {
|
static void httpStopThread(HttpThread *pThread) {
|
||||||
pThread->stop = true;
|
pThread->stop = true;
|
||||||
|
|
||||||
// signal the thread to stop, try graceful method first,
|
// signal the thread to stop, try graceful method first,
|
||||||
// and use pthread_cancel when failed
|
// and use pthread_cancel when failed
|
||||||
|
#ifdef __APPLE__
|
||||||
|
int sv[2];
|
||||||
|
sv[0] = sv[1] = -1;
|
||||||
|
int r = socketpair(PF_LOCAL, SOCK_STREAM, 0, sv);
|
||||||
|
do {
|
||||||
|
if (r) break;
|
||||||
|
struct epoll_event ev = {0};
|
||||||
|
ev.events = EPOLLIN;
|
||||||
|
ev.data.ptr = &sv_dummy;
|
||||||
|
pThread->stop = true;
|
||||||
|
r = epoll_ctl(pThread->pollFd, EPOLL_CTL_ADD, sv[0], &ev);
|
||||||
|
if (r) break;
|
||||||
|
if (1 != send(sv[1], "1", 1, 0)) {
|
||||||
|
r = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (0);
|
||||||
|
if (r) {
|
||||||
|
pthread_cancel(pThread->thread);
|
||||||
|
}
|
||||||
|
#else
|
||||||
struct epoll_event event = {.events = EPOLLIN};
|
struct epoll_event event = {.events = EPOLLIN};
|
||||||
eventfd_t fd = eventfd(1, 0);
|
eventfd_t fd = eventfd(1, 0);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
|
@ -44,11 +69,24 @@ static void httpStopThread(HttpThread *pThread) {
|
||||||
pThread->label, strerror(errno));
|
pThread->label, strerror(errno));
|
||||||
pthread_cancel(pThread->thread);
|
pthread_cancel(pThread->thread);
|
||||||
}
|
}
|
||||||
|
#endif // __APPLE__
|
||||||
|
|
||||||
pthread_join(pThread->thread, NULL);
|
pthread_join(pThread->thread, NULL);
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
if (sv[0] != -1) {
|
||||||
|
close(sv[0]);
|
||||||
|
sv[0] = -1;
|
||||||
|
}
|
||||||
|
if (sv[1] != -1) {
|
||||||
|
close(sv[1]);
|
||||||
|
sv[1] = -1;
|
||||||
|
}
|
||||||
|
#else // __APPLE__
|
||||||
if (fd != -1) {
|
if (fd != -1) {
|
||||||
taosCloseSocket(fd);
|
taosCloseSocket(fd);
|
||||||
}
|
}
|
||||||
|
#endif // __APPLE__
|
||||||
|
|
||||||
EpollClose(pThread->pollFd);
|
EpollClose(pThread->pollFd);
|
||||||
pthread_mutex_destroy(&(pThread->threadMutex));
|
pthread_mutex_destroy(&(pThread->threadMutex));
|
||||||
|
@ -91,6 +129,15 @@ static void httpProcessHttpData(void *param) {
|
||||||
if (fdNum <= 0) continue;
|
if (fdNum <= 0) continue;
|
||||||
|
|
||||||
for (int32_t i = 0; i < fdNum; ++i) {
|
for (int32_t i = 0; i < fdNum; ++i) {
|
||||||
|
#ifdef __APPLE__
|
||||||
|
if (events[i].data.ptr == &sv_dummy) {
|
||||||
|
// no need to drain the recv buffer of sv[0]
|
||||||
|
// since there's only one time to send at most 1 byte to sv[0]
|
||||||
|
// btw, pThread->stop shall be already set, thus never reached here
|
||||||
|
httpDebug("if you see this line, there's internal logic error");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#endif // __APPLE__
|
||||||
pContext = httpGetContext(events[i].data.ptr);
|
pContext = httpGetContext(events[i].data.ptr);
|
||||||
if (pContext == NULL) {
|
if (pContext == NULL) {
|
||||||
httpError("context:%p, is already released, close connect", events[i].data.ptr);
|
httpError("context:%p, is already released, close connect", events[i].data.ptr);
|
||||||
|
|
|
@ -29,7 +29,7 @@ bool httpCheckUsedbSql(char *sql) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void httpTimeToString(time_t t, char *buf, int32_t buflen) {
|
void httpTimeToString(int32_t t, char *buf, int32_t buflen) {
|
||||||
memset(buf, 0, (size_t)buflen);
|
memset(buf, 0, (size_t)buflen);
|
||||||
char ts[32] = {0};
|
char ts[32] = {0};
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ void httpTimeToString(time_t t, char *buf, int32_t buflen) {
|
||||||
time_t tt = t / 1000;
|
time_t tt = t / 1000;
|
||||||
ptm = localtime(&tt);
|
ptm = localtime(&tt);
|
||||||
strftime(ts, 31, "%Y-%m-%d %H:%M:%S", ptm);
|
strftime(ts, 31, "%Y-%m-%d %H:%M:%S", ptm);
|
||||||
sprintf(buf, "%s.%03" PRId64, ts, t % 1000);
|
sprintf(buf, "%s.%03d", ts, t % 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t httpAddToSqlCmdBuffer(HttpContext *pContext, const char *const format, ...) {
|
int32_t httpAddToSqlCmdBuffer(HttpContext *pContext, const char *const format, ...) {
|
||||||
|
|
|
@ -6,7 +6,6 @@ INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/client/inc)
|
||||||
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/query/inc)
|
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/query/inc)
|
||||||
AUX_SOURCE_DIRECTORY(./src SRC)
|
AUX_SOURCE_DIRECTORY(./src SRC)
|
||||||
|
|
||||||
IF (TD_LINUX OR TD_WINDOWS)
|
|
||||||
ADD_LIBRARY(monitor ${SRC})
|
ADD_LIBRARY(monitor ${SRC})
|
||||||
|
|
||||||
IF (TD_SOMODE_STATIC)
|
IF (TD_SOMODE_STATIC)
|
||||||
|
@ -14,4 +13,3 @@ IF (TD_LINUX OR TD_WINDOWS)
|
||||||
ELSE ()
|
ELSE ()
|
||||||
TARGET_LINK_LIBRARIES(monitor taos)
|
TARGET_LINK_LIBRARIES(monitor taos)
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
ENDIF ()
|
|
||||||
|
|
|
@ -18,3 +18,15 @@ IF (TD_LINUX)
|
||||||
TARGET_LINK_LIBRARIES(mqtt taos)
|
TARGET_LINK_LIBRARIES(mqtt taos)
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
|
IF (TD_DARWIN)
|
||||||
|
ADD_LIBRARY(mqtt ${SRC})
|
||||||
|
TARGET_LINK_LIBRARIES(mqtt cJson mqttc)
|
||||||
|
|
||||||
|
IF (TD_SOMODE_STATIC)
|
||||||
|
TARGET_LINK_LIBRARIES(mqtt taos_static)
|
||||||
|
ELSE ()
|
||||||
|
TARGET_LINK_LIBRARIES(mqtt taos)
|
||||||
|
ENDIF ()
|
||||||
|
ENDIF ()
|
||||||
|
|
||||||
|
|
|
@ -14,3 +14,8 @@ IF (TD_LINUX)
|
||||||
TARGET_LINK_LIBRARIES(query m rt)
|
TARGET_LINK_LIBRARIES(query m rt)
|
||||||
ADD_SUBDIRECTORY(tests)
|
ADD_SUBDIRECTORY(tests)
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
|
IF (TD_DARWIN)
|
||||||
|
TARGET_LINK_LIBRARIES(query m)
|
||||||
|
ADD_SUBDIRECTORY(tests)
|
||||||
|
ENDIF ()
|
||||||
|
|
|
@ -1398,13 +1398,13 @@ static int32_t doTSJoinFilter(SQueryRuntimeEnv *pRuntimeEnv, int32_t offset) {
|
||||||
if (key < elem.ts) {
|
if (key < elem.ts) {
|
||||||
return TS_JOIN_TS_NOT_EQUALS;
|
return TS_JOIN_TS_NOT_EQUALS;
|
||||||
} else if (key > elem.ts) {
|
} else if (key > elem.ts) {
|
||||||
assert(false);
|
longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_INCONSISTAN);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (key > elem.ts) {
|
if (key > elem.ts) {
|
||||||
return TS_JOIN_TS_NOT_EQUALS;
|
return TS_JOIN_TS_NOT_EQUALS;
|
||||||
} else if (key < elem.ts) {
|
} else if (key < elem.ts) {
|
||||||
assert(false);
|
longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_INCONSISTAN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3828,6 +3828,11 @@ void scanOneTableDataBlocks(SQueryRuntimeEnv *pRuntimeEnv, TSKEY start) {
|
||||||
setQueryStatus(pQuery, QUERY_NOT_COMPLETED);
|
setQueryStatus(pQuery, QUERY_NOT_COMPLETED);
|
||||||
pRuntimeEnv->scanFlag = REPEAT_SCAN;
|
pRuntimeEnv->scanFlag = REPEAT_SCAN;
|
||||||
|
|
||||||
|
if (pRuntimeEnv->pTsBuf) {
|
||||||
|
bool ret = tsBufNextPos(pRuntimeEnv->pTsBuf);
|
||||||
|
assert(ret);
|
||||||
|
}
|
||||||
|
|
||||||
qDebug("QInfo:%p start to repeat scan data blocks due to query func required, qrange:%"PRId64"-%"PRId64, pQInfo,
|
qDebug("QInfo:%p start to repeat scan data blocks due to query func required, qrange:%"PRId64"-%"PRId64, pQInfo,
|
||||||
cond.twindow.skey, cond.twindow.ekey);
|
cond.twindow.skey, cond.twindow.ekey);
|
||||||
}
|
}
|
||||||
|
@ -6424,6 +6429,11 @@ static int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SArray **pTableIdList,
|
||||||
pMsg += pQueryMsg->tbnameCondLen;
|
pMsg += pQueryMsg->tbnameCondLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//skip ts buf
|
||||||
|
if ((pQueryMsg->tsOffset + pQueryMsg->tsLen) > 0) {
|
||||||
|
pMsg = (char *)pQueryMsg + pQueryMsg->tsOffset + pQueryMsg->tsLen;
|
||||||
|
}
|
||||||
|
|
||||||
*sql = strndup(pMsg, pQueryMsg->sqlstrLen);
|
*sql = strndup(pMsg, pQueryMsg->sqlstrLen);
|
||||||
|
|
||||||
if (!validateQuerySourceCols(pQueryMsg, *pExpr, *tagCols)) {
|
if (!validateQuerySourceCols(pQueryMsg, *pExpr, *tagCols)) {
|
||||||
|
|
|
@ -315,6 +315,7 @@ void *taosInitTcpClient(uint32_t ip, uint16_t port, char *label, int num, void *
|
||||||
pthread_attr_destroy(&thattr);
|
pthread_attr_destroy(&thattr);
|
||||||
if (code != 0) {
|
if (code != 0) {
|
||||||
EpollClose(pThreadObj->pollFd);
|
EpollClose(pThreadObj->pollFd);
|
||||||
|
pThreadObj->pollFd = -1;
|
||||||
free(pThreadObj);
|
free(pThreadObj);
|
||||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||||
tError("%s failed to create TCP read data thread(%s)", label, strerror(errno));
|
tError("%s failed to create TCP read data thread(%s)", label, strerror(errno));
|
||||||
|
@ -478,6 +479,9 @@ static void *taosProcessTcpData(void *param) {
|
||||||
struct epoll_event events[maxEvents];
|
struct epoll_event events[maxEvents];
|
||||||
SRecvInfo recvInfo;
|
SRecvInfo recvInfo;
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
taos_block_sigalrm();
|
||||||
|
#endif // __APPLE__
|
||||||
while (1) {
|
while (1) {
|
||||||
int fdNum = epoll_wait(pThreadObj->pollFd, events, maxEvents, TAOS_EPOLL_WAIT_TIME);
|
int fdNum = epoll_wait(pThreadObj->pollFd, events, maxEvents, TAOS_EPOLL_WAIT_TIME);
|
||||||
if (pThreadObj->stop) {
|
if (pThreadObj->stop) {
|
||||||
|
@ -519,7 +523,10 @@ static void *taosProcessTcpData(void *param) {
|
||||||
if (pThreadObj->stop) break;
|
if (pThreadObj->stop) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pThreadObj->pollFd >=0) EpollClose(pThreadObj->pollFd);
|
if (pThreadObj->pollFd >=0) {
|
||||||
|
EpollClose(pThreadObj->pollFd);
|
||||||
|
pThreadObj->pollFd = -1;
|
||||||
|
}
|
||||||
|
|
||||||
while (pThreadObj->pHead) {
|
while (pThreadObj->pHead) {
|
||||||
SFdObj *pFdObj = pThreadObj->pHead;
|
SFdObj *pFdObj = pThreadObj->pHead;
|
||||||
|
|
|
@ -16,3 +16,17 @@ IF (TD_LINUX)
|
||||||
ADD_EXECUTABLE(rserver ${SERVER_SRC})
|
ADD_EXECUTABLE(rserver ${SERVER_SRC})
|
||||||
TARGET_LINK_LIBRARIES(rserver trpc)
|
TARGET_LINK_LIBRARIES(rserver trpc)
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
|
IF (TD_DARWIN)
|
||||||
|
LIST(APPEND CLIENT_SRC ./rclient.c)
|
||||||
|
ADD_EXECUTABLE(rclient ${CLIENT_SRC})
|
||||||
|
TARGET_LINK_LIBRARIES(rclient trpc)
|
||||||
|
|
||||||
|
LIST(APPEND SCLIENT_SRC ./rsclient.c)
|
||||||
|
ADD_EXECUTABLE(rsclient ${SCLIENT_SRC})
|
||||||
|
TARGET_LINK_LIBRARIES(rsclient trpc)
|
||||||
|
|
||||||
|
LIST(APPEND SERVER_SRC ./rserver.c)
|
||||||
|
ADD_EXECUTABLE(rserver ${SERVER_SRC})
|
||||||
|
TARGET_LINK_LIBRARIES(rserver trpc)
|
||||||
|
ENDIF ()
|
||||||
|
|
|
@ -4,7 +4,6 @@ PROJECT(TDengine)
|
||||||
INCLUDE_DIRECTORIES(inc)
|
INCLUDE_DIRECTORIES(inc)
|
||||||
AUX_SOURCE_DIRECTORY(src SRC)
|
AUX_SOURCE_DIRECTORY(src SRC)
|
||||||
|
|
||||||
IF (TD_LINUX OR TD_WINDOWS)
|
|
||||||
LIST(REMOVE_ITEM SRC src/syncArbitrator.c)
|
LIST(REMOVE_ITEM SRC src/syncArbitrator.c)
|
||||||
ADD_LIBRARY(sync ${SRC})
|
ADD_LIBRARY(sync ${SRC})
|
||||||
TARGET_LINK_LIBRARIES(sync tutil pthread common)
|
TARGET_LINK_LIBRARIES(sync tutil pthread common)
|
||||||
|
@ -15,4 +14,3 @@ IF (TD_LINUX OR TD_WINDOWS)
|
||||||
TARGET_LINK_LIBRARIES(tarbitrator sync common osdetail tutil)
|
TARGET_LINK_LIBRARIES(tarbitrator sync common osdetail tutil)
|
||||||
|
|
||||||
#ADD_SUBDIRECTORY(test)
|
#ADD_SUBDIRECTORY(test)
|
||||||
ENDIF ()
|
|
||||||
|
|
|
@ -303,7 +303,7 @@ static SThreadObj *syncGetTcpThread(SPoolObj *pPool) {
|
||||||
pthread_attr_destroy(&thattr);
|
pthread_attr_destroy(&thattr);
|
||||||
|
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
taosCloseSocket(pThread->pollFd);
|
EpollClose(pThread->pollFd);
|
||||||
tfree(pThread);
|
tfree(pThread);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,4 +13,3 @@ IF (TD_LINUX)
|
||||||
TARGET_LINK_LIBRARIES(syncServer sync trpc common)
|
TARGET_LINK_LIBRARIES(syncServer sync trpc common)
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -233,7 +233,7 @@ typedef struct {
|
||||||
SMemTable* mem;
|
SMemTable* mem;
|
||||||
SMemTable* imem;
|
SMemTable* imem;
|
||||||
STsdbFileH* tsdbFileH;
|
STsdbFileH* tsdbFileH;
|
||||||
sem_t readyToCommit;
|
tsem_t readyToCommit;
|
||||||
pthread_mutex_t mutex;
|
pthread_mutex_t mutex;
|
||||||
bool repoLocked;
|
bool repoLocked;
|
||||||
int32_t code; // Commit code
|
int32_t code; // Commit code
|
||||||
|
|
|
@ -166,7 +166,7 @@ static void tsdbEndCommit(STsdbRepo *pRepo, int eno) {
|
||||||
pRepo->imem = NULL;
|
pRepo->imem = NULL;
|
||||||
tsdbUnlockRepo(pRepo);
|
tsdbUnlockRepo(pRepo);
|
||||||
tsdbUnRefMemTable(pRepo, pIMem);
|
tsdbUnRefMemTable(pRepo, pIMem);
|
||||||
sem_post(&(pRepo->readyToCommit));
|
tsem_post(&(pRepo->readyToCommit));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tsdbHasDataToCommit(SCommitIter *iters, int nIters, TSKEY minKey, TSKEY maxKey) {
|
static int tsdbHasDataToCommit(SCommitIter *iters, int nIters, TSKEY minKey, TSKEY maxKey) {
|
||||||
|
|
|
@ -146,7 +146,7 @@ int tsdbCloseRepo(TSDB_REPO_T *repo, int toCommit) {
|
||||||
|
|
||||||
if (toCommit) {
|
if (toCommit) {
|
||||||
tsdbAsyncCommit(pRepo);
|
tsdbAsyncCommit(pRepo);
|
||||||
sem_wait(&(pRepo->readyToCommit));
|
tsem_wait(&(pRepo->readyToCommit));
|
||||||
terrno = pRepo->code;
|
terrno = pRepo->code;
|
||||||
}
|
}
|
||||||
tsdbUnRefMemTable(pRepo, pRepo->mem);
|
tsdbUnRefMemTable(pRepo, pRepo->mem);
|
||||||
|
@ -643,8 +643,9 @@ static STsdbRepo *tsdbNewRepo(char *rootDir, STsdbAppH *pAppH, STsdbCfg *pCfg) {
|
||||||
goto _err;
|
goto _err;
|
||||||
}
|
}
|
||||||
|
|
||||||
code = sem_init(&(pRepo->readyToCommit), 0, 1);
|
code = tsem_init(&(pRepo->readyToCommit), 0, 1);
|
||||||
if (code != 0) {
|
if (code != 0) {
|
||||||
|
code = errno;
|
||||||
terrno = TAOS_SYSTEM_ERROR(code);
|
terrno = TAOS_SYSTEM_ERROR(code);
|
||||||
goto _err;
|
goto _err;
|
||||||
}
|
}
|
||||||
|
@ -693,7 +694,7 @@ static void tsdbFreeRepo(STsdbRepo *pRepo) {
|
||||||
// tsdbFreeMemTable(pRepo->mem);
|
// tsdbFreeMemTable(pRepo->mem);
|
||||||
// tsdbFreeMemTable(pRepo->imem);
|
// tsdbFreeMemTable(pRepo->imem);
|
||||||
tfree(pRepo->rootDir);
|
tfree(pRepo->rootDir);
|
||||||
sem_destroy(&(pRepo->readyToCommit));
|
tsem_destroy(&(pRepo->readyToCommit));
|
||||||
pthread_mutex_destroy(&pRepo->mutex);
|
pthread_mutex_destroy(&pRepo->mutex);
|
||||||
free(pRepo);
|
free(pRepo);
|
||||||
}
|
}
|
||||||
|
|
|
@ -207,7 +207,7 @@ void *tsdbAllocBytes(STsdbRepo *pRepo, int bytes) {
|
||||||
int tsdbAsyncCommit(STsdbRepo *pRepo) {
|
int tsdbAsyncCommit(STsdbRepo *pRepo) {
|
||||||
if (pRepo->mem == NULL) return 0;
|
if (pRepo->mem == NULL) return 0;
|
||||||
|
|
||||||
sem_wait(&(pRepo->readyToCommit));
|
tsem_wait(&(pRepo->readyToCommit));
|
||||||
|
|
||||||
ASSERT(pRepo->imem == NULL);
|
ASSERT(pRepo->imem == NULL);
|
||||||
|
|
||||||
|
@ -229,8 +229,8 @@ int tsdbSyncCommit(TSDB_REPO_T *repo) {
|
||||||
STsdbRepo *pRepo = (STsdbRepo *)repo;
|
STsdbRepo *pRepo = (STsdbRepo *)repo;
|
||||||
|
|
||||||
tsdbAsyncCommit(pRepo);
|
tsdbAsyncCommit(pRepo);
|
||||||
sem_wait(&(pRepo->readyToCommit));
|
tsem_wait(&(pRepo->readyToCommit));
|
||||||
sem_post(&(pRepo->readyToCommit));
|
tsem_post(&(pRepo->readyToCommit));
|
||||||
|
|
||||||
if (pRepo->code != TSDB_CODE_SUCCESS) {
|
if (pRepo->code != TSDB_CODE_SUCCESS) {
|
||||||
terrno = pRepo->code;
|
terrno = pRepo->code;
|
||||||
|
|
|
@ -28,5 +28,6 @@ IF (TD_LINUX)
|
||||||
ELSEIF (TD_WINDOWS)
|
ELSEIF (TD_WINDOWS)
|
||||||
TARGET_LINK_LIBRARIES(tutil iconv regex winmm IPHLPAPI ws2_32 wepoll)
|
TARGET_LINK_LIBRARIES(tutil iconv regex winmm IPHLPAPI ws2_32 wepoll)
|
||||||
ELSEIF(TD_DARWIN)
|
ELSEIF(TD_DARWIN)
|
||||||
|
TARGET_LINK_LIBRARIES(tutil m)
|
||||||
TARGET_LINK_LIBRARIES(tutil iconv)
|
TARGET_LINK_LIBRARIES(tutil iconv)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
|
@ -354,6 +354,8 @@ int32_t taosKeepTcpAlive(SOCKET sockFd) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef __APPLE__
|
||||||
|
// all fails on macosx
|
||||||
int32_t probes = 3;
|
int32_t probes = 3;
|
||||||
if (taosSetSockOpt(sockFd, SOL_TCP, TCP_KEEPCNT, (void *)&probes, sizeof(probes)) < 0) {
|
if (taosSetSockOpt(sockFd, SOL_TCP, TCP_KEEPCNT, (void *)&probes, sizeof(probes)) < 0) {
|
||||||
uError("fd:%d setsockopt SO_KEEPCNT failed: %d (%s)", sockFd, errno, strerror(errno));
|
uError("fd:%d setsockopt SO_KEEPCNT failed: %d (%s)", sockFd, errno, strerror(errno));
|
||||||
|
@ -374,6 +376,7 @@ int32_t taosKeepTcpAlive(SOCKET sockFd) {
|
||||||
taosCloseSocket(sockFd);
|
taosCloseSocket(sockFd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
#endif // __APPLE__
|
||||||
|
|
||||||
int32_t nodelay = 1;
|
int32_t nodelay = 1;
|
||||||
if (taosSetSockOpt(sockFd, IPPROTO_TCP, TCP_NODELAY, (void *)&nodelay, sizeof(nodelay)) < 0) {
|
if (taosSetSockOpt(sockFd, IPPROTO_TCP, TCP_NODELAY, (void *)&nodelay, sizeof(nodelay)) < 0) {
|
||||||
|
|
|
@ -10,7 +10,5 @@ INCLUDE_DIRECTORIES(${TD_ENTERPRISE_DIR}/src/inc)
|
||||||
INCLUDE_DIRECTORIES(inc)
|
INCLUDE_DIRECTORIES(inc)
|
||||||
AUX_SOURCE_DIRECTORY(src SRC)
|
AUX_SOURCE_DIRECTORY(src SRC)
|
||||||
|
|
||||||
IF (TD_LINUX OR TD_WINDOWS)
|
|
||||||
ADD_LIBRARY(vnode ${SRC})
|
ADD_LIBRARY(vnode ${SRC})
|
||||||
TARGET_LINK_LIBRARIES(vnode tsdb tcq)
|
TARGET_LINK_LIBRARIES(vnode tsdb tcq)
|
||||||
ENDIF ()
|
|
||||||
|
|
|
@ -4,8 +4,6 @@ PROJECT(TDengine)
|
||||||
INCLUDE_DIRECTORIES(inc)
|
INCLUDE_DIRECTORIES(inc)
|
||||||
AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/src SRC)
|
AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/src SRC)
|
||||||
|
|
||||||
IF (TD_LINUX OR TD_WINDOWS)
|
|
||||||
ADD_LIBRARY(twal ${SRC})
|
ADD_LIBRARY(twal ${SRC})
|
||||||
TARGET_LINK_LIBRARIES(twal tutil common)
|
TARGET_LINK_LIBRARIES(twal tutil common)
|
||||||
ADD_SUBDIRECTORY(test)
|
ADD_SUBDIRECTORY(test)
|
||||||
ENDIF ()
|
|
||||||
|
|
|
@ -10,4 +10,12 @@ IF (TD_LINUX)
|
||||||
|
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
|
IF (TD_DARWIN)
|
||||||
|
INCLUDE_DIRECTORIES(../inc)
|
||||||
|
|
||||||
|
LIST(APPEND WALTEST_SRC ./waltest.c)
|
||||||
|
ADD_EXECUTABLE(waltest ${WALTEST_SRC})
|
||||||
|
TARGET_LINK_LIBRARIES(waltest twal osdetail tutil)
|
||||||
|
|
||||||
|
ENDIF ()
|
||||||
|
|
||||||
|
|
|
@ -5,3 +5,8 @@ IF (TD_LINUX)
|
||||||
add_executable(tdengineTest tdengineTest.c)
|
add_executable(tdengineTest tdengineTest.c)
|
||||||
target_link_libraries(tdengineTest taos_static tutil common pthread)
|
target_link_libraries(tdengineTest taos_static tutil common pthread)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
|
IF (TD_DARWIN)
|
||||||
|
add_executable(tdengineTest tdengineTest.c)
|
||||||
|
target_link_libraries(tdengineTest taos_static tutil common pthread)
|
||||||
|
ENDIF()
|
||||||
|
|
|
@ -14,13 +14,14 @@ public class JdbcRestfulDemo {
|
||||||
String url = "jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata";
|
String url = "jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata";
|
||||||
|
|
||||||
Properties properties = new Properties();
|
Properties properties = new Properties();
|
||||||
properties.setProperty("charset", "UTF-8");
|
// properties.setProperty("charset", "UTF-8");
|
||||||
properties.setProperty("locale", "en_US.UTF-8");
|
// properties.setProperty("locale", "en_US.UTF-8");
|
||||||
properties.setProperty("timezone", "UTC-8");
|
// properties.setProperty("timezone", "UTC-8");
|
||||||
|
|
||||||
Connection conn = DriverManager.getConnection(url, properties);
|
Connection conn = DriverManager.getConnection(url, properties);
|
||||||
Statement stmt = conn.createStatement();
|
Statement stmt = conn.createStatement();
|
||||||
|
|
||||||
|
stmt.execute("drop database if exists restful_test");
|
||||||
stmt.execute("create database if not exists restful_test");
|
stmt.execute("create database if not exists restful_test");
|
||||||
stmt.execute("use restful_test");
|
stmt.execute("use restful_test");
|
||||||
stmt.execute("create table restful_test.weather(ts timestamp, temperature float) tags(location nchar(64))");
|
stmt.execute("create table restful_test.weather(ts timestamp, temperature float) tags(location nchar(64))");
|
||||||
|
@ -34,6 +35,7 @@ public class JdbcRestfulDemo {
|
||||||
System.out.println();
|
System.out.println();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rs.close();
|
||||||
stmt.close();
|
stmt.close();
|
||||||
conn.close();
|
conn.close();
|
||||||
} catch (ClassNotFoundException e) {
|
} catch (ClassNotFoundException e) {
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue