Merge branch 'develop' into xiaoping/add_test_case

This commit is contained in:
Ping Xiao 2021-01-27 15:17:21 +08:00
commit 245813e842
111 changed files with 5434 additions and 2281 deletions

View File

@ -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

View File

@ -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 ()

79
Jenkinsfile vendored
View File

@ -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"
)
}
}
} }

View File

@ -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.

View File

@ -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)

View File

@ -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")

6
deps/CMakeLists.txt vendored
View File

@ -12,4 +12,8 @@ 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 ()

View File

@ -2,7 +2,7 @@
TDengine 提供了遵循 JDBC 标准3.0API 规范的 `taos-jdbcdriver` 实现,可在 maven 的中央仓库 [Sonatype Repository][1] 搜索下载。 TDengine 提供了遵循 JDBC 标准3.0API 规范的 `taos-jdbcdriver` 实现,可在 maven 的中央仓库 [Sonatype Repository][1] 搜索下载。
`taos-jdbcdriver` 的实现包括 2 种形式: JDBC-JNI 和 JDBC-RESTfultaos-jdbcdriver-2.0.17 开始支持 JDBC-RESTful。 JDBC-JNI 通过调用客户端 libtaos.so或 taos.dll )的本地方法实现, JDBC-RESTful 则在内部封装了 RESTful 接口实现。 `taos-jdbcdriver` 的实现包括 2 种形式: JDBC-JNI 和 JDBC-RESTfultaos-jdbcdriver-2.0.18 开始支持 JDBC-RESTful。 JDBC-JNI 通过调用客户端 libtaos.so或 taos.dll )的本地方法实现, JDBC-RESTful 则在内部封装了 RESTful 接口实现。
![tdengine-connector](../assets/tdengine-jdbc-connector.png) ![tdengine-connector](../assets/tdengine-jdbc-connector.png)
@ -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");
properties.put("timeBetweenEvictionRunsMillis","3000");// the interval milliseconds to test connection dataSource.setPassword("taosdata");
// pool configurations
properties.put("minEvictableIdleTimeMillis","60000");//the minimum milliseconds to keep idle dataSource.setInitialSize(10);
properties.put("maxEvictableIdleTimeMillis","90000");//the maximum milliseconds to keep idle dataSource.setMinIdle(10);
dataSource.setMaxActive(10);
properties.put("validationQuery","describe log.dn"); //validation query dataSource.setMaxWait(30000);
properties.put("testWhileIdle","true"); // test connection while idle dataSource.setValidationQuery("select server_status()");
properties.put("testOnBorrow","false"); // don't need while testWhileIdle is true
properties.put("testOnReturn","false"); // don't need while testWhileIdle is true Connection connection = dataSource.getConnection(); // get connection
//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
// ... // ...

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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.* || :
${csudo} rm -f ${lib64_link_dir}/libtaos.* || : if [ "$osType" != "Darwin" ]; then
${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
${csudo} ldconfig if [ "$osType" != "Darwin" ]; then
${csudo} ldconfig
fi
} }
function install_header() { function install_header() {

View File

@ -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 ()

View File

@ -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)

View File

@ -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);

View File

@ -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;
} }

View File

@ -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;

View File

@ -1250,8 +1250,10 @@ 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)) {
tstrncpy(pShowMsg->db, pObj->db, sizeof(pShowMsg->db)); pthread_mutex_lock(&pObj->mutex);
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;
} }

View File

@ -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);
} }
} }

View File

@ -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;

View File

@ -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);

View File

@ -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;
} }
@ -867,4 +867,4 @@ int32_t tVariantTypeSetType(tVariant *pVariant, char type) {
} }
return 0; return 0;
} }

View File

@ -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})

View File

@ -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>

View File

@ -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>

View File

@ -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");

View File

@ -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

View File

@ -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;
} }

View File

@ -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));
pos++;
if (pos < resultSet.size() - 1) { if (pos <= resultSet.size() - 1) {
pos++;
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);
} }
} }

View File

@ -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 {
return false; 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;
}
} }
@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 {
return 0; 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;
}
} }
@Override @Override
public int getScale(int column) throws SQLException { public int getScale(int column) throws SQLException {
return 0; String type = this.fields.get(column - 1).type.toUpperCase();
switch (type) {
case "FLOAT":
return 5;
case "DOUBLE":
return 9;
default:
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);
} }
} }

