feat:[TD-32642] add timezone support in windows
This commit is contained in:
parent
86c2d5c1c0
commit
5cfadb657f
|
@ -661,9 +661,10 @@ ELSEIF(TD_DARWIN)
|
||||||
SET(TZ_OUTPUT_PATH /var/db/timezone/zoneinfo)
|
SET(TZ_OUTPUT_PATH /var/db/timezone/zoneinfo)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
MESSAGE(STATUS "timezone file path: " ${TZ_OUTPUT_PATH})
|
|
||||||
|
|
||||||
if(NOT ${TD_WINDOWS})
|
if(NOT ${TD_WINDOWS})
|
||||||
|
MESSAGE(STATUS "timezone file path: " ${TZ_OUTPUT_PATH})
|
||||||
|
|
||||||
execute_process(
|
execute_process(
|
||||||
COMMAND make TZDIR=${TZ_OUTPUT_PATH}/ tzdir.h
|
COMMAND make TZDIR=${TZ_OUTPUT_PATH}/ tzdir.h
|
||||||
WORKING_DIRECTORY "${TD_CONTRIB_DIR}/tz"
|
WORKING_DIRECTORY "${TD_CONTRIB_DIR}/tz"
|
||||||
|
|
|
@ -687,12 +687,22 @@ TDengine 客户端驱动的版本号与 TDengine 服务端的版本号是一一
|
||||||
- **返回值**:`0`:成功,`-1`:失败。
|
- **返回值**:`0`:成功,`-1`:失败。
|
||||||
|
|
||||||
- `int taos_options_connection(TAOS *taos, TSDB_OPTION_CONNECTION option, const void *arg, ...)`
|
- `int taos_options_connection(TAOS *taos, TSDB_OPTION_CONNECTION option, const void *arg, ...)`
|
||||||
- **接口说明**:设置客户端每个连接选项(不影响服务端的行为,特别对于 charset 和 timezone),目前支持字符集设置(`TSDB_OPTION_CONNECTION_CHARSET`)、时区设置(`TSDB_OPTION_CONNECTION_TIMEZONE`)、用户 IP 设置(`TSDB_OPTION_CONNECTION_USER_IP`)、用户 APP 设置(`TSDB_OPTION_CONNECTION_USER_APP`)。字符集、时区默认为操作系统当前设置,windows 不支持连接级别的时区设置,多次调用接口设置相同的配置,以后面的设置为准。
|
- **接口说明**:设置客户端每个连接选项,目前支持字符集设置(`TSDB_OPTION_CONNECTION_CHARSET`)、时区设置(`TSDB_OPTION_CONNECTION_TIMEZONE`)、用户 IP 设置(`TSDB_OPTION_CONNECTION_USER_IP`)、用户 APP 设置(`TSDB_OPTION_CONNECTION_USER_APP`)。
|
||||||
- **参数说明**:
|
- **参数说明**:
|
||||||
- `taos`: [入参] taos_connect 返回的连接句柄。
|
- `taos`: [入参] taos_connect 返回的连接句柄。
|
||||||
- `option`:[入参] 设置项类型,具体类型的使用方法及约束详见 taos.h 文件。
|
- `option`:[入参] 设置项类型。
|
||||||
- `arg`:[入参] 设置项值。为 NULL 时表示重置该选项。
|
- `arg`:[入参] 设置项值。
|
||||||
- **返回值**:`0`:成功,`非0`:失败。
|
- **返回值**:`0`:成功,`非0`:失败。
|
||||||
|
- **说明**:
|
||||||
|
- 字符集、时区默认为操作系统当前设置,windows 不支持连接级别的时区设置。
|
||||||
|
- arg 为 NULL 时表示重置该选项。
|
||||||
|
- 该接口只对当前连接有效,不会影响其他连接。
|
||||||
|
- 同样参数多次调用该接口,以后面的为准,可以作为修改的方法。
|
||||||
|
- TSDB_OPTION_CONNECTION_CLEAR 选项用于重置所有连接选项。
|
||||||
|
- 时区和字符集重置后,使用操作系统的设置,user ip 和 user app 重置后为空。
|
||||||
|
- 连接选项的值都是 string 类型,user app 参数值最大为 23,超过该值会被截断;其他参数非法时报错。
|
||||||
|
- 时区参数设置为空或非法时,默认为 UTC。
|
||||||
|
- 时区和字符集只在 client 侧起作用,对于在服务端的相关行为不起作用。
|
||||||
|
|
||||||
- `char *taos_get_client_info()`
|
- `char *taos_get_client_info()`
|
||||||
- **接口说明**:获取客户端版本信息。
|
- **接口说明**:获取客户端版本信息。
|
||||||
|
|
|
@ -181,31 +181,14 @@ typedef struct TAOS_STMT_OPTIONS {
|
||||||
bool singleTableBindOnce;
|
bool singleTableBindOnce;
|
||||||
} TAOS_STMT_OPTIONS;
|
} TAOS_STMT_OPTIONS;
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
description:
|
|
||||||
taos_options_connection use to set extra connect options and affect behavior for a connection.
|
|
||||||
This function may be called multiple times to set several options.
|
|
||||||
Call taos_options_connection() after taos_connect() or taos_connect_auth().
|
|
||||||
The option argument is the option that you want to set; the arg argument is the value for the option.
|
|
||||||
If you want to reset the option, set arg to NULL.
|
|
||||||
input:
|
|
||||||
taos: returned by taos_connect
|
|
||||||
option: option name
|
|
||||||
arg: option value
|
|
||||||
output:
|
|
||||||
0: success
|
|
||||||
others: fail, error msg can be got by taos_errstr(NULL)
|
|
||||||
*/
|
|
||||||
DLL_EXPORT int taos_options_connection(TAOS *taos, TSDB_OPTION_CONNECTION option, const void *arg, ...);
|
|
||||||
|
|
||||||
DLL_EXPORT void taos_cleanup(void);
|
DLL_EXPORT void taos_cleanup(void);
|
||||||
DLL_EXPORT int taos_options(TSDB_OPTION option, const void *arg, ...);
|
DLL_EXPORT int taos_options(TSDB_OPTION option, const void *arg, ...);
|
||||||
|
DLL_EXPORT int taos_options_connection(TAOS *taos, TSDB_OPTION_CONNECTION option, const void *arg, ...);
|
||||||
DLL_EXPORT setConfRet taos_set_config(const char *config);
|
DLL_EXPORT setConfRet taos_set_config(const char *config);
|
||||||
DLL_EXPORT int taos_init(void);
|
DLL_EXPORT int taos_init(void);
|
||||||
DLL_EXPORT TAOS *taos_connect(const char *ip, const char *user, const char *pass, const char *db, uint16_t port);
|
DLL_EXPORT TAOS *taos_connect(const char *ip, const char *user, const char *pass, const char *db, uint16_t port);
|
||||||
DLL_EXPORT TAOS *taos_connect_auth(const char *ip, const char *user, const char *auth, const char *db, uint16_t port);
|
DLL_EXPORT TAOS *taos_connect_auth(const char *ip, const char *user, const char *auth, const char *db, uint16_t port);
|
||||||
DLL_EXPORT void taos_close(TAOS *taos);
|
DLL_EXPORT void taos_close(TAOS *taos);
|
||||||
|
|
||||||
DLL_EXPORT const char *taos_data_type(int type);
|
DLL_EXPORT const char *taos_data_type(int type);
|
||||||
|
|
||||||
|
|
|
@ -413,18 +413,20 @@ static FORCE_INLINE int32_t tDecodeBinary(SDecoder* pCoder, uint8_t** val, uint3
|
||||||
|
|
||||||
static FORCE_INLINE int32_t tDecodeCStrAndLen(SDecoder* pCoder, char** val, uint32_t* len) {
|
static FORCE_INLINE int32_t tDecodeCStrAndLen(SDecoder* pCoder, char** val, uint32_t* len) {
|
||||||
TAOS_CHECK_RETURN(tDecodeBinary(pCoder, (uint8_t**)val, len));
|
TAOS_CHECK_RETURN(tDecodeBinary(pCoder, (uint8_t**)val, len));
|
||||||
(*len) -= 1; // *len = 0 - 1
|
if (*len > 0) { // notice!!! *len maybe 0
|
||||||
|
(*len) -= 1;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static FORCE_INLINE int32_t tDecodeCStr(SDecoder* pCoder, char** val) {
|
static FORCE_INLINE int32_t tDecodeCStr(SDecoder* pCoder, char** val) {
|
||||||
uint32_t len;
|
uint32_t len = 0;
|
||||||
return tDecodeCStrAndLen(pCoder, val, &len);
|
return tDecodeCStrAndLen(pCoder, val, &len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t tDecodeCStrTo(SDecoder* pCoder, char* val) {
|
static int32_t tDecodeCStrTo(SDecoder* pCoder, char* val) {
|
||||||
char* pStr;
|
char* pStr = NULL;
|
||||||
uint32_t len;
|
uint32_t len = 0;
|
||||||
TAOS_CHECK_RETURN(tDecodeCStrAndLen(pCoder, &pStr, &len));
|
TAOS_CHECK_RETURN(tDecodeCStrAndLen(pCoder, &pStr, &len));
|
||||||
|
|
||||||
if (len < pCoder->size) {
|
if (len < pCoder->size) {
|
||||||
|
@ -482,12 +484,14 @@ static FORCE_INLINE int32_t tDecodeBinaryAlloc32(SDecoder* pCoder, void** val, u
|
||||||
|
|
||||||
static FORCE_INLINE int32_t tDecodeCStrAndLenAlloc(SDecoder* pCoder, char** val, uint64_t* len) {
|
static FORCE_INLINE int32_t tDecodeCStrAndLenAlloc(SDecoder* pCoder, char** val, uint64_t* len) {
|
||||||
TAOS_CHECK_RETURN(tDecodeBinaryAlloc(pCoder, (void**)val, len));
|
TAOS_CHECK_RETURN(tDecodeBinaryAlloc(pCoder, (void**)val, len));
|
||||||
(*len) -= 1;
|
if (*len > 0){
|
||||||
|
(*len) -= 1;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static FORCE_INLINE int32_t tDecodeCStrAlloc(SDecoder* pCoder, char** val) {
|
static FORCE_INLINE int32_t tDecodeCStrAlloc(SDecoder* pCoder, char** val) {
|
||||||
uint64_t len;
|
uint64_t len = 0;
|
||||||
return tDecodeCStrAndLenAlloc(pCoder, val, &len);
|
return tDecodeCStrAndLenAlloc(pCoder, val, &len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1489,4 +1489,124 @@ TEST(clientCase, sub_tb_mt_test) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(clientCase, timezone_Test) {
|
||||||
|
{
|
||||||
|
// taos_options( TSDB_OPTION_TIMEZONE, "UTC-8");
|
||||||
|
int code = taos_options(TSDB_OPTION_TIMEZONE, "UTC-8");
|
||||||
|
ASSERT_TRUE(code == 0);
|
||||||
|
TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
|
||||||
|
ASSERT_NE(pConn, nullptr);
|
||||||
|
|
||||||
|
TAOS_RES* pRes = taos_query(pConn, "drop database if exists db1");
|
||||||
|
ASSERT_EQ(taos_errno(pRes), TSDB_CODE_SUCCESS);
|
||||||
|
taos_free_result(pRes);
|
||||||
|
|
||||||
|
pRes = taos_query(pConn, "create database db1");
|
||||||
|
ASSERT_EQ(taos_errno(pRes), TSDB_CODE_SUCCESS);
|
||||||
|
taos_free_result(pRes);
|
||||||
|
|
||||||
|
pRes = taos_query(pConn, "create table db1.t1 (ts timestamp, v int)");
|
||||||
|
ASSERT_EQ(taos_errno(pRes), TSDB_CODE_SUCCESS);
|
||||||
|
taos_free_result(pRes);
|
||||||
|
|
||||||
|
char sql[256] = {0};
|
||||||
|
(void)sprintf(sql, "insert into db1.t1 values('2023-09-16 17:00:00', 1)");
|
||||||
|
pRes = taos_query(pConn, sql);
|
||||||
|
ASSERT_EQ(taos_errno(pRes), TSDB_CODE_SUCCESS);
|
||||||
|
taos_free_result(pRes);
|
||||||
|
|
||||||
|
pRes = taos_query(pConn, "select * from db1.t1 where ts == '2023-09-16 17:00:00'");
|
||||||
|
ASSERT_EQ(taos_errno(pRes), TSDB_CODE_SUCCESS);
|
||||||
|
|
||||||
|
TAOS_ROW pRow = NULL;
|
||||||
|
TAOS_FIELD* pFields = taos_fetch_fields(pRes);
|
||||||
|
int32_t numOfFields = taos_num_fields(pRes);
|
||||||
|
|
||||||
|
char str[512] = {0};
|
||||||
|
int rows = 0;
|
||||||
|
while ((pRow = taos_fetch_row(pRes)) != NULL) {
|
||||||
|
rows++;
|
||||||
|
}
|
||||||
|
ASSERT_TRUE(rows == 1);
|
||||||
|
|
||||||
|
taos_free_result(pRes);
|
||||||
|
|
||||||
|
taos_close(pConn);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// taos_options( TSDB_OPTION_TIMEZONE, "UTC+8");
|
||||||
|
int code = taos_options(TSDB_OPTION_TIMEZONE, "UTC+8");
|
||||||
|
ASSERT_TRUE(code == 0);
|
||||||
|
TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
|
||||||
|
ASSERT_NE(pConn, nullptr);
|
||||||
|
|
||||||
|
TAOS_RES* pRes = taos_query(pConn, "select * from db1.t1 where ts == '2023-09-16 01:00:00'");
|
||||||
|
ASSERT_EQ(taos_errno(pRes), TSDB_CODE_SUCCESS);
|
||||||
|
|
||||||
|
TAOS_ROW pRow = NULL;
|
||||||
|
TAOS_FIELD* pFields = taos_fetch_fields(pRes);
|
||||||
|
int32_t numOfFields = taos_num_fields(pRes);
|
||||||
|
|
||||||
|
int rows = 0;
|
||||||
|
char str[512] = {0};
|
||||||
|
while ((pRow = taos_fetch_row(pRes)) != NULL) {
|
||||||
|
rows++;
|
||||||
|
}
|
||||||
|
ASSERT_TRUE(rows == 1);
|
||||||
|
|
||||||
|
taos_free_result(pRes);
|
||||||
|
|
||||||
|
char sql[256] = {0};
|
||||||
|
(void)sprintf(sql, "insert into db1.t1 values('2023-09-16 17:00:01', 1)");
|
||||||
|
pRes = taos_query(pConn, sql);
|
||||||
|
ASSERT_EQ(taos_errno(pRes), TSDB_CODE_SUCCESS);
|
||||||
|
|
||||||
|
taos_free_result(pRes);
|
||||||
|
|
||||||
|
taos_close(pConn);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// taos_options( TSDB_OPTION_TIMEZONE, "UTC+0");
|
||||||
|
int code = taos_options(TSDB_OPTION_TIMEZONE, "UTC+0");
|
||||||
|
ASSERT_TRUE(code == 0);
|
||||||
|
TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
|
||||||
|
ASSERT_NE(pConn, nullptr);
|
||||||
|
|
||||||
|
TAOS_RES* pRes = taos_query(pConn, "select * from db1.t1 where ts == '2023-09-16 09:00:00'");
|
||||||
|
ASSERT_EQ(taos_errno(pRes), TSDB_CODE_SUCCESS);
|
||||||
|
|
||||||
|
TAOS_ROW pRow = NULL;
|
||||||
|
TAOS_FIELD* pFields = taos_fetch_fields(pRes);
|
||||||
|
int32_t numOfFields = taos_num_fields(pRes);
|
||||||
|
|
||||||
|
int rows = 0;
|
||||||
|
char str[512] = {0};
|
||||||
|
while ((pRow = taos_fetch_row(pRes)) != NULL) {
|
||||||
|
rows++;
|
||||||
|
}
|
||||||
|
ASSERT_TRUE(rows == 1);
|
||||||
|
taos_free_result(pRes);
|
||||||
|
|
||||||
|
{
|
||||||
|
TAOS_RES* pRes = taos_query(pConn, "select * from db1.t1 where ts == '2023-09-17 01:00:01'");
|
||||||
|
ASSERT_EQ(taos_errno(pRes), TSDB_CODE_SUCCESS);
|
||||||
|
|
||||||
|
TAOS_ROW pRow = NULL;
|
||||||
|
TAOS_FIELD* pFields = taos_fetch_fields(pRes);
|
||||||
|
int32_t numOfFields = taos_num_fields(pRes);
|
||||||
|
|
||||||
|
int rows = 0;
|
||||||
|
char str[512] = {0};
|
||||||
|
while ((pRow = taos_fetch_row(pRes)) != NULL) {
|
||||||
|
rows++;
|
||||||
|
}
|
||||||
|
ASSERT_TRUE(rows == 1);
|
||||||
|
taos_free_result(pRes);
|
||||||
|
}
|
||||||
|
|
||||||
|
taos_close(pConn);
|
||||||
|
}
|
||||||
|
}
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
|
|
|
@ -903,7 +903,7 @@ TEST(timezoneCase, localtime_performance_Test) {
|
||||||
timezone_t sp = tzalloc("Asia/Shanghai");
|
timezone_t sp = tzalloc("Asia/Shanghai");
|
||||||
ASSERT(sp);
|
ASSERT(sp);
|
||||||
|
|
||||||
int cnt = 10000000;
|
int cnt = 1000000;
|
||||||
int times = 10;
|
int times = 10;
|
||||||
int64_t time_localtime = 0;
|
int64_t time_localtime = 0;
|
||||||
int64_t time_localtime_rz = 0;
|
int64_t time_localtime_rz = 0;
|
||||||
|
|
|
@ -2077,8 +2077,7 @@ static int32_t taosCfgDynamicOptionsForClient(SConfig *pCfg, const char *name) {
|
||||||
int32_t code = TSDB_CODE_SUCCESS;
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
int32_t lino = 0;
|
int32_t lino = 0;
|
||||||
|
|
||||||
if (strcasecmp("locale", name) == 0 || strcasecmp("charset", name) == 0
|
if (strcasecmp("charset", name) == 0 || strcasecmp("timezone", name) == 0) {
|
||||||
|| strcasecmp("timezone", name) == 0) {
|
|
||||||
goto _out;
|
goto _out;
|
||||||
}
|
}
|
||||||
cfgLock(pCfg);
|
cfgLock(pCfg);
|
||||||
|
@ -2169,6 +2168,22 @@ static int32_t taosCfgDynamicOptionsForClient(SConfig *pCfg, const char *name) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 'l': {
|
||||||
|
if (strcasecmp("locale", name) == 0) {
|
||||||
|
SConfigItem *pLocaleItem = cfgGetItem(pCfg, "locale");
|
||||||
|
if (pLocaleItem == NULL) {
|
||||||
|
uError("failed to get locale from cfg");
|
||||||
|
code = TSDB_CODE_CFG_NOT_FOUND;
|
||||||
|
goto _out;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *locale = pLocaleItem->str;
|
||||||
|
TAOS_CHECK_GOTO(taosSetSystemLocale(locale), &lino, _out);
|
||||||
|
uInfo("locale set to '%s'", locale);
|
||||||
|
matched = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case 'm': {
|
case 'm': {
|
||||||
if (strcasecmp("metaCacheMaxSize", name) == 0) {
|
if (strcasecmp("metaCacheMaxSize", name) == 0) {
|
||||||
atomic_store_32(&tsMetaCacheMaxSize, pItem->i32);
|
atomic_store_32(&tsMetaCacheMaxSize, pItem->i32);
|
||||||
|
|
|
@ -230,8 +230,8 @@ static int32_t tSStructA_v1_decode(SCoder *pCoder, SStructA_v1 *pSAV1) {
|
||||||
|
|
||||||
if (tDecodeI32(pCoder, &pSAV1->A_a) < 0) return -1;
|
if (tDecodeI32(pCoder, &pSAV1->A_a) < 0) return -1;
|
||||||
if (tDecodeI64(pCoder, &pSAV1->A_b) < 0) return -1;
|
if (tDecodeI64(pCoder, &pSAV1->A_b) < 0) return -1;
|
||||||
const char *tstr;
|
const char *tstr = NULL;
|
||||||
uint64_t len;
|
uint64_t len = 0;
|
||||||
if (tDecodeCStrAndLen(pCoder, &tstr, &len) < 0) return -1;
|
if (tDecodeCStrAndLen(pCoder, &tstr, &len) < 0) return -1;
|
||||||
pSAV1->A_c = (char *)tCoderMalloc(pCoder, len + 1);
|
pSAV1->A_c = (char *)tCoderMalloc(pCoder, len + 1);
|
||||||
memcpy(pSAV1->A_c, tstr, len + 1);
|
memcpy(pSAV1->A_c, tstr, len + 1);
|
||||||
|
@ -269,8 +269,8 @@ static int32_t tSStructA_v2_decode(SCoder *pCoder, SStructA_v2 *pSAV2) {
|
||||||
|
|
||||||
if (tDecodeI32(pCoder, &pSAV2->A_a) < 0) return -1;
|
if (tDecodeI32(pCoder, &pSAV2->A_a) < 0) return -1;
|
||||||
if (tDecodeI64(pCoder, &pSAV2->A_b) < 0) return -1;
|
if (tDecodeI64(pCoder, &pSAV2->A_b) < 0) return -1;
|
||||||
const char *tstr;
|
const char *tstr = NULL;
|
||||||
uint64_t len;
|
uint64_t len = 0;
|
||||||
if (tDecodeCStrAndLen(pCoder, &tstr, &len) < 0) return -1;
|
if (tDecodeCStrAndLen(pCoder, &tstr, &len) < 0) return -1;
|
||||||
pSAV2->A_c = (char *)tCoderMalloc(pCoder, len + 1);
|
pSAV2->A_c = (char *)tCoderMalloc(pCoder, len + 1);
|
||||||
memcpy(pSAV2->A_c, tstr, len + 1);
|
memcpy(pSAV2->A_c, tstr, len + 1);
|
||||||
|
|
Loading…
Reference in New Issue