Merge branch 'odbc-win' into odbc
This commit is contained in:
commit
8b1468421f
|
@ -17,6 +17,8 @@ IF (TD_LINUX_64)
|
||||||
if(NOT FLEX_FOUND)
|
if(NOT FLEX_FOUND)
|
||||||
message(FATAL_ERROR "you need to install flex first")
|
message(FATAL_ERROR "you need to install flex first")
|
||||||
else ()
|
else ()
|
||||||
|
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wconversion")
|
||||||
|
SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Wconversion")
|
||||||
ADD_SUBDIRECTORY(src)
|
ADD_SUBDIRECTORY(src)
|
||||||
ADD_SUBDIRECTORY(tests)
|
ADD_SUBDIRECTORY(tests)
|
||||||
endif()
|
endif()
|
||||||
|
@ -26,3 +28,20 @@ IF (TD_LINUX_64)
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
|
IF (TD_WINDOWS_64)
|
||||||
|
find_package(ODBC)
|
||||||
|
if (NOT ODBC_FOUND)
|
||||||
|
message(FATAL_ERROR "you need to install ODBC first")
|
||||||
|
else ()
|
||||||
|
message(STATUS "ODBC_INCLUDE_DIRS: ${ODBC_INCLUDE_DIRS}")
|
||||||
|
message(STATUS "ODBC_LIBRARIES: ${ODBC_LIBRARIES}")
|
||||||
|
message(STATUS "ODBC_CONFIG: ${ODBC_CONFIG}")
|
||||||
|
endif ()
|
||||||
|
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 ()
|
||||||
|
|
|
@ -16,9 +16,35 @@ IF (TD_LINUX_64)
|
||||||
SET_TARGET_PROPERTIES(todbc PROPERTIES CLEAN_DIRECT_OUTPUT 1)
|
SET_TARGET_PROPERTIES(todbc PROPERTIES CLEAN_DIRECT_OUTPUT 1)
|
||||||
SET_TARGET_PROPERTIES(todbc PROPERTIES VERSION ${TD_VER_NUMBER} SOVERSION 1)
|
SET_TARGET_PROPERTIES(todbc PROPERTIES VERSION ${TD_VER_NUMBER} SOVERSION 1)
|
||||||
TARGET_LINK_LIBRARIES(todbc taos)
|
TARGET_LINK_LIBRARIES(todbc taos)
|
||||||
target_include_directories(todbc PUBLIC
|
target_include_directories(todbc PUBLIC .)
|
||||||
.)
|
|
||||||
|
|
||||||
install(CODE "execute_process(COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/install.sh ${CMAKE_BINARY_DIR})")
|
install(CODE "execute_process(COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/install.sh ${CMAKE_BINARY_DIR})")
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
|
IF (TD_WINDOWS_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 (*.dll)
|
||||||
|
ADD_LIBRARY(todbc SHARED
|
||||||
|
${SRC}
|
||||||
|
${todbc_flex_scanner_src}
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/todbc.rc
|
||||||
|
todbc.def)
|
||||||
|
TARGET_LINK_LIBRARIES(todbc taos_static)
|
||||||
|
target_include_directories(todbc PUBLIC .)
|
||||||
|
target_compile_definitions(todbc PRIVATE "todbc_EXPORT")
|
||||||
|
|
||||||
|
CONFIGURE_FILE("todbc.rc.in"
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/todbc.rc")
|
||||||
|
SET_TARGET_PROPERTIES(todbc PROPERTIES LINK_FLAGS
|
||||||
|
/DEF:todbc.def)
|
||||||
|
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /GL")
|
||||||
|
SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /GL")
|
||||||
|
ENDIF ()
|
||||||
|
|
|
@ -17,19 +17,17 @@
|
||||||
#define _XOPEN_SOURCE
|
#define _XOPEN_SOURCE
|
||||||
#define _DEFAULT_SOURCE
|
#define _DEFAULT_SOURCE
|
||||||
|
|
||||||
|
#include "todbc_log.h"
|
||||||
|
#include "todbc_flex.h"
|
||||||
|
|
||||||
#include "taos.h"
|
#include "taos.h"
|
||||||
|
|
||||||
#include "os.h"
|
|
||||||
#include "taoserror.h"
|
#include "taoserror.h"
|
||||||
#include "todbc_util.h"
|
#include "todbc_util.h"
|
||||||
#include "todbc_conv.h"
|
#include "todbc_conv.h"
|
||||||
|
|
||||||
#include <sql.h>
|
|
||||||
#include <sqlext.h>
|
#include <sqlext.h>
|
||||||
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
|
|
||||||
#define GET_REF(obj) atomic_load_64(&obj->refcount)
|
#define GET_REF(obj) atomic_load_64(&obj->refcount)
|
||||||
#define INC_REF(obj) atomic_add_fetch_64(&obj->refcount, 1)
|
#define INC_REF(obj) atomic_add_fetch_64(&obj->refcount, 1)
|
||||||
#define DEC_REF(obj) atomic_sub_fetch_64(&obj->refcount, 1)
|
#define DEC_REF(obj) atomic_sub_fetch_64(&obj->refcount, 1)
|
||||||
|
@ -47,10 +45,10 @@ do {
|
||||||
basename((char*)__FILE__), __LINE__, \
|
basename((char*)__FILE__), __LINE__, \
|
||||||
##__VA_ARGS__); \
|
##__VA_ARGS__); \
|
||||||
if (n<0) break; \
|
if (n<0) break; \
|
||||||
char *err_str = (char*)realloc(obj->err.err_str, n+1); \
|
char *err_str = (char*)realloc(obj->err.err_str, (size_t)n+1); \
|
||||||
if (!err_str) break; \
|
if (!err_str) break; \
|
||||||
obj->err.err_str = err_str; \
|
obj->err.err_str = err_str; \
|
||||||
snprintf(obj->err.err_str, n+1, "[TSDB:%x]%s: @%s[%d]" err_fmt "", \
|
snprintf(obj->err.err_str, (size_t)n+1, "[TSDB:%x]%s: @%s[%d]" err_fmt "", \
|
||||||
eno, estr, \
|
eno, estr, \
|
||||||
basename((char*)__FILE__), __LINE__, \
|
basename((char*)__FILE__), __LINE__, \
|
||||||
##__VA_ARGS__); \
|
##__VA_ARGS__); \
|
||||||
|
@ -69,9 +67,9 @@ do {
|
||||||
size_t n = sizeof(obj->err.sql_state); \
|
size_t n = sizeof(obj->err.sql_state); \
|
||||||
if (Sqlstate) strncpy((char*)Sqlstate, (char*)obj->err.sql_state, n); \
|
if (Sqlstate) strncpy((char*)Sqlstate, (char*)obj->err.sql_state, n); \
|
||||||
if (NativeError) *NativeError = obj->err.err_no; \
|
if (NativeError) *NativeError = obj->err.err_no; \
|
||||||
snprintf((char*)MessageText, BufferLength, "%s", obj->err.err_str); \
|
snprintf((char*)MessageText, (size_t)BufferLength, "%s", obj->err.err_str); \
|
||||||
if (TextLength && obj->err.err_str) *TextLength = strlen(obj->err.err_str); \
|
if (TextLength && obj->err.err_str) *TextLength = (SQLSMALLINT)strlen(obj->err.err_str); \
|
||||||
if (TextLength && obj->err.err_str) *TextLength = utf8_chars(obj->err.err_str); \
|
if (TextLength && obj->err.err_str) *TextLength = (SQLSMALLINT)utf8_chars(obj->err.err_str); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define FREE_ERROR(obj) \
|
#define FREE_ERROR(obj) \
|
||||||
|
@ -94,7 +92,7 @@ do {
|
||||||
SET_ERROR(obj, sqlstate, TSDB_CODE_QRY_INVALID_QHANDLE, err_fmt, ##__VA_ARGS__); \
|
SET_ERROR(obj, sqlstate, TSDB_CODE_QRY_INVALID_QHANDLE, err_fmt, ##__VA_ARGS__); \
|
||||||
} while (0);
|
} while (0);
|
||||||
|
|
||||||
#define SDUP(s,n) (s ? (s[n] ? (const char*)strndup((const char*)s,n) : (const char*)s) : strdup(""))
|
#define SDUP(s,n) (s ? (s[(size_t)n] ? (const char*)strndup((const char*)s,(size_t)n) : (const char*)s) : strdup(""))
|
||||||
#define SFRE(x,s,n) \
|
#define SFRE(x,s,n) \
|
||||||
do { \
|
do { \
|
||||||
if (x==(const char*)s) break; \
|
if (x==(const char*)s) break; \
|
||||||
|
@ -145,7 +143,7 @@ do { \
|
||||||
gettimeofday(&tv1, NULL); \
|
gettimeofday(&tv1, NULL); \
|
||||||
double delta = difftime(tv1.tv_sec, tv0.tv_sec); \
|
double delta = difftime(tv1.tv_sec, tv0.tv_sec); \
|
||||||
delta *= 1000000; \
|
delta *= 1000000; \
|
||||||
delta += (tv1.tv_usec-tv0.tv_usec); \
|
delta += (double)(tv1.tv_usec-tv0.tv_usec); \
|
||||||
delta /= 1000000; \
|
delta /= 1000000; \
|
||||||
D("%s: elapsed: [%.6f]s", #statement, delta); \
|
D("%s: elapsed: [%.6f]s", #statement, delta); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
@ -259,7 +257,7 @@ struct c_target_s {
|
||||||
static pthread_once_t init_once = PTHREAD_ONCE_INIT;
|
static pthread_once_t init_once = PTHREAD_ONCE_INIT;
|
||||||
static void init_routine(void);
|
static void init_routine(void);
|
||||||
|
|
||||||
static int do_field_display_size(TAOS_FIELD *field);
|
static size_t do_field_display_size(TAOS_FIELD *field);
|
||||||
static iconv_t sql_get_w2c(sql_t *sql) {
|
static iconv_t sql_get_w2c(sql_t *sql) {
|
||||||
if (sql->w2c == (iconv_t)-1) {
|
if (sql->w2c == (iconv_t)-1) {
|
||||||
sql->w2c = iconv_open("UTF-8", "UCS-2LE");
|
sql->w2c = iconv_open("UTF-8", "UCS-2LE");
|
||||||
|
@ -416,9 +414,9 @@ static SQLRETURN doSQLConnect(SQLHDBC ConnectionHandle,
|
||||||
return SQL_ERROR;
|
return SQL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
NameLength1 = (NameLength1==SQL_NTS) ? strlen((const char*)ServerName) : NameLength1;
|
NameLength1 = (NameLength1==SQL_NTS) ? (SQLSMALLINT)strlen((const char*)ServerName) : NameLength1;
|
||||||
NameLength2 = (NameLength2==SQL_NTS) ? strlen((const char*)UserName) : NameLength2;
|
NameLength2 = (NameLength2==SQL_NTS) ? (SQLSMALLINT)strlen((const char*)UserName) : NameLength2;
|
||||||
NameLength3 = (NameLength3==SQL_NTS) ? strlen((const char*)Authentication) : NameLength3;
|
NameLength3 = (NameLength3==SQL_NTS) ? (SQLSMALLINT)strlen((const char*)Authentication) : NameLength3;
|
||||||
|
|
||||||
if (NameLength1 < 0 || NameLength2 < 0 || NameLength3 < 0) {
|
if (NameLength1 < 0 || NameLength2 < 0 || NameLength3 < 0) {
|
||||||
SET_ERROR(conn, "HY090", TSDB_CODE_ODBC_BAD_ARG, "");
|
SET_ERROR(conn, "HY090", TSDB_CODE_ODBC_BAD_ARG, "");
|
||||||
|
@ -678,8 +676,8 @@ SQLRETURN SQL_API SQLExecDirect(SQLHSTMT StatementHandle,
|
||||||
SQLRETURN SQL_API SQLExecDirectW(SQLHSTMT hstmt, SQLWCHAR *szSqlStr, SQLINTEGER cbSqlStr)
|
SQLRETURN SQL_API SQLExecDirectW(SQLHSTMT hstmt, SQLWCHAR *szSqlStr, SQLINTEGER cbSqlStr)
|
||||||
{
|
{
|
||||||
size_t bytes = 0;
|
size_t bytes = 0;
|
||||||
SQLCHAR *utf8 = wchars_to_chars(szSqlStr, cbSqlStr, &bytes);
|
SQLCHAR *utf8 = wchars_to_chars(szSqlStr, (size_t)cbSqlStr, &bytes);
|
||||||
SQLRETURN r = SQLExecDirect(hstmt, utf8, bytes);
|
SQLRETURN r = SQLExecDirect(hstmt, utf8, (SQLINTEGER)bytes);
|
||||||
if (utf8) free(utf8);
|
if (utf8) free(utf8);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -707,7 +705,7 @@ static SQLRETURN doSQLNumResultCols(SQLHSTMT StatementHandle,
|
||||||
|
|
||||||
int fields = taos_field_count(sql->rs);
|
int fields = taos_field_count(sql->rs);
|
||||||
if (ColumnCount) {
|
if (ColumnCount) {
|
||||||
*ColumnCount = fields;
|
*ColumnCount = (SQLSMALLINT)fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
return SQL_SUCCESS;
|
return SQL_SUCCESS;
|
||||||
|
@ -788,11 +786,11 @@ static SQLRETURN doSQLColAttribute(SQLHSTMT StatementHandle,
|
||||||
|
|
||||||
switch (FieldIdentifier) {
|
switch (FieldIdentifier) {
|
||||||
case SQL_COLUMN_DISPLAY_SIZE: {
|
case SQL_COLUMN_DISPLAY_SIZE: {
|
||||||
*NumericAttribute = do_field_display_size(field);
|
*NumericAttribute = (SQLLEN)do_field_display_size(field);
|
||||||
} break;
|
} break;
|
||||||
case SQL_COLUMN_LABEL: {
|
case SQL_COLUMN_LABEL: {
|
||||||
size_t n = sizeof(field->name);
|
size_t n = sizeof(field->name);
|
||||||
strncpy(CharacterAttribute, field->name, (n>BufferLength ? BufferLength : n));
|
strncpy(CharacterAttribute, field->name, (n>BufferLength ? (size_t)BufferLength : n));
|
||||||
} break;
|
} break;
|
||||||
case SQL_COLUMN_UNSIGNED: {
|
case SQL_COLUMN_UNSIGNED: {
|
||||||
*NumericAttribute = SQL_FALSE;
|
*NumericAttribute = SQL_FALSE;
|
||||||
|
@ -910,7 +908,7 @@ static SQLRETURN doSQLGetData(SQLHSTMT StatementHandle,
|
||||||
CHK_CONV(0, tsdb_int64_to_double(v, TargetValue));
|
CHK_CONV(0, tsdb_int64_to_double(v, TargetValue));
|
||||||
} break;
|
} break;
|
||||||
case SQL_C_CHAR: {
|
case SQL_C_CHAR: {
|
||||||
CHK_CONV(0, tsdb_int64_to_char(v, TargetValue, BufferLength));
|
CHK_CONV(0, tsdb_int64_to_char(v, TargetValue, (size_t)BufferLength));
|
||||||
} break;
|
} break;
|
||||||
default: {
|
default: {
|
||||||
SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_NOT_SUPPORT,
|
SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_NOT_SUPPORT,
|
||||||
|
@ -932,7 +930,7 @@ static SQLRETURN doSQLGetData(SQLHSTMT StatementHandle,
|
||||||
return SQL_SUCCESS;
|
return SQL_SUCCESS;
|
||||||
} break;
|
} break;
|
||||||
case SQL_C_CHAR: {
|
case SQL_C_CHAR: {
|
||||||
CHK_CONV(0, tsdb_double_to_char(v, TargetValue, BufferLength));
|
CHK_CONV(0, tsdb_double_to_char(v, TargetValue, (size_t)BufferLength));
|
||||||
} break;
|
} break;
|
||||||
default: {
|
default: {
|
||||||
SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_NOT_SUPPORT,
|
SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_NOT_SUPPORT,
|
||||||
|
@ -950,7 +948,7 @@ static SQLRETURN doSQLGetData(SQLHSTMT StatementHandle,
|
||||||
return SQL_SUCCESS;
|
return SQL_SUCCESS;
|
||||||
} break;
|
} break;
|
||||||
case SQL_C_CHAR: {
|
case SQL_C_CHAR: {
|
||||||
CHK_CONV(0, tsdb_double_to_char(v, TargetValue, BufferLength));
|
CHK_CONV(0, tsdb_double_to_char(v, TargetValue, (size_t)BufferLength));
|
||||||
} break;
|
} break;
|
||||||
default: {
|
default: {
|
||||||
SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_NOT_SUPPORT,
|
SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_NOT_SUPPORT,
|
||||||
|
@ -964,22 +962,22 @@ static SQLRETURN doSQLGetData(SQLHSTMT StatementHandle,
|
||||||
SQL_TIMESTAMP_STRUCT ts = {0};
|
SQL_TIMESTAMP_STRUCT ts = {0};
|
||||||
int64_t v = *(int64_t*)row;
|
int64_t v = *(int64_t*)row;
|
||||||
time_t t = v/1000;
|
time_t t = v/1000;
|
||||||
struct tm tm = {0};
|
struct tm vtm = {0};
|
||||||
localtime_r(&t, &tm);
|
localtime_r(&t, &vtm);
|
||||||
ts.year = tm.tm_year + 1900;
|
ts.year = (SQLSMALLINT)(vtm.tm_year + 1900);
|
||||||
ts.month = tm.tm_mon + 1;
|
ts.month = (SQLUSMALLINT)(vtm.tm_mon + 1);
|
||||||
ts.day = tm.tm_mday;
|
ts.day = (SQLUSMALLINT)(vtm.tm_mday);
|
||||||
ts.hour = tm.tm_hour;
|
ts.hour = (SQLUSMALLINT)(vtm.tm_hour);
|
||||||
ts.minute = tm.tm_min;
|
ts.minute = (SQLUSMALLINT)(vtm.tm_min);
|
||||||
ts.second = tm.tm_sec;
|
ts.second = (SQLUSMALLINT)(vtm.tm_sec);
|
||||||
ts.fraction = v%1000 * 1000000;
|
ts.fraction = (SQLUINTEGER)(v%1000 * 1000000);
|
||||||
switch (target.ct) {
|
switch (target.ct) {
|
||||||
case SQL_C_SBIGINT: {
|
case SQL_C_SBIGINT: {
|
||||||
*(int64_t*)TargetValue = v;
|
*(int64_t*)TargetValue = v;
|
||||||
return SQL_SUCCESS;
|
return SQL_SUCCESS;
|
||||||
} break;
|
} break;
|
||||||
case SQL_C_CHAR: {
|
case SQL_C_CHAR: {
|
||||||
CHK_CONV(0, tsdb_timestamp_to_char(ts, TargetValue, BufferLength));
|
CHK_CONV(0, tsdb_timestamp_to_char(ts, TargetValue, (size_t)BufferLength));
|
||||||
} break;
|
} break;
|
||||||
case SQL_C_TYPE_TIMESTAMP:
|
case SQL_C_TYPE_TIMESTAMP:
|
||||||
case SQL_C_TIMESTAMP: {
|
case SQL_C_TIMESTAMP: {
|
||||||
|
@ -995,11 +993,11 @@ static SQLRETURN doSQLGetData(SQLHSTMT StatementHandle,
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case TSDB_DATA_TYPE_BINARY: {
|
case TSDB_DATA_TYPE_BINARY: {
|
||||||
size_t field_bytes = field->bytes;
|
size_t field_bytes = (size_t)field->bytes;
|
||||||
field_bytes -= VARSTR_HEADER_SIZE;
|
field_bytes -= VARSTR_HEADER_SIZE;
|
||||||
switch (target.ct) {
|
switch (target.ct) {
|
||||||
case SQL_C_CHAR: {
|
case SQL_C_CHAR: {
|
||||||
CHK_CONV(0, tsdb_chars_to_char((const char*)row, field_bytes, TargetValue, BufferLength));
|
CHK_CONV(0, tsdb_chars_to_char((const char*)row, field_bytes, TargetValue, (size_t)BufferLength));
|
||||||
} break;
|
} break;
|
||||||
default: {
|
default: {
|
||||||
SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_NOT_SUPPORT,
|
SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_NOT_SUPPORT,
|
||||||
|
@ -1010,11 +1008,11 @@ static SQLRETURN doSQLGetData(SQLHSTMT StatementHandle,
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case TSDB_DATA_TYPE_NCHAR: {
|
case TSDB_DATA_TYPE_NCHAR: {
|
||||||
size_t field_bytes = field->bytes;
|
size_t field_bytes = (size_t)field->bytes;
|
||||||
field_bytes -= VARSTR_HEADER_SIZE;
|
field_bytes -= VARSTR_HEADER_SIZE;
|
||||||
switch (target.ct) {
|
switch (target.ct) {
|
||||||
case SQL_C_CHAR: {
|
case SQL_C_CHAR: {
|
||||||
CHK_CONV(0, tsdb_chars_to_char((const char*)row, field_bytes, TargetValue, BufferLength));
|
CHK_CONV(0, tsdb_chars_to_char((const char*)row, field_bytes, TargetValue, (size_t)BufferLength));
|
||||||
} break;
|
} break;
|
||||||
default: {
|
default: {
|
||||||
SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_NOT_SUPPORT,
|
SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_NOT_SUPPORT,
|
||||||
|
@ -1106,7 +1104,7 @@ static SQLRETURN doSQLPrepare(SQLHSTMT StatementHandle,
|
||||||
|
|
||||||
int ok = 0;
|
int ok = 0;
|
||||||
do {
|
do {
|
||||||
int r = taos_stmt_prepare(sql->stmt, (const char *)StatementText, TextLength);
|
int r = taos_stmt_prepare(sql->stmt, (const char *)StatementText, (unsigned long)TextLength);
|
||||||
if (r) {
|
if (r) {
|
||||||
SET_ERROR(sql, "HY000", r, "failed to prepare a TAOS statement");
|
SET_ERROR(sql, "HY000", r, "failed to prepare a TAOS statement");
|
||||||
break;
|
break;
|
||||||
|
@ -1130,7 +1128,7 @@ static SQLRETURN doSQLPrepare(SQLHSTMT StatementHandle,
|
||||||
DASSERT(params>=0);
|
DASSERT(params>=0);
|
||||||
|
|
||||||
if (params>0) {
|
if (params>0) {
|
||||||
param_bind_t *ar = (param_bind_t*)calloc(1, params * sizeof(*ar));
|
param_bind_t *ar = (param_bind_t*)calloc(1, ((size_t)params) * sizeof(*ar));
|
||||||
if (!ar) {
|
if (!ar) {
|
||||||
SET_ERROR(sql, "HY001", TSDB_CODE_ODBC_OOM, "");
|
SET_ERROR(sql, "HY001", TSDB_CODE_ODBC_OOM, "");
|
||||||
break;
|
break;
|
||||||
|
@ -1173,11 +1171,11 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin
|
||||||
return SQL_ERROR;
|
return SQL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
SQLPOINTER paramValue = param->ParameterValue;
|
unsigned char *paramValue = param->ParameterValue;
|
||||||
SQLSMALLINT valueType = param->ValueType;
|
SQLSMALLINT valueType = param->ValueType;
|
||||||
SQLLEN *soi = param->StrLen_or_Ind;
|
SQLLEN *soi = param->StrLen_or_Ind;
|
||||||
|
|
||||||
size_t offset = idx_row * sql->rowlen + sql->ptr_offset;
|
size_t offset = ((size_t)idx_row) * sql->rowlen + sql->ptr_offset;
|
||||||
|
|
||||||
if (paramValue) paramValue += offset;
|
if (paramValue) paramValue += offset;
|
||||||
if (soi) soi = (SQLLEN*)((char*)soi + offset);
|
if (soi) soi = (SQLLEN*)((char*)soi + offset);
|
||||||
|
@ -1271,10 +1269,10 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin
|
||||||
CHK_CONV(1, tsdb_double_to_bit(*(double*)paramValue, &bind->u.b));
|
CHK_CONV(1, tsdb_double_to_bit(*(double*)paramValue, &bind->u.b));
|
||||||
} break;
|
} break;
|
||||||
case SQL_C_CHAR: {
|
case SQL_C_CHAR: {
|
||||||
CHK_CONV(1, tsdb_chars_to_bit((const char *)paramValue, *soi, &bind->u.b));
|
CHK_CONV(1, tsdb_chars_to_bit((const char *)paramValue, (size_t)*soi, &bind->u.b));
|
||||||
} break;
|
} break;
|
||||||
case SQL_C_WCHAR: {
|
case SQL_C_WCHAR: {
|
||||||
CHK_CONV(1, tsdb_wchars_to_bit(sql_get_w2c(sql), (const unsigned char*)paramValue, *soi, &bind->u.b));
|
CHK_CONV(1, tsdb_wchars_to_bit(sql_get_w2c(sql), (const unsigned char*)paramValue, (size_t)*soi, &bind->u.b));
|
||||||
} break;
|
} break;
|
||||||
case SQL_C_USHORT:
|
case SQL_C_USHORT:
|
||||||
case SQL_C_ULONG:
|
case SQL_C_ULONG:
|
||||||
|
@ -1323,10 +1321,10 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin
|
||||||
CHK_CONV(1, tsdb_int64_to_tinyint(*(int64_t*)paramValue, &bind->u.v1));
|
CHK_CONV(1, tsdb_int64_to_tinyint(*(int64_t*)paramValue, &bind->u.v1));
|
||||||
} break;
|
} break;
|
||||||
case SQL_C_CHAR: {
|
case SQL_C_CHAR: {
|
||||||
CHK_CONV(1, tsdb_chars_to_tinyint((const char*)paramValue, *soi, &bind->u.v1));
|
CHK_CONV(1, tsdb_chars_to_tinyint((const char*)paramValue, (size_t)*soi, &bind->u.v1));
|
||||||
} break;
|
} break;
|
||||||
case SQL_C_WCHAR: {
|
case SQL_C_WCHAR: {
|
||||||
CHK_CONV(1, tsdb_wchars_to_tinyint(sql_get_w2c(sql), (const unsigned char*)paramValue, *soi, &bind->u.v1));
|
CHK_CONV(1, tsdb_wchars_to_tinyint(sql_get_w2c(sql), (const unsigned char*)paramValue, (size_t)*soi, &bind->u.v1));
|
||||||
} break;
|
} break;
|
||||||
case SQL_C_USHORT:
|
case SQL_C_USHORT:
|
||||||
case SQL_C_ULONG:
|
case SQL_C_ULONG:
|
||||||
|
@ -1377,10 +1375,10 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin
|
||||||
CHK_CONV(1, tsdb_int64_to_smallint(*(int64_t*)paramValue, &bind->u.v2));
|
CHK_CONV(1, tsdb_int64_to_smallint(*(int64_t*)paramValue, &bind->u.v2));
|
||||||
} break;
|
} break;
|
||||||
case SQL_C_CHAR: {
|
case SQL_C_CHAR: {
|
||||||
CHK_CONV(1, tsdb_chars_to_smallint((const char*)paramValue, *soi, &bind->u.v2));
|
CHK_CONV(1, tsdb_chars_to_smallint((const char*)paramValue, (size_t)*soi, &bind->u.v2));
|
||||||
} break;
|
} break;
|
||||||
case SQL_C_WCHAR: {
|
case SQL_C_WCHAR: {
|
||||||
CHK_CONV(1, tsdb_wchars_to_smallint(sql_get_w2c(sql), (const unsigned char*)paramValue, *soi, &bind->u.v2));
|
CHK_CONV(1, tsdb_wchars_to_smallint(sql_get_w2c(sql), (const unsigned char*)paramValue, (size_t)*soi, &bind->u.v2));
|
||||||
} break;
|
} break;
|
||||||
case SQL_C_USHORT:
|
case SQL_C_USHORT:
|
||||||
case SQL_C_ULONG:
|
case SQL_C_ULONG:
|
||||||
|
@ -1431,10 +1429,10 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin
|
||||||
CHK_CONV(1, tsdb_int64_to_int(*(int64_t*)paramValue, &bind->u.v4));
|
CHK_CONV(1, tsdb_int64_to_int(*(int64_t*)paramValue, &bind->u.v4));
|
||||||
} break;
|
} break;
|
||||||
case SQL_C_CHAR: {
|
case SQL_C_CHAR: {
|
||||||
CHK_CONV(1, tsdb_chars_to_int((const char*)paramValue, *soi, &bind->u.v4));
|
CHK_CONV(1, tsdb_chars_to_int((const char*)paramValue, (size_t)*soi, &bind->u.v4));
|
||||||
} break;
|
} break;
|
||||||
case SQL_C_WCHAR: {
|
case SQL_C_WCHAR: {
|
||||||
CHK_CONV(1, tsdb_wchars_to_int(sql_get_w2c(sql), (const unsigned char*)paramValue, *soi, &bind->u.v4));
|
CHK_CONV(1, tsdb_wchars_to_int(sql_get_w2c(sql), (const unsigned char*)paramValue, (size_t)*soi, &bind->u.v4));
|
||||||
} break;
|
} break;
|
||||||
case SQL_C_USHORT:
|
case SQL_C_USHORT:
|
||||||
case SQL_C_ULONG:
|
case SQL_C_ULONG:
|
||||||
|
@ -1485,10 +1483,10 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin
|
||||||
CHK_CONV(1, tsdb_int64_to_bigint(*(int64_t*)paramValue, &bind->u.v8));
|
CHK_CONV(1, tsdb_int64_to_bigint(*(int64_t*)paramValue, &bind->u.v8));
|
||||||
} break;
|
} break;
|
||||||
case SQL_C_CHAR: {
|
case SQL_C_CHAR: {
|
||||||
CHK_CONV(1, tsdb_chars_to_bigint((const char*)paramValue, *soi, &bind->u.v8));
|
CHK_CONV(1, tsdb_chars_to_bigint((const char*)paramValue, (size_t)*soi, &bind->u.v8));
|
||||||
} break;
|
} break;
|
||||||
case SQL_C_WCHAR: {
|
case SQL_C_WCHAR: {
|
||||||
CHK_CONV(1, tsdb_wchars_to_bigint(sql_get_w2c(sql), (const unsigned char*)paramValue, *soi, &bind->u.v8));
|
CHK_CONV(1, tsdb_wchars_to_bigint(sql_get_w2c(sql), (const unsigned char*)paramValue, (size_t)*soi, &bind->u.v8));
|
||||||
} break;
|
} break;
|
||||||
case SQL_C_USHORT:
|
case SQL_C_USHORT:
|
||||||
case SQL_C_ULONG:
|
case SQL_C_ULONG:
|
||||||
|
@ -1545,10 +1543,10 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin
|
||||||
bind->u.f4 = (float)*(double*)paramValue;
|
bind->u.f4 = (float)*(double*)paramValue;
|
||||||
} break;
|
} break;
|
||||||
case SQL_C_CHAR: {
|
case SQL_C_CHAR: {
|
||||||
CHK_CONV(1, tsdb_chars_to_float((const char*)paramValue, *soi, &bind->u.f4));
|
CHK_CONV(1, tsdb_chars_to_float((const char*)paramValue, (size_t)*soi, &bind->u.f4));
|
||||||
} break;
|
} break;
|
||||||
case SQL_C_WCHAR: {
|
case SQL_C_WCHAR: {
|
||||||
CHK_CONV(1, tsdb_wchars_to_float(sql_get_w2c(sql), (const unsigned char*)paramValue, *soi, &bind->u.f4));
|
CHK_CONV(1, tsdb_wchars_to_float(sql_get_w2c(sql), (const unsigned char*)paramValue, (size_t)*soi, &bind->u.f4));
|
||||||
} break;
|
} break;
|
||||||
case SQL_C_USHORT:
|
case SQL_C_USHORT:
|
||||||
case SQL_C_ULONG:
|
case SQL_C_ULONG:
|
||||||
|
@ -1603,10 +1601,10 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin
|
||||||
bind->u.f8 = *(double*)paramValue;
|
bind->u.f8 = *(double*)paramValue;
|
||||||
} break;
|
} break;
|
||||||
case SQL_C_CHAR: {
|
case SQL_C_CHAR: {
|
||||||
CHK_CONV(1, tsdb_chars_to_double((const char*)paramValue, *soi, &bind->u.f8));
|
CHK_CONV(1, tsdb_chars_to_double((const char*)paramValue, (size_t)*soi, &bind->u.f8));
|
||||||
} break;
|
} break;
|
||||||
case SQL_C_WCHAR: {
|
case SQL_C_WCHAR: {
|
||||||
CHK_CONV(1, tsdb_wchars_to_double(sql_get_w2c(sql), (const unsigned char*)paramValue, *soi, &bind->u.f8));
|
CHK_CONV(1, tsdb_wchars_to_double(sql_get_w2c(sql), (const unsigned char*)paramValue, (size_t)*soi, &bind->u.f8));
|
||||||
} break;
|
} break;
|
||||||
case SQL_C_USHORT:
|
case SQL_C_USHORT:
|
||||||
case SQL_C_ULONG:
|
case SQL_C_ULONG:
|
||||||
|
@ -1638,7 +1636,7 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin
|
||||||
DASSERT(soi);
|
DASSERT(soi);
|
||||||
DASSERT(*soi != SQL_NTS);
|
DASSERT(*soi != SQL_NTS);
|
||||||
size_t bytes = 0;
|
size_t bytes = 0;
|
||||||
SQLCHAR *utf8 = wchars_to_chars(paramValue, *soi/2, &bytes);
|
SQLCHAR *utf8 = wchars_to_chars((const SQLWCHAR*)paramValue, (size_t)*soi/2, &bytes);
|
||||||
bind->allocated = 1;
|
bind->allocated = 1;
|
||||||
bind->u.bin = utf8;
|
bind->u.bin = utf8;
|
||||||
bind->buffer_length = bytes;
|
bind->buffer_length = bytes;
|
||||||
|
@ -1649,7 +1647,7 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin
|
||||||
if (*soi == SQL_NTS) {
|
if (*soi == SQL_NTS) {
|
||||||
bind->buffer_length = strlen((const char*)paramValue);
|
bind->buffer_length = strlen((const char*)paramValue);
|
||||||
} else {
|
} else {
|
||||||
bind->buffer_length = *soi;
|
bind->buffer_length = (uintptr_t)*soi;
|
||||||
}
|
}
|
||||||
bind->buffer = bind->u.bin;
|
bind->buffer = bind->u.bin;
|
||||||
} break;
|
} break;
|
||||||
|
@ -1697,9 +1695,9 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin
|
||||||
size_t bytes = 0;
|
size_t bytes = 0;
|
||||||
int r = 0;
|
int r = 0;
|
||||||
int64_t t = 0;
|
int64_t t = 0;
|
||||||
SQLCHAR *utf8 = wchars_to_chars(paramValue, *soi/2, &bytes);
|
SQLCHAR *utf8 = wchars_to_chars((const SQLWCHAR*)paramValue, (size_t)*soi/2, &bytes);
|
||||||
// why cast utf8 to 'char*' ?
|
// why cast utf8 to 'char*' ?
|
||||||
r = taosParseTime((char*)utf8, &t, strlen((const char*)utf8), TSDB_TIME_PRECISION_MILLI, 0);
|
r = taosParseTime((char*)utf8, &t, (int)strlen((const char*)utf8), TSDB_TIME_PRECISION_MILLI, 0);
|
||||||
bind->u.v8 = t;
|
bind->u.v8 = t;
|
||||||
free(utf8);
|
free(utf8);
|
||||||
if (r) {
|
if (r) {
|
||||||
|
@ -1753,7 +1751,7 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin
|
||||||
DASSERT(soi);
|
DASSERT(soi);
|
||||||
DASSERT(*soi != SQL_NTS);
|
DASSERT(*soi != SQL_NTS);
|
||||||
size_t bytes = 0;
|
size_t bytes = 0;
|
||||||
SQLCHAR *utf8 = wchars_to_chars(paramValue, *soi/2, &bytes);
|
SQLCHAR *utf8 = wchars_to_chars((const SQLWCHAR*)paramValue, (size_t)(*soi/2), &bytes);
|
||||||
bind->allocated = 1;
|
bind->allocated = 1;
|
||||||
bind->u.nchar = (char*)utf8;
|
bind->u.nchar = (char*)utf8;
|
||||||
bind->buffer_length = bytes;
|
bind->buffer_length = bytes;
|
||||||
|
@ -1764,7 +1762,7 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin
|
||||||
if (*soi == SQL_NTS) {
|
if (*soi == SQL_NTS) {
|
||||||
bind->buffer_length = strlen((const char*)paramValue);
|
bind->buffer_length = strlen((const char*)paramValue);
|
||||||
} else {
|
} else {
|
||||||
bind->buffer_length = *soi;
|
bind->buffer_length = (uintptr_t)*soi;
|
||||||
}
|
}
|
||||||
bind->buffer = bind->u.nchar;
|
bind->buffer = bind->u.nchar;
|
||||||
} break;
|
} break;
|
||||||
|
@ -1845,7 +1843,7 @@ static SQLRETURN do_execute(sql_t *sql)
|
||||||
for (int i=0; i<sql->n_rows; ++i) {
|
for (int i=0; i<sql->n_rows; ++i) {
|
||||||
TAOS_BIND *binds = NULL;
|
TAOS_BIND *binds = NULL;
|
||||||
if (sql->n_params>0) {
|
if (sql->n_params>0) {
|
||||||
binds = (TAOS_BIND*)calloc(sql->n_params, sizeof(*binds));
|
binds = (TAOS_BIND*)calloc((size_t)sql->n_params, sizeof(*binds));
|
||||||
if (!binds) {
|
if (!binds) {
|
||||||
SET_ERROR(sql, "HY001", TSDB_CODE_ODBC_OOM, "");
|
SET_ERROR(sql, "HY001", TSDB_CODE_ODBC_OOM, "");
|
||||||
return SQL_ERROR;
|
return SQL_ERROR;
|
||||||
|
@ -1921,7 +1919,7 @@ static SQLRETURN doSQLGetDiagField(SQLSMALLINT HandleType, SQLHANDLE Handle,
|
||||||
SQLSMALLINT *StringLength)
|
SQLSMALLINT *StringLength)
|
||||||
{
|
{
|
||||||
// if this function is not exported, isql will never call SQLGetDiagRec
|
// if this function is not exported, isql will never call SQLGetDiagRec
|
||||||
return SQL_ERROR;
|
return SQL_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
SQLRETURN SQL_API SQLGetDiagField(SQLSMALLINT HandleType, SQLHANDLE Handle,
|
SQLRETURN SQL_API SQLGetDiagField(SQLSMALLINT HandleType, SQLHANDLE Handle,
|
||||||
|
@ -2117,14 +2115,14 @@ static SQLRETURN doSQLDriverConnect(
|
||||||
if (host) {
|
if (host) {
|
||||||
char *p = strchr(host, ':');
|
char *p = strchr(host, ':');
|
||||||
if (p) {
|
if (p) {
|
||||||
ip = strndup(host, p-host);
|
ip = strndup(host, (size_t)(p-host));
|
||||||
port = atoi(p+1);
|
port = atoi(p+1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: data-race
|
// TODO: data-race
|
||||||
// TODO: shall receive ip/port from odbc.ini
|
// TODO: shall receive ip/port from odbc.ini
|
||||||
conn->taos = taos_connect(ip ? ip : "localhost", userName, auth, NULL, port);
|
conn->taos = taos_connect(ip ? ip : "localhost", userName, auth, NULL, (uint16_t)port);
|
||||||
free(ip); ip = NULL;
|
free(ip); ip = NULL;
|
||||||
if (!conn->taos) {
|
if (!conn->taos) {
|
||||||
SET_ERROR(conn, "HY000", terrno, "failed to connect to data source");
|
SET_ERROR(conn, "HY000", terrno, "failed to connect to data source");
|
||||||
|
@ -2132,7 +2130,7 @@ static SQLRETURN doSQLDriverConnect(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (szConnStrOut) {
|
if (szConnStrOut) {
|
||||||
snprintf((char*)szConnStrOut, cbConnStrOutMax, "%s", connStr);
|
snprintf((char*)szConnStrOut, (size_t)cbConnStrOutMax, "%s", connStr);
|
||||||
}
|
}
|
||||||
if (pcbConnStrOut) {
|
if (pcbConnStrOut) {
|
||||||
*pcbConnStrOut = cbConnStrIn;
|
*pcbConnStrOut = cbConnStrIn;
|
||||||
|
@ -2220,13 +2218,13 @@ static SQLRETURN doSQLDescribeCol(SQLHSTMT StatementHandle,
|
||||||
TAOS_FIELD *field = fields + ColumnNumber - 1;
|
TAOS_FIELD *field = fields + ColumnNumber - 1;
|
||||||
if (ColumnName) {
|
if (ColumnName) {
|
||||||
size_t n = sizeof(field->name);
|
size_t n = sizeof(field->name);
|
||||||
if (n>BufferLength) n = BufferLength;
|
if (n>BufferLength) n = (size_t)BufferLength;
|
||||||
strncpy((char*)ColumnName, field->name, n);
|
strncpy((char*)ColumnName, field->name, n);
|
||||||
}
|
}
|
||||||
if (NameLength) {
|
if (NameLength) {
|
||||||
*NameLength = strnlen(field->name, sizeof(field->name));
|
*NameLength = (SQLSMALLINT)strnlen(field->name, sizeof(field->name));
|
||||||
}
|
}
|
||||||
if (ColumnSize) *ColumnSize = field->bytes;
|
if (ColumnSize) *ColumnSize = (SQLULEN)field->bytes;
|
||||||
if (DecimalDigits) *DecimalDigits = 0;
|
if (DecimalDigits) *DecimalDigits = 0;
|
||||||
|
|
||||||
if (DataType) {
|
if (DataType) {
|
||||||
|
@ -2334,7 +2332,7 @@ static SQLRETURN doSQLNumParams(SQLHSTMT hstmt, SQLSMALLINT *pcpar)
|
||||||
return SQL_ERROR;
|
return SQL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pcpar) *pcpar = params;
|
if (pcpar) *pcpar = (SQLSMALLINT)params;
|
||||||
|
|
||||||
return SQL_SUCCESS;
|
return SQL_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -2420,7 +2418,7 @@ static void init_routine(void) {
|
||||||
taos_init();
|
taos_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_field_display_size(TAOS_FIELD *field) {
|
static size_t do_field_display_size(TAOS_FIELD *field) {
|
||||||
switch (field->type) {
|
switch (field->type) {
|
||||||
case TSDB_DATA_TYPE_TINYINT:
|
case TSDB_DATA_TYPE_TINYINT:
|
||||||
return 5;
|
return 5;
|
||||||
|
@ -2448,7 +2446,7 @@ static int do_field_display_size(TAOS_FIELD *field) {
|
||||||
|
|
||||||
case TSDB_DATA_TYPE_BINARY:
|
case TSDB_DATA_TYPE_BINARY:
|
||||||
case TSDB_DATA_TYPE_NCHAR: {
|
case TSDB_DATA_TYPE_NCHAR: {
|
||||||
return 3*(field->bytes - VARSTR_HEADER_SIZE) + 2;
|
return 3*((size_t)field->bytes - VARSTR_HEADER_SIZE) + 2;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case TSDB_DATA_TYPE_TIMESTAMP:
|
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
EXPORTS
|
||||||
|
SQLAllocEnv
|
||||||
|
SQLFreeEnv
|
||||||
|
SQLAllocConnect
|
||||||
|
SQLFreeConnect
|
||||||
|
SQLConnect
|
||||||
|
SQLDisconnect
|
||||||
|
SQLAllocStmt
|
||||||
|
SQLAllocHandle
|
||||||
|
SQLFreeStmt
|
||||||
|
SQLExecDirect
|
||||||
|
SQLExecDirectW
|
||||||
|
SQLNumResultCols
|
||||||
|
SQLRowCount
|
||||||
|
SQLColAttribute
|
||||||
|
SQLGetData
|
||||||
|
SQLFetch
|
||||||
|
SQLPrepare
|
||||||
|
SQLExecute
|
||||||
|
SQLGetDiagField
|
||||||
|
SQLGetDiagRec
|
||||||
|
SQLBindParameter
|
||||||
|
SQLDriverConnect
|
||||||
|
SQLSetConnectAttr
|
||||||
|
SQLDescribeCol
|
||||||
|
SQLNumParams
|
||||||
|
SQLSetStmtAttr
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
1 VERSIONINFO
|
||||||
|
FILEVERSION ${TD_VER_NUMBER}
|
||||||
|
PRODUCTVERSION ${TD_VER_NUMBER}
|
||||||
|
FILEFLAGSMASK 0x17L
|
||||||
|
#ifdef _DEBUG
|
||||||
|
FILEFLAGS 0x1L
|
||||||
|
#else
|
||||||
|
FILEFLAGS 0x0L
|
||||||
|
#endif
|
||||||
|
FILEOS 0x4L
|
||||||
|
FILETYPE 0x0L
|
||||||
|
FILESUBTYPE 0x0L
|
||||||
|
BEGIN
|
||||||
|
BLOCK "StringFileInfo"
|
||||||
|
BEGIN
|
||||||
|
BLOCK "040904b0"
|
||||||
|
BEGIN
|
||||||
|
VALUE "FileDescription", "ODBC Driver for TDengine"
|
||||||
|
VALUE "FileVersion", "${TD_VER_NUMBER}"
|
||||||
|
VALUE "InternalName", "todbc.dll(${TD_VER_CPUTYPE})"
|
||||||
|
VALUE "LegalCopyright", "Copyright (C) 2020 TAOS Data"
|
||||||
|
VALUE "OriginalFilename", ""
|
||||||
|
VALUE "ProductName", "todbc.dll(${TD_VER_CPUTYPE})"
|
||||||
|
VALUE "ProductVersion", "${TD_VER_NUMBER}"
|
||||||
|
END
|
||||||
|
END
|
||||||
|
BLOCK "VarFileInfo"
|
||||||
|
BEGIN
|
||||||
|
VALUE "Translation", 0x409, 1200
|
||||||
|
END
|
||||||
|
END
|
|
@ -0,0 +1,5 @@
|
||||||
|
INSTALLDRIVER "TAOS ODBC|Driver=todbc.dll|FileUsage=0|ConnectFunctions=YYN"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -15,8 +15,6 @@
|
||||||
|
|
||||||
#include "todbc_conv.h"
|
#include "todbc_conv.h"
|
||||||
|
|
||||||
#include "todbc_util.h"
|
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -74,7 +72,7 @@ TSDB_CONV_CODE tsdb_iconv_conv(iconv_t cnv, const unsigned char *src, size_t *sl
|
||||||
size_t sl = *slen;
|
size_t sl = *slen;
|
||||||
size_t dl = *dlen;
|
size_t dl = *dlen;
|
||||||
|
|
||||||
int n = iconv(cnv, &s, &sl, &d, &dl);
|
size_t n = iconv(cnv, &s, &sl, &d, &dl);
|
||||||
int e = errno;
|
int e = errno;
|
||||||
if (dl) *d = '\0'; // what if all consumed?
|
if (dl) *d = '\0'; // what if all consumed?
|
||||||
|
|
||||||
|
|
|
@ -16,11 +16,9 @@
|
||||||
#ifndef _todbc_conv_h_
|
#ifndef _todbc_conv_h_
|
||||||
#define _todbc_conv_h_
|
#define _todbc_conv_h_
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include "os.h"
|
||||||
#include <sqltypes.h>
|
#include <iconv.h>
|
||||||
#include <stddef.h>
|
#include <sql.h>
|
||||||
|
|
||||||
#include "iconv.h"
|
|
||||||
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
/*
|
||||||
|
* 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_FLEX_H_
|
||||||
|
#define _TODBC_FLEX_H_
|
||||||
|
|
||||||
|
int todbc_parse_conn_string(const char *conn, char **dsn, char **uid, char **pwd, char **host);
|
||||||
|
|
||||||
|
#endif // _TODBC_FLEX_H_
|
||||||
|
|
|
@ -16,9 +16,7 @@
|
||||||
#ifndef _todbc_log_h_
|
#ifndef _todbc_log_h_
|
||||||
#define _todbc_log_h_
|
#define _todbc_log_h_
|
||||||
|
|
||||||
#include <libgen.h>
|
#include "os.h"
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#define D(fmt, ...) \
|
#define D(fmt, ...) \
|
||||||
fprintf(stderr, \
|
fprintf(stderr, \
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
%{
|
%{
|
||||||
#include "todbc_util.h"
|
#include "todbc_flex.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#define strncasecmp _strnicmp
|
||||||
|
#define strcasecmp _stricmp
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct params_s params_t;
|
typedef struct params_s params_t;
|
||||||
struct params_s {
|
struct params_s {
|
||||||
char *key;
|
char *key;
|
||||||
|
@ -68,6 +72,8 @@ do { \
|
||||||
|
|
||||||
%option prefix="todbc_yy"
|
%option prefix="todbc_yy"
|
||||||
%option extra-type="struct params_s *"
|
%option extra-type="struct params_s *"
|
||||||
|
%option nounistd
|
||||||
|
%option never-interactive
|
||||||
%option reentrant
|
%option reentrant
|
||||||
%option noyywrap
|
%option noyywrap
|
||||||
%option noinput nounput
|
%option noinput nounput
|
||||||
|
@ -98,8 +104,7 @@ do { \
|
||||||
<EQ>[{] { CHG_STATE(BRACE1); }
|
<EQ>[{] { CHG_STATE(BRACE1); }
|
||||||
<EQ>.|\n { return -1; }
|
<EQ>.|\n { return -1; }
|
||||||
|
|
||||||
<BRACE1>[[:space:]]+ { }
|
<BRACE1>[^{}\n]+ { set_val(); CHG_STATE(BRACE2); }
|
||||||
<BRACE1>[^{}\n[:space:]]+ { set_val(); CHG_STATE(BRACE2); }
|
|
||||||
<BRACE1>.|\n { return -1; }
|
<BRACE1>.|\n { return -1; }
|
||||||
|
|
||||||
<BRACE2>[[:space:]]+ { }
|
<BRACE2>[[:space:]]+ { }
|
||||||
|
|
|
@ -14,14 +14,10 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "todbc_util.h"
|
#include "todbc_util.h"
|
||||||
|
#include "todbc_log.h"
|
||||||
#include "iconv.h"
|
#include <iconv.h>
|
||||||
|
|
||||||
#include <sql.h>
|
|
||||||
#include <sqltypes.h>
|
|
||||||
#include <sqlext.h>
|
#include <sqlext.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
const char* sql_sql_type(int type) {
|
const char* sql_sql_type(int type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
@ -125,7 +121,7 @@ int string_conv(const char *fromcode, const char *tocode,
|
||||||
iconv_t conv = iconv_open(tocode, fromcode);
|
iconv_t conv = iconv_open(tocode, fromcode);
|
||||||
if (!conv) return -1;
|
if (!conv) return -1;
|
||||||
|
|
||||||
int r = 0;
|
size_t r = 0;
|
||||||
do {
|
do {
|
||||||
char *s = (char*)src;
|
char *s = (char*)src;
|
||||||
char *d = (char*)dst;
|
char *d = (char*)dst;
|
||||||
|
@ -141,7 +137,7 @@ int string_conv(const char *fromcode, const char *tocode,
|
||||||
} while (0);
|
} while (0);
|
||||||
|
|
||||||
iconv_close(conv);
|
iconv_close(conv);
|
||||||
return r;
|
return (int)r;
|
||||||
}
|
}
|
||||||
|
|
||||||
int utf8_chars(const char *src)
|
int utf8_chars(const char *src)
|
||||||
|
@ -161,7 +157,7 @@ int utf8_chars(const char *src)
|
||||||
|
|
||||||
size_t chars = (sizeof(buf) - dlen) / 2;
|
size_t chars = (sizeof(buf) - dlen) / 2;
|
||||||
iconv_close(conv);
|
iconv_close(conv);
|
||||||
return chars;
|
return (int)chars;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char* utf8_to_ucs4le(const char *utf8, size_t *chars)
|
unsigned char* utf8_to_ucs4le(const char *utf8, size_t *chars)
|
||||||
|
@ -240,7 +236,7 @@ size_t wchars_to_chars2(const SQLWCHAR *src, size_t slen, SQLCHAR *dst, size_t d
|
||||||
{
|
{
|
||||||
size_t consumed=0, generated=0;
|
size_t consumed=0, generated=0;
|
||||||
int n = string_conv("UCS-2LE", "UTF-8", (const unsigned char*)src, slen, dst, dlen, &consumed, &generated);
|
int n = string_conv("UCS-2LE", "UTF-8", (const unsigned char*)src, slen, dst, dlen, &consumed, &generated);
|
||||||
if (n) return -1;
|
if (n) return (size_t)-1;
|
||||||
return generated;
|
return generated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,7 +244,7 @@ size_t chars_to_wchars2(const SQLCHAR *src, size_t slen, SQLWCHAR *dst, size_t d
|
||||||
{
|
{
|
||||||
size_t consumed=0, generated=0;
|
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);
|
int n = string_conv("UTF-8", "UCS-2LE", (const unsigned char*)src, slen, (unsigned char*)dst, dlen, &consumed, &generated);
|
||||||
if (n) return -1;
|
if (n) return (size_t)-1;
|
||||||
return generated;
|
return generated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,10 +16,10 @@
|
||||||
#ifndef _TODBC_UTIL_H_
|
#ifndef _TODBC_UTIL_H_
|
||||||
#define _TODBC_UTIL_H_
|
#define _TODBC_UTIL_H_
|
||||||
|
|
||||||
#include "todbc_log.h"
|
#include "os.h"
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <sql.h>
|
#include <sql.h>
|
||||||
|
#include <sqltypes.h>
|
||||||
|
|
||||||
const char* sql_sql_type(int type);
|
const char* sql_sql_type(int type);
|
||||||
const char* sql_c_type(int type);
|
const char* sql_c_type(int type);
|
||||||
|
@ -27,8 +27,6 @@ const char* sql_c_type(int type);
|
||||||
int is_valid_sql_c_type(int type);
|
int is_valid_sql_c_type(int type);
|
||||||
int is_valid_sql_sql_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,
|
int string_conv(const char *fromcode, const char *tocode,
|
||||||
const unsigned char *src, size_t sbytes,
|
const unsigned char *src, size_t sbytes,
|
||||||
unsigned char *dst, size_t dbytes,
|
unsigned char *dst, size_t dbytes,
|
||||||
|
|
|
@ -5,3 +5,9 @@ IF (TD_LINUX)
|
||||||
ADD_EXECUTABLE(tcodbc main.c)
|
ADD_EXECUTABLE(tcodbc main.c)
|
||||||
TARGET_LINK_LIBRARIES(tcodbc odbc)
|
TARGET_LINK_LIBRARIES(tcodbc odbc)
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
|
IF (TD_WINDOWS_64)
|
||||||
|
AUX_SOURCE_DIRECTORY(. SRC)
|
||||||
|
ADD_EXECUTABLE(tcodbc main.c)
|
||||||
|
TARGET_LINK_LIBRARIES(tcodbc odbc32 os)
|
||||||
|
ENDIF ()
|
||||||
|
|
|
@ -1,17 +1,16 @@
|
||||||
#include <libgen.h>
|
#include "../src/todbc_log.h"
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#include <winsock2.h>
|
||||||
|
#include <windows.h>
|
||||||
|
#include "os.h"
|
||||||
|
#endif
|
||||||
#include <sql.h>
|
#include <sql.h>
|
||||||
#include <sqlext.h>
|
#include <sqlext.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#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) \
|
#define CHK_TEST(statement) \
|
||||||
do { \
|
do { \
|
||||||
D("testing: %s", #statement); \
|
D("testing: %s", #statement); \
|
||||||
|
@ -72,9 +71,9 @@ static int open_connect(const char *dsn, const char *uid, const char *pwd, SQLHE
|
||||||
CHK_RESULT(r, SQL_HANDLE_ENV, env, "");
|
CHK_RESULT(r, SQL_HANDLE_ENV, env, "");
|
||||||
if (r!=SQL_SUCCESS) break;
|
if (r!=SQL_SUCCESS) break;
|
||||||
do {
|
do {
|
||||||
r = SQLConnect(conn, (SQLCHAR*)dsn, strlen(dsn),
|
r = SQLConnect(conn, (SQLCHAR*)dsn, (SQLSMALLINT)strlen(dsn),
|
||||||
(SQLCHAR*)uid, strlen(uid),
|
(SQLCHAR*)uid, (SQLSMALLINT)strlen(uid),
|
||||||
(SQLCHAR*)pwd, strlen(pwd));
|
(SQLCHAR*)pwd, (SQLSMALLINT)strlen(pwd));
|
||||||
CHK_RESULT(r, SQL_HANDLE_DBC, conn, "");
|
CHK_RESULT(r, SQL_HANDLE_DBC, conn, "");
|
||||||
if (r==SQL_SUCCESS) {
|
if (r==SQL_SUCCESS) {
|
||||||
*pEnv = env;
|
*pEnv = env;
|
||||||
|
@ -105,7 +104,7 @@ static int open_driver_connect(const char *connstr, SQLHENV *pEnv, SQLHDBC *pCon
|
||||||
SQLHDBC ConnectionHandle = conn;
|
SQLHDBC ConnectionHandle = conn;
|
||||||
SQLHWND WindowHandle = NULL;
|
SQLHWND WindowHandle = NULL;
|
||||||
SQLCHAR * InConnectionString = (SQLCHAR*)connstr;
|
SQLCHAR * InConnectionString = (SQLCHAR*)connstr;
|
||||||
SQLSMALLINT StringLength1 = strlen(connstr);
|
SQLSMALLINT StringLength1 = (SQLSMALLINT)strlen(connstr);
|
||||||
SQLCHAR * OutConnectionString = buf;
|
SQLCHAR * OutConnectionString = buf;
|
||||||
SQLSMALLINT BufferLength = sizeof(buf);
|
SQLSMALLINT BufferLength = sizeof(buf);
|
||||||
SQLSMALLINT * StringLength2Ptr = &blen;
|
SQLSMALLINT * StringLength2Ptr = &blen;
|
||||||
|
@ -144,7 +143,7 @@ static int do_statement(SQLHSTMT stmt, const char *statement) {
|
||||||
CHK_RESULT(r, SQL_HANDLE_STMT, stmt, "");
|
CHK_RESULT(r, SQL_HANDLE_STMT, stmt, "");
|
||||||
for (size_t i=0; i<cols; ++i) {
|
for (size_t i=0; i<cols; ++i) {
|
||||||
SQLLEN soi = 0;
|
SQLLEN soi = 0;
|
||||||
r = SQLGetData(stmt, i+1, SQL_C_CHAR, buf, sizeof(buf), &soi);
|
r = SQLGetData(stmt, (SQLUSMALLINT)(i+1), SQL_C_CHAR, buf, sizeof(buf), &soi);
|
||||||
CHK_RESULT(r, SQL_HANDLE_STMT, stmt, "");
|
CHK_RESULT(r, SQL_HANDLE_STMT, stmt, "");
|
||||||
if (r) {
|
if (r) {
|
||||||
if (r!=SQL_SUCCESS_WITH_INFO) {
|
if (r!=SQL_SUCCESS_WITH_INFO) {
|
||||||
|
@ -185,10 +184,10 @@ static int do_insert(SQLHSTMT stmt, data_t data) {
|
||||||
SQLLEN lblob;
|
SQLLEN lblob;
|
||||||
|
|
||||||
const char *statement = "insert into t values (?, ?, ?, ?, ?, ?, ?, ?, ?,?)";
|
const char *statement = "insert into t values (?, ?, ?, ?, ?, ?, ?, ?, ?,?)";
|
||||||
int ignored = 0;
|
#define ignored 0
|
||||||
|
|
||||||
do {
|
do {
|
||||||
r = SQLPrepare(stmt, (SQLCHAR*)statement, strlen(statement));
|
r = SQLPrepare(stmt, (SQLCHAR*)statement, (SQLINTEGER)strlen(statement));
|
||||||
CHK_RESULT(r, SQL_HANDLE_STMT, stmt, "statement: %s", statement);
|
CHK_RESULT(r, SQL_HANDLE_STMT, stmt, "statement: %s", statement);
|
||||||
if (r) break;
|
if (r) break;
|
||||||
|
|
||||||
|
@ -243,28 +242,30 @@ static int do_insert(SQLHSTMT stmt, data_t data) {
|
||||||
// r = SQLExecute(stmt);
|
// r = SQLExecute(stmt);
|
||||||
// if (r) break;
|
// if (r) break;
|
||||||
} while (0);
|
} while (0);
|
||||||
|
|
||||||
|
#undef ignored
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int test1(const char *dsn, const char *uid, const char *pwd) {
|
static int test1(const char *dsn, const char *uid, const char *pwd) {
|
||||||
SQLRETURN r = SQL_SUCCESS;
|
|
||||||
SQLHENV env = {0};
|
SQLHENV env = {0};
|
||||||
SQLHDBC conn = {0};
|
SQLHDBC conn = {0};
|
||||||
int n = open_connect(dsn, uid, pwd, &env, &conn);
|
int n = open_connect(dsn, uid, pwd, &env, &conn);
|
||||||
if (n) return 1;
|
if (n) return 1;
|
||||||
|
|
||||||
|
int ok = 0;
|
||||||
do {
|
do {
|
||||||
|
SQLRETURN r = SQL_SUCCESS;
|
||||||
SQLHSTMT stmt = {0};
|
SQLHSTMT stmt = {0};
|
||||||
r = SQLAllocHandle(SQL_HANDLE_STMT, conn, &stmt);
|
r = SQLAllocHandle(SQL_HANDLE_STMT, conn, &stmt);
|
||||||
if (r!=SQL_SUCCESS) break;
|
if (r!=SQL_SUCCESS) break;
|
||||||
do {
|
do {
|
||||||
if (do_statement(stmt, "drop database if exists db")) {
|
if (do_statement(stmt, "drop database if exists db")) {
|
||||||
r = SQL_ERROR;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
for (size_t i=0; i<sizeof(pre_stmts)/sizeof(pre_stmts[0]); ++i) {
|
for (size_t i=0; i<sizeof(pre_stmts)/sizeof(pre_stmts[0]); ++i) {
|
||||||
r = do_statement(stmt, pre_stmts[i]);
|
n = do_statement(stmt, pre_stmts[i]);
|
||||||
if (r!=SQL_SUCCESS) break;
|
if (n) break;
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
data_t data = {0};
|
data_t data = {0};
|
||||||
|
@ -274,7 +275,7 @@ static int test1(const char *dsn, const char *uid, const char *pwd) {
|
||||||
data.v2 = 32767;
|
data.v2 = 32767;
|
||||||
data.v4 = 2147483647;
|
data.v4 = 2147483647;
|
||||||
data.v8 = 9223372036854775807;
|
data.v8 = 9223372036854775807;
|
||||||
data.f4 = 123.456;
|
data.f4 = 123.456f;
|
||||||
data.f8 = 9999999.999999;
|
data.f8 = 9999999.999999;
|
||||||
memset(data.bin, 0, sizeof(data.bin));
|
memset(data.bin, 0, sizeof(data.bin));
|
||||||
memset(data.blob, 0, sizeof(data.blob));
|
memset(data.blob, 0, sizeof(data.blob));
|
||||||
|
@ -285,8 +286,8 @@ static int test1(const char *dsn, const char *uid, const char *pwd) {
|
||||||
r = SQLAllocHandle(SQL_HANDLE_STMT, conn, &stmt);
|
r = SQLAllocHandle(SQL_HANDLE_STMT, conn, &stmt);
|
||||||
if (r!=SQL_SUCCESS) break;
|
if (r!=SQL_SUCCESS) break;
|
||||||
do {
|
do {
|
||||||
r = do_insert(stmt, data);
|
n = do_insert(stmt, data);
|
||||||
if (r!=SQL_SUCCESS) break;
|
if (n) break;
|
||||||
} while (0);
|
} while (0);
|
||||||
SQLFreeHandle(SQL_HANDLE_STMT, stmt);
|
SQLFreeHandle(SQL_HANDLE_STMT, stmt);
|
||||||
|
|
||||||
|
@ -297,12 +298,15 @@ static int test1(const char *dsn, const char *uid, const char *pwd) {
|
||||||
// if (r!=SQL_SUCCESS) break;
|
// if (r!=SQL_SUCCESS) break;
|
||||||
// } while (0);
|
// } while (0);
|
||||||
// SQLFreeHandle(SQL_HANDLE_STMT, stmt);
|
// SQLFreeHandle(SQL_HANDLE_STMT, stmt);
|
||||||
|
ok = 1;
|
||||||
} while (0);
|
} while (0);
|
||||||
if (r!=SQL_SUCCESS) break;
|
if (!ok) break;
|
||||||
|
ok = 0;
|
||||||
for (size_t i=0; i<sizeof(pro_stmts)/sizeof(pro_stmts[0]); ++i) {
|
for (size_t i=0; i<sizeof(pro_stmts)/sizeof(pro_stmts[0]); ++i) {
|
||||||
r = do_statement(stmt, pro_stmts[i]);
|
n = do_statement(stmt, pro_stmts[i]);
|
||||||
if (r!=SQL_SUCCESS) break;
|
if (n) break;
|
||||||
}
|
}
|
||||||
|
ok = 1;
|
||||||
} while (0);
|
} while (0);
|
||||||
SQLFreeHandle(SQL_HANDLE_STMT, stmt);
|
SQLFreeHandle(SQL_HANDLE_STMT, stmt);
|
||||||
} while (0);
|
} while (0);
|
||||||
|
@ -310,7 +314,7 @@ static int test1(const char *dsn, const char *uid, const char *pwd) {
|
||||||
SQLFreeConnect(conn);
|
SQLFreeConnect(conn);
|
||||||
SQLFreeEnv(env);
|
SQLFreeEnv(env);
|
||||||
|
|
||||||
return r ? 1 : 0;
|
return ok ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int test_statements(const char *dsn, const char *uid, const char *pwd, const char **statements) {
|
int test_statements(const char *dsn, const char *uid, const char *pwd, const char **statements) {
|
||||||
|
@ -418,7 +422,12 @@ int test_sqls_in_stmt(SQLHENV env, SQLHDBC conn, SQLHSTMT stmt, const char *sqls
|
||||||
char *line = NULL;
|
char *line = NULL;
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
|
|
||||||
ssize_t n = getline(&line, &len, f);
|
ssize_t n = 0;
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
n = taosGetline(&line, &len, f);
|
||||||
|
#else
|
||||||
|
n = getline(&line, &len, f);
|
||||||
|
#endif
|
||||||
if (n==-1) break;
|
if (n==-1) break;
|
||||||
|
|
||||||
const char *p = NULL;
|
const char *p = NULL;
|
||||||
|
@ -493,6 +502,11 @@ int main(int argc, char *argv[]) {
|
||||||
const char *connstr = (argc>4) ? argv[4] : NULL;
|
const char *connstr = (argc>4) ? argv[4] : NULL;
|
||||||
const char *sqls = (argc>5) ? argv[5] : NULL;
|
const char *sqls = (argc>5) ? argv[5] : NULL;
|
||||||
|
|
||||||
|
dsn = NULL;
|
||||||
|
uid = NULL;
|
||||||
|
pwd = NULL;
|
||||||
|
connstr = argv[1];
|
||||||
|
sqls = argv[2];
|
||||||
if (0) {
|
if (0) {
|
||||||
CHK_TEST(test_env());
|
CHK_TEST(test_env());
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
P:drop database if exists m;
|
||||||
|
P:create database m;
|
||||||
|
P:use m;
|
||||||
|
|
||||||
|
P: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));
|
||||||
|
P:insert into t (ts, b) values('2020-10-10 00:00:00', 0);
|
||||||
|
P:insert into t (ts, b) values('2020-10-10 00:00:00.001', 1);
|
||||||
|
P:insert into t (ts, b) values('2020-10-10 00:00:00.002', 10);
|
||||||
|
P:select * from t;
|
||||||
|
|
||||||
|
P:drop table t;
|
||||||
|
P: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));
|
||||||
|
P:insert into t (ts, v1) values('2020-10-10 00:00:00', 0);
|
||||||
|
P:insert into t (ts, v1) values('2020-10-10 00:00:00.001', 1);
|
||||||
|
P:insert into t (ts, v1) values('2020-10-10 00:00:00.002', 10);
|
||||||
|
P:select * from t;
|
||||||
|
|
||||||
|
P:drop table t;
|
||||||
|
P: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));
|
||||||
|
P:insert into t (ts, name) values('2020-10-10 00:00:00', 0);
|
||||||
|
P:insert into t (ts, name) values('2020-10-10 00:00:00.001', 1);
|
||||||
|
P:insert into t (ts, name) values('2020-10-10 00:00:00.002', '人');
|
||||||
|
P:insert into t (ts, name) values('2020-10-10 00:00:00.003', 'a');
|
||||||
|
P:select * from t;
|
||||||
|
|
||||||
|
P:drop table t;
|
||||||
|
P:create table t (ts timestamp, b bool, v1 tinyint, v2 smallint, v4 int, v8 bigint, f4 float, f8 double, blob binary(3), name nchar(1));
|
||||||
|
P:insert into t (ts, blob) values('2020-10-10 00:00:00', 0);
|
||||||
|
P:insert into t (ts, blob) values('2020-10-10 00:00:00.001', 1);
|
||||||
|
P:insert into t (ts, blob) values('2020-10-10 00:00:00.002', 'a');
|
||||||
|
P:insert into t (ts, blob) values('2020-10-10 00:00:00.003', 'b');
|
||||||
|
P:insert into t (ts, blob) values('2020-10-10 00:00:00.004', '人');
|
||||||
|
P:select * from t;
|
||||||
|
|
||||||
|
P:drop table t;
|
||||||
|
P:create table t (ts timestamp, b bool, v1 tinyint, v2 smallint, v4 int, v8 bigint, f4 float, f8 double, blob binary(3), name nchar(1));
|
||||||
|
N:insert into t (ts, blob) values('2020-10-10 00:00:00', '1234');
|
||||||
|
N:insert into t (ts, blob) values('2020-10-10 00:00:00.001', '0000');
|
||||||
|
N:insert into t (ts, blob) values('2020-10-10 00:00:00.002', '人a');
|
||||||
|
P:insert into t (ts, blob) values('2020-10-10 00:00:00.003', 'a');
|
||||||
|
P:insert into t (ts, blob) values('2020-10-10 00:00:00.004', 'b');
|
||||||
|
P:insert into t (ts, blob) values('2020-10-10 00:00:00.005', '人');
|
||||||
|
P:select * from t;
|
||||||
|
|
|
@ -24,9 +24,9 @@ extern "C" {
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#ifdef TAOS_ERROR_C
|
#ifdef TAOS_ERROR_C
|
||||||
#define TAOS_DEFINE_ERROR(name, mod, code, msg) {.val = (0x80000000 | ((mod)<<16) | (code)), .str=(msg)},
|
#define TAOS_DEFINE_ERROR(name, mod, code, msg) {.val = (int32_t)((0x80000000 | ((mod)<<16) | (code))), .str=(msg)},
|
||||||
#else
|
#else
|
||||||
#define TAOS_DEFINE_ERROR(name, mod, code, msg) static const int32_t name = (0x80000000 | ((mod)<<16) | (code));
|
#define TAOS_DEFINE_ERROR(name, mod, code, msg) static const int32_t name = (int32_t)((0x80000000 | ((mod)<<16) | (code)));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define TAOS_SYSTEM_ERROR(code) (0x80ff0000 | (code))
|
#define TAOS_SYSTEM_ERROR(code) (0x80ff0000 | (code))
|
||||||
|
|
|
@ -38,14 +38,14 @@ int32_t taosGetTimestampSec();
|
||||||
static FORCE_INLINE int64_t taosGetTimestampMs() {
|
static FORCE_INLINE int64_t taosGetTimestampMs() {
|
||||||
struct timeval systemTime;
|
struct timeval systemTime;
|
||||||
gettimeofday(&systemTime, NULL);
|
gettimeofday(&systemTime, NULL);
|
||||||
return (int64_t)systemTime.tv_sec * 1000L + (uint64_t)systemTime.tv_usec / 1000;
|
return (int64_t)systemTime.tv_sec * 1000L + (int64_t)systemTime.tv_usec / 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
//@return timestamp in microsecond
|
//@return timestamp in microsecond
|
||||||
static FORCE_INLINE int64_t taosGetTimestampUs() {
|
static FORCE_INLINE int64_t taosGetTimestampUs() {
|
||||||
struct timeval systemTime;
|
struct timeval systemTime;
|
||||||
gettimeofday(&systemTime, NULL);
|
gettimeofday(&systemTime, NULL);
|
||||||
return (int64_t)systemTime.tv_sec * 1000000L + (uint64_t)systemTime.tv_usec;
|
return (int64_t)systemTime.tv_sec * 1000000L + (int64_t)systemTime.tv_usec;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
#include "msvcProcess.h"
|
#include "msvcProcess.h"
|
||||||
#include "msvcDirect.h"
|
#include "msvcDirect.h"
|
||||||
#include "msvcFcntl.h"
|
#include "msvcFcntl.h"
|
||||||
|
#include "msvcLibgen.h"
|
||||||
#include "msvcStdio.h"
|
#include "msvcStdio.h"
|
||||||
#include "sys/msvcStat.h"
|
#include "sys/msvcStat.h"
|
||||||
#include "sys/msvcTypes.h"
|
#include "sys/msvcTypes.h"
|
||||||
|
|
|
@ -31,7 +31,10 @@
|
||||||
#pragma comment(lib, "Mswsock.lib ")
|
#pragma comment(lib, "Mswsock.lib ")
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable:4091)
|
||||||
#include <DbgHelp.h>
|
#include <DbgHelp.h>
|
||||||
|
#pragma warning(pop)
|
||||||
|
|
||||||
static void taosGetSystemTimezone() {
|
static void taosGetSystemTimezone() {
|
||||||
// get and set default timezone
|
// get and set default timezone
|
||||||
|
|
Loading…
Reference in New Issue