View File

@ -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;
} }

View File

@ -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");
} }
} }

View File

@ -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);
}
}

View File

@ -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();
}
}
}

View File

@ -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) {
} }
} }

View File

@ -6,76 +6,67 @@ 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) { 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 = connection.createStatement();
statement.executeUpdate("drop database if exists " + dbName);
statement.executeUpdate("create database if not exists " + dbName);
statement.executeUpdate("use " + dbName);
String createTableSql = "create table " + stbName + "(ts timestamp, name binary(64))";
statement.executeUpdate(createTableSql);
} catch (ClassNotFoundException | SQLException e) {
return; return;
} }
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 + ":0/", properties);
statement = connection.createStatement();
statement.executeUpdate("drop database if exists " + dbName);
statement.executeUpdate("create database if not exists " + dbName);
statement.executeUpdate("use " + dbName);
String createTableSql = "create table " + stbName + "(ts timestamp, name binary(6))";
statement.executeUpdate(createTableSql);
} }
@Test
public void testQueryBinaryData() throws SQLException{
String insertSql = "insert into " + stbName + " values(now, 'taosda')";
System.out.println(insertSql);
@Test
public void testQueryBinaryData() throws SQLException {
String insertSql = "insert into " + stbName + " values(now, 'taosdata')";
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() {
statement.close(); try {
connection.close(); if (statement != null)
Thread.sleep(10); statement.close();
if (connection != null)
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
} }
} }

View File

@ -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) { Properties properties = new Properties();
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
connection = DriverManager.getConnection("jdbc:TAOS://" + host + ":0/", properties);
statement = connection.createStatement();
statement.executeUpdate("drop database if exists " + dbName);
statement.executeUpdate("create database if not exists " + dbName);
statement.execute("use " + dbName);
statement.executeUpdate("create table if not exists " + dbName + "." + tName + " (ts timestamp, k1 int, k2 bigint, k3 float, k4 double, k5 binary(30), k6 smallint, k7 bool, k8 nchar(20))");
} catch (ClassNotFoundException | SQLException e) {
return; return;
} }
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_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 = connection.createStatement();
statement.executeUpdate("drop database if exists " + dbName);
statement.executeUpdate("create database if not exists " + dbName);
statement.executeUpdate("create table if not exists " + dbName + "." + tName +
" (ts timestamp, k1 int, k2 bigint, k3 float, k4 double, k5 binary(30), k6 smallint, k7 bool, k8 nchar(20))");
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
public static void close() throws Exception {
statement.executeUpdate("drop database " + dbName);
statement.close();
connection.close();
Thread.sleep(10);
@AfterClass
public static void close() {
try {
statement.executeUpdate("drop database " + dbName);
if (statement != null)
statement.close();
if (connection != null)
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
} }
} }

View File

@ -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();

View File

@ -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");
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/?user=root&password=taosdata", properties);
statement = connection.createStatement();
statement.executeUpdate("drop database if exists " + dbName);
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
return; 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/?user=root&password=taosdata", properties);
statement = connection.createStatement();
statement.executeUpdate("drop database if exists " + dbName);
} }
@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);
statement.close(); if (statement != null)
connection.close(); statement.close();
Thread.sleep(10); if (connection != null)
connection.close();
} catch (SQLException e) {
e.printStackTrace();
} }
} }
} }

View File

@ -10,36 +10,37 @@ 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) { Properties properties = new Properties();
return; properties.setProperty(TSDBDriver.PROPERTY_KEY_HOST, host);
} properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
Properties properties = new Properties(); properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
properties.setProperty(TSDBDriver.PROPERTY_KEY_HOST, host); properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8"); connection = DriverManager.getConnection("jdbc:TAOS://" + host + ":0/", properties);
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 = connection.createStatement(); statement = connection.createStatement();
statement.executeUpdate("create database if not exists " + dbName); statement.executeUpdate("create database if not exists " + dbName);
statement.executeUpdate("create table if not exists " + dbName + "." + tName + " (ts timestamp, k int, v int)"); statement.executeUpdate("create table if not exists " + dbName + "." + tName + " (ts timestamp, k int, v int)");
long ts = System.currentTimeMillis(); long ts = System.currentTimeMillis();
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
ts += i; ts += i;
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;
} }
} }
@ -79,10 +80,16 @@ public class SubscribeTest extends BaseTest {
} }
@After @After
public void close() throws Exception { public void close() {
statement.executeQuery("drop database " + dbName); try {
statement.close(); statement.executeQuery("drop database " + dbName);
connection.close(); if (statement != null)
Thread.sleep(10); statement.close();
if (connection != null)
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
} }
} }

