Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
qq_50753323
TDengine
提交
a11a2dac
T
TDengine
项目概览
qq_50753323
/
TDengine
与 Fork 源项目一致
Fork自
taosdata / TDengine
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
TDengine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
a11a2dac
编写于
10月 26, 2020
作者:
sangshuduo
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'freemine-3981' into coverity
上级
a030ea4f
2170b69e
变更
13
展开全部
隐藏空白更改
内联
并排
Showing
13 changed file
with
1616 addition
and
1507 deletion
+1616
-1507
src/client/src/tscPrepare.c
src/client/src/tscPrepare.c
+1
-2
src/connector/odbc/CMakeLists.txt
src/connector/odbc/CMakeLists.txt
+7
-12
src/connector/odbc/src/CMakeLists.txt
src/connector/odbc/src/CMakeLists.txt
+24
-0
src/connector/odbc/src/todbc.c
src/connector/odbc/src/todbc.c
+349
-1358
src/connector/odbc/src/todbc_conv.c
src/connector/odbc/src/todbc_conv.c
+530
-0
src/connector/odbc/src/todbc_conv.h
src/connector/odbc/src/todbc_conv.h
+84
-0
src/connector/odbc/src/todbc_log.h
src/connector/odbc/src/todbc_log.h
+44
-0
src/connector/odbc/src/todbc_scanner.l
src/connector/odbc/src/todbc_scanner.l
+129
-0
src/connector/odbc/src/todbc_util.c
src/connector/odbc/src/todbc_util.c
+16
-0
src/connector/odbc/src/todbc_util.h
src/connector/odbc/src/todbc_util.h
+8
-25
src/connector/odbc/tests/main.c
src/connector/odbc/tests/main.c
+396
-96
src/connector/odbc/tests/odbc.py
src/connector/odbc/tests/odbc.py
+12
-1
src/inc/taoserror.h
src/inc/taoserror.h
+16
-13
未找到文件。
src/client/src/tscPrepare.c
浏览文件 @
a11a2dac
...
...
@@ -268,7 +268,6 @@ static int doBindParam(char* data, SParamInfo* param, TAOS_BIND* bind) {
if
(
1
)
{
// allow user bind param data with different type
short
size
=
0
;
union
{
int8_t
v1
;
int16_t
v2
;
...
...
@@ -600,7 +599,7 @@ static int doBindParam(char* data, SParamInfo* param, TAOS_BIND* bind) {
if
((
*
bind
->
length
)
>
(
uintptr_t
)
param
->
bytes
)
{
return
TSDB_CODE_TSC_INVALID_VALUE
;
}
size
=
(
short
)
*
bind
->
length
;
s
hort
s
ize
=
(
short
)
*
bind
->
length
;
STR_WITH_SIZE_TO_VARSTR
(
data
+
param
->
offset
,
bind
->
buffer
,
size
);
return
TSDB_CODE_SUCCESS
;
}
break
;
...
...
src/connector/odbc/CMakeLists.txt
浏览文件 @
a11a2dac
...
...
@@ -3,7 +3,6 @@ PROJECT(TDengine)
IF
(
TD_LINUX_64
)
find_program
(
HAVE_ODBCINST NAMES odbcinst
)
IF
(
HAVE_ODBCINST
)
include
(
CheckSymbolExists
)
# shall we revert CMAKE_REQUIRED_LIBRARIES and how?
...
...
@@ -14,17 +13,13 @@ IF (TD_LINUX_64)
message
(
WARNING
"unixodbc-dev is not installed yet, you may install it under ubuntu by typing: sudo apt install unixodbc-dev"
)
else
()
message
(
STATUS
"unixodbc/unixodbc-dev are installed, and odbc connector will be built"
)
AUX_SOURCE_DIRECTORY
(
src SRC
)
# generate dynamic library (*.so)
ADD_LIBRARY
(
todbc SHARED
${
SRC
}
)
SET_TARGET_PROPERTIES
(
todbc PROPERTIES CLEAN_DIRECT_OUTPUT 1
)
SET_TARGET_PROPERTIES
(
todbc PROPERTIES VERSION
${
TD_VER_NUMBER
}
SOVERSION 1
)
TARGET_LINK_LIBRARIES
(
todbc taos
)
install
(
CODE
"execute_process(COMMAND
${
CMAKE_CURRENT_SOURCE_DIR
}
/src/install.sh
${
CMAKE_BINARY_DIR
}
)"
)
ADD_SUBDIRECTORY
(
tests
)
find_package
(
FLEX
)
if
(
NOT FLEX_FOUND
)
message
(
FATAL_ERROR
"you need to install flex first"
)
else
()
ADD_SUBDIRECTORY
(
src
)
ADD_SUBDIRECTORY
(
tests
)
endif
()
endif
()
ELSE
()
message
(
WARNING
"unixodbc is not installed yet, you may install it under ubuntu by typing: sudo apt install unixodbc"
)
...
...
src/connector/odbc/src/CMakeLists.txt
0 → 100644
浏览文件 @
a11a2dac
CMAKE_MINIMUM_REQUIRED
(
VERSION 2.8
)
PROJECT
(
TDengine
)
IF
(
TD_LINUX_64
)
FLEX_TARGET
(
todbcFlexScanner
todbc_scanner.l
${
CMAKE_CURRENT_BINARY_DIR
}
/todbc_scanner.c
)
set
(
todbc_flex_scanner_src
${
FLEX_todbcFlexScanner_OUTPUTS
}
)
AUX_SOURCE_DIRECTORY
(
. SRC
)
# generate dynamic library (*.so)
ADD_LIBRARY
(
todbc SHARED
${
SRC
}
${
todbc_flex_scanner_src
}
)
SET_TARGET_PROPERTIES
(
todbc PROPERTIES CLEAN_DIRECT_OUTPUT 1
)
SET_TARGET_PROPERTIES
(
todbc PROPERTIES VERSION
${
TD_VER_NUMBER
}
SOVERSION 1
)
TARGET_LINK_LIBRARIES
(
todbc taos
)
target_include_directories
(
todbc PUBLIC
.
)
install
(
CODE
"execute_process(COMMAND
${
CMAKE_CURRENT_SOURCE_DIR
}
/install.sh
${
CMAKE_BINARY_DIR
}
)"
)
ENDIF
()
src/connector/odbc/src/todbc.c
浏览文件 @
a11a2dac
此差异已折叠。
点击以展开。
src/connector/odbc/src/todbc_conv.c
0 → 100644
浏览文件 @
a11a2dac
/*
* 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/>.
*/
#include "todbc_conv.h"
#include "todbc_util.h"
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
typedef
struct
buf_s
buf_t
;
struct
buf_s
{
char
buf
[
1024
*
16
+
1
];
char
*
ptr
;
};
static
char
*
buf_init
(
buf_t
*
buf
,
size_t
len
);
static
void
buf_clean
(
buf_t
*
buf
);
static
char
*
buf_init
(
buf_t
*
buf
,
size_t
len
)
{
if
(
len
>
sizeof
(
buf
->
buf
))
{
buf
->
ptr
=
(
char
*
)
malloc
(
len
);
}
else
if
(
len
>
0
)
{
buf
->
ptr
=
&
buf
->
buf
[
0
];
}
else
{
buf
->
ptr
=
NULL
;
}
return
buf
->
ptr
;
}
static
void
buf_clean
(
buf_t
*
buf
)
{
if
(
buf
->
ptr
&&
buf
->
ptr
!=
buf
->
buf
)
{
free
(
buf
->
ptr
);
buf
->
ptr
=
NULL
;
}
}
const
char
*
tsdb_conv_code_str
(
TSDB_CONV_CODE
code
)
{
switch
(
code
)
{
case
TSDB_CONV_OK
:
return
"TSDB_CONV_OK"
;
case
TSDB_CONV_OOM
:
return
"TSDB_CONV_OOM"
;
case
TSDB_CONV_OOR
:
return
"TSDB_CONV_OOR"
;
case
TSDB_CONV_TRUNC_FRACTION
:
return
"TSDB_CONV_TRUNC_FRACTION"
;
case
TSDB_CONV_TRUNC
:
return
"TSDB_CONV_TRUNC"
;
case
TSDB_CONV_CHAR_NOT_NUM
:
return
"TSDB_CONV_CHAR_NOT_NUM"
;
case
TSDB_CONV_GENERAL
:
return
"TSDB_CONV_GENERAL"
;
case
TSDB_CONV_BAD_CHAR
:
return
"TSDB_CONV_BAD_CHAR"
;
default:
return
"UNKNOWN"
;
};
}
TSDB_CONV_CODE
tsdb_iconv_conv
(
iconv_t
cnv
,
const
unsigned
char
*
src
,
size_t
*
slen
,
unsigned
char
*
dst
,
size_t
*
dlen
)
{
if
(
cnv
==
(
iconv_t
)
-
1
)
return
TSDB_CONV_GENERAL
;
char
*
s
=
(
char
*
)
src
;
char
*
d
=
(
char
*
)
dst
;
size_t
sl
=
*
slen
;
size_t
dl
=
*
dlen
;
int
n
=
iconv
(
cnv
,
&
s
,
&
sl
,
&
d
,
&
dl
);
int
e
=
errno
;
if
(
dl
)
*
d
=
'\0'
;
// what if all consumed?
*
slen
=
sl
;
*
dlen
=
dl
;
if
(
e
==
0
)
{
if
(
n
)
return
TSDB_CONV_BAD_CHAR
;
return
TSDB_CONV_OK
;
}
iconv
(
cnv
,
NULL
,
NULL
,
NULL
,
NULL
);
switch
(
e
)
{
case
E2BIG
:
return
TSDB_CONV_TRUNC
;
case
EILSEQ
:
return
TSDB_CONV_BAD_CHAR
;
case
EINVAL
:
return
TSDB_CONV_BAD_CHAR
;
default:
return
TSDB_CONV_GENERAL
;
}
}
// src: int
TSDB_CONV_CODE
tsdb_int64_to_bit
(
int64_t
src
,
int8_t
*
dst
)
{
*
dst
=
(
int8_t
)
src
;
if
(
src
==
0
||
src
==
1
)
return
TSDB_CONV_OK
;
return
TSDB_CONV_OOR
;
}
TSDB_CONV_CODE
tsdb_int64_to_tinyint
(
int64_t
src
,
int8_t
*
dst
)
{
*
dst
=
(
int8_t
)
src
;
if
(
src
==
*
dst
)
return
TSDB_CONV_OK
;
return
TSDB_CONV_OOR
;
}
TSDB_CONV_CODE
tsdb_int64_to_smallint
(
int64_t
src
,
int16_t
*
dst
)
{
*
dst
=
(
int16_t
)
src
;
if
(
src
==
*
dst
)
return
TSDB_CONV_OK
;
return
TSDB_CONV_OOR
;
}
TSDB_CONV_CODE
tsdb_int64_to_int
(
int64_t
src
,
int32_t
*
dst
)
{
*
dst
=
(
int32_t
)
src
;
if
(
src
==
*
dst
)
return
TSDB_CONV_OK
;
return
TSDB_CONV_OOR
;
}
TSDB_CONV_CODE
tsdb_int64_to_bigint
(
int64_t
src
,
int64_t
*
dst
)
{
*
dst
=
src
;
return
TSDB_CONV_OK
;
}
TSDB_CONV_CODE
tsdb_int64_to_ts
(
int64_t
src
,
int64_t
*
dst
)
{
*
dst
=
src
;
time_t
t
=
(
time_t
)(
src
/
1000
);
struct
tm
tm
=
{
0
};
if
(
localtime_r
(
&
t
,
&
tm
))
return
TSDB_CONV_OK
;
return
TSDB_CONV_OOR
;
}
TSDB_CONV_CODE
tsdb_int64_to_float
(
int64_t
src
,
float
*
dst
)
{
*
dst
=
(
float
)
src
;
int64_t
v
=
(
int64_t
)
*
dst
;
if
(
v
==
src
)
return
TSDB_CONV_OK
;
return
TSDB_CONV_OOR
;
}
TSDB_CONV_CODE
tsdb_int64_to_double
(
int64_t
src
,
double
*
dst
)
{
*
dst
=
(
double
)
src
;
int64_t
v
=
(
int64_t
)
*
dst
;
if
(
v
==
src
)
return
TSDB_CONV_OK
;
return
TSDB_CONV_OOR
;
}
TSDB_CONV_CODE
tsdb_int64_to_char
(
int64_t
src
,
char
*
dst
,
size_t
dlen
)
{
int
n
=
snprintf
(
dst
,
dlen
,
"%"
PRId64
""
,
src
);
if
(
n
<
dlen
)
return
TSDB_CONV_OK
;
return
TSDB_CONV_TRUNC
;
}
// src: double
TSDB_CONV_CODE
tsdb_double_to_bit
(
double
src
,
int8_t
*
dst
)
{
*
dst
=
(
int8_t
)
src
;
if
(
src
<
0
||
src
>=
2
)
return
TSDB_CONV_OOR
;
if
(
src
==
*
dst
)
return
TSDB_CONV_OK
;
int64_t
v
=
(
int64_t
)
src
;
if
(
v
==
*
dst
)
return
TSDB_CONV_TRUNC_FRACTION
;
return
TSDB_CONV_TRUNC
;
}
TSDB_CONV_CODE
tsdb_double_to_tinyint
(
double
src
,
int8_t
*
dst
)
{
*
dst
=
(
int8_t
)
src
;
if
(
src
<
SCHAR_MIN
||
src
>
SCHAR_MAX
)
return
TSDB_CONV_OOR
;
if
(
src
==
*
dst
)
return
TSDB_CONV_OK
;
int64_t
v
=
(
int64_t
)
src
;
if
(
v
==
*
dst
)
return
TSDB_CONV_TRUNC_FRACTION
;
return
TSDB_CONV_TRUNC
;
}
TSDB_CONV_CODE
tsdb_double_to_smallint
(
double
src
,
int16_t
*
dst
)
{
*
dst
=
(
int16_t
)
src
;
if
(
src
<
SHRT_MIN
||
src
>
SHRT_MAX
)
return
TSDB_CONV_OOR
;
if
(
src
==
*
dst
)
return
TSDB_CONV_OK
;
int64_t
v
=
(
int64_t
)
src
;
if
(
v
==
*
dst
)
return
TSDB_CONV_TRUNC_FRACTION
;
return
TSDB_CONV_TRUNC
;
}
TSDB_CONV_CODE
tsdb_double_to_int
(
double
src
,
int32_t
*
dst
)
{
*
dst
=
(
int32_t
)
src
;
if
(
src
<
LONG_MIN
||
src
>
LONG_MAX
)
return
TSDB_CONV_OOR
;
if
(
src
==
*
dst
)
return
TSDB_CONV_OK
;
int64_t
v
=
(
int64_t
)
src
;
if
(
v
==
*
dst
)
return
TSDB_CONV_TRUNC_FRACTION
;
return
TSDB_CONV_TRUNC
;
}
TSDB_CONV_CODE
tsdb_double_to_bigint
(
double
src
,
int64_t
*
dst
)
{
*
dst
=
(
int64_t
)
src
;
if
(
src
<
LLONG_MIN
||
src
>
LLONG_MAX
)
return
TSDB_CONV_OOR
;
if
(
src
==
*
dst
)
return
TSDB_CONV_OK
;
int64_t
v
=
(
int64_t
)
src
;
if
(
v
==
*
dst
)
return
TSDB_CONV_TRUNC_FRACTION
;
return
TSDB_CONV_TRUNC
;
}
TSDB_CONV_CODE
tsdb_double_to_ts
(
double
src
,
int64_t
*
dst
)
{
TSDB_CONV_CODE
code
=
tsdb_double_to_bigint
(
src
,
dst
);
if
(
code
==
TSDB_CONV_OK
||
code
==
TSDB_CONV_TRUNC_FRACTION
)
{
int64_t
v
=
(
int64_t
)
src
;
time_t
t
=
(
time_t
)(
v
/
1000
);
struct
tm
tm
=
{
0
};
if
(
localtime_r
(
&
t
,
&
tm
))
return
TSDB_CONV_OK
;
return
TSDB_CONV_OOR
;
}
return
code
;
}
TSDB_CONV_CODE
tsdb_double_to_char
(
double
src
,
char
*
dst
,
size_t
dlen
)
{
int
n
=
snprintf
(
dst
,
dlen
,
"%lg"
,
src
);
if
(
n
<
dlen
)
return
TSDB_CONV_OK
;
return
TSDB_CONV_TRUNC
;
}
// src: SQL_TIMESTAMP_STRUCT
TSDB_CONV_CODE
tsdb_timestamp_to_char
(
SQL_TIMESTAMP_STRUCT
src
,
char
*
dst
,
size_t
dlen
)
{
int
n
=
snprintf
(
dst
,
dlen
,
"%04d-%02d-%02d %02d:%02d:%02d.%03d"
,
src
.
year
,
src
.
month
,
src
.
day
,
src
.
hour
,
src
.
minute
,
src
.
second
,
src
.
fraction
/
1000000
);
if
(
n
<
dlen
)
return
TSDB_CONV_OK
;
if
(
strlen
(
dst
)
>=
19
)
return
TSDB_CONV_TRUNC_FRACTION
;
return
TSDB_CONV_TRUNC
;
}
// src: chars
TSDB_CONV_CODE
tsdb_chars_to_bit
(
const
char
*
src
,
size_t
smax
,
int8_t
*
dst
)
{
if
(
strcmp
(
src
,
"0"
)
==
0
)
{
*
dst
=
0
;
return
TSDB_CONV_OK
;
}
if
(
strcmp
(
src
,
"1"
)
==
0
)
{
*
dst
=
1
;
return
TSDB_CONV_OK
;
}
double
v
;
int
bytes
;
int
n
=
sscanf
(
src
,
"%lg%n"
,
&
v
,
&
bytes
);
if
(
n
!=
1
)
return
TSDB_CONV_CHAR_NOT_NUM
;
if
(
bytes
!=
strlen
(
src
))
return
TSDB_CONV_CHAR_NOT_NUM
;
if
(
v
<
0
||
v
>=
2
)
return
TSDB_CONV_OOR
;
return
TSDB_CONV_TRUNC_FRACTION
;
}
TSDB_CONV_CODE
tsdb_chars_to_tinyint
(
const
char
*
src
,
size_t
smax
,
int8_t
*
dst
)
{
int64_t
v
;
TSDB_CONV_CODE
code
=
tsdb_chars_to_bigint
(
src
,
smax
,
&
v
);
if
(
code
!=
TSDB_CONV_OK
)
return
code
;
*
dst
=
(
int8_t
)
v
;
if
(
v
==*
dst
)
return
TSDB_CONV_OK
;
return
TSDB_CONV_OOR
;
}
TSDB_CONV_CODE
tsdb_chars_to_smallint
(
const
char
*
src
,
size_t
smax
,
int16_t
*
dst
)
{
int64_t
v
;
TSDB_CONV_CODE
code
=
tsdb_chars_to_bigint
(
src
,
smax
,
&
v
);
if
(
code
!=
TSDB_CONV_OK
)
return
code
;
*
dst
=
(
int16_t
)
v
;
if
(
v
==*
dst
)
return
TSDB_CONV_OK
;
return
TSDB_CONV_OOR
;
}
TSDB_CONV_CODE
tsdb_chars_to_int
(
const
char
*
src
,
size_t
smax
,
int32_t
*
dst
)
{
int64_t
v
;
TSDB_CONV_CODE
code
=
tsdb_chars_to_bigint
(
src
,
smax
,
&
v
);
if
(
code
!=
TSDB_CONV_OK
)
return
code
;
*
dst
=
(
int32_t
)
v
;
if
(
v
==*
dst
)
return
TSDB_CONV_OK
;
return
TSDB_CONV_OOR
;
}
TSDB_CONV_CODE
tsdb_chars_to_bigint
(
const
char
*
src
,
size_t
smax
,
int64_t
*
dst
)
{
int
bytes
;
int
n
=
sscanf
(
src
,
"%"
PRId64
"%n"
,
dst
,
&
bytes
);
if
(
n
!=
1
)
return
TSDB_CONV_CHAR_NOT_NUM
;
if
(
bytes
==
strlen
(
src
))
{
return
TSDB_CONV_OK
;
}
double
v
;
n
=
sscanf
(
src
,
"%lg%n"
,
&
v
,
&
bytes
);
if
(
n
!=
1
)
return
TSDB_CONV_CHAR_NOT_NUM
;
if
(
bytes
==
strlen
(
src
))
{
return
TSDB_CONV_TRUNC_FRACTION
;
}
return
TSDB_CONV_OK
;
}
TSDB_CONV_CODE
tsdb_chars_to_ts
(
const
char
*
src
,
size_t
smax
,
int64_t
*
dst
)
{
int64_t
v
;
TSDB_CONV_CODE
code
=
tsdb_chars_to_bigint
(
src
,
smax
,
&
v
);
if
(
code
!=
TSDB_CONV_OK
)
return
code
;
*
dst
=
v
;
if
(
v
==*
dst
)
{
time_t
t
=
(
time_t
)(
v
/
1000
);
struct
tm
tm
=
{
0
};
if
(
localtime_r
(
&
t
,
&
tm
))
return
TSDB_CONV_OK
;
}
return
TSDB_CONV_OOR
;
}
TSDB_CONV_CODE
tsdb_chars_to_float
(
const
char
*
src
,
size_t
smax
,
float
*
dst
)
{
int
bytes
;
int
n
=
sscanf
(
src
,
"%g%n"
,
dst
,
&
bytes
);
if
(
n
==
1
&&
bytes
==
strlen
(
src
))
{
return
TSDB_CONV_OK
;
}
return
TSDB_CONV_CHAR_NOT_NUM
;
}
TSDB_CONV_CODE
tsdb_chars_to_double
(
const
char
*
src
,
size_t
smax
,
double
*
dst
)
{
int
bytes
;
int
n
=
sscanf
(
src
,
"%lg%n"
,
dst
,
&
bytes
);
if
(
n
==
1
&&
bytes
==
strlen
(
src
))
{
return
TSDB_CONV_OK
;
}
return
TSDB_CONV_CHAR_NOT_NUM
;
}
TSDB_CONV_CODE
tsdb_chars_to_char
(
const
char
*
src
,
size_t
smax
,
char
*
dst
,
size_t
dmax
)
{
int
n
=
snprintf
(
dst
,
dmax
,
"%s"
,
src
);
if
(
n
<
dmax
)
return
TSDB_CONV_OK
;
return
TSDB_CONV_TRUNC
;
}
// src: wchars
TSDB_CONV_CODE
tsdb_wchars_to_bit
(
iconv_t
cnv
,
const
unsigned
char
*
src
,
size_t
smax
,
int8_t
*
dst
)
{
if
(
cnv
==
(
iconv_t
)
-
1
)
return
TSDB_CONV_GENERAL
;
size_t
len
=
smax
*
2
;
buf_t
buf
;
buf_init
(
&
buf
,
len
+
1
);
if
(
!
buf
.
ptr
)
return
TSDB_CONV_OOM
;
size_t
dmax
=
len
+
1
;
TSDB_CONV_CODE
code
=
tsdb_iconv_conv
(
cnv
,
src
,
&
smax
,
(
unsigned
char
*
)
buf
.
ptr
,
&
dmax
);
if
(
code
==
TSDB_CONV_OK
)
{
code
=
tsdb_chars_to_bit
(
buf
.
ptr
,
len
+
1
-
dmax
,
dst
);
}
buf_clean
(
&
buf
);
return
code
;
}
TSDB_CONV_CODE
tsdb_wchars_to_tinyint
(
iconv_t
cnv
,
const
unsigned
char
*
src
,
size_t
smax
,
int8_t
*
dst
)
{
if
(
cnv
==
(
iconv_t
)
-
1
)
return
TSDB_CONV_GENERAL
;
size_t
len
=
smax
*
2
;
buf_t
buf
;
buf_init
(
&
buf
,
len
+
1
);
if
(
!
buf
.
ptr
)
return
TSDB_CONV_OOM
;
size_t
dmax
=
len
+
1
;
TSDB_CONV_CODE
code
=
tsdb_iconv_conv
(
cnv
,
src
,
&
smax
,
(
unsigned
char
*
)
buf
.
ptr
,
&
dmax
);
if
(
code
==
TSDB_CONV_OK
)
{
code
=
tsdb_chars_to_tinyint
(
buf
.
ptr
,
len
+
1
-
dmax
,
dst
);
}
buf_clean
(
&
buf
);
return
code
;
}
TSDB_CONV_CODE
tsdb_wchars_to_smallint
(
iconv_t
cnv
,
const
unsigned
char
*
src
,
size_t
smax
,
int16_t
*
dst
)
{
if
(
cnv
==
(
iconv_t
)
-
1
)
return
TSDB_CONV_GENERAL
;
size_t
len
=
smax
*
2
;
buf_t
buf
;
buf_init
(
&
buf
,
len
+
1
);
if
(
!
buf
.
ptr
)
return
TSDB_CONV_OOM
;
size_t
dmax
=
len
+
1
;
TSDB_CONV_CODE
code
=
tsdb_iconv_conv
(
cnv
,
src
,
&
smax
,
(
unsigned
char
*
)
buf
.
ptr
,
&
dmax
);
if
(
code
==
TSDB_CONV_OK
)
{
code
=
tsdb_chars_to_smallint
(
buf
.
ptr
,
len
+
1
-
dmax
,
dst
);
}
buf_clean
(
&
buf
);
return
code
;
}
TSDB_CONV_CODE
tsdb_wchars_to_int
(
iconv_t
cnv
,
const
unsigned
char
*
src
,
size_t
smax
,
int32_t
*
dst
)
{
if
(
cnv
==
(
iconv_t
)
-
1
)
return
TSDB_CONV_GENERAL
;
size_t
len
=
smax
*
2
;
buf_t
buf
;
buf_init
(
&
buf
,
len
+
1
);
if
(
!
buf
.
ptr
)
return
TSDB_CONV_OOM
;
size_t
dmax
=
len
+
1
;
TSDB_CONV_CODE
code
=
tsdb_iconv_conv
(
cnv
,
src
,
&
smax
,
(
unsigned
char
*
)
buf
.
ptr
,
&
dmax
);
if
(
code
==
TSDB_CONV_OK
)
{
code
=
tsdb_chars_to_int
(
buf
.
ptr
,
len
+
1
-
dmax
,
dst
);
}
buf_clean
(
&
buf
);
return
code
;
}
TSDB_CONV_CODE
tsdb_wchars_to_bigint
(
iconv_t
cnv
,
const
unsigned
char
*
src
,
size_t
smax
,
int64_t
*
dst
)
{
if
(
cnv
==
(
iconv_t
)
-
1
)
return
TSDB_CONV_GENERAL
;
size_t
len
=
smax
*
2
;
buf_t
buf
;
buf_init
(
&
buf
,
len
+
1
);
if
(
!
buf
.
ptr
)
return
TSDB_CONV_OOM
;
size_t
dmax
=
len
+
1
;
TSDB_CONV_CODE
code
=
tsdb_iconv_conv
(
cnv
,
src
,
&
smax
,
(
unsigned
char
*
)
buf
.
ptr
,
&
dmax
);
if
(
code
==
TSDB_CONV_OK
)
{
code
=
tsdb_chars_to_bigint
(
buf
.
ptr
,
len
+
1
-
dmax
,
dst
);
}
buf_clean
(
&
buf
);
return
code
;
}
TSDB_CONV_CODE
tsdb_wchars_to_ts
(
iconv_t
cnv
,
const
unsigned
char
*
src
,
size_t
smax
,
int64_t
*
dst
)
{
return
tsdb_wchars_to_bigint
(
cnv
,
src
,
smax
,
dst
);
}
TSDB_CONV_CODE
tsdb_wchars_to_float
(
iconv_t
cnv
,
const
unsigned
char
*
src
,
size_t
smax
,
float
*
dst
)
{
if
(
cnv
==
(
iconv_t
)
-
1
)
return
TSDB_CONV_GENERAL
;
size_t
len
=
smax
*
2
;
buf_t
buf
;
buf_init
(
&
buf
,
len
+
1
);
if
(
!
buf
.
ptr
)
return
TSDB_CONV_OOM
;
size_t
dmax
=
len
+
1
;
TSDB_CONV_CODE
code
=
tsdb_iconv_conv
(
cnv
,
src
,
&
smax
,
(
unsigned
char
*
)
buf
.
ptr
,
&
dmax
);
if
(
code
==
TSDB_CONV_OK
)
{
code
=
tsdb_chars_to_float
(
buf
.
ptr
,
len
+
1
-
dmax
,
dst
);
}
buf_clean
(
&
buf
);
return
code
;
}
TSDB_CONV_CODE
tsdb_wchars_to_double
(
iconv_t
cnv
,
const
unsigned
char
*
src
,
size_t
smax
,
double
*
dst
)
{
if
(
cnv
==
(
iconv_t
)
-
1
)
return
TSDB_CONV_GENERAL
;
size_t
len
=
smax
*
2
;
buf_t
buf
;
buf_init
(
&
buf
,
len
+
1
);
if
(
!
buf
.
ptr
)
return
TSDB_CONV_OOM
;
size_t
dmax
=
len
+
1
;
TSDB_CONV_CODE
code
=
tsdb_iconv_conv
(
cnv
,
src
,
&
smax
,
(
unsigned
char
*
)
buf
.
ptr
,
&
dmax
);
if
(
code
==
TSDB_CONV_OK
)
{
code
=
tsdb_chars_to_double
(
buf
.
ptr
,
len
+
1
-
dmax
,
dst
);
}
buf_clean
(
&
buf
);
return
code
;
}
TSDB_CONV_CODE
tsdb_wchars_to_char
(
iconv_t
cnv
,
const
unsigned
char
*
src
,
size_t
smax
,
char
*
dst
,
size_t
dmax
)
{
return
tsdb_iconv_conv
(
cnv
,
src
,
&
smax
,
(
unsigned
char
*
)
dst
,
&
dmax
);
}
src/connector/odbc/src/todbc_conv.h
0 → 100644
浏览文件 @
a11a2dac
/*
* 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 _todbc_conv_h_
#define _todbc_conv_h_
#include <inttypes.h>
#include <sqltypes.h>
#include <stddef.h>
#include "iconv.h"
typedef
enum
{
TSDB_CONV_OK
=
0
,
TSDB_CONV_OOM
,
TSDB_CONV_OOR
,
TSDB_CONV_TRUNC_FRACTION
,
TSDB_CONV_TRUNC
,
TSDB_CONV_CHAR_NOT_NUM
,
TSDB_CONV_GENERAL
,
TSDB_CONV_BAD_CHAR
,
}
TSDB_CONV_CODE
;
const
char
*
tsdb_conv_code_str
(
TSDB_CONV_CODE
code
);
TSDB_CONV_CODE
tsdb_iconv_conv
(
iconv_t
cnv
,
const
unsigned
char
*
src
,
size_t
*
slen
,
unsigned
char
*
dst
,
size_t
*
dlen
);
TSDB_CONV_CODE
tsdb_int64_to_bit
(
int64_t
src
,
int8_t
*
dst
);
TSDB_CONV_CODE
tsdb_int64_to_tinyint
(
int64_t
src
,
int8_t
*
dst
);
TSDB_CONV_CODE
tsdb_int64_to_smallint
(
int64_t
src
,
int16_t
*
dst
);
TSDB_CONV_CODE
tsdb_int64_to_int
(
int64_t
src
,
int32_t
*
dst
);
TSDB_CONV_CODE
tsdb_int64_to_bigint
(
int64_t
src
,
int64_t
*
dst
);
TSDB_CONV_CODE
tsdb_int64_to_ts
(
int64_t
src
,
int64_t
*
dst
);
TSDB_CONV_CODE
tsdb_int64_to_float
(
int64_t
src
,
float
*
dst
);
TSDB_CONV_CODE
tsdb_int64_to_double
(
int64_t
src
,
double
*
dst
);
TSDB_CONV_CODE
tsdb_int64_to_char
(
int64_t
src
,
char
*
dst
,
size_t
dlen
);
TSDB_CONV_CODE
tsdb_double_to_bit
(
double
src
,
int8_t
*
dst
);
TSDB_CONV_CODE
tsdb_double_to_tinyint
(
double
src
,
int8_t
*
dst
);
TSDB_CONV_CODE
tsdb_double_to_smallint
(
double
src
,
int16_t
*
dst
);
TSDB_CONV_CODE
tsdb_double_to_int
(
double
src
,
int32_t
*
dst
);
TSDB_CONV_CODE
tsdb_double_to_bigint
(
double
src
,
int64_t
*
dst
);
TSDB_CONV_CODE
tsdb_double_to_ts
(
double
src
,
int64_t
*
dst
);
TSDB_CONV_CODE
tsdb_double_to_char
(
double
src
,
char
*
dst
,
size_t
dlen
);
TSDB_CONV_CODE
tsdb_timestamp_to_char
(
SQL_TIMESTAMP_STRUCT
src
,
char
*
dst
,
size_t
dlen
);
TSDB_CONV_CODE
tsdb_chars_to_bit
(
const
char
*
src
,
size_t
smax
,
int8_t
*
dst
);
TSDB_CONV_CODE
tsdb_chars_to_tinyint
(
const
char
*
src
,
size_t
smax
,
int8_t
*
dst
);
TSDB_CONV_CODE
tsdb_chars_to_smallint
(
const
char
*
src
,
size_t
smax
,
int16_t
*
dst
);
TSDB_CONV_CODE
tsdb_chars_to_int
(
const
char
*
src
,
size_t
smax
,
int32_t
*
dst
);
TSDB_CONV_CODE
tsdb_chars_to_bigint
(
const
char
*
src
,
size_t
smax
,
int64_t
*
dst
);
TSDB_CONV_CODE
tsdb_chars_to_ts
(
const
char
*
src
,
size_t
smax
,
int64_t
*
dst
);
TSDB_CONV_CODE
tsdb_chars_to_float
(
const
char
*
src
,
size_t
smax
,
float
*
dst
);
TSDB_CONV_CODE
tsdb_chars_to_double
(
const
char
*
src
,
size_t
smax
,
double
*
dst
);
TSDB_CONV_CODE
tsdb_chars_to_char
(
const
char
*
src
,
size_t
smax
,
char
*
dst
,
size_t
dmax
);
TSDB_CONV_CODE
tsdb_wchars_to_bit
(
iconv_t
cnv
,
const
unsigned
char
*
src
,
size_t
smax
,
int8_t
*
dst
);
TSDB_CONV_CODE
tsdb_wchars_to_tinyint
(
iconv_t
cnv
,
const
unsigned
char
*
src
,
size_t
smax
,
int8_t
*
dst
);
TSDB_CONV_CODE
tsdb_wchars_to_smallint
(
iconv_t
cnv
,
const
unsigned
char
*
src
,
size_t
smax
,
int16_t
*
dst
);
TSDB_CONV_CODE
tsdb_wchars_to_int
(
iconv_t
cnv
,
const
unsigned
char
*
src
,
size_t
smax
,
int32_t
*
dst
);
TSDB_CONV_CODE
tsdb_wchars_to_bigint
(
iconv_t
cnv
,
const
unsigned
char
*
src
,
size_t
smax
,
int64_t
*
dst
);
TSDB_CONV_CODE
tsdb_wchars_to_ts
(
iconv_t
cnv
,
const
unsigned
char
*
src
,
size_t
smax
,
int64_t
*
dst
);
TSDB_CONV_CODE
tsdb_wchars_to_float
(
iconv_t
cnv
,
const
unsigned
char
*
src
,
size_t
smax
,
float
*
dst
);
TSDB_CONV_CODE
tsdb_wchars_to_double
(
iconv_t
cnv
,
const
unsigned
char
*
src
,
size_t
smax
,
double
*
dst
);
TSDB_CONV_CODE
tsdb_wchars_to_char
(
iconv_t
cnv
,
const
unsigned
char
*
src
,
size_t
smax
,
char
*
dst
,
size_t
dmax
);
#endif // _todbc_conv_h_
src/connector/odbc/src/todbc_log.h
0 → 100644
浏览文件 @
a11a2dac
/*
* 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 _todbc_log_h_
#define _todbc_log_h_
#include <libgen.h>
#include <stdio.h>
#include <stdlib.h>
#define D(fmt, ...) \
fprintf(stderr, \
"%s[%d]:%s() " fmt "\n", \
basename((char*)__FILE__), __LINE__, __func__, \
##__VA_ARGS__)
#define DASSERT(statement) \
do { \
if (statement) break; \
D("Assertion failure: %s", #statement); \
abort(); \
} while (0)
#define DASSERTX(statement, fmt, ...) \
do { \
if (statement) break; \
D("Assertion failure: %s, " fmt "", #statement, ##__VA_ARGS__); \
abort(); \
} while (0)
#endif // _todbc_log_h_
src/connector/odbc/src/todbc_scanner.l
0 → 100644
浏览文件 @
a11a2dac
%{
#include "todbc_util.h"
#include <stdio.h>
typedef struct params_s params_t;
struct params_s {
char *key;
char *dsn;
char *uid;
char *pwd;
char *host;
};
#define PUSH_STATE(state) yy_push_state(state, yyscanner)
#define POP_STATE() yy_pop_state(yyscanner)
#define CHG_STATE(state) \
do { \
yy_pop_state(yyscanner); \
yy_push_state(state, yyscanner); \
} while (0)
#define TOP_STATE(top) \
do { \
yy_push_state(INITIAL, yyscanner); \
top = yy_top_state(yyscanner); \
yy_pop_state(yyscanner); \
} while (0)
#define UNPUT() \
do { \
while (yyleng) unput(yytext[yyleng-1]); \
} while (0)
#define set_key() \
do { \
free(yyextra->key); \
yyextra->key = strdup(yytext); \
} while (0)
#define set_val() \
do { \
if (!yyextra->key) break; \
if (strcasecmp(yyextra->key, "DSN")==0) { \
free(yyextra->dsn); \
yyextra->dsn = strdup(yytext); \
break; \
} \
if (strcasecmp(yyextra->key, "UID")==0) { \
free(yyextra->uid); \
yyextra->uid = strdup(yytext); \
break; \
} \
if (strcasecmp(yyextra->key, "PWD")==0) { \
free(yyextra->pwd); \
yyextra->pwd = strdup(yytext); \
break; \
} \
if (strcasecmp(yyextra->key, "HOST")==0) { \
free(yyextra->host); \
yyextra->host = strdup(yytext); \
break; \
} \
} while (0)
%}
%option prefix="todbc_yy"
%option extra-type="struct params_s *"
%option reentrant
%option noyywrap
%option noinput nounput
%option debug verbose
%option stack
%option nodefault
%option warn
%option perf-report
%option 8bit
%x KEY EQ BRACE1 BRACE2 VAL
%%
<<EOF>> { int state; TOP_STATE(state);
if (state == INITIAL) yyterminate();
if (state == VAL) yyterminate();
return -1; }
[[:space:]]+ { }
[[:alnum:]]+ { set_key(); PUSH_STATE(KEY); }
.|\n { return -1; }
<KEY>[[:space:]]+ { }
<KEY>[=] { CHG_STATE(EQ); }
<KEY>.|\n { return -1; }
<EQ>[[:space:]]+ { }
<EQ>[^][{}(),;?*=!@/\\\n[:space:]]+ { set_val(); CHG_STATE(VAL); }
<EQ>[{] { CHG_STATE(BRACE1); }
<EQ>.|\n { return -1; }
<BRACE1>[[:space:]]+ { }
<BRACE1>[^{}\n[:space:]]+ { set_val(); CHG_STATE(BRACE2); }
<BRACE1>.|\n { return -1; }
<BRACE2>[[:space:]]+ { }
<BRACE2>[}] { CHG_STATE(VAL); }
<BRACE2>.|\n { return -1; }
<VAL>[;] { POP_STATE(); }
<VAL>.|\n { return -1; }
%%
int todbc_parse_conn_string(const char *conn, char **dsn, char **uid, char **pwd, char **host) {
yyscan_t arg = {0};
params_t params = {0};
yylex_init(&arg);
yyset_debug(0, arg);
yyset_extra(¶ms, arg);
yy_scan_string(conn, arg);
int ret =yylex(arg);
yylex_destroy(arg);
*dsn = params.dsn;
*uid = params.uid;
*pwd = params.pwd;
*host = params.host;
return ret ? -1 : 0;
}
src/connector/odbc/src/todbc_util.c
浏览文件 @
a11a2dac
...
...
@@ -236,3 +236,19 @@ SQLCHAR* wchars_to_chars(const SQLWCHAR *wchars, size_t chs, size_t *bytes)
return
dst
;
}
size_t
wchars_to_chars2
(
const
SQLWCHAR
*
src
,
size_t
slen
,
SQLCHAR
*
dst
,
size_t
dlen
)
{
size_t
consumed
=
0
,
generated
=
0
;
int
n
=
string_conv
(
"UCS-2LE"
,
"UTF-8"
,
(
const
unsigned
char
*
)
src
,
slen
,
dst
,
dlen
,
&
consumed
,
&
generated
);
if
(
n
)
return
-
1
;
return
generated
;
}
size_t
chars_to_wchars2
(
const
SQLCHAR
*
src
,
size_t
slen
,
SQLWCHAR
*
dst
,
size_t
dlen
)
{
size_t
consumed
=
0
,
generated
=
0
;
int
n
=
string_conv
(
"UTF-8"
,
"UCS-2LE"
,
(
const
unsigned
char
*
)
src
,
slen
,
(
unsigned
char
*
)
dst
,
dlen
,
&
consumed
,
&
generated
);
if
(
n
)
return
-
1
;
return
generated
;
}
src/connector/odbc/src/todbc_util.h
浏览文件 @
a11a2dac
...
...
@@ -16,40 +16,19 @@
#ifndef _TODBC_UTIL_H_
#define _TODBC_UTIL_H_
#include <libgen.h>
#include "todbc_log.h"
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <sql.h>
#define D(fmt, ...) \
fprintf(stderr, \
"%s[%d]:%s() " fmt "\n", \
basename((char*)__FILE__), __LINE__, __func__, \
##__VA_ARGS__)
#define DASSERT(statement) \
do { \
if (statement) break; \
D("Assertion failure: %s", #statement); \
abort(); \
} while (0)
#define DASSERTX(statement, fmt, ...) \
do { \
if (statement) break; \
D("Assertion failure: %s, " fmt "", #statement, ##__VA_ARGS__); \
abort(); \
} while (0)
const
char
*
sql_sql_type
(
int
type
);
const
char
*
sql_c_type
(
int
type
);
int
is_valid_sql_c_type
(
int
type
);
int
is_valid_sql_sql_type
(
int
type
);
int
todbc_parse_conn_string
(
const
char
*
conn
,
char
**
dsn
,
char
**
uid
,
char
**
pwd
,
char
**
host
);
int
string_conv
(
const
char
*
fromcode
,
const
char
*
tocode
,
const
unsigned
char
*
src
,
size_t
sbytes
,
unsigned
char
*
dst
,
size_t
dbytes
,
...
...
@@ -60,4 +39,8 @@ unsigned char* utf8_to_ucs4le(const char *utf8, size_t *chars);
char
*
ucs4le_to_utf8
(
const
unsigned
char
*
ucs4le
,
size_t
slen
,
size_t
*
chars
);
SQLCHAR
*
wchars_to_chars
(
const
SQLWCHAR
*
wchars
,
size_t
chs
,
size_t
*
bytes
);
size_t
wchars_to_chars2
(
const
SQLWCHAR
*
src
,
size_t
slen
,
SQLCHAR
*
dst
,
size_t
dlen
);
size_t
chars_to_wchars2
(
const
SQLCHAR
*
src
,
size_t
slen
,
SQLWCHAR
*
dst
,
size_t
dlen
);
#endif // _TODBC_UTIL_H_
src/connector/odbc/tests/main.c
浏览文件 @
a11a2dac
#include <libgen.h>
#include <sql.h>
#include <sqlext.h>
...
...
@@ -5,11 +6,20 @@
#include <string.h>
#include "os.h"
#include "../src/todbc_log.h"
// static const char *dsn = "TAOS_DSN";
// static const char *uid = "root";
// static const char *pwd = "taosdata";
#define CHK_TEST(statement) \
do { \
D("testing: %s", #statement); \
int r = (statement); \
if (r) return 1; \
} while (0);
typedef
struct
data_s
data_t
;
struct
data_s
{
int64_t
ts
;
...
...
@@ -37,7 +47,7 @@ static const char *pro_stmts[] = {
// "drop database db"
};
#define CHK_RESULT(r, ht, h
)
\
#define CHK_RESULT(r, ht, h
, fmt, ...)
\
do { \
if (r==0) break; \
SQLCHAR ss[10]; \
...
...
@@ -48,23 +58,124 @@ do {
es[0] = '\0'; \
SQLRETURN ret = SQLGetDiagRec(ht, h, 1, ss, &ne, es, sizeof(es), &n); \
if (ret) break; \
fprintf(stderr, "%s%s\n", ss, es);
\
D("[%s]%s: " fmt "", ss, es, ##__VA_ARGS__);
\
} while (0)
static
int
open_connect
(
const
char
*
dsn
,
const
char
*
uid
,
const
char
*
pwd
,
SQLHENV
*
pEnv
,
SQLHDBC
*
pConn
)
{
SQLRETURN
r
;
SQLHENV
env
=
{
0
};
SQLHDBC
conn
=
{
0
};
r
=
SQLAllocEnv
(
&
env
);
if
(
r
!=
SQL_SUCCESS
)
return
1
;
do
{
r
=
SQLAllocConnect
(
env
,
&
conn
);
CHK_RESULT
(
r
,
SQL_HANDLE_ENV
,
env
,
""
);
if
(
r
!=
SQL_SUCCESS
)
break
;
do
{
r
=
SQLConnect
(
conn
,
(
SQLCHAR
*
)
dsn
,
strlen
(
dsn
),
(
SQLCHAR
*
)
uid
,
strlen
(
uid
),
(
SQLCHAR
*
)
pwd
,
strlen
(
pwd
));
CHK_RESULT
(
r
,
SQL_HANDLE_DBC
,
conn
,
""
);
if
(
r
==
SQL_SUCCESS
)
{
*
pEnv
=
env
;
*
pConn
=
conn
;
return
0
;
}
}
while
(
0
);
SQLFreeConnect
(
conn
);
}
while
(
0
);
SQLFreeEnv
(
env
);
return
1
;
}
static
int
open_driver_connect
(
const
char
*
connstr
,
SQLHENV
*
pEnv
,
SQLHDBC
*
pConn
)
{
SQLRETURN
r
;
SQLHENV
env
=
{
0
};
SQLHDBC
conn
=
{
0
};
r
=
SQLAllocEnv
(
&
env
);
if
(
r
!=
SQL_SUCCESS
)
return
1
;
do
{
r
=
SQLAllocConnect
(
env
,
&
conn
);
CHK_RESULT
(
r
,
SQL_HANDLE_ENV
,
env
,
""
);
if
(
r
!=
SQL_SUCCESS
)
break
;
do
{
SQLCHAR
buf
[
4096
];
SQLSMALLINT
blen
=
0
;
SQLHDBC
ConnectionHandle
=
conn
;
SQLHWND
WindowHandle
=
NULL
;
SQLCHAR
*
InConnectionString
=
(
SQLCHAR
*
)
connstr
;
SQLSMALLINT
StringLength1
=
strlen
(
connstr
);
SQLCHAR
*
OutConnectionString
=
buf
;
SQLSMALLINT
BufferLength
=
sizeof
(
buf
);
SQLSMALLINT
*
StringLength2Ptr
=
&
blen
;
SQLUSMALLINT
DriverCompletion
=
SQL_DRIVER_NOPROMPT
;
r
=
SQLDriverConnect
(
ConnectionHandle
,
WindowHandle
,
InConnectionString
,
StringLength1
,
OutConnectionString
,
BufferLength
,
StringLength2Ptr
,
DriverCompletion
);
CHK_RESULT
(
r
,
SQL_HANDLE_DBC
,
conn
,
""
);
if
(
r
==
SQL_SUCCESS
)
{
*
pEnv
=
env
;
*
pConn
=
conn
;
return
0
;
}
}
while
(
0
);
SQLFreeConnect
(
conn
);
}
while
(
0
);
SQLFreeEnv
(
env
);
return
1
;
}
static
int
do_statement
(
SQLHSTMT
stmt
,
const
char
*
statement
)
{
SQLRETURN
r
=
0
;
do
{
fprintf
(
stderr
,
"prepare [%s]
\n
"
,
statement
);
r
=
SQLPrepare
(
stmt
,
(
SQLCHAR
*
)
statement
,
strlen
(
statement
));
CHK_RESULT
(
r
,
SQL_HANDLE_STMT
,
stmt
);
r
=
SQLExecDirect
(
stmt
,
(
SQLCHAR
*
)
statement
,
SQL_NTS
);
CHK_RESULT
(
r
,
SQL_HANDLE_STMT
,
stmt
,
"statement: [%s]"
,
statement
);
if
(
r
)
break
;
fprintf
(
stderr
,
"execute [%s]
\n
"
,
statement
)
;
r
=
SQL
Execute
(
stmt
);
CHK_RESULT
(
r
,
SQL_HANDLE_STMT
,
stmt
);
SQLSMALLINT
cols
=
0
;
r
=
SQL
NumResultCols
(
stmt
,
&
cols
);
CHK_RESULT
(
r
,
SQL_HANDLE_STMT
,
stmt
,
""
);
if
(
r
)
break
;
fprintf
(
stderr
,
"done
\n
"
);
if
(
cols
<=
0
)
break
;
char
buf
[
4096
];
while
(
1
)
{
SQLRETURN
r
=
SQLFetch
(
stmt
);
if
(
r
==
SQL_NO_DATA
)
break
;
CHK_RESULT
(
r
,
SQL_HANDLE_STMT
,
stmt
,
""
);
for
(
size_t
i
=
0
;
i
<
cols
;
++
i
)
{
SQLLEN
soi
=
0
;
r
=
SQLGetData
(
stmt
,
i
+
1
,
SQL_C_CHAR
,
buf
,
sizeof
(
buf
),
&
soi
);
CHK_RESULT
(
r
,
SQL_HANDLE_STMT
,
stmt
,
""
);
if
(
r
)
{
if
(
r
!=
SQL_SUCCESS_WITH_INFO
)
{
if
(
i
>
0
)
fprintf
(
stdout
,
"
\n
"
);
return
r
;
}
}
if
(
soi
==
SQL_NULL_DATA
)
{
fprintf
(
stdout
,
"%snull"
,
i
==
0
?
""
:
","
);
}
else
{
fprintf
(
stdout
,
"%s
\"
%s
\"
"
,
i
==
0
?
""
:
","
,
buf
);
}
}
fprintf
(
stdout
,
"
\n
"
);
}
// r = SQLFetch(stmt);
// if (r==SQL_NO_DATA) {
// D("..........");
// r = SQL_SUCCESS;
// break;
// }
// CHK_RESULT(r, SQL_HANDLE_STMT, stmt, "");
// if (r) break;
// r = SQLPrepare(stmt, (SQLCHAR*)statement, strlen(statement));
// CHK_RESULT(r, SQL_HANDLE_STMT, stmt, "");
// if (r) break;
// r = SQLExecute(stmt);
// CHK_RESULT(r, SQL_HANDLE_STMT, stmt, "statement: %s", statement);
// if (r) break;
}
while
(
0
);
fprintf
(
stderr
,
"r: [%x][%d]
\n
"
,
r
,
r
);
return
r
;
}
...
...
@@ -77,155 +188,344 @@ static int do_insert(SQLHSTMT stmt, data_t data) {
int
ignored
=
0
;
do
{
fprintf
(
stderr
,
"prepare [%s]
\n
"
,
statement
);
r
=
SQLPrepare
(
stmt
,
(
SQLCHAR
*
)
statement
,
strlen
(
statement
));
CHK_RESULT
(
r
,
SQL_HANDLE_STMT
,
stmt
);
CHK_RESULT
(
r
,
SQL_HANDLE_STMT
,
stmt
,
"statement: %s"
,
statement
);
if
(
r
)
break
;
fprintf
(
stderr
,
"bind 1 [%s]
\n
"
,
statement
);
r
=
SQLBindParameter
(
stmt
,
1
,
SQL_PARAM_INPUT
,
SQL_C_SBIGINT
,
SQL_TIMESTAMP
,
ignored
,
ignored
,
&
data
.
ts
,
ignored
,
NULL
);
CHK_RESULT
(
r
,
SQL_HANDLE_STMT
,
stmt
);
CHK_RESULT
(
r
,
SQL_HANDLE_STMT
,
stmt
,
"statement: %s"
,
statement
);
if
(
r
)
break
;
fprintf
(
stderr
,
"bind 2 [%s]
\n
"
,
statement
);
r
=
SQLBindParameter
(
stmt
,
2
,
SQL_PARAM_INPUT
,
SQL_C_BIT
,
SQL_BIT
,
ignored
,
ignored
,
&
data
.
b
,
ignored
,
NULL
);
CHK_RESULT
(
r
,
SQL_HANDLE_STMT
,
stmt
);
CHK_RESULT
(
r
,
SQL_HANDLE_STMT
,
stmt
,
"statement: %s"
,
statement
);
if
(
r
)
break
;
fprintf
(
stderr
,
"bind 3 [%s]
\n
"
,
statement
);
r
=
SQLBindParameter
(
stmt
,
3
,
SQL_PARAM_INPUT
,
SQL_C_TINYINT
,
SQL_TINYINT
,
ignored
,
ignored
,
&
data
.
v1
,
ignored
,
NULL
);
CHK_RESULT
(
r
,
SQL_HANDLE_STMT
,
stmt
);
CHK_RESULT
(
r
,
SQL_HANDLE_STMT
,
stmt
,
"statement: %s"
,
statement
);
if
(
r
)
break
;
fprintf
(
stderr
,
"bind 4 [%s]
\n
"
,
statement
);
r
=
SQLBindParameter
(
stmt
,
4
,
SQL_PARAM_INPUT
,
SQL_C_SHORT
,
SQL_SMALLINT
,
ignored
,
ignored
,
&
data
.
v2
,
ignored
,
NULL
);
CHK_RESULT
(
r
,
SQL_HANDLE_STMT
,
stmt
);
CHK_RESULT
(
r
,
SQL_HANDLE_STMT
,
stmt
,
"statement: %s"
,
statement
);
if
(
r
)
break
;
fprintf
(
stderr
,
"bind 5 [%s]
\n
"
,
statement
);
r
=
SQLBindParameter
(
stmt
,
5
,
SQL_PARAM_INPUT
,
SQL_C_LONG
,
SQL_INTEGER
,
ignored
,
ignored
,
&
data
.
v4
,
ignored
,
NULL
);
CHK_RESULT
(
r
,
SQL_HANDLE_STMT
,
stmt
);
CHK_RESULT
(
r
,
SQL_HANDLE_STMT
,
stmt
,
"statement: %s"
,
statement
);
if
(
r
)
break
;
fprintf
(
stderr
,
"bind 6 [%s]
\n
"
,
statement
);
r
=
SQLBindParameter
(
stmt
,
6
,
SQL_PARAM_INPUT
,
SQL_C_SBIGINT
,
SQL_BIGINT
,
ignored
,
ignored
,
&
data
.
v8
,
ignored
,
NULL
);
CHK_RESULT
(
r
,
SQL_HANDLE_STMT
,
stmt
);
CHK_RESULT
(
r
,
SQL_HANDLE_STMT
,
stmt
,
"statement: %s"
,
statement
);
if
(
r
)
break
;
fprintf
(
stderr
,
"bind 7 [%s]
\n
"
,
statement
);
r
=
SQLBindParameter
(
stmt
,
7
,
SQL_PARAM_INPUT
,
SQL_C_FLOAT
,
SQL_FLOAT
,
ignored
,
ignored
,
&
data
.
f4
,
ignored
,
NULL
);
CHK_RESULT
(
r
,
SQL_HANDLE_STMT
,
stmt
);
CHK_RESULT
(
r
,
SQL_HANDLE_STMT
,
stmt
,
"statement: %s"
,
statement
);
if
(
r
)
break
;
fprintf
(
stderr
,
"bind 8 [%s]
\n
"
,
statement
);
r
=
SQLBindParameter
(
stmt
,
8
,
SQL_PARAM_INPUT
,
SQL_C_DOUBLE
,
SQL_DOUBLE
,
ignored
,
ignored
,
&
data
.
f8
,
ignored
,
NULL
);
CHK_RESULT
(
r
,
SQL_HANDLE_STMT
,
stmt
);
CHK_RESULT
(
r
,
SQL_HANDLE_STMT
,
stmt
,
"statement: %s"
,
statement
);
if
(
r
)
break
;
fprintf
(
stderr
,
"bind 9 [%s]
\n
"
,
statement
);
lbin
=
SQL_NTS
;
r
=
SQLBindParameter
(
stmt
,
9
,
SQL_PARAM_INPUT
,
SQL_C_BINARY
,
SQL_VARBINARY
,
sizeof
(
data
.
bin
)
-
1
,
ignored
,
&
data
.
bin
,
ignored
,
&
lbin
);
CHK_RESULT
(
r
,
SQL_HANDLE_STMT
,
stmt
);
CHK_RESULT
(
r
,
SQL_HANDLE_STMT
,
stmt
,
"statement: %s"
,
statement
);
if
(
r
)
break
;
fprintf
(
stderr
,
"bind 10 [%s]
\n
"
,
statement
);
lblob
=
SQL_NTS
;
r
=
SQLBindParameter
(
stmt
,
10
,
SQL_PARAM_INPUT
,
SQL_C_CHAR
,
SQL_VARCHAR
,
sizeof
(
data
.
blob
)
-
1
,
ignored
,
&
data
.
blob
,
ignored
,
&
lblob
);
CHK_RESULT
(
r
,
SQL_HANDLE_STMT
,
stmt
);
CHK_RESULT
(
r
,
SQL_HANDLE_STMT
,
stmt
,
"statement: %s"
,
statement
);
if
(
r
)
break
;
fprintf
(
stderr
,
"execute [%s]
\n
"
,
statement
);
r
=
SQLExecute
(
stmt
);
CHK_RESULT
(
r
,
SQL_HANDLE_STMT
,
stmt
);
CHK_RESULT
(
r
,
SQL_HANDLE_STMT
,
stmt
,
"statement: %s"
,
statement
);
if
(
r
)
break
;
// ts += 1;
// v = 2;
// fprintf(stderr, "execute [%s]\n", statement);
// r = SQLExecute(stmt);
// if (r) break;
fprintf
(
stderr
,
"done
\n
"
);
}
while
(
0
);
fprintf
(
stderr
,
"r: [%x][%d]
\n
"
,
r
,
r
);
return
r
;
}
int
main
(
int
argc
,
char
*
argv
[])
{
if
(
argc
<
4
)
return
1
;
const
char
*
dsn
=
argv
[
1
];
const
char
*
uid
=
argv
[
2
];
const
char
*
pwd
=
argv
[
3
];
SQLRETURN
r
;
static
int
test1
(
const
char
*
dsn
,
const
char
*
uid
,
const
char
*
pwd
)
{
SQLRETURN
r
=
SQL_SUCCESS
;
SQLHENV
env
=
{
0
};
SQLHDBC
conn
=
{
0
};
r
=
SQLAllocEnv
(
&
env
);
if
(
r
!=
SQL_SUCCESS
)
return
1
;
int
n
=
open_connect
(
dsn
,
uid
,
pwd
,
&
env
,
&
conn
);
if
(
n
)
return
1
;
do
{
r
=
SQLAllocConnect
(
env
,
&
conn
)
;
CHK_RESULT
(
r
,
SQL_HANDLE_ENV
,
env
);
SQLHSTMT
stmt
=
{
0
}
;
r
=
SQLAllocHandle
(
SQL_HANDLE_STMT
,
conn
,
&
stmt
);
if
(
r
!=
SQL_SUCCESS
)
break
;
do
{
r
=
SQLConnect
(
conn
,
(
SQLCHAR
*
)
dsn
,
strlen
(
dsn
),
(
SQLCHAR
*
)
uid
,
strlen
(
uid
),
(
SQLCHAR
*
)
pwd
,
strlen
(
pwd
));
CHK_RESULT
(
r
,
SQL_HANDLE_DBC
,
conn
);
if
(
r
!=
SQL_SUCCESS
)
break
;
if
(
do_statement
(
stmt
,
"drop database if exists db"
))
{
r
=
SQL_ERROR
;
break
;
}
for
(
size_t
i
=
0
;
i
<
sizeof
(
pre_stmts
)
/
sizeof
(
pre_stmts
[
0
]);
++
i
)
{
r
=
do_statement
(
stmt
,
pre_stmts
[
i
]);
if
(
r
!=
SQL_SUCCESS
)
break
;
}
do
{
data_t
data
=
{
0
};
data
.
ts
=
1591060628001
;
data
.
b
=
1
;
data
.
v1
=
127
;
data
.
v2
=
32767
;
data
.
v4
=
2147483647
;
data
.
v8
=
9223372036854775807
;
data
.
f4
=
123
.
456
;
data
.
f8
=
9999999
.
999999
;
memset
(
data
.
bin
,
0
,
sizeof
(
data
.
bin
));
memset
(
data
.
blob
,
0
,
sizeof
(
data
.
blob
));
snprintf
(
data
.
bin
,
sizeof
(
data
.
bin
),
"hel我lo"
);
snprintf
(
data
.
blob
,
sizeof
(
data
.
blob
),
"world"
);
snprintf
(
data
.
blob
,
sizeof
(
data
.
blob
),
"wo人rld"
);
SQLHSTMT
stmt
=
{
0
};
r
=
SQLAllocHandle
(
SQL_HANDLE_STMT
,
conn
,
&
stmt
);
if
(
r
!=
SQL_SUCCESS
)
break
;
do
{
do_statement
(
stmt
,
"drop database db"
);
for
(
size_t
i
=
0
;
i
<
sizeof
(
pre_stmts
)
/
sizeof
(
pre_stmts
[
0
]);
++
i
)
{
r
=
do_statement
(
stmt
,
pre_stmts
[
i
]);
if
(
r
!=
SQL_SUCCESS
)
break
;
}
do
{
data_t
data
=
{
0
};
data
.
ts
=
1591060628001
;
data
.
b
=
1
;
data
.
v1
=
127
;
data
.
v2
=
32767
;
data
.
v4
=
2147483647
;
data
.
v8
=
9223372036854775807
;
data
.
f4
=
123
.
456
;
data
.
f8
=
9999999
.
999999
;
memset
(
data
.
bin
,
0
,
sizeof
(
data
.
bin
));
memset
(
data
.
blob
,
0
,
sizeof
(
data
.
blob
));
snprintf
(
data
.
bin
,
sizeof
(
data
.
bin
),
"hel我lo"
);
snprintf
(
data
.
blob
,
sizeof
(
data
.
blob
),
"world"
);
snprintf
(
data
.
blob
,
sizeof
(
data
.
blob
),
"wo人rld"
);
SQLHSTMT
stmt
=
{
0
};
r
=
SQLAllocHandle
(
SQL_HANDLE_STMT
,
conn
,
&
stmt
);
if
(
r
!=
SQL_SUCCESS
)
break
;
do
{
r
=
do_insert
(
stmt
,
data
);
if
(
r
!=
SQL_SUCCESS
)
break
;
}
while
(
0
);
SQLFreeHandle
(
SQL_HANDLE_STMT
,
stmt
);
// r = SQLAllocHandle(SQL_HANDLE_STMT, conn, &stmt);
// if (r!=SQL_SUCCESS) break;
// do {
// r = do_insert(stmt, ts++, v++);
// if (r!=SQL_SUCCESS) break;
// } while (0);
// SQLFreeHandle(SQL_HANDLE_STMT, stmt);
}
while
(
0
);
r
=
do_insert
(
stmt
,
data
);
if
(
r
!=
SQL_SUCCESS
)
break
;
for
(
size_t
i
=
0
;
i
<
sizeof
(
pro_stmts
)
/
sizeof
(
pro_stmts
[
0
]);
++
i
)
{
r
=
do_statement
(
stmt
,
pro_stmts
[
i
]);
if
(
r
!=
SQL_SUCCESS
)
break
;
}
}
while
(
0
);
SQLFreeHandle
(
SQL_HANDLE_STMT
,
stmt
);
// r = SQLAllocHandle(SQL_HANDLE_STMT, conn, &stmt);
// if (r!=SQL_SUCCESS) break;
// do {
// r = do_insert(stmt, ts++, v++);
// if (r!=SQL_SUCCESS) break;
// } while (0);
// SQLFreeHandle(SQL_HANDLE_STMT, stmt);
}
while
(
0
);
SQLDisconnect
(
conn
);
if
(
r
!=
SQL_SUCCESS
)
break
;
for
(
size_t
i
=
0
;
i
<
sizeof
(
pro_stmts
)
/
sizeof
(
pro_stmts
[
0
]);
++
i
)
{
r
=
do_statement
(
stmt
,
pro_stmts
[
i
]);
if
(
r
!=
SQL_SUCCESS
)
break
;
}
}
while
(
0
);
SQLFree
Connect
(
conn
);
SQLFree
Handle
(
SQL_HANDLE_STMT
,
stmt
);
}
while
(
0
);
SQLDisconnect
(
conn
);
SQLFreeConnect
(
conn
);
SQLFreeEnv
(
env
);
return
r
?
1
:
0
;
}
int
test_statements
(
const
char
*
dsn
,
const
char
*
uid
,
const
char
*
pwd
,
const
char
**
statements
)
{
SQLRETURN
r
=
SQL_SUCCESS
;
SQLHENV
env
=
{
0
};
SQLHDBC
conn
=
{
0
};
int
n
=
open_connect
(
dsn
,
uid
,
pwd
,
&
env
,
&
conn
);
if
(
n
)
return
1
;
do
{
SQLHSTMT
stmt
=
{
0
};
r
=
SQLAllocHandle
(
SQL_HANDLE_STMT
,
conn
,
&
stmt
);
if
(
r
!=
SQL_SUCCESS
)
break
;
const
char
**
p
=
statements
;
while
(
*
p
)
{
if
(
do_statement
(
stmt
,
*
p
))
{
r
=
SQL_ERROR
;
break
;
}
++
p
;
}
SQLFreeHandle
(
SQL_HANDLE_STMT
,
stmt
);
}
while
(
0
);
SQLDisconnect
(
conn
);
SQLFreeConnect
(
conn
);
SQLFreeEnv
(
env
);
return
r
?
1
:
0
;
}
int
test_driver_connect
(
const
char
*
connstr
)
{
SQLRETURN
r
=
SQL_SUCCESS
;
SQLHENV
env
=
{
0
};
SQLHDBC
conn
=
{
0
};
int
n
=
open_driver_connect
(
connstr
,
&
env
,
&
conn
);
if
(
n
)
return
1
;
SQLDisconnect
(
conn
);
SQLFreeConnect
(
conn
);
SQLFreeEnv
(
env
);
return
r
?
1
:
0
;
}
int
create_statement
(
SQLHENV
env
,
SQLHDBC
conn
,
SQLHSTMT
*
pStmt
)
{
SQLHSTMT
stmt
=
{
0
};
SQLRETURN
r
=
SQLAllocHandle
(
SQL_HANDLE_STMT
,
conn
,
&
stmt
);
CHK_RESULT
(
r
,
SQL_HANDLE_DBC
,
conn
,
""
);
if
(
r
==
SQL_SUCCESS
)
{
*
pStmt
=
stmt
;
return
0
;
}
if
(
r
==
SQL_SUCCESS_WITH_INFO
)
{
SQLFreeHandle
(
SQL_HANDLE_STMT
,
stmt
);
}
return
1
;
}
int
do_statements
(
SQLHSTMT
stmt
,
const
char
**
statements
)
{
const
char
**
p
=
statements
;
while
(
p
&&
*
p
)
{
CHK_TEST
(
do_statement
(
stmt
,
*
p
));
++
p
;
}
return
0
;
}
int
tests_stmt
(
SQLHENV
env
,
SQLHDBC
conn
,
SQLHSTMT
stmt
)
{
const
char
*
statements
[]
=
{
"drop database if exists m"
,
"create database m"
,
"use m"
,
// "create table t (ts timestamp, b bool, v1 tinyint, v2 smallint, v4 int, v8 bigint, f4 float, f8 double, blob binary(1), name nchar(1))",
"create table t (ts timestamp, b bool)"
,
"insert into t values('2020-10-10 00:00:00', 0)"
,
"insert into t values('2020-10-10 00:00:00.001', 1)"
,
NULL
};
CHK_TEST
(
do_statements
(
stmt
,
statements
));
return
0
;
}
int
tests
(
SQLHENV
env
,
SQLHDBC
conn
)
{
SQLHSTMT
stmt
=
{
0
};
CHK_TEST
(
create_statement
(
env
,
conn
,
&
stmt
));
int
r
=
tests_stmt
(
env
,
conn
,
stmt
);
SQLFreeHandle
(
SQL_HANDLE_STMT
,
stmt
);
return
r
?
1
:
0
;
}
int
test_env
(
void
)
{
SQLRETURN
r
;
SQLHENV
env
=
{
0
};
r
=
SQLAllocEnv
(
&
env
);
if
(
r
!=
SQL_SUCCESS
)
return
1
;
SQLFreeEnv
(
env
);
return
0
;
}
int
test_sqls_in_stmt
(
SQLHENV
env
,
SQLHDBC
conn
,
SQLHSTMT
stmt
,
const
char
*
sqls
)
{
FILE
*
f
=
fopen
(
sqls
,
"rb"
);
if
(
!
f
)
{
D
(
"failed to open file [%s]"
,
sqls
);
return
-
1
;
}
int
r
=
0
;
while
(
!
feof
(
f
))
{
char
*
line
=
NULL
;
size_t
len
=
0
;
ssize_t
n
=
getline
(
&
line
,
&
len
,
f
);
if
(
n
==-
1
)
break
;
const
char
*
p
=
NULL
;
do
{
if
(
line
[
0
]
==
'#'
)
break
;
if
(
line
[
n
-
1
]
==
'\n'
)
line
[
n
-
1
]
=
'\0'
;
p
=
line
;
while
(
isspace
(
*
p
))
++
p
;
if
(
*
p
==
0
)
break
;
int
positive
=
1
;
if
(
strncmp
(
p
,
"N:"
,
2
)
==
0
)
{
positive
=
0
;
p
+=
2
;
}
else
if
(
strncmp
(
p
,
"P:"
,
2
)
==
0
)
{
p
+=
2
;
}
D
(
"statement: [%s]"
,
p
);
r
=
do_statement
(
stmt
,
p
);
if
(
positive
&&
r
==
0
)
break
;
if
(
!
positive
&&
r
)
{
r
=
0
;
break
;
}
if
(
positive
)
return
r
;
D
(
"expecting negative result, but got positive"
);
return
-
1
;
}
while
(
0
);
free
(
line
);
if
(
r
)
break
;
}
fclose
(
f
);
return
r
?
1
:
0
;
}
int
test_sqls_in_conn
(
SQLHENV
env
,
SQLHDBC
conn
,
const
char
*
sqls
)
{
SQLHSTMT
stmt
=
{
0
};
CHK_TEST
(
create_statement
(
env
,
conn
,
&
stmt
));
int
r
=
test_sqls_in_stmt
(
env
,
conn
,
stmt
,
sqls
);
SQLFreeHandle
(
SQL_HANDLE_STMT
,
stmt
);
return
r
?
1
:
0
;
}
int
test_sqls
(
const
char
*
dsn
,
const
char
*
uid
,
const
char
*
pwd
,
const
char
*
connstr
,
const
char
*
sqls
)
{
int
r
=
0
;
SQLHENV
env
=
{
0
};
SQLHDBC
conn
=
{
0
};
if
(
dsn
)
{
CHK_TEST
(
open_connect
(
dsn
,
uid
,
pwd
,
&
env
,
&
conn
));
}
else
{
CHK_TEST
(
open_driver_connect
(
connstr
,
&
env
,
&
conn
));
}
r
=
test_sqls_in_conn
(
env
,
conn
,
sqls
);
SQLDisconnect
(
conn
);
SQLFreeConnect
(
conn
);
SQLFreeEnv
(
env
);
return
r
?
1
:
0
;
}
int
main
(
int
argc
,
char
*
argv
[])
{
if
(
argc
==
1
)
{
CHK_TEST
(
test_env
());
return
0
;
}
const
char
*
dsn
=
(
argc
>
1
)
?
argv
[
1
]
:
NULL
;
const
char
*
uid
=
(
argc
>
2
)
?
argv
[
2
]
:
NULL
;
const
char
*
pwd
=
(
argc
>
3
)
?
argv
[
3
]
:
NULL
;
const
char
*
connstr
=
(
argc
>
4
)
?
argv
[
4
]
:
NULL
;
const
char
*
sqls
=
(
argc
>
5
)
?
argv
[
5
]
:
NULL
;
if
(
0
)
{
CHK_TEST
(
test_env
());
CHK_TEST
(
test1
(
dsn
,
uid
,
pwd
));
const
char
*
statements
[]
=
{
"drop database if exists m"
,
"create database m"
,
"use m"
,
"drop database m"
,
NULL
};
CHK_TEST
(
test_statements
(
dsn
,
uid
,
pwd
,
statements
));
if
(
connstr
)
CHK_TEST
(
test_driver_connect
(
connstr
));
if
(
connstr
)
{
SQLHENV
env
=
{
0
};
SQLHDBC
conn
=
{
0
};
CHK_TEST
(
open_driver_connect
(
connstr
,
&
env
,
&
conn
));
int
r
=
tests
(
env
,
conn
);
SQLDisconnect
(
conn
);
SQLFreeConnect
(
conn
);
SQLFreeEnv
(
env
);
if
(
r
)
return
1
;
}
}
if
((
dsn
||
connstr
)
&&
1
)
{
CHK_TEST
(
test_sqls
(
dsn
,
uid
,
pwd
,
connstr
,
sqls
));
}
return
0
;
}
src/connector/odbc/tests/odbc.py
浏览文件 @
a11a2dac
import
pyodbc
cnxn
=
pyodbc
.
connect
(
'DSN=TAOS_DSN;UID=root;PWD=taosdata'
,
autocommit
=
True
)
# cnxn = pyodbc.connect('DSN={TAOS_DSN};UID={ root };PWD={ taosdata };HOST={ localhost:6030 }', autocommit=True)
cnxn
=
pyodbc
.
connect
(
'DSN={TAOS_DSN}; UID=root;PWD=taosdata; HOST=localhost:6030'
,
autocommit
=
True
)
cnxn
.
setdecoding
(
pyodbc
.
SQL_CHAR
,
encoding
=
'utf-8'
)
#cnxn.setdecoding(pyodbc.SQL_WCHAR, encoding='utf-8')
#cnxn.setencoding(encoding='utf-8')
...
...
@@ -118,3 +119,13 @@ while row:
row
=
cursor
.
fetchone
()
cursor
.
close
()
cursor
=
cnxn
.
cursor
()
cursor
.
execute
(
"create table db.f (ts timestamp, v1 float)"
)
cursor
.
close
()
params
=
[
(
'2020-10-20 00:00:10'
,
'123.3'
)
]
cursor
=
cnxn
.
cursor
()
cursor
.
fast_executemany
=
True
cursor
.
executemany
(
"insert into db.f values (?, ?)"
,
params
)
cursor
.
close
()
src/inc/taoserror.h
浏览文件 @
a11a2dac
...
...
@@ -355,20 +355,23 @@ TAOS_DEFINE_ERROR(TSDB_CODE_HTTP_OP_VALUE_NULL, 0, 0x11A5, "value not
TAOS_DEFINE_ERROR
(
TSDB_CODE_HTTP_OP_VALUE_TYPE
,
0
,
0x11A6
,
"value type should be boolean, number or string"
)
TAOS_DEFINE_ERROR
(
TSDB_CODE_ODBC_OOM
,
0
,
0x2101
,
"out of memory"
)
TAOS_DEFINE_ERROR
(
TSDB_CODE_ODBC_OOM
,
0
,
0x2100
,
"out of memory"
)
TAOS_DEFINE_ERROR
(
TSDB_CODE_ODBC_CONV_CHAR_NOT_NUM
,
0
,
0x2101
,
"convertion not a valid literal input"
)
TAOS_DEFINE_ERROR
(
TSDB_CODE_ODBC_CONV_UNDEF
,
0
,
0x2102
,
"convertion undefined"
)
TAOS_DEFINE_ERROR
(
TSDB_CODE_ODBC_CONV_TRUNC
,
0
,
0x2103
,
"convertion truncated"
)
TAOS_DEFINE_ERROR
(
TSDB_CODE_ODBC_CONV_NOT_SUPPORT
,
0
,
0x2104
,
"convertion not supported"
)
TAOS_DEFINE_ERROR
(
TSDB_CODE_ODBC_OUT_OF_RANGE
,
0
,
0x2105
,
"out of range"
)
TAOS_DEFINE_ERROR
(
TSDB_CODE_ODBC_NOT_SUPPORT
,
0
,
0x2106
,
"not supported yet"
)
TAOS_DEFINE_ERROR
(
TSDB_CODE_ODBC_INVALID_HANDLE
,
0
,
0x2107
,
"invalid handle"
)
TAOS_DEFINE_ERROR
(
TSDB_CODE_ODBC_NO_RESULT
,
0
,
0x2108
,
"no result set"
)
TAOS_DEFINE_ERROR
(
TSDB_CODE_ODBC_NO_FIELDS
,
0
,
0x2109
,
"no fields returned"
)
TAOS_DEFINE_ERROR
(
TSDB_CODE_ODBC_INVALID_CURSOR
,
0
,
0x2110
,
"invalid cursor"
)
TAOS_DEFINE_ERROR
(
TSDB_CODE_ODBC_STATEMENT_NOT_READY
,
0
,
0x2111
,
"statement not ready"
)
TAOS_DEFINE_ERROR
(
TSDB_CODE_ODBC_CONNECTION_BUSY
,
0
,
0x2112
,
"connection still busy"
)
TAOS_DEFINE_ERROR
(
TSDB_CODE_ODBC_BAD_CONNSTR
,
0
,
0x2113
,
"bad connection string"
)
TAOS_DEFINE_ERROR
(
TSDB_CODE_ODBC_BAD_ARG
,
0
,
0x2114
,
"bad argument"
)
TAOS_DEFINE_ERROR
(
TSDB_CODE_ODBC_CONV_TRUNC_FRAC
,
0
,
0x2103
,
"convertion fractional truncated"
)
TAOS_DEFINE_ERROR
(
TSDB_CODE_ODBC_CONV_TRUNC
,
0
,
0x2104
,
"convertion truncated"
)
TAOS_DEFINE_ERROR
(
TSDB_CODE_ODBC_CONV_NOT_SUPPORT
,
0
,
0x2105
,
"convertion not supported"
)
TAOS_DEFINE_ERROR
(
TSDB_CODE_ODBC_CONV_OOR
,
0
,
0x2106
,
"convertion numeric value out of range"
)
TAOS_DEFINE_ERROR
(
TSDB_CODE_ODBC_OUT_OF_RANGE
,
0
,
0x2107
,
"out of range"
)
TAOS_DEFINE_ERROR
(
TSDB_CODE_ODBC_NOT_SUPPORT
,
0
,
0x2108
,
"not supported yet"
)
TAOS_DEFINE_ERROR
(
TSDB_CODE_ODBC_INVALID_HANDLE
,
0
,
0x2109
,
"invalid handle"
)
TAOS_DEFINE_ERROR
(
TSDB_CODE_ODBC_NO_RESULT
,
0
,
0x210a
,
"no result set"
)
TAOS_DEFINE_ERROR
(
TSDB_CODE_ODBC_NO_FIELDS
,
0
,
0x210b
,
"no fields returned"
)
TAOS_DEFINE_ERROR
(
TSDB_CODE_ODBC_INVALID_CURSOR
,
0
,
0x210c
,
"invalid cursor"
)
TAOS_DEFINE_ERROR
(
TSDB_CODE_ODBC_STATEMENT_NOT_READY
,
0
,
0x210d
,
"statement not ready"
)
TAOS_DEFINE_ERROR
(
TSDB_CODE_ODBC_CONNECTION_BUSY
,
0
,
0x210e
,
"connection still busy"
)
TAOS_DEFINE_ERROR
(
TSDB_CODE_ODBC_BAD_CONNSTR
,
0
,
0x210f
,
"bad connection string"
)
TAOS_DEFINE_ERROR
(
TSDB_CODE_ODBC_BAD_ARG
,
0
,
0x2110
,
"bad argument"
)
#ifdef TAOS_ERROR_C
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录