View File

@ -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();
}
}
} }

View File

@ -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();
}
}
} }

View File

@ -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();
}
}
}

View File

@ -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,57 +16,71 @@ 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();
} }
} }
@Test @Test
public void testBatchInsert(){ public void testBatchInsert() {
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 try {
public void run() { long startTime = System.currentTimeMillis();
try { Statement statement = connection.createStatement(); // get statement
long startTime = System.currentTimeMillis(); StringBuilder sb = new StringBuilder();
Statement statement = connection.createStatement(); // get statement sb.append("INSERT INTO " + tablePrefix + index + " VALUES");
StringBuilder sb = new StringBuilder(); Random rand = new Random();
sb.append("INSERT INTO " + tablePrefix + index + " VALUES"); for (int j = 1; j <= numOfRecordsPerTable; j++) {
Random rand = new Random(); sb.append("(" + (ts + j) + ", ");
for (int j = 1; j <= numOfRecordsPerTable; j++) { sb.append(rand.nextInt(100) + ", ");
sb.append("(" + (ts + j) + ", "); sb.append(rand.nextInt(100) + ", ");
sb.append(rand.nextInt(100) + ", "); 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();
} }
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();
} }
}); });
} }
@ -80,7 +92,7 @@ public class BatchInsertTest {
e.printStackTrace(); e.printStackTrace();
} }
try{ try {
Statement statement = connection.createStatement(); Statement statement = connection.createStatement();
ResultSet rs = statement.executeQuery("select * from meters"); ResultSet rs = statement.executeQuery("select * from meters");
int num = 0; int num = 0;
@ -89,7 +101,7 @@ public class BatchInsertTest {
} }
assertEquals(num, numOfTables * numOfRecordsPerTable); assertEquals(num, numOfTables * numOfRecordsPerTable);
rs.close(); rs.close();
}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();
} }
} }
} }

View File

@ -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();
}
}

View File

@ -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;

View File

@ -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();
}
} }

View File

@ -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();
}
}
}

View File

@ -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();
}
}
}

View File

@ -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

View File

@ -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());
}
}
}

View File

@ -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"));
} }
} }

View File

@ -6,12 +6,10 @@ 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) ELSE ()
ELSE () TARGET_LINK_LIBRARIES(tcq tutil common taos)
TARGET_LINK_LIBRARIES(tcq tutil common taos)
ENDIF ()
ADD_SUBDIRECTORY(test)
ENDIF () ENDIF ()
ADD_SUBDIRECTORY(test)

View File

@ -10,40 +10,38 @@ 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)
IF (TD_SOMODE_STATIC) IF (TD_SOMODE_STATIC)
TARGET_LINK_LIBRARIES(taosd taos_static) TARGET_LINK_LIBRARIES(taosd taos_static)
ELSE () ELSE ()
TARGET_LINK_LIBRARIES(taosd taos) TARGET_LINK_LIBRARIES(taosd taos)
ENDIF ()
IF (TD_ACCOUNT)
TARGET_LINK_LIBRARIES(taosd account)
ENDIF ()
IF (TD_GRANT)
TARGET_LINK_LIBRARIES(taosd grant)
ENDIF ()
IF (TD_LINUX AND TD_MQTT)
TARGET_LINK_LIBRARIES(taosd mqtt)
ENDIF ()
SET(PREPARE_ENV_CMD "prepare_env_cmd")
SET(PREPARE_ENV_TARGET "prepare_env_target")
ADD_CUSTOM_COMMAND(OUTPUT ${PREPARE_ENV_CMD}
POST_BUILD
COMMAND echo "make test directory"
DEPENDS taosd
COMMAND ${CMAKE_COMMAND} -E make_directory ${TD_TESTS_OUTPUT_DIR}/cfg/
COMMAND ${CMAKE_COMMAND} -E make_directory ${TD_TESTS_OUTPUT_DIR}/log/
COMMAND ${CMAKE_COMMAND} -E make_directory ${TD_TESTS_OUTPUT_DIR}/data/
COMMAND ${CMAKE_COMMAND} -E echo dataDir ${TD_TESTS_OUTPUT_DIR}/data > ${TD_TESTS_OUTPUT_DIR}/cfg/taos.cfg
COMMAND ${CMAKE_COMMAND} -E echo logDir ${TD_TESTS_OUTPUT_DIR}/log >> ${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")
ADD_CUSTOM_TARGET(${PREPARE_ENV_TARGET} ALL WORKING_DIRECTORY ${TD_EXECUTABLE_OUTPUT_PATH} DEPENDS ${PREPARE_ENV_CMD})
ENDIF () ENDIF ()
IF (TD_ACCOUNT)
TARGET_LINK_LIBRARIES(taosd account)
ENDIF ()
IF (TD_GRANT)
TARGET_LINK_LIBRARIES(taosd grant)
ENDIF ()
IF ((TD_LINUX OR TD_WINDOWS) AND TD_MQTT)
TARGET_LINK_LIBRARIES(taosd mqtt)
ENDIF ()
SET(PREPARE_ENV_CMD "prepare_env_cmd")
SET(PREPARE_ENV_TARGET "prepare_env_target")
ADD_CUSTOM_COMMAND(OUTPUT ${PREPARE_ENV_CMD}
POST_BUILD
COMMAND echo "make test directory"
DEPENDS taosd
COMMAND ${CMAKE_COMMAND} -E make_directory ${TD_TESTS_OUTPUT_DIR}/cfg/
COMMAND ${CMAKE_COMMAND} -E make_directory ${TD_TESTS_OUTPUT_DIR}/log/
COMMAND ${CMAKE_COMMAND} -E make_directory ${TD_TESTS_OUTPUT_DIR}/data/
COMMAND ${CMAKE_COMMAND} -E echo dataDir ${TD_TESTS_OUTPUT_DIR}/data > ${TD_TESTS_OUTPUT_DIR}/cfg/taos.cfg
COMMAND ${CMAKE_COMMAND} -E echo logDir ${TD_TESTS_OUTPUT_DIR}/log >> ${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")
ADD_CUSTOM_TARGET(${PREPARE_ENV_TARGET} ALL WORKING_DIRECTORY ${TD_EXECUTABLE_OUTPUT_PATH} DEPENDS ${PREPARE_ENV_CMD})

View File

@ -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);

View File

@ -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

View File

@ -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")

View File

@ -9,14 +9,14 @@ IF (TD_LINUX)
AUX_SOURCE_DIRECTORY(./src SRC) AUX_SOURCE_DIRECTORY(./src SRC)
LIST(REMOVE_ITEM SRC ./src/shellWindows.c) LIST(REMOVE_ITEM SRC ./src/shellWindows.c)
LIST(REMOVE_ITEM SRC ./src/shellDarwin.c) LIST(REMOVE_ITEM SRC ./src/shellDarwin.c)
ADD_EXECUTABLE(shell ${SRC}) ADD_EXECUTABLE(shell ${SRC})
IF (TD_SOMODE_STATIC) IF (TD_SOMODE_STATIC)
TARGET_LINK_LIBRARIES(shell taos_static) TARGET_LINK_LIBRARIES(shell taos_static)
ELSE () ELSE ()
TARGET_LINK_LIBRARIES(shell taos) TARGET_LINK_LIBRARIES(shell taos)
ENDIF () ENDIF ()
SET_TARGET_PROPERTIES(shell PROPERTIES OUTPUT_NAME taos) SET_TARGET_PROPERTIES(shell PROPERTIES OUTPUT_NAME taos)
ELSEIF (TD_WINDOWS) ELSEIF (TD_WINDOWS)
LIST(APPEND SRC ./src/shellEngine.c) LIST(APPEND SRC ./src/shellEngine.c)
@ -27,7 +27,7 @@ ELSEIF (TD_WINDOWS)
IF (TD_POWER) IF (TD_POWER)
SET_TARGET_PROPERTIES(shell PROPERTIES OUTPUT_NAME power) SET_TARGET_PROPERTIES(shell PROPERTIES OUTPUT_NAME power)
ELSE () ELSE ()
SET_TARGET_PROPERTIES(shell PROPERTIES OUTPUT_NAME taos) SET_TARGET_PROPERTIES(shell PROPERTIES OUTPUT_NAME taos)
ENDIF () ENDIF ()
ELSEIF (TD_DARWIN) ELSEIF (TD_DARWIN)
@ -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 ()

View File

@ -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;

View File

@ -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();

View File

@ -7,7 +7,7 @@ INCLUDE_DIRECTORIES(inc)
IF (TD_LINUX) IF (TD_LINUX)
AUX_SOURCE_DIRECTORY(. SRC) AUX_SOURCE_DIRECTORY(. SRC)
ADD_EXECUTABLE(taosdemo ${SRC}) ADD_EXECUTABLE(taosdemo ${SRC})
IF (TD_SOMODE_STATIC) IF (TD_SOMODE_STATIC)
TARGET_LINK_LIBRARIES(taosdemo taos_static) TARGET_LINK_LIBRARIES(taosdemo taos_static)
ELSE () ELSE ()
@ -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 ()

View File

@ -4,22 +4,44 @@ PROJECT(TDengine)
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/client/inc) INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/client/inc)
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/libcurl/include) INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/libcurl/include)
IF (TD_LINUX) IF (TD_LINUX)
AUX_SOURCE_DIRECTORY(. SRC) AUX_SOURCE_DIRECTORY(. SRC)
ADD_EXECUTABLE(taosdemox ${SRC}) ADD_EXECUTABLE(taosdemox ${SRC})
#find_program(HAVE_CURL NAMES curl) #find_program(HAVE_CURL NAMES curl)
IF ((NOT TD_ARM_64) AND (NOT TD_ARM_32)) IF ((NOT TD_ARM_64) AND (NOT TD_ARM_32))
ADD_DEFINITIONS(-DTD_LOWA_CURL) ADD_DEFINITIONS(-DTD_LOWA_CURL)
LINK_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/libcurl/lib) LINK_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/libcurl/lib)
ADD_LIBRARY(curl STATIC IMPORTED) ADD_LIBRARY(curl STATIC IMPORTED)
SET_PROPERTY(TARGET curl PROPERTY IMPORTED_LOCATION ${TD_COMMUNITY_DIR}/deps/libcurl/lib/libcurl.a) SET_PROPERTY(TARGET curl PROPERTY IMPORTED_LOCATION ${TD_COMMUNITY_DIR}/deps/libcurl/lib/libcurl.a)
TARGET_LINK_LIBRARIES(taosdemox curl) TARGET_LINK_LIBRARIES(taosdemox curl)
ENDIF () ENDIF ()
IF (TD_SOMODE_STATIC) IF (TD_SOMODE_STATIC)
TARGET_LINK_LIBRARIES(taosdemox taos_static cJson) TARGET_LINK_LIBRARIES(taosdemox taos_static cJson)
ELSE () ELSE ()
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 ()

View File

@ -12,5 +12,15 @@ IF (TD_LINUX)
TARGET_LINK_LIBRARIES(taosdump taos_static) TARGET_LINK_LIBRARIES(taosdump taos_static)
ELSE () ELSE ()
TARGET_LINK_LIBRARIES(taosdump taos) TARGET_LINK_LIBRARIES(taosdump taos)
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 () ENDIF ()

View File

@ -1,12 +1,10 @@
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)
INCLUDE_DIRECTORIES(inc) INCLUDE_DIRECTORIES(inc)
AUX_SOURCE_DIRECTORY(src SRC) AUX_SOURCE_DIRECTORY(src SRC)
ADD_LIBRARY(mnode ${SRC}) ADD_LIBRARY(mnode ${SRC})
ENDIF ()

93
src/os/inc/eok.h Normal file
View File

@ -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_

View File

@ -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

View File

@ -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

View File

@ -30,3 +30,4 @@ void osInit() {
strcpy(tsScriptDir, "~/TDengine/cfg"); strcpy(tsScriptDir, "~/TDengine/cfg");
strcpy(tsOsName, "Darwin"); strcpy(tsOsName, "Darwin");
} }

View File

@ -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
return -1;
} else { #ifdef SEM_USE_SEM
return 0; #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;
}
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;
}

View File

@ -101,4 +101,16 @@ int taosSystem(const char *cmd) {
return -1; return -1;
} }
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;
}

View File

@ -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

893
src/os/src/darwin/eok.c Normal file
View File

@ -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;
}

View File

@ -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 ()

View File

@ -83,4 +83,4 @@ const char *taosInetNtoa(struct in_addr ipInt) {
return inet_ntoa(ipInt); return inet_ntoa(ipInt);
} }
#endif #endif

View File

@ -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

View File

@ -8,18 +8,16 @@ INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/client/inc)
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/query/inc) 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})
TARGET_LINK_LIBRARIES(http z)
IF (TD_SOMODE_STATIC) ADD_LIBRARY(http ${SRC})
TARGET_LINK_LIBRARIES(http taos_static) TARGET_LINK_LIBRARIES(http z)
ELSE ()
TARGET_LINK_LIBRARIES(http taos)
ENDIF ()
IF (TD_ADMIN) IF (TD_SOMODE_STATIC)
TARGET_LINK_LIBRARIES(http admin) TARGET_LINK_LIBRARIES(http taos_static)
ENDIF () ELSE ()
TARGET_LINK_LIBRARIES(http taos)
ENDIF ()
IF (TD_ADMIN)
TARGET_LINK_LIBRARIES(http admin)
ENDIF () ENDIF ()

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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, ...) {

View File

@ -6,12 +6,10 @@ 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) TARGET_LINK_LIBRARIES(monitor taos_static)
TARGET_LINK_LIBRARIES(monitor taos_static) ELSE ()
ELSE () TARGET_LINK_LIBRARIES(monitor taos)
TARGET_LINK_LIBRARIES(monitor taos) ENDIF ()
ENDIF ()
ENDIF ()

View File

@ -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 ()

View File

@ -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 ()

View File

@ -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)) {

View File

@ -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));
@ -477,7 +478,10 @@ static void *taosProcessTcpData(void *param) {
SFdObj *pFdObj; SFdObj *pFdObj;
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;

View File

@ -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 ()

View File

@ -3,16 +3,14 @@ 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)
ADD_LIBRARY(sync ${SRC})
TARGET_LINK_LIBRARIES(sync tutil pthread common)
LIST(APPEND BIN_SRC src/syncArbitrator.c) LIST(REMOVE_ITEM SRC src/syncArbitrator.c)
LIST(APPEND BIN_SRC src/syncTcp.c) ADD_LIBRARY(sync ${SRC})
ADD_EXECUTABLE(tarbitrator ${BIN_SRC}) TARGET_LINK_LIBRARIES(sync tutil pthread common)
TARGET_LINK_LIBRARIES(tarbitrator sync common osdetail tutil)
#ADD_SUBDIRECTORY(test) LIST(APPEND BIN_SRC src/syncArbitrator.c)
ENDIF () LIST(APPEND BIN_SRC src/syncTcp.c)
ADD_EXECUTABLE(tarbitrator ${BIN_SRC})
TARGET_LINK_LIBRARIES(tarbitrator sync common osdetail tutil)
#ADD_SUBDIRECTORY(test)

View File

@ -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;
} }

View File

@ -13,4 +13,3 @@ IF (TD_LINUX)
TARGET_LINK_LIBRARIES(syncServer sync trpc common) TARGET_LINK_LIBRARIES(syncServer sync trpc common)
ENDIF () ENDIF ()

View File

@ -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
@ -616,4 +616,4 @@ int tsdbScheduleCommit(STsdbRepo *pRepo);
} }
#endif #endif
#endif #endif

View File

@ -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) {

View File

@ -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);
} }

View File

@ -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;
@ -927,4 +927,4 @@ static int tsdbUpdateTableLatestInfo(STsdbRepo *pRepo, STable *pTable, SDataRow
} }
return 0; return 0;
} }

View File

@ -5,7 +5,7 @@ INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/rpc/inc)
AUX_SOURCE_DIRECTORY(src SRC) AUX_SOURCE_DIRECTORY(src SRC)
ADD_LIBRARY(tutil ${SRC}) ADD_LIBRARY(tutil ${SRC})
TARGET_LINK_LIBRARIES(tutil pthread osdetail lz4 z) TARGET_LINK_LIBRARIES(tutil pthread osdetail lz4 z)
IF (TD_LINUX) IF (TD_LINUX)
TARGET_LINK_LIBRARIES(tutil m rt) TARGET_LINK_LIBRARIES(tutil m rt)
# ADD_SUBDIRECTORY(tests) # ADD_SUBDIRECTORY(tests)
@ -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()

View File

@ -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) {

View File

@ -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 ()

View File

@ -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 ()

View File

@ -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 ()

View File

@ -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()